summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'desktop')
-rw-r--r--desktop/inc/app.hxx213
-rw-r--r--desktop/inc/deployment.hrc87
-rw-r--r--desktop/inc/makefile.mk47
-rw-r--r--desktop/inc/pch/precompiled_desktop.cxx29
-rw-r--r--desktop/inc/pch/precompiled_desktop.hxx40
-rw-r--r--desktop/os2/source/applauncher/launcher.cxx122
-rw-r--r--desktop/os2/source/applauncher/launcher.hxx9
-rw-r--r--desktop/os2/source/applauncher/makefile.mk121
-rw-r--r--desktop/os2/source/applauncher/officeloader.cxx3
-rw-r--r--desktop/os2/source/applauncher/quickstart.cxx3
-rw-r--r--desktop/os2/source/applauncher/sbase.cxx3
-rw-r--r--desktop/os2/source/applauncher/scalc.cxx3
-rw-r--r--desktop/os2/source/applauncher/sdraw.cxx3
-rw-r--r--desktop/os2/source/applauncher/simpress.cxx3
-rw-r--r--desktop/os2/source/applauncher/smath.cxx3
-rw-r--r--desktop/os2/source/applauncher/swriter.cxx3
-rw-r--r--desktop/prj/build.lst43
-rw-r--r--desktop/prj/d.lst145
-rw-r--r--desktop/qa/deployment_misc/makefile.mk54
-rw-r--r--desktop/qa/deployment_misc/test_dp_version.cxx90
-rw-r--r--desktop/qa/deployment_misc/version.map34
-rw-r--r--desktop/registry/data/org/openoffice/Office/Jobs.xcu74
-rw-r--r--desktop/registry/data/org/openoffice/Office/makefile.mk77
-rw-r--r--desktop/scripts/basis-link1
-rw-r--r--desktop/scripts/makefile.mk67
-rw-r--r--desktop/scripts/mozwrapper.sh8
-rw-r--r--desktop/scripts/odf-basis-link1
-rw-r--r--desktop/scripts/sbase.sh4
-rw-r--r--desktop/scripts/scalc.sh4
-rw-r--r--desktop/scripts/sdraw.sh4
-rw-r--r--desktop/scripts/simpress.sh4
-rw-r--r--desktop/scripts/smaster.sh4
-rw-r--r--desktop/scripts/smath.sh4
-rw-r--r--desktop/scripts/so-basis-link1
-rw-r--r--desktop/scripts/soffice.sh135
-rw-r--r--desktop/scripts/sweb.sh4
-rw-r--r--desktop/scripts/swriter.sh4
-rw-r--r--desktop/scripts/unoinfo.sh56
-rw-r--r--desktop/scripts/unopkg.sh76
-rw-r--r--desktop/scripts/ure-link1
-rw-r--r--desktop/source/app/app.cxx3045
-rw-r--r--desktop/source/app/appfirststart.cxx274
-rw-r--r--desktop/source/app/appinit.cxx484
-rw-r--r--desktop/source/app/appinit.hxx50
-rw-r--r--desktop/source/app/appsys.cxx69
-rw-r--r--desktop/source/app/appsys.hxx42
-rwxr-xr-xdesktop/source/app/check_ext_deps.cxx431
-rw-r--r--desktop/source/app/checkinstall.cxx118
-rw-r--r--desktop/source/app/checkinstall.hxx42
-rw-r--r--desktop/source/app/cmdlineargs.cxx900
-rw-r--r--desktop/source/app/cmdlineargs.hxx212
-rw-r--r--desktop/source/app/cmdlinehelp.cxx173
-rw-r--r--desktop/source/app/cmdlinehelp.hxx23
-rw-r--r--desktop/source/app/configinit.cxx303
-rw-r--r--desktop/source/app/configinit.hxx71
-rw-r--r--desktop/source/app/copyright_ascii_ooo.c10
-rw-r--r--desktop/source/app/copyright_ascii_sun.c8
-rw-r--r--desktop/source/app/desktop.hrc91
-rw-r--r--desktop/source/app/desktop.src234
-rw-r--r--desktop/source/app/desktopcontext.cxx63
-rw-r--r--desktop/source/app/desktopcontext.hxx50
-rw-r--r--desktop/source/app/desktopresid.cxx44
-rw-r--r--desktop/source/app/desktopresid.hxx44
-rw-r--r--desktop/source/app/dispatchwatcher.cxx514
-rw-r--r--desktop/source/app/dispatchwatcher.hxx124
-rw-r--r--desktop/source/app/exports.dxp3
-rw-r--r--desktop/source/app/langselect.cxx558
-rw-r--r--desktop/source/app/langselect.hxx74
-rw-r--r--desktop/source/app/lockfile.cxx256
-rw-r--r--desktop/source/app/lockfile.hxx99
-rw-r--r--desktop/source/app/lockfile2.cxx70
-rw-r--r--desktop/source/app/main.c36
-rw-r--r--desktop/source/app/makefile.mk115
-rw-r--r--desktop/source/app/officeipcthread.cxx996
-rw-r--r--desktop/source/app/officeipcthread.hxx165
-rw-r--r--desktop/source/app/omutexmember.hxx61
-rw-r--r--desktop/source/app/sofficemain.cxx52
-rw-r--r--desktop/source/app/sofficemain.h43
-rw-r--r--desktop/source/app/userinstall.cxx301
-rw-r--r--desktop/source/app/userinstall.hxx52
-rw-r--r--desktop/source/app/version.map34
-rw-r--r--desktop/source/deployment/dp_log.cxx211
-rw-r--r--desktop/source/deployment/dp_persmap.cxx253
-rw-r--r--desktop/source/deployment/dp_services.cxx136
-rw-r--r--desktop/source/deployment/dp_xml.cxx78
-rw-r--r--desktop/source/deployment/gui/descedit.cxx100
-rw-r--r--desktop/source/deployment/gui/descedit.hxx57
-rw-r--r--desktop/source/deployment/gui/dp_gui.h98
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui.hrc180
-rw-r--r--desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx74
-rw-r--r--desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx51
-rw-r--r--desktop/source/deployment/gui/dp_gui_backend.src131
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.cxx86
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.hxx68
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.src70
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_dialog.src345
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_dialog2.cxx1776
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_dialog2.hxx266
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.src252
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx1212
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx111
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_extlistbox.cxx1210
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_extlistbox.hxx270
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_service.cxx376
-rw-r--r--desktop/source/deployment/gui/dp_gui_shared.hxx62
-rw-r--r--desktop/source/deployment/gui/dp_gui_system.cxx59
-rw-r--r--desktop/source/deployment/gui/dp_gui_system.hxx37
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_theextmgr.cxx531
-rwxr-xr-xdesktop/source/deployment/gui/dp_gui_theextmgr.hxx131
-rw-r--r--desktop/source/deployment/gui/dp_gui_thread.cxx82
-rw-r--r--desktop/source/deployment/gui/dp_gui_thread.hxx84
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedata.hxx86
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.cxx1301
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.hxx233
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.src265
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx756
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx144
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.src203
-rw-r--r--desktop/source/deployment/gui/dp_gui_versionboxes.src76
-rw-r--r--desktop/source/deployment/gui/license_dialog.cxx330
-rw-r--r--desktop/source/deployment/gui/license_dialog.hxx71
-rw-r--r--desktop/source/deployment/gui/makefile.mk109
-rw-r--r--desktop/source/deployment/inc/db.hxx173
-rw-r--r--desktop/source/deployment/inc/dp_dependencies.hxx82
-rw-r--r--desktop/source/deployment/inc/dp_descriptioninfoset.hxx299
-rw-r--r--desktop/source/deployment/inc/dp_identifier.hxx92
-rw-r--r--desktop/source/deployment/inc/dp_interact.h150
-rw-r--r--desktop/source/deployment/inc/dp_misc.h179
-rw-r--r--desktop/source/deployment/inc/dp_misc.mk42
-rw-r--r--desktop/source/deployment/inc/dp_misc_api.hxx40
-rw-r--r--desktop/source/deployment/inc/dp_persmap.h65
-rw-r--r--desktop/source/deployment/inc/dp_platform.hxx56
-rw-r--r--desktop/source/deployment/inc/dp_resource.h67
-rw-r--r--desktop/source/deployment/inc/dp_ucb.h91
-rwxr-xr-xdesktop/source/deployment/inc/dp_update.hxx147
-rw-r--r--desktop/source/deployment/inc/dp_version.hxx48
-rw-r--r--desktop/source/deployment/inc/dp_xml.h57
-rw-r--r--desktop/source/deployment/makefile.mk112
-rw-r--r--desktop/source/deployment/manager/dp_activepackages.cxx206
-rw-r--r--desktop/source/deployment/manager/dp_activepackages.hxx99
-rw-r--r--desktop/source/deployment/manager/dp_commandenvironments.cxx286
-rw-r--r--desktop/source/deployment/manager/dp_commandenvironments.hxx160
-rw-r--r--desktop/source/deployment/manager/dp_extensionmanager.cxx1361
-rw-r--r--desktop/source/deployment/manager/dp_extensionmanager.hxx307
-rw-r--r--desktop/source/deployment/manager/dp_informationprovider.cxx393
-rw-r--r--desktop/source/deployment/manager/dp_manager.cxx1673
-rw-r--r--desktop/source/deployment/manager/dp_manager.h294
-rw-r--r--desktop/source/deployment/manager/dp_manager.hrc39
-rw-r--r--desktop/source/deployment/manager/dp_manager.src59
-rw-r--r--desktop/source/deployment/manager/dp_managerfac.cxx200
-rw-r--r--desktop/source/deployment/manager/dp_properties.cxx169
-rw-r--r--desktop/source/deployment/manager/dp_properties.hxx81
-rw-r--r--desktop/source/deployment/manager/makefile.mk55
-rw-r--r--desktop/source/deployment/misc/db.cxx272
-rw-r--r--desktop/source/deployment/misc/dp_dependencies.cxx171
-rw-r--r--desktop/source/deployment/misc/dp_descriptioninfoset.cxx864
-rw-r--r--desktop/source/deployment/misc/dp_identifier.cxx73
-rw-r--r--desktop/source/deployment/misc/dp_interact.cxx185
-rw-r--r--desktop/source/deployment/misc/dp_misc.cxx625
-rw-r--r--desktop/source/deployment/misc/dp_misc.hrc33
-rw-r--r--desktop/source/deployment/misc/dp_misc.src40
-rw-r--r--desktop/source/deployment/misc/dp_platform.cxx232
-rw-r--r--desktop/source/deployment/misc/dp_resource.cxx233
-rw-r--r--desktop/source/deployment/misc/dp_ucb.cxx320
-rwxr-xr-xdesktop/source/deployment/misc/dp_update.cxx397
-rw-r--r--desktop/source/deployment/misc/dp_version.cxx74
-rw-r--r--desktop/source/deployment/misc/makefile.mk95
-rw-r--r--desktop/source/deployment/registry/component/dp_compbackenddb.cxx156
-rw-r--r--desktop/source/deployment/registry/component/dp_compbackenddb.hxx120
-rw-r--r--desktop/source/deployment/registry/component/dp_component.cxx1586
-rw-r--r--desktop/source/deployment/registry/component/dp_component.hrc39
-rw-r--r--desktop/source/deployment/registry/component/dp_component.src54
-rw-r--r--desktop/source/deployment/registry/component/makefile.mk48
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.cxx783
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.hrc36
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.src39
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx186
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx96
-rw-r--r--desktop/source/deployment/registry/configuration/makefile.mk52
-rw-r--r--desktop/source/deployment/registry/dp_backend.cxx807
-rw-r--r--desktop/source/deployment/registry/dp_backenddb.cxx649
-rw-r--r--desktop/source/deployment/registry/dp_registry.cxx555
-rw-r--r--desktop/source/deployment/registry/dp_registry.src59
-rw-r--r--desktop/source/deployment/registry/executable/dp_executable.cxx331
-rw-r--r--desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx84
-rw-r--r--desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx79
-rw-r--r--desktop/source/deployment/registry/executable/makefile.mk44
-rw-r--r--desktop/source/deployment/registry/help/dp_help.cxx598
-rw-r--r--desktop/source/deployment/registry/help/dp_help.hrc39
-rw-r--r--desktop/source/deployment/registry/help/dp_help.src44
-rw-r--r--desktop/source/deployment/registry/help/dp_helpbackenddb.cxx178
-rw-r--r--desktop/source/deployment/registry/help/dp_helpbackenddb.hxx92
-rw-r--r--desktop/source/deployment/registry/help/makefile.mk52
-rw-r--r--desktop/source/deployment/registry/inc/dp_backend.h379
-rw-r--r--desktop/source/deployment/registry/inc/dp_backenddb.hxx170
-rw-r--r--desktop/source/deployment/registry/inc/dp_registry.hrc40
-rw-r--r--desktop/source/deployment/registry/makefile.mk49
-rw-r--r--desktop/source/deployment/registry/package/dp_extbackenddb.cxx135
-rw-r--r--desktop/source/deployment/registry/package/dp_extbackenddb.hxx96
-rw-r--r--desktop/source/deployment/registry/package/dp_package.cxx1655
-rw-r--r--desktop/source/deployment/registry/package/dp_package.hrc35
-rw-r--r--desktop/source/deployment/registry/package/dp_package.src34
-rw-r--r--desktop/source/deployment/registry/package/makefile.mk48
-rw-r--r--desktop/source/deployment/registry/script/dp_lib_container.cxx73
-rw-r--r--desktop/source/deployment/registry/script/dp_lib_container.h57
-rw-r--r--desktop/source/deployment/registry/script/dp_script.cxx499
-rw-r--r--desktop/source/deployment/registry/script/dp_script.hrc39
-rw-r--r--desktop/source/deployment/registry/script/dp_script.src49
-rw-r--r--desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx88
-rw-r--r--desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx76
-rw-r--r--desktop/source/deployment/registry/script/makefile.mk49
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx130
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx89
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.cxx408
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.hrc35
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.src35
-rw-r--r--desktop/source/deployment/registry/sfwk/makefile.mk48
-rw-r--r--desktop/source/deployment/target.pmk36
-rw-r--r--desktop/source/deployment/unopkg/makefile.mk48
-rw-r--r--desktop/source/deployment/unopkg/unopkg.src84
-rw-r--r--desktop/source/inc/exithelper.hxx68
-rw-r--r--desktop/source/inc/helpid.hrc78
-rw-r--r--desktop/source/migration/cfgfilter.cxx333
-rw-r--r--desktop/source/migration/cfgfilter.hxx173
-rw-r--r--desktop/source/migration/makefile.mk59
-rwxr-xr-xdesktop/source/migration/migration.cxx1365
-rw-r--r--desktop/source/migration/migration.hxx46
-rw-r--r--desktop/source/migration/migration_impl.hxx252
-rw-r--r--desktop/source/migration/pages.cxx673
-rw-r--r--desktop/source/migration/pages.hxx214
-rw-r--r--desktop/source/migration/services/autocorrmigration.cxx285
-rw-r--r--desktop/source/migration/services/autocorrmigration.hxx102
-rw-r--r--desktop/source/migration/services/basicmigration.cxx274
-rw-r--r--desktop/source/migration/services/basicmigration.hxx102
-rw-r--r--desktop/source/migration/services/cexports.cxx80
-rwxr-xr-xdesktop/source/migration/services/cexportsoo3.cxx71
-rw-r--r--desktop/source/migration/services/cppumaker.mk36
-rw-r--r--desktop/source/migration/services/jvmfwk.cxx529
-rw-r--r--desktop/source/migration/services/jvmfwk.hxx50
-rw-r--r--desktop/source/migration/services/makefile.mk119
-rw-r--r--desktop/source/migration/services/migrationoo2.xml78
-rwxr-xr-xdesktop/source/migration/services/migrationoo3.map8
-rw-r--r--desktop/source/migration/services/misc.hxx48
-rw-r--r--desktop/source/migration/services/oo3extensionmigration.cxx586
-rw-r--r--desktop/source/migration/services/oo3extensionmigration.hxx163
-rwxr-xr-xdesktop/source/migration/services/wordbookmigration.cxx322
-rwxr-xr-xdesktop/source/migration/services/wordbookmigration.hxx102
-rw-r--r--desktop/source/migration/wizard.cxx654
-rw-r--r--desktop/source/migration/wizard.hrc99
-rw-r--r--desktop/source/migration/wizard.hxx106
-rw-r--r--desktop/source/migration/wizard.src424
-rw-r--r--desktop/source/offacc/acceptor.cxx367
-rw-r--r--desktop/source/offacc/acceptor.hxx129
-rw-r--r--desktop/source/offacc/makefile.mk62
-rw-r--r--desktop/source/pagein/file_image.h78
-rw-r--r--desktop/source/pagein/file_image_unx.c150
-rw-r--r--desktop/source/pagein/makefile.mk165
-rw-r--r--desktop/source/pagein/pagein.c149
-rw-r--r--desktop/source/pkgchk/unopkg/makefile.mk104
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_app.cxx658
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx433
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_main.c36
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_main.h43
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_misc.cxx532
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_shared.h182
-rw-r--r--desktop/source/pkgchk/unopkg/version.map34
-rw-r--r--desktop/source/registration/com/sun/star/registration/Registration.java339
-rw-r--r--desktop/source/registration/com/sun/star/registration/makefile.mk55
-rw-r--r--desktop/source/registration/com/sun/star/registration/manifest2
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java201
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/Installer.java943
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java323
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/RegistrationData.java531
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java440
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/Registry.java554
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/ServiceTag.java636
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java64
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java421
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/SunConnection.java292
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java376
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java436
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java55
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/Util.java293
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java232
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/makefile.mk79
-rw-r--r--desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd366
-rw-r--r--desktop/source/so_comp/evaluation.cxx205
-rw-r--r--desktop/source/so_comp/evaluation.hxx92
-rw-r--r--desktop/source/so_comp/makefile.mk77
-rw-r--r--desktop/source/so_comp/oemjob.cxx280
-rw-r--r--desktop/source/so_comp/oemjob.hxx92
-rw-r--r--desktop/source/so_comp/services.cxx160
-rwxr-xr-xdesktop/source/splash/firststart.cxx156
-rwxr-xr-xdesktop/source/splash/firststart.hxx90
-rw-r--r--desktop/source/splash/makefile.mk89
-rwxr-xr-xdesktop/source/splash/services_spl.cxx157
-rw-r--r--desktop/source/splash/splash.cxx715
-rw-r--r--desktop/source/splash/splash.hxx136
-rw-r--r--desktop/test/deployment/boxt/Addons.xcu50
-rw-r--r--desktop/test/deployment/boxt/ProtocolHandler.xcu38
-rw-r--r--desktop/test/deployment/boxt/boxt.cxx235
-rw-r--r--desktop/test/deployment/boxt/description.xml39
-rw-r--r--desktop/test/deployment/boxt/makefile.mk70
-rw-r--r--desktop/test/deployment/boxt/manifest.xml37
-rw-r--r--desktop/test/deployment/dependencies/broken-dependency.oxtbin0 -> 1655 bytes
-rw-r--r--desktop/test/deployment/dependencies/double-dependencies.oxtbin0 -> 1651 bytes
-rw-r--r--desktop/test/deployment/dependencies/empty-dependencies.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/dependencies/funny-dependency.oxtbin0 -> 1730 bytes
-rw-r--r--desktop/test/deployment/dependencies/license-dependency.oxtbin0 -> 1891 bytes
-rw-r--r--desktop/test/deployment/dependencies/many-dependencies.oxtbin0 -> 1702 bytes
-rw-r--r--desktop/test/deployment/dependencies/minattr22.oxtbin0 -> 1690 bytes
-rw-r--r--desktop/test/deployment/dependencies/minattr23.oxtbin0 -> 1690 bytes
-rw-r--r--desktop/test/deployment/dependencies/minattr24.oxtbin0 -> 1690 bytes
-rw-r--r--desktop/test/deployment/dependencies/no-dependencies.oxtbin0 -> 1611 bytes
-rw-r--r--desktop/test/deployment/dependencies/no-description.oxtbin0 -> 1360 bytes
-rw-r--r--desktop/test/deployment/dependencies/readme.txt82
-rw-r--r--desktop/test/deployment/dependencies/unknown-dependency.oxtbin0 -> 1633 bytes
-rw-r--r--desktop/test/deployment/dependencies/version10000.oxtbin0 -> 1668 bytes
-rw-r--r--desktop/test/deployment/dependencies/version21.oxtbin0 -> 1666 bytes
-rw-r--r--desktop/test/deployment/dependencies/version21ns.oxtbin0 -> 1661 bytes
-rw-r--r--desktop/test/deployment/dependencies/version21other.oxtbin0 -> 1679 bytes
-rw-r--r--desktop/test/deployment/dependencies/version22.oxtbin0 -> 1666 bytes
-rw-r--r--desktop/test/deployment/dependencies/version23.oxtbin0 -> 1666 bytes
-rw-r--r--desktop/test/deployment/dependencies/versionempty.oxtbin0 -> 1675 bytes
-rw-r--r--desktop/test/deployment/dependencies/versionnone.oxtbin0 -> 1674 bytes
-rw-r--r--desktop/test/deployment/description/desc1.oxtbin0 -> 2096 bytes
-rw-r--r--desktop/test/deployment/description/desc2.oxtbin0 -> 2091 bytes
-rw-r--r--desktop/test/deployment/description/desc3.oxtbin0 -> 2070 bytes
-rw-r--r--desktop/test/deployment/description/desc4.oxtbin0 -> 2061 bytes
-rw-r--r--desktop/test/deployment/description/desc5.oxtbin0 -> 2041 bytes
-rwxr-xr-xdesktop/test/deployment/description/readme.txt23
-rw-r--r--desktop/test/deployment/display_name/name1.oxtbin0 -> 704 bytes
-rw-r--r--desktop/test/deployment/display_name/name2.oxtbin0 -> 699 bytes
-rw-r--r--desktop/test/deployment/display_name/name3.oxtbin0 -> 681 bytes
-rw-r--r--desktop/test/deployment/display_name/name4.oxtbin0 -> 675 bytes
-rw-r--r--desktop/test/deployment/display_name/name5.oxtbin0 -> 654 bytes
-rw-r--r--desktop/test/deployment/display_name/readme.txt26
-rw-r--r--desktop/test/deployment/executable_content/build/hello.c45
-rw-r--r--desktop/test/deployment/executable_content/build/makefile.mk51
-rw-r--r--desktop/test/deployment/executable_content/build/readme.txt2
-rw-r--r--desktop/test/deployment/executable_content/hello.oxtbin0 -> 35048 bytes
-rw-r--r--desktop/test/deployment/executable_content/readme.txt12
-rw-r--r--desktop/test/deployment/identifier/explicit/identifier.oxtbin0 -> 1660 bytes
-rw-r--r--desktop/test/deployment/identifier/legacy/identifier.oxtbin0 -> 1634 bytes
-rw-r--r--desktop/test/deployment/identifier/readme.txt33
-rw-r--r--desktop/test/deployment/locationtest/LocationTest.idl40
-rw-r--r--desktop/test/deployment/locationtest/LocationTest.java165
-rw-r--r--desktop/test/deployment/locationtest/LocationTest.odtbin0 -> 7681 bytes
-rw-r--r--desktop/test/deployment/locationtest/MANIFEST.MF2
-rw-r--r--desktop/test/deployment/locationtest/delzip1
-rw-r--r--desktop/test/deployment/locationtest/description.xml13
-rw-r--r--desktop/test/deployment/locationtest/makefile.mk84
-rw-r--r--desktop/test/deployment/locationtest/manifest.xml5
-rw-r--r--desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/MANIFEST.MF2
-rw-r--r--desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/OptionsEventHandler.java449
-rw-r--r--desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/makefile.mk53
-rw-r--r--desktop/test/deployment/options/leaf1.oxtbin0 -> 8308 bytes
-rw-r--r--desktop/test/deployment/options/leaf1mod.oxtbin0 -> 8310 bytes
-rw-r--r--desktop/test/deployment/options/leaf2.oxtbin0 -> 8338 bytes
-rw-r--r--desktop/test/deployment/options/leaves1.oxtbin0 -> 21158 bytes
-rw-r--r--desktop/test/deployment/options/leaves2.oxtbin0 -> 21153 bytes
-rw-r--r--desktop/test/deployment/options/leaves3.oxtbin0 -> 21080 bytes
-rw-r--r--desktop/test/deployment/options/modules1.oxtbin0 -> 24317 bytes
-rw-r--r--desktop/test/deployment/options/modules2.oxtbin0 -> 24196 bytes
-rw-r--r--desktop/test/deployment/options/nodes1.oxtbin0 -> 1882 bytes
-rw-r--r--desktop/test/deployment/options/nodes2.oxtbin0 -> 24287 bytes
-rw-r--r--desktop/test/deployment/options/nodes3.oxtbin0 -> 24315 bytes
-rw-r--r--desktop/test/deployment/options/nodes4.oxtbin0 -> 24318 bytes
-rw-r--r--desktop/test/deployment/options/nodes5.oxtbin0 -> 12616 bytes
-rw-r--r--desktop/test/deployment/options/readme.txt200
-rw-r--r--desktop/test/deployment/simple_license/BadDesc.oxtbin0 -> 9663 bytes
-rw-r--r--desktop/test/deployment/simple_license/BadNamespace.oxtbin0 -> 9736 bytes
-rw-r--r--desktop/test/deployment/simple_license/BadRoot.oxtbin0 -> 9073 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale1.oxtbin0 -> 2126 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale2.oxtbin0 -> 2121 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale3.oxtbin0 -> 2101 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale4.oxtbin0 -> 2094 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale5.oxtbin0 -> 2072 bytes
-rw-r--r--desktop/test/deployment/simple_license/Locale6.oxtbin0 -> 1397 bytes
-rw-r--r--desktop/test/deployment/simple_license/LongLic.oxtbin0 -> 9521 bytes
-rw-r--r--desktop/test/deployment/simple_license/MissingLic.oxtbin0 -> 9214 bytes
-rw-r--r--desktop/test/deployment/simple_license/MissingLicRef.oxtbin0 -> 9332 bytes
-rw-r--r--desktop/test/deployment/simple_license/NoDefLang.oxtbin0 -> 9360 bytes
-rw-r--r--desktop/test/deployment/simple_license/NoDesc.oxtbin0 -> 8722 bytes
-rw-r--r--desktop/test/deployment/simple_license/NoLang.oxtbin0 -> 9217 bytes
-rw-r--r--desktop/test/deployment/simple_license/Prefix.oxtbin0 -> 1112 bytes
-rw-r--r--desktop/test/deployment/simple_license/ShortLicense.oxtbin0 -> 9381 bytes
-rw-r--r--desktop/test/deployment/simple_license/ShortLicenseShared.oxtbin0 -> 9382 bytes
-rwxr-xr-xdesktop/test/deployment/simple_license/suppress_license.oxtbin0 -> 2143 bytes
-rw-r--r--desktop/test/deployment/simple_license/tests_simple_license.odtbin0 -> 16629 bytes
-rw-r--r--desktop/test/deployment/update/changing_display_name/change1.oxtbin0 -> 1650 bytes
-rw-r--r--desktop/test/deployment/update/changing_display_name/change1_mod.oxtbin0 -> 1673 bytes
-rw-r--r--desktop/test/deployment/update/changing_display_name/readme.txt13
-rw-r--r--desktop/test/deployment/update/changing_display_name/update1/change1.oxtbin0 -> 1675 bytes
-rw-r--r--desktop/test/deployment/update/changing_display_name/update1/change1.update.xml10
-rw-r--r--desktop/test/deployment/update/changing_display_name/update2/change1.oxtbin0 -> 1687 bytes
-rw-r--r--desktop/test/deployment/update/changing_display_name/update2/change1.update.xml10
-rw-r--r--desktop/test/deployment/update/default_url/default1.oxtbin0 -> 1544 bytes
-rw-r--r--desktop/test/deployment/update/default_url/default2.oxtbin0 -> 1544 bytes
-rw-r--r--desktop/test/deployment/update/default_url/readme.txt9
-rw-r--r--desktop/test/deployment/update/default_url/update/default1.oxtbin0 -> 1546 bytes
-rw-r--r--desktop/test/deployment/update/default_url/update/default1.update.xml10
-rw-r--r--desktop/test/deployment/update/default_url/update/default2.oxtbin0 -> 1546 bytes
-rw-r--r--desktop/test/deployment/update/default_url/update/default2.update.xml10
-rw-r--r--desktop/test/deployment/update/default_url/update/feed1.xml33
-rw-r--r--desktop/test/deployment/update/defect/fail1.oxtbin0 -> 2189 bytes
-rw-r--r--desktop/test/deployment/update/defect/fail2.oxtbin0 -> 2188 bytes
-rw-r--r--desktop/test/deployment/update/defect/fail3.oxtbin0 -> 2188 bytes
-rw-r--r--desktop/test/deployment/update/defect/fail4.oxtbin0 -> 2189 bytes
-rw-r--r--desktop/test/deployment/update/defect/info1.oxtbin0 -> 2188 bytes
-rw-r--r--desktop/test/deployment/update/defect/info2.oxtbin0 -> 2187 bytes
-rw-r--r--desktop/test/deployment/update/defect/info3.oxtbin0 -> 2187 bytes
-rw-r--r--desktop/test/deployment/update/defect/readme.txt15
-rw-r--r--desktop/test/deployment/update/defect/update/fail1.oxtbin0 -> 2193 bytes
-rw-r--r--desktop/test/deployment/update/defect/update/fail1.update.xml10
-rw-r--r--desktop/test/deployment/update/defect/update/fail2.oxtbin0 -> 2436 bytes
-rw-r--r--desktop/test/deployment/update/defect/update/fail2.update.xml10
-rw-r--r--desktop/test/deployment/update/defect/update/fail3.oxtbin0 -> 2396 bytes
-rw-r--r--desktop/test/deployment/update/defect/update/fail3.update.xml10
-rw-r--r--desktop/test/deployment/update/defect/update/fail4.oxt0
-rw-r--r--desktop/test/deployment/update/defect/update/fail4.update.xml10
-rw-r--r--desktop/test/deployment/update/defect/update/info1.update.xml0
-rw-r--r--desktop/test/deployment/update/defect/update/info2.update.xml1
-rw-r--r--desktop/test/deployment/update/defect/update/info3.oxtbin0 -> 2189 bytes
-rw-r--r--desktop/test/deployment/update/defect/update/info3.update.xml10
-rw-r--r--desktop/test/deployment/update/dependencies/publisher_en.html9
-rw-r--r--desktop/test/deployment/update/dependencies/readme.txt32
-rw-r--r--desktop/test/deployment/update/dependencies/release-notes_en.html8
-rw-r--r--desktop/test/deployment/update/dependencies/update-dependencies.oxtbin0 -> 1751 bytes
-rw-r--r--desktop/test/deployment/update/dependencies/update/update-dependencies.update.xml71
-rw-r--r--desktop/test/deployment/update/license/lic1.oxtbin0 -> 3608 bytes
-rw-r--r--desktop/test/deployment/update/license/lic2.oxtbin0 -> 3625 bytes
-rw-r--r--desktop/test/deployment/update/license/lic3.oxtbin0 -> 3624 bytes
-rw-r--r--desktop/test/deployment/update/license/readme.txt9
-rw-r--r--desktop/test/deployment/update/license/update/lic1.oxtbin0 -> 3610 bytes
-rw-r--r--desktop/test/deployment/update/license/update/lic1.update.xml10
-rw-r--r--desktop/test/deployment/update/license/update/lic2.oxtbin0 -> 3627 bytes
-rw-r--r--desktop/test/deployment/update/license/update/lic2.update.xml10
-rw-r--r--desktop/test/deployment/update/license/update/lic3.oxtbin0 -> 3626 bytes
-rw-r--r--desktop/test/deployment/update/license/update/lic3.update.xml10
-rw-r--r--desktop/test/deployment/update/platform/all1.oxtbin0 -> 692 bytes
-rw-r--r--desktop/test/deployment/update/platform/all2.oxtbin0 -> 702 bytes
-rw-r--r--desktop/test/deployment/update/platform/all3.oxtbin0 -> 297 bytes
-rw-r--r--desktop/test/deployment/update/platform/freebsd_x86.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/freebsd_x86_64.oxtbin0 -> 711 bytes
-rw-r--r--desktop/test/deployment/update/platform/invalid1.oxtbin0 -> 653 bytes
-rw-r--r--desktop/test/deployment/update/platform/invalid2.oxtbin0 -> 653 bytes
-rw-r--r--desktop/test/deployment/update/platform/invalid3.oxtbin0 -> 655 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_arm_eabi.oxtbin0 -> 709 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_arm_oabi.oxtbin0 -> 710 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_ia64.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_mips_eb.oxtbin0 -> 709 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_mips_el.oxtbin0 -> 708 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_powerpc.oxtbin0 -> 708 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_powerpc64.oxtbin0 -> 710 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_s390.oxtbin0 -> 705 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_s390x.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_sparc.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_x86.oxtbin0 -> 705 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_x86_64.oxtbin0 -> 708 bytes
-rw-r--r--desktop/test/deployment/update/platform/macosx_powerpc.oxtbin0 -> 710 bytes
-rw-r--r--desktop/test/deployment/update/platform/macosx_x86.oxtbin0 -> 707 bytes
-rw-r--r--desktop/test/deployment/update/platform/mul1.oxtbin0 -> 952 bytes
-rw-r--r--desktop/test/deployment/update/platform/os2_x86.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/readme.txt49
-rw-r--r--desktop/test/deployment/update/platform/solaris_sparc.oxtbin0 -> 709 bytes
-rw-r--r--desktop/test/deployment/update/platform/solaris_x86.oxtbin0 -> 706 bytes
-rw-r--r--desktop/test/deployment/update/platform/windows_x86.oxtbin0 -> 707 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub1.oxtbin0 -> 1882 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub10.oxtbin0 -> 1742 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub11.oxtbin0 -> 1601 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub2.oxtbin0 -> 1866 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub3.oxtbin0 -> 1829 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub4.oxtbin0 -> 1812 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub5.oxtbin0 -> 1769 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub6.oxtbin0 -> 1814 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub7.oxtbin0 -> 1769 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub8.oxtbin0 -> 1853 bytes
-rw-r--r--desktop/test/deployment/update/publisher/pub9.oxtbin0 -> 1779 bytes
-rw-r--r--desktop/test/deployment/update/publisher/publisher_de-DE-altmark.html9
-rw-r--r--desktop/test/deployment/update/publisher/publisher_de-DE.html9
-rw-r--r--desktop/test/deployment/update/publisher/publisher_de.html9
-rw-r--r--desktop/test/deployment/update/publisher/publisher_en-GB.html9
-rw-r--r--desktop/test/deployment/update/publisher/publisher_en-US-region1.html9
-rw-r--r--desktop/test/deployment/update/publisher/publisher_en-US-region2.html9
-rw-r--r--desktop/test/deployment/update/publisher/publisher_en-US.html9
-rw-r--r--desktop/test/deployment/update/publisher/publisher_en-region3.html9
-rw-r--r--desktop/test/deployment/update/publisher/publisher_en.html9
-rw-r--r--desktop/test/deployment/update/publisher/readme.txt212
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_de-DE-altmark.html8
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_de-DE.html8
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_de.html8
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_en-GB.html8
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_en-US-region1.html8
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_en-US-region2.html8
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_en-US.html8
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_en-region3.html8
-rw-r--r--desktop/test/deployment/update/publisher/release-notes_en.html8
-rw-r--r--desktop/test/deployment/update/publisher/update/pub1.oxtbin0 -> 1885 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub1.update.xml36
-rw-r--r--desktop/test/deployment/update/publisher/update/pub10.oxtbin0 -> 1744 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub11.oxtbin0 -> 1603 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub2.oxtbin0 -> 1871 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub2.update.xml34
-rw-r--r--desktop/test/deployment/update/publisher/update/pub3.oxtbin0 -> 1833 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub3.update.xml30
-rw-r--r--desktop/test/deployment/update/publisher/update/pub4.oxtbin0 -> 1815 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub4.update.xml28
-rw-r--r--desktop/test/deployment/update/publisher/update/pub5.oxtbin0 -> 1774 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub5.update.xml24
-rw-r--r--desktop/test/deployment/update/publisher/update/pub6.oxtbin0 -> 1816 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub6.update.xml24
-rw-r--r--desktop/test/deployment/update/publisher/update/pub7.oxtbin0 -> 1771 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub7.update.xml24
-rw-r--r--desktop/test/deployment/update/publisher/update/pub8.oxtbin0 -> 1855 bytes
-rw-r--r--desktop/test/deployment/update/publisher/update/pub9.oxtbin0 -> 1781 bytes
-rw-r--r--desktop/test/deployment/update/readme.txt68
-rw-r--r--desktop/test/deployment/update/simple/plain1.oxtbin0 -> 1642 bytes
-rw-r--r--desktop/test/deployment/update/simple/plain2.oxtbin0 -> 1643 bytes
-rw-r--r--desktop/test/deployment/update/simple/plain3.oxtbin0 -> 1643 bytes
-rw-r--r--desktop/test/deployment/update/simple/readme.txt31
-rw-r--r--desktop/test/deployment/update/simple/update/plain1.oxtbin0 -> 1645 bytes
-rw-r--r--desktop/test/deployment/update/simple/update/plain1.update.xml10
-rw-r--r--desktop/test/deployment/update/simple/update/plain2.oxtbin0 -> 1645 bytes
-rw-r--r--desktop/test/deployment/update/simple/update/plain2.update.xml10
-rw-r--r--desktop/test/deployment/update/simple/update/plain3.oxtbin0 -> 1645 bytes
-rw-r--r--desktop/test/deployment/update/simple/update/plain3.update.xml10
-rw-r--r--desktop/test/deployment/update/updatefeed/feed1.oxtbin0 -> 2184 bytes
-rw-r--r--desktop/test/deployment/update/updatefeed/feed2.oxtbin0 -> 2184 bytes
-rw-r--r--desktop/test/deployment/update/updatefeed/update/feed1.oxtbin0 -> 2184 bytes
-rw-r--r--desktop/test/deployment/update/updatefeed/update/feed1.update.xml10
-rw-r--r--desktop/test/deployment/update/updatefeed/update/feed1.xml33
-rw-r--r--desktop/test/deployment/update/updatefeed/update/feed2.oxtbin0 -> 2184 bytes
-rw-r--r--desktop/test/deployment/update/updatefeed/update/feed2.update.xml10
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/MANIFEST.MF2
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/TestExtension.idl40
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/TestExtension.java165
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/delzip1
-rw-r--r--desktop/test/deployment/update/updateinfocreation/build/description.xml13
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/makefile.mk88
-rwxr-xr-xdesktop/test/deployment/update/updateinfocreation/build/manifest.xml5
-rw-r--r--desktop/test/deployment/update/updateinfocreation/readme.txt38
-rw-r--r--desktop/test/deployment/update/updateinfocreation/update/updateinfo.oxtbin0 -> 4295 bytes
-rw-r--r--desktop/test/deployment/update/updateinfocreation/updateinfo.oxtbin0 -> 4295 bytes
-rw-r--r--desktop/test/deployment/update/website_update/readme.txt133
-rw-r--r--desktop/test/deployment/update/website_update/update/web1.oxtbin0 -> 1695 bytes
-rw-r--r--desktop/test/deployment/update/website_update/update/web1.update.xml20
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_de-DE-altmark.html18
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_de-DE.html18
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_de.html19
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_en-GB.html19
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_en-US-region1.html19
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_en-US-region2.html19
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_en-US.html20
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_en-region3.html19
-rw-r--r--desktop/test/deployment/update/website_update/update/web1_en.html19
-rw-r--r--desktop/test/deployment/update/website_update/update/web2.oxtbin0 -> 1695 bytes
-rw-r--r--desktop/test/deployment/update/website_update/update/web2.update.xml19
-rw-r--r--desktop/test/deployment/update/website_update/update/web3.oxtbin0 -> 1695 bytes
-rw-r--r--desktop/test/deployment/update/website_update/update/web3.update.xml17
-rw-r--r--desktop/test/deployment/update/website_update/update/web4.oxtbin0 -> 1695 bytes
-rw-r--r--desktop/test/deployment/update/website_update/update/web4.update.xml16
-rw-r--r--desktop/test/deployment/update/website_update/update/web5.oxtbin0 -> 1695 bytes
-rw-r--r--desktop/test/deployment/update/website_update/update/web5.update.xml14
-rw-r--r--desktop/test/deployment/update/website_update/update/web6.oxtbin0 -> 1640 bytes
-rw-r--r--desktop/test/deployment/update/website_update/update/web6/description.xml11
-rw-r--r--desktop/test/deployment/update/website_update/update/web6/readme.txt5
-rw-r--r--desktop/test/deployment/update/website_update/update/web7.oxtbin0 -> 1897 bytes
-rw-r--r--desktop/test/deployment/update/website_update/update/web7/description.xml36
-rw-r--r--desktop/test/deployment/update/website_update/update/web7/readme.txt5
-rw-r--r--desktop/test/deployment/update/website_update/web1.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web2.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web3.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web4.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web5.oxtbin0 -> 1693 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web6.oxtbin0 -> 1638 bytes
-rw-r--r--desktop/test/deployment/update/website_update/web7.oxtbin0 -> 1894 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/readme.txt18
-rw-r--r--desktop/test/deployment/update/wrong_url/update/url1.oxtbin0 -> 2192 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/update/url1.update.xml11
-rw-r--r--desktop/test/deployment/update/wrong_url/update/url2.oxtbin0 -> 2206 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/update/url2.update.xml10
-rw-r--r--desktop/test/deployment/update/wrong_url/update/wrongdownload1.update.xml11
-rw-r--r--desktop/test/deployment/update/wrong_url/update/wrongdownload2.update.xml11
-rw-r--r--desktop/test/deployment/update/wrong_url/update/wrongdownload3.update.xml11
-rw-r--r--desktop/test/deployment/update/wrong_url/url1.oxtbin0 -> 2190 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/url2.oxtbin0 -> 2205 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/url3.oxtbin0 -> 2204 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/wrongdownload1.oxtbin0 -> 2194 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/wrongdownload2.oxtbin0 -> 2194 bytes
-rw-r--r--desktop/test/deployment/update/wrong_url/wrongdownload3.oxtbin0 -> 2194 bytes
-rw-r--r--desktop/test/deployment/version/readme.txt85
-rw-r--r--desktop/test/deployment/version/version_0.0/dependency.oxtbin0 -> 1657 bytes
-rw-r--r--desktop/test/deployment/version/version_0.0/license.oxtbin0 -> 1733 bytes
-rw-r--r--desktop/test/deployment/version/version_0.0/plain.oxtbin0 -> 1618 bytes
-rw-r--r--desktop/test/deployment/version/version_1.02.4.7.0/dependency.oxtbin0 -> 1662 bytes
-rw-r--r--desktop/test/deployment/version/version_1.02.4.7.0/license.oxtbin0 -> 1738 bytes
-rw-r--r--desktop/test/deployment/version/version_1.02.4.7.0/plain.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.15.3/dependency.oxtbin0 -> 1662 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.15.3/license.oxtbin0 -> 1738 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.15.3/plain.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.3/dependency.oxtbin0 -> 1659 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.3/license.oxtbin0 -> 1735 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.3/plain.oxtbin0 -> 1620 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.4.7/dependency.oxtbin0 -> 1661 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.4.7/license.oxtbin0 -> 1737 bytes
-rw-r--r--desktop/test/deployment/version/version_1.2.4.7/plain.oxtbin0 -> 1623 bytes
-rw-r--r--desktop/test/deployment/version/version_badelement/dependency.oxtbin0 -> 1654 bytes
-rw-r--r--desktop/test/deployment/version/version_badelement/license.oxtbin0 -> 1731 bytes
-rw-r--r--desktop/test/deployment/version/version_badelement/plain.oxtbin0 -> 1616 bytes
-rw-r--r--desktop/test/deployment/version/version_badvalue/dependency.oxtbin0 -> 1657 bytes
-rw-r--r--desktop/test/deployment/version/version_badvalue/license.oxtbin0 -> 1733 bytes
-rw-r--r--desktop/test/deployment/version/version_badvalue/plain.oxtbin0 -> 1618 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_0.0/dependency.oxtbin0 -> 1618 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_1.02.4.7.0/dependency.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_1.2.15.3/dependency.oxtbin0 -> 1624 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_1.2.3/dependency.oxtbin0 -> 1620 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_1.2.4.7/dependency.oxtbin0 -> 1623 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_badelement/dependency.oxtbin0 -> 1616 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_badvalue/dependency.oxtbin0 -> 1618 bytes
-rw-r--r--desktop/test/deployment/version/version_nodependencies_none/dependency.oxtbin0 -> 1598 bytes
-rw-r--r--desktop/test/deployment/version/version_none/dependency.oxtbin0 -> 1645 bytes
-rw-r--r--desktop/test/deployment/version/version_none/license.oxtbin0 -> 1722 bytes
-rw-r--r--desktop/test/deployment/version/version_none/plain.oxtbin0 -> 1598 bytes
-rw-r--r--desktop/unx/source/officeloader/makefile.mk47
-rwxr-xr-xdesktop/unx/source/officeloader/officeloader.cxx110
-rw-r--r--desktop/util/hidother.src54
-rw-r--r--desktop/util/makefile.mk277
-rw-r--r--desktop/util/ooverinfo.rc138
-rw-r--r--desktop/util/ooverinfo2.rc90
-rw-r--r--desktop/util/soffice.icobin0 -> 4990 bytes
-rw-r--r--desktop/util/template.manifest10
-rw-r--r--desktop/util/verinfo.rc142
-rw-r--r--desktop/util/writer.r1
-rw-r--r--desktop/win32/source/applauncher/launcher.cxx146
-rw-r--r--desktop/win32/source/applauncher/launcher.hxx21
-rw-r--r--desktop/win32/source/applauncher/makefile.mk148
-rw-r--r--desktop/win32/source/applauncher/ooo/makefile.mk130
-rw-r--r--desktop/win32/source/applauncher/ooo/verinfo.rc97
-rw-r--r--desktop/win32/source/applauncher/sbase.cxx34
-rw-r--r--desktop/win32/source/applauncher/scalc.cxx34
-rw-r--r--desktop/win32/source/applauncher/sdraw.cxx34
-rw-r--r--desktop/win32/source/applauncher/simpress.cxx34
-rw-r--r--desktop/win32/source/applauncher/smath.cxx34
-rw-r--r--desktop/win32/source/applauncher/sweb.cxx34
-rw-r--r--desktop/win32/source/applauncher/swriter.cxx32
-rw-r--r--desktop/win32/source/applauncher/verinfo.rc102
-rw-r--r--desktop/win32/source/extendloaderenvironment.cxx182
-rw-r--r--desktop/win32/source/extendloaderenvironment.hxx95
-rw-r--r--desktop/win32/source/guiloader/genericloader.cxx176
-rw-r--r--desktop/win32/source/guiloader/makefile.mk64
-rw-r--r--desktop/win32/source/guistdio/guistdio.cxx30
-rw-r--r--desktop/win32/source/guistdio/guistdio.inc453
-rw-r--r--desktop/win32/source/guistdio/makefile.mk58
-rw-r--r--desktop/win32/source/guistdio/unopkgio.cxx31
-rw-r--r--desktop/win32/source/lwrapa.cxx32
-rw-r--r--desktop/win32/source/lwrapw.cxx33
-rw-r--r--desktop/win32/source/main.h13
-rw-r--r--desktop/win32/source/makefile.mk63
-rw-r--r--desktop/win32/source/officeloader/makefile.mk63
-rw-r--r--desktop/win32/source/officeloader/officeloader.cxx424
-rw-r--r--desktop/win32/source/rebase/Resource.h38
-rw-r--r--desktop/win32/source/rebase/makefile.mk89
-rw-r--r--desktop/win32/source/rebase/rcfooter.txt2
-rw-r--r--desktop/win32/source/rebase/rcheader.txt39
-rw-r--r--desktop/win32/source/rebase/rctmpl.txt9
-rw-r--r--desktop/win32/source/rebase/rebase.cxx187
-rw-r--r--desktop/win32/source/rebase/rebasegui.cxx197
-rw-r--r--desktop/win32/source/rebase/rebasegui.ulf11
-rw-r--r--desktop/win32/source/rwrapa.cxx32
-rw-r--r--desktop/win32/source/rwrapw.cxx33
-rw-r--r--desktop/win32/source/setup/Resource.h79
-rw-r--r--desktop/win32/source/setup/makefile.mk91
-rw-r--r--desktop/win32/source/setup/rcfooter.txt2
-rw-r--r--desktop/win32/source/setup/rcheader.txt43
-rw-r--r--desktop/win32/source/setup/rctmpl.txt49
-rwxr-xr-xdesktop/win32/source/setup/setup.cpp2066
-rw-r--r--desktop/win32/source/setup/setup.hxx154
-rw-r--r--desktop/win32/source/setup/setup.icobin0 -> 4710 bytes
-rw-r--r--desktop/win32/source/setup/setup.ulf162
-rw-r--r--desktop/win32/source/setup/setup_a.cxx31
-rw-r--r--desktop/win32/source/setup/setup_help.hxx47
-rw-r--r--desktop/win32/source/setup/setup_main.cxx147
-rw-r--r--desktop/win32/source/setup/setup_main.hxx74
-rw-r--r--desktop/win32/source/setup/setup_w.cxx35
-rw-r--r--desktop/win32/source/sowrapper.cxx47
-rw-r--r--desktop/win32/source/unoinfo.cxx148
-rw-r--r--desktop/win32/source/wrapper.h173
-rw-r--r--desktop/win32/source/wrappera.cxx31
-rw-r--r--desktop/win32/source/wrapperw.cxx32
-rw-r--r--desktop/zipintro/delzip1
-rw-r--r--desktop/zipintro/makefile.mk134
692 files changed, 76863 insertions, 0 deletions
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
new file mode 100644
index 000000000000..8867a940a6ad
--- /dev/null
+++ b/desktop/inc/app.hxx
@@ -0,0 +1,213 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_APP_HXX_
+#define _DESKTOP_APP_HXX_
+
+// stl includes first
+#include <map>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <vcl/svapp.hxx>
+#ifndef _VCL_TIMER_HXX_
+#include <vcl/timer.hxx>
+#endif
+#include <tools/resmgr.hxx>
+#include <unotools/bootstrap.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <osl/mutex.hxx>
+
+using namespace com::sun::star::task;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace rtl;
+
+#define DESKTOP_SAVETASKS_MOD 0x1
+#define DESKTOP_SAVETASKS_UNMOD 0x2
+#define DESKTOP_SAVETASKS_ALL 0x3
+
+namespace desktop
+{
+
+/*--------------------------------------------------------------------
+ Description: Application-class
+ --------------------------------------------------------------------*/
+class CommandLineArgs;
+class Lockfile;
+class AcceptorMap : public std::map< OUString, Reference<XInitialization> > {};
+struct ConvertData;
+class Desktop : public Application
+{
+ friend class UserInstall;
+
+ public:
+ enum BootstrapError
+ {
+ BE_OK,
+ BE_UNO_SERVICEMANAGER,
+ BE_UNO_SERVICE_CONFIG_MISSING,
+ BE_PATHINFO_MISSING,
+ BE_USERINSTALL_FAILED,
+ BE_LANGUAGE_MISSING,
+ BE_USERINSTALL_NOTENOUGHDISKSPACE,
+ BE_USERINSTALL_NOWRITEACCESS,
+ BE_OFFICECONFIG_BROKEN
+ };
+ enum BootstrapStatus
+ {
+ BS_OK,
+ BS_TERMINATE
+ };
+
+ Desktop();
+ ~Desktop();
+ virtual void Main( );
+ virtual void Init();
+ virtual void DeInit();
+ virtual BOOL QueryExit();
+ virtual USHORT Exception(USHORT nError);
+ virtual void SystemSettingsChanging( AllSettings& rSettings, Window* pFrame );
+ virtual void AppEvent( const ApplicationEvent& rAppEvent );
+
+ DECL_LINK( OpenClients_Impl, void* );
+
+ static void OpenClients();
+ static void OpenDefault();
+
+ DECL_LINK( EnableAcceptors_Impl, void*);
+
+ static void HandleAppEvent( const ApplicationEvent& rAppEvent );
+ static ResMgr* GetDesktopResManager();
+ static CommandLineArgs* GetCommandLineArgs();
+
+ void HandleBootstrapErrors( BootstrapError );
+ void SetBootstrapError( BootstrapError nError )
+ {
+ if ( m_aBootstrapError == BE_OK )
+ m_aBootstrapError = nError;
+ }
+ BootstrapError GetBootstrapError() const
+ {
+ return m_aBootstrapError;
+ }
+
+ void SetBootstrapStatus( BootstrapStatus nStatus )
+ {
+ m_aBootstrapStatus = nStatus;
+ }
+ BootstrapStatus GetBootstrapStatus() const
+ {
+ return m_aBootstrapStatus;
+ }
+
+ static sal_Bool CheckOEM();
+ static sal_Bool isCrashReporterEnabled();
+
+ // first-start (ever) & license relate methods
+ static rtl::OUString GetLicensePath();
+ static sal_Bool LicenseNeedsAcceptance();
+ static sal_Bool IsFirstStartWizardNeeded();
+ static sal_Bool CheckExtensionDependencies();
+
+ void SynchronizeExtensionRepositories();
+ void SetSplashScreenText( const ::rtl::OUString& rText );
+ void SetSplashScreenProgress( sal_Int32 );
+
+ private:
+ // Bootstrap methods
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > CreateApplicationServiceManager();
+
+ void RegisterServices( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr );
+ void DeregisterServices();
+
+ void DestroyApplicationServiceManager( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr );
+
+ void CreateTemporaryDirectory();
+ void RemoveTemporaryDirectory();
+
+ sal_Bool InitializeInstallation( const rtl::OUString& rAppFilename );
+ sal_Bool InitializeConfiguration();
+ sal_Bool InitializeQuickstartMode( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr );
+
+ void HandleBootstrapPathErrors( ::utl::Bootstrap::Status, const ::rtl::OUString& aMsg );
+ void StartSetup( const ::rtl::OUString& aParameters );
+
+ // Get a resource message string securely e.g. if resource cannot be retrieved return aFaultBackMsg
+ ::rtl::OUString GetMsgString( USHORT nId, const ::rtl::OUString& aFaultBackMsg );
+
+ // Create a error message depending on bootstrap failure code and an optional file url
+ ::rtl::OUString CreateErrorMsgString( utl::Bootstrap::FailureCode nFailureCode,
+ const ::rtl::OUString& aFileURL );
+
+ static void PreloadModuleData( CommandLineArgs* );
+ static void PreloadConfigurationData();
+
+ Reference<XStatusIndicator> m_rSplashScreen;
+ void OpenSplashScreen();
+ void CloseSplashScreen();
+
+ void EnableOleAutomation();
+ DECL_LINK( ImplInitFilterHdl, ConvertData* );
+ DECL_LINK( AsyncInitFirstRun, void* );
+ /** checks if the office is run the first time
+ <p>If so, <method>DoFirstRunInitializations</method> is called (asynchronously and delayed) and the
+ respective flag in the configuration is reset.</p>
+ */
+ void CheckFirstRun( );
+
+ /// does initializations which are necessary for the first run of the office
+ void DoFirstRunInitializations();
+
+ static sal_Bool SaveTasks();
+ static sal_Bool _bTasksSaved;
+
+ static void retrieveCrashReporterState();
+ static sal_Bool isUIOnSessionShutdownAllowed();
+
+ // on-demand acceptors
+ static void createAcceptor(const OUString& aDescription);
+ static void enableAcceptors();
+ static void destroyAcceptor(const OUString& aDescription);
+
+ sal_Bool m_bMinimized;
+ sal_Bool m_bInvisible;
+ bool m_bServicesRegistered;
+ USHORT m_nAppEvents;
+ BootstrapError m_aBootstrapError;
+ BootstrapStatus m_aBootstrapStatus;
+
+ Lockfile *m_pLockfile;
+ Timer m_firstRunTimer;
+
+ static ResMgr* pResMgr;
+ static sal_Bool bSuppressOpenDefault;
+};
+
+}
+
+#endif // _DESKTOP_APP_HXX_
diff --git a/desktop/inc/deployment.hrc b/desktop/inc/deployment.hrc
new file mode 100644
index 000000000000..370996c710ae
--- /dev/null
+++ b/desktop/inc/deployment.hrc
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_DEPLOYMENT_HRC
+#define INCLUDED_DEPLOYMENT_HRC
+
+#define MASKCOLOR MaskColor = \
+ Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+
+#define RID_DEPLOYMENT_START 2000
+
+#define RID_DEPLOYMENT_GUI_START RID_DEPLOYMENT_START
+#define RID_DEPLOYMENT_MISC_START (RID_DEPLOYMENT_START+500)
+#define RID_DEPLOYMENT_MANAGER_START (RID_DEPLOYMENT_START+1000)
+#define RID_DEPLOYMENT_REGISTRY_START (RID_DEPLOYMENT_START+1500)
+
+#define RID_DEPLOYMENT_BUNDLE_START (RID_DEPLOYMENT_START+2000)
+#define RID_IMG_DEF_PACKAGE_BUNDLE RID_DEPLOYMENT_BUNDLE_START
+#define RID_IMG_DEF_PACKAGE_BUNDLE_HC (RID_DEPLOYMENT_BUNDLE_START+1)
+
+#define RID_DEPLOYMENT_SCRIPT_START (RID_DEPLOYMENT_START+2500)
+#define RID_IMG_SCRIPTLIB RID_DEPLOYMENT_SCRIPT_START
+#define RID_IMG_SCRIPTLIB_HC (RID_DEPLOYMENT_SCRIPT_START+1)
+#define RID_IMG_DIALOGLIB (RID_DEPLOYMENT_SCRIPT_START+2)
+#define RID_IMG_DIALOGLIB_HC (RID_DEPLOYMENT_SCRIPT_START+3)
+
+#define RID_DEPLOYMENT_CONF_START (RID_DEPLOYMENT_START+3000)
+#define RID_IMG_CONF_XML RID_DEPLOYMENT_CONF_START
+#define RID_IMG_CONF_XML_HC (RID_DEPLOYMENT_CONF_START+1)
+
+#define RID_DEPLOYMENT_COMPONENT_START (RID_DEPLOYMENT_START+3500)
+#define RID_IMG_COMPONENT RID_DEPLOYMENT_COMPONENT_START
+#define RID_IMG_COMPONENT_HC (RID_DEPLOYMENT_COMPONENT_START+1)
+#define RID_IMG_JAVA_COMPONENT (RID_DEPLOYMENT_COMPONENT_START+2)
+#define RID_IMG_JAVA_COMPONENT_HC (RID_DEPLOYMENT_COMPONENT_START+3)
+#define RID_IMG_TYPELIB (RID_DEPLOYMENT_COMPONENT_START+4)
+#define RID_IMG_TYPELIB_HC (RID_DEPLOYMENT_COMPONENT_START+5)
+#define RID_IMG_JAVA_TYPELIB (RID_DEPLOYMENT_COMPONENT_START+6)
+#define RID_IMG_JAVA_TYPELIB_HC (RID_DEPLOYMENT_COMPONENT_START+7)
+
+#define RID_DEPLOYMENT_UNOPKG_START (RID_DEPLOYMENT_START+4000)
+#define RID_STR_UNOPKG_ACCEPT_LIC_1 (RID_DEPLOYMENT_UNOPKG_START+1)
+#define RID_STR_UNOPKG_ACCEPT_LIC_2 (RID_DEPLOYMENT_UNOPKG_START+2)
+#define RID_STR_UNOPKG_ACCEPT_LIC_3 (RID_DEPLOYMENT_UNOPKG_START+3)
+#define RID_STR_UNOPKG_ACCEPT_LIC_4 (RID_DEPLOYMENT_UNOPKG_START+4)
+#define RID_STR_UNOPKG_ACCEPT_LIC_YES (RID_DEPLOYMENT_UNOPKG_START+5)
+#define RID_STR_UNOPKG_ACCEPT_LIC_Y (RID_DEPLOYMENT_UNOPKG_START+6)
+#define RID_STR_UNOPKG_ACCEPT_LIC_NO (RID_DEPLOYMENT_UNOPKG_START+7)
+#define RID_STR_UNOPKG_ACCEPT_LIC_N (RID_DEPLOYMENT_UNOPKG_START+8)
+#define RID_STR_UNOPKG_ERROR (RID_DEPLOYMENT_UNOPKG_START+9)
+#define RID_STR_CONCURRENTINSTANCE (RID_DEPLOYMENT_UNOPKG_START+10)
+
+#define RID_DEPLOYMENT_DEPENDENCIES_START (RID_DEPLOYMENT_START + 4400)
+#define RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN RID_DEPLOYMENT_DEPENDENCIES_START
+#define RID_DEPLYOMENT_DEPENDENCIES_MIN (RID_DEPLOYMENT_DEPENDENCIES_START+1)
+#define RID_DEPLYOMENT_DEPENDENCIES_MAX (RID_DEPLOYMENT_DEPENDENCIES_START+2)
+
+#define RID_DEPLOYMENT_LICENSE_START (RID_DEPLOYMENT_START+4500)
+
+#define RID_DEPLOYMENT_HELP_START (RID_DEPLOYMENT_START+5000)
+#define RID_IMG_HELP RID_DEPLOYMENT_HELP_START
+#define RID_IMG_HELP_HC (RID_DEPLOYMENT_HELP_START+1)
+#endif
diff --git a/desktop/inc/makefile.mk b/desktop/inc/makefile.mk
new file mode 100644
index 000000000000..8715d814274f
--- /dev/null
+++ b/desktop/inc/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+PRJ=..
+
+PRJNAME=desktop
+TARGET=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/desktop/inc/pch/precompiled_desktop.cxx b/desktop/inc/pch/precompiled_desktop.cxx
new file mode 100644
index 000000000000..f95c8300208b
--- /dev/null
+++ b/desktop/inc/pch/precompiled_desktop.cxx
@@ -0,0 +1,29 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "precompiled_desktop.hxx"
+
diff --git a/desktop/inc/pch/precompiled_desktop.hxx b/desktop/inc/pch/precompiled_desktop.hxx
new file mode 100644
index 000000000000..796ed48aa7a2
--- /dev/null
+++ b/desktop/inc/pch/precompiled_desktop.hxx
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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): Generated on 2006-09-01 17:49:39.170923
+
+#ifdef PRECOMPILED_HEADERS
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "comphelper/processfactory.hxx"
+#include "osl/file.hxx"
+#include "rtl/bootstrap.hxx"
+#include "rtl/ustring.hxx"
+#include "tools/datetime.hxx"
+#include "tools/debug.hxx"
+#include "unotools/configmgr.hxx"
+#endif
diff --git a/desktop/os2/source/applauncher/launcher.cxx b/desktop/os2/source/applauncher/launcher.cxx
new file mode 100644
index 000000000000..36c23e1eb4e0
--- /dev/null
+++ b/desktop/os2/source/applauncher/launcher.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <process.h>
+
+int main( int argc, char* argv[])
+{
+ PPIB pib;
+ APIRET rc;
+ RESULTCODES result = {0};
+ char szFail[ _MAX_PATH];
+
+ HAB hab = WinInitialize( 0);
+ HMQ hmq = WinCreateMsgQueue( hab, 0);
+ ERRORID erridErrorCode = 0;
+ erridErrorCode = WinGetLastError(hab);
+
+ // Calculate application name
+ CHAR szLibpath[_MAX_PATH*2];
+ CHAR szApplicationName[_MAX_PATH];
+ CHAR szDrive[_MAX_PATH];
+ CHAR szDir[_MAX_PATH];
+ CHAR szFileName[_MAX_PATH];
+ CHAR szExt[_MAX_PATH];
+
+ // get executable fullpath
+ DosGetInfoBlocks(NULL, &pib);
+ DosQueryModuleName(pib->pib_hmte, sizeof(szApplicationName), szApplicationName);
+
+ // adjust libpath
+ _splitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
+ char* basedir = strstr( szDir, "\\PROGRAM\\");
+ if (basedir) *basedir = 0;
+ sprintf( szLibpath, "\"%s%s\\URE\\BIN\";\"%s%s\\BASIS\\PROGRAM\";%BeginLIBPATH%",
+ szDrive, szDir, szDrive, szDir);
+ DosSetExtLIBPATH( (PCSZ)szLibpath, BEGIN_LIBPATH);
+ // make sure we load DLL from our path only, so multiple instances/versions
+ // can be loaded.
+#if 0
+ // YD this feature is not compatible with innowin b20,
+ // java cannot load with this flag enabled
+ DosSetExtLIBPATH( (PCSZ)"T", LIBPATHSTRICT);
+#endif
+
+ // adjust exe name
+ _splitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
+ _makepath( szApplicationName, szDrive, szDir, OFFICE_IMAGE_NAME, (".bin") );
+
+ // copy command line parameters
+ int i, len;
+ len = strlen(szApplicationName) + 1 + strlen( APPLICATION_SWITCH) + 1 + 1;
+ for( i=1; i<argc; i++)
+ len += strlen( argv[i]) + 1;
+
+ char* pszCommandLine, *pszArgs;
+ pszCommandLine = (char*) calloc( 1, len);
+ strcpy( pszCommandLine, szApplicationName);
+ pszArgs = pszCommandLine + strlen(szApplicationName) + 1;
+ strcat( pszArgs, APPLICATION_SWITCH);
+ strcat( pszArgs, " ");
+ for( i=1; i<argc; i++) {
+ // add quotes if argument has spaces!
+ if (strchr( argv[i], ' '))
+ strcat( pszArgs, "\"");
+ strcat( pszArgs, argv[i]);
+ if (strchr( argv[i], ' '))
+ strcat( pszArgs, "\"");
+ strcat( pszArgs, " ");
+ }
+ pszArgs[ strlen( pszArgs) + 0] = 0;
+
+ // execute
+ rc = DosExecPgm(szFail, sizeof(szFail),
+ EXEC_SYNC, (PCSZ)pszCommandLine, (PCSZ)NULL, &result,
+ (PCSZ)szApplicationName);
+ if (rc) {
+ char szMessage[ _MAX_PATH*2];
+ sprintf( szMessage, "Execution failed! Contact technical support.\n\nReturn code: %d\nFailing module:%s\n", rc, szFail);
+ rc = WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
+ (PSZ)szMessage,
+ (PSZ)"Unable to start OpenOffice.org!",
+ 0, MB_ERROR | MB_OK);
+ WinDestroyMsgQueue( hmq);
+ WinTerminate( hab);
+ exit(1);
+ }
+
+ WinDestroyMsgQueue( hmq);
+ WinTerminate( hab);
+
+ exit( result.codeResult);
+}
diff --git a/desktop/os2/source/applauncher/launcher.hxx b/desktop/os2/source/applauncher/launcher.hxx
new file mode 100644
index 000000000000..181289275dea
--- /dev/null
+++ b/desktop/os2/source/applauncher/launcher.hxx
@@ -0,0 +1,9 @@
+
+#define INCL_DOS
+#define INCL_PM
+#include <os2.h>
+
+#define OFFICE_IMAGE_NAME ("soffice")
+
+extern CHAR APPLICATION_SWITCH[];
+
diff --git a/desktop/os2/source/applauncher/makefile.mk b/desktop/os2/source/applauncher/makefile.mk
new file mode 100644
index 000000000000..bf71b57c2fdf
--- /dev/null
+++ b/desktop/os2/source/applauncher/makefile.mk
@@ -0,0 +1,121 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET=applauncher
+LIBTARGET=NO
+TARGETTYPE=GUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= \
+ $(OBJ)$/launcher.obj \
+ $(OBJ)$/swriter.obj \
+ $(OBJ)$/scalc.obj \
+ $(OBJ)$/sdraw.obj \
+ $(OBJ)$/simpress.obj \
+ $(OBJ)$/sbase.obj \
+ $(OBJ)$/smath.obj \
+ $(OBJ)$/officeloader.obj \
+ $(OBJ)$/quickstart.obj
+
+APP1TARGET=swriter
+APP1NOSAL=TRUE
+APP1LINKRES=$(MISC)$/$(TARGET)1.res
+APP1ICON=$(SOLARRESDIR)$/icons$/ooo-writer-app.ico
+APP1OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/swriter.obj
+
+
+APP2TARGET=scalc
+APP2NOSAL=TRUE
+APP2LINKRES=$(MISC)$/$(TARGET)2.res
+APP2ICON=$(SOLARRESDIR)$/icons$/ooo-calc-app.ico
+APP2OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/scalc.obj
+
+APP3TARGET=sdraw
+APP3NOSAL=TRUE
+APP3LINKRES=$(MISC)$/$(TARGET)3.res
+APP3ICON=$(SOLARRESDIR)$/icons$/ooo-draw-app.ico
+APP3OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sdraw.obj
+
+APP4TARGET=simpress
+APP4NOSAL=TRUE
+APP4LINKRES=$(MISC)$/$(TARGET)4.res
+APP4ICON=$(SOLARRESDIR)$/icons$/ooo-impress-app.ico
+APP4OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/simpress.obj
+
+APP5TARGET=sbase
+APP5NOSAL=TRUE
+APP5LINKRES=$(MISC)$/$(TARGET)5.res
+APP5ICON=$(SOLARRESDIR)$/icons$/ooo-base-app.ico
+APP5OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sbase.obj
+
+APP6TARGET=smath
+APP6NOSAL=TRUE
+APP6LINKRES=$(MISC)$/$(TARGET)6.res
+APP6ICON=$(SOLARRESDIR)$/icons$/ooo-math-app.ico
+APP6OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/smath.obj
+
+APP7TARGET=officeloader
+APP7NOSAL=TRUE
+APP7LINKRES=$(MISC)$/$(TARGET)7.res
+APP7ICON=$(SOLARRESDIR)$/icons$/ooo-main-app.ico
+APP7OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/officeloader.obj
+
+APP8TARGET=quickstart
+APP8NOSAL=TRUE
+APP8LINKRES=$(MISC)$/$(TARGET)8.res
+APP8ICON=$(SOLARRESDIR)$/icons$/ooo-main-app.ico
+APP8OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/quickstart.obj
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/os2/source/applauncher/officeloader.cxx b/desktop/os2/source/applauncher/officeloader.cxx
new file mode 100644
index 000000000000..9a664ab68d43
--- /dev/null
+++ b/desktop/os2/source/applauncher/officeloader.cxx
@@ -0,0 +1,3 @@
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "" );
diff --git a/desktop/os2/source/applauncher/quickstart.cxx b/desktop/os2/source/applauncher/quickstart.cxx
new file mode 100644
index 000000000000..63585434bb50
--- /dev/null
+++ b/desktop/os2/source/applauncher/quickstart.cxx
@@ -0,0 +1,3 @@
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-quickstart" );
diff --git a/desktop/os2/source/applauncher/sbase.cxx b/desktop/os2/source/applauncher/sbase.cxx
new file mode 100644
index 000000000000..a60a46be4cf4
--- /dev/null
+++ b/desktop/os2/source/applauncher/sbase.cxx
@@ -0,0 +1,3 @@
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-base" );
diff --git a/desktop/os2/source/applauncher/scalc.cxx b/desktop/os2/source/applauncher/scalc.cxx
new file mode 100644
index 000000000000..dc4470ca08d3
--- /dev/null
+++ b/desktop/os2/source/applauncher/scalc.cxx
@@ -0,0 +1,3 @@
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-calc" );
diff --git a/desktop/os2/source/applauncher/sdraw.cxx b/desktop/os2/source/applauncher/sdraw.cxx
new file mode 100644
index 000000000000..76893e1f4f87
--- /dev/null
+++ b/desktop/os2/source/applauncher/sdraw.cxx
@@ -0,0 +1,3 @@
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-draw" );
diff --git a/desktop/os2/source/applauncher/simpress.cxx b/desktop/os2/source/applauncher/simpress.cxx
new file mode 100644
index 000000000000..15f03ab7afa3
--- /dev/null
+++ b/desktop/os2/source/applauncher/simpress.cxx
@@ -0,0 +1,3 @@
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-impress" );
diff --git a/desktop/os2/source/applauncher/smath.cxx b/desktop/os2/source/applauncher/smath.cxx
new file mode 100644
index 000000000000..cad0b8631e23
--- /dev/null
+++ b/desktop/os2/source/applauncher/smath.cxx
@@ -0,0 +1,3 @@
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-math" );
diff --git a/desktop/os2/source/applauncher/swriter.cxx b/desktop/os2/source/applauncher/swriter.cxx
new file mode 100644
index 000000000000..ded9cf089da8
--- /dev/null
+++ b/desktop/os2/source/applauncher/swriter.cxx
@@ -0,0 +1,3 @@
+#include "launcher.hxx"
+
+CHAR APPLICATION_SWITCH[] = ( "-writer" );
diff --git a/desktop/prj/build.lst b/desktop/prj/build.lst
new file mode 100644
index 000000000000..dc5d7a99b2d6
--- /dev/null
+++ b/desktop/prj/build.lst
@@ -0,0 +1,43 @@
+dt desktop : l10n sfx2 stoc BERKELEYDB:berkeleydb sysui SO:sysui_so BOOST:boost svx xmlhelp sal unoil officecfg offuh NULL
+dt desktop usr1 - all dt_mkout NULL
+dt desktop\inc nmake - all dt_inc NULL
+dt desktop\prj get - all dt_prj NULL
+dt desktop\res get - all dt_res NULL
+dt desktop\source\app nmake - all dt_app dt_migr dt_inc dt_dp_misc NULL
+dt desktop\source\migration nmake - all dt_migr dt_inc NULL
+dt desktop\source\migration\services nmake - all dt_services dt_inc dt_dp_misc NULL
+dt desktop\source\so_comp nmake - all dt_so_comp dt_inc NULL
+dt desktop\source\offacc nmake - all dt_offac dt_inc NULL
+dt desktop\source\splash nmake - all dt_spl dt_migr dt_inc NULL
+dt desktop\win32\source nmake - w dt_wrapper dt_inc NULL
+dt desktop\win32\source\setup nmake - w dt_setup dt_inc NULL
+dt desktop\win32\source\officeloader nmake - w dt_officeloader dt_inc NULL
+dt desktop\win32\source\guiloader nmake - w dt_guiloader dt_wrapper.w dt_inc NULL
+dt desktop\win32\source\guistdio nmake - w dt_guistdio dt_inc NULL
+dt desktop\win32\source\applauncher nmake - w dt_applauncher dt_inc NULL
+dt desktop\win32\source\applauncher\ooo nmake - w dt_applauncher_ooo dt_applauncher.w dt_inc NULL
+dt desktop\win32\source\rebase nmake - w dt_rebase dt_inc NULL
+dt desktop\os2\source\applauncher nmake - p dt_applauncher dt_inc NULL
+dt desktop\unx\source\officeloader nmake - u dt_officeloader_unx dt_inc NULL
+dt desktop\source\pagein nmake - u dt_pagein dt_inc NULL
+dt desktop\source\pkgchk\unopkg nmake - all dt_unopkg dt_dp_misc dt_app dt_inc dt_guiloader.w NULL
+dt desktop\source\deployment nmake - all dt_deployment dt_dp_manager dt_dp_registry dt_dp_registry_package dt_dp_registry_executable dt_dp_registry_help dt_dp_registry_script dt_dp_registry_sfwk dt_dp_registry_component dt_dp_registry_configuration dt_dp_unopkg dt_inc dt_dp_misc NULL
+dt desktop\source\deployment\misc nmake - all dt_dp_misc dt_inc NULL
+dt desktop\source\deployment\unopkg nmake - all dt_dp_unopkg dt_inc NULL
+dt desktop\source\deployment\gui nmake - all dt_dp_gui dt_dp_misc dt_inc NULL
+dt desktop\source\deployment\manager nmake - all dt_dp_manager dt_inc NULL
+dt desktop\source\deployment\registry nmake - all dt_dp_registry dt_inc NULL
+dt desktop\source\deployment\registry\package nmake - all dt_dp_registry_package dt_inc NULL
+dt desktop\source\deployment\registry\script nmake - all dt_dp_registry_script dt_inc NULL
+dt desktop\source\deployment\registry\sfwk nmake - all dt_dp_registry_sfwk dt_inc NULL
+dt desktop\source\deployment\registry\component nmake - all dt_dp_registry_component dt_inc NULL
+dt desktop\source\deployment\registry\configuration nmake - all dt_dp_registry_configuration dt_inc NULL
+dt desktop\source\deployment\registry\help nmake - all dt_dp_registry_help dt_inc NULL
+dt desktop\source\deployment\registry\executable nmake - all dt_dp_registry_executable dt_inc NULL
+dt desktop\scripts nmake - u dt_scripts dt_inc NULL
+dt desktop\util nmake - all dt_util dt_app dt_pagein.u dt_so_comp dt_spl dt_wrapper.w dt_officeloader.w dt_officeloader_unx.u dt_migr dt_rebase.w NULL
+dt desktop\zipintro nmake - all dt_zipintro NULL
+dt desktop\registry\data\org\openoffice\Office nmake - all sn_regconfig NULL
+dt desktop\source\registration\com\sun\star\servicetag\resources get - all sn_svctagres NULL
+dt desktop\source\registration\com\sun\star\servicetag nmake - all sn_svctag NULL
+dt desktop\source\registration\com\sun\star\registration nmake - all sn_regjob sn_svctag NULL
diff --git a/desktop/prj/d.lst b/desktop/prj/d.lst
new file mode 100644
index 000000000000..92a4853c2bed
--- /dev/null
+++ b/desktop/prj/d.lst
@@ -0,0 +1,145 @@
+mkdir: %COMMON_DEST%\bin%_EXT%\hid
+mkdir: %_DEST%\bin%_EXT%\so
+mkdir: %_DEST%\bin%_EXT%\c01
+mkdir: %_DEST%\bin%_EXT%\c05
+mkdir: %_DEST%\bin%_EXT%\c08
+mkdir: %_DEST%\bin%_EXT%\odf4ms
+
+..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid
+..\%__SRC%\bin\soffice.bin %_DEST%\bin%_EXT%\soffice.bin
+..\%__SRC%\bin\officeloader.exe %_DEST%\bin%_EXT%\soffice.exe
+..\%__SRC%\bin\soffice %_DEST%\bin%_EXT%\soffice.bin
+..\%__SRC%\bin\soffice_mac %_DEST%\bin%_EXT%\soffice
+..\%__SRC%\bin\so\soffice.bin %_DEST%\bin%_EXT%\so\soffice.bin
+..\%__SRC%\bin\so\officeloader.exe %_DEST%\bin%_EXT%\so\soffice.exe
+..\%__SRC%\bin\so\soffice %_DEST%\bin%_EXT%\so\soffice.bin
+..\%__SRC%\bin\so\soffice_mac %_DEST%\bin%_EXT%\so\soffice
+..\%__SRC%\bin\sofficea*.dll %_DEST%\bin%_EXT%\sofficea*.dll
+..\%__SRC%\lib\isofficeapp.lib %_DEST%\lib%_EXT%\isofficeapp.lib
+..\%__SRC%\lib\libsofficeapp.dylib %_DEST%\lib%_EXT%\libsofficeapp.dylib
+..\%__SRC%\lib\libsofficeapp.so %_DEST%\lib%_EXT%\libsofficeapp.so
+
+..\%__SRC%\bin\soffice_oo.exe %_DEST%\bin%_EXT%\soffice_oo.exe
+..\%__SRC%\bin\soffice_oo %_DEST%\bin%_EXT%\soffice_oo.bin
+..\%__SRC%\bin\so\soffice_so.exe %_DEST%\bin%_EXT%\so\soffice_so.exe
+..\%__SRC%\bin\so\soffice_so %_DEST%\bin%_EXT%\so\soffice_so.bin
+
+..\%__SRC%\bin\scalc.exe %_DEST%\bin%_EXT%\scalc.exe
+..\%__SRC%\bin\sdraw.exe %_DEST%\bin%_EXT%\sdraw.exe
+..\%__SRC%\bin\simpress.exe %_DEST%\bin%_EXT%\simpress.exe
+..\%__SRC%\bin\smath.exe %_DEST%\bin%_EXT%\smath.exe
+..\%__SRC%\bin\swriter.exe %_DEST%\bin%_EXT%\swriter.exe
+..\%__SRC%\bin\sbase.exe %_DEST%\bin%_EXT%\sbase.exe
+..\%__SRC%\bin\sweb.exe %_DEST%\bin%_EXT%\sweb.exe
+..\%__SRC%\bin\quickstart.exe %_DEST%\bin%_EXT%\quickstart.exe
+..\%__SRC%\bin\so\scalc.exe %_DEST%\bin%_EXT%\so\scalc.exe
+..\%__SRC%\bin\so\sdraw.exe %_DEST%\bin%_EXT%\so\sdraw.exe
+..\%__SRC%\bin\so\simpress.exe %_DEST%\bin%_EXT%\so\simpress.exe
+..\%__SRC%\bin\so\smath.exe %_DEST%\bin%_EXT%\so\smath.exe
+..\%__SRC%\bin\so\swriter.exe %_DEST%\bin%_EXT%\so\swriter.exe
+..\%__SRC%\bin\so\sbase.exe %_DEST%\bin%_EXT%\so\sbase.exe
+..\%__SRC%\bin\so\sweb.exe %_DEST%\bin%_EXT%\so\sweb.exe
+
+..\%__SRC%\misc\soffice.exe.manifest %_DEST%\bin%_EXT%\soffice.exe.manifest
+..\%__SRC%\misc\soffice.bin.manifest %_DEST%\bin%_EXT%\soffice.bin.manifest
+..\%__SRC%\bin\wrp*.dll %_DEST%\bin%_EXT%\wrp*.dll
+..\%__SRC%\bin\spl*.dll %_DEST%\bin%_EXT%\spl*.dll
+..\%__SRC%\bin\socomp.dll %_DEST%\bin%_EXT%\socomp.dll
+..\%__SRC%\obj\officeloader.obj %_DEST%\lib%_EXT%\officeloader.obj
+..\%__SRC%\obj\extendloaderenvironment.obj %_DEST%\lib%_EXT%\extendloaderenvironment.obj
+..\%__SRC%\obj\copyright_ascii_sun.obj %_DEST%\lib%_EXT%\copyright_ascii_sun.obj
+..\%__SRC%\obj\main.obj %_DEST%\lib%_EXT%\main.obj
+..\%__SRC%\lib\libwrp*.so %_DEST%\lib%_EXT%\libwrp*.so
+..\%__SRC%\lib\libwrp*.dylib %_DEST%\lib%_EXT%\libwrp*.dylib
+..\%__SRC%\lib\libspl*.so %_DEST%\lib%_EXT%\libspl*.so
+..\%__SRC%\lib\libspl*.dylib %_DEST%\lib%_EXT%\libspl*.dylib
+..\%__SRC%\lib\libsocomp.so %_DEST%\lib%_EXT%\libsocomp.so
+..\%__SRC%\lib\libsocomp.dylib %_DEST%\lib%_EXT%\libsocomp.dylib
+..\%__SRC%\bin\offacc*.dll %_DEST%\bin%_EXT%\offacc*.dll
+..\%__SRC%\lib\liboffacc*.so %_DEST%\lib%_EXT%\liboffacc*.so
+..\%__SRC%\lib\liboffacc*.dylib %_DEST%\lib%_EXT%\liboffacc*.dylib
+..\%__SRC%\bin\migratio*.dll %_DEST%\bin%_EXT%\migratio*.dll
+..\%__SRC%\lib\migratio*.uno.so %_DEST%\lib%_EXT%\migratio*.uno.so
+..\%__SRC%\lib\migratio*.uno.dylib %_DEST%\lib%_EXT%\migratio*.uno.dylib
+
+..\%__SRC%\bin\sweb %_DEST%\bin%_EXT%\sweb.bin
+
+..\%__SRC%\bin\loader2.ex? %_DEST%\bin%_EXT%\loader2.ex?
+
+..\%__SRC%\bin\depl*.dll %_DEST%\bin%_EXT%\depl*.dll
+..\%__SRC%\lib\deployment*.uno.so %_DEST%\lib%_EXT%\deployment*.uno.so
+..\%__SRC%\lib\deployment*.uno.dylib %_DEST%\lib%_EXT%\deployment*.uno.dylib
+..\%__SRC%\bin\deploymentmisc*.dll %_DEST%\bin%_EXT%\deploymentmisc*.dll
+..\%__SRC%\lib\libdeploymentmisc*.so %_DEST%\lib%_EXT%\libdeploymentmisc*.so
+..\%__SRC%\lib\libdeploymentmisc*.dylib %_DEST%\lib%_EXT%\libdeploymentmisc*.dylib
+..\%__SRC%\bin\guiloader.exe %_DEST%\bin%_EXT%\unopkg.exe
+..\%__SRC%\bin\so\guiloader.exe %_DEST%\bin%_EXT%\so\unopkg.exe
+..\%__SRC%\bin\unopkg %_DEST%\bin%_EXT%\unopkg.bin
+..\%__SRC%\bin\so\unopkg %_DEST%\bin%_EXT%\so\unopkg.bin
+..\%__SRC%\bin\unopkg.exe %_DEST%\bin%_EXT%\unopkg.bin
+..\%__SRC%\bin\so\unopkg.exe %_DEST%\bin%_EXT%\so\unopkg.bin
+..\%__SRC%\misc\unopkg.sh %_DEST%\bin%_EXT%\unopkg
+..\%__SRC%\bin\unopkga*.dll %_DEST%\bin%_EXT%\unopkga*.dll
+..\%__SRC%\lib\libunopkgapp.dylib %_DEST%\lib%_EXT%\libunopkgapp.dylib
+..\%__SRC%\lib\libunopkgapp.so %_DEST%\lib%_EXT%\libunopkgapp.so
+..\%__SRC%\bin\rebasegui.exe %_DEST%\bin%_EXT%\rebasegui.exe
+..\%__SRC%\bin\rebaseoo.exe %_DEST%\bin%_EXT%\rebaseoo.exe
+
+..\%__SRC%\bin\pagein %_DEST%\bin%_EXT%\pagein
+..\%__SRC%\misc\pagein-* %_DEST%\bin%_EXT%\pagein-*
+
+..\%__SRC%\bin\unoinfo.exe %_DEST%\bin%_EXT%\unoinfo.exe
+..\%__SRC%\misc\unoinfo.sh %_DEST%\bin%_EXT%\unoinfo
+
+..\%__SRC%\bin\*.res %_DEST%\bin%_EXT%\*.res
+
+..\%__SRC%\misc\soffice.sh-expanded %_DEST%\bin%_EXT%\soffice
+..\%__SRC%\misc\sbase.sh %_DEST%\bin%_EXT%\sbase
+..\%__SRC%\misc\scalc.sh %_DEST%\bin%_EXT%\scalc
+..\%__SRC%\misc\sdraw.sh %_DEST%\bin%_EXT%\sdraw
+..\%__SRC%\misc\simpress.sh %_DEST%\bin%_EXT%\simpress
+..\%__SRC%\misc\smaster.sh %_DEST%\bin%_EXT%\smaster
+..\%__SRC%\misc\smath.sh %_DEST%\bin%_EXT%\smath
+..\%__SRC%\misc\sweb.sh %_DEST%\bin%_EXT%\sweb
+..\%__SRC%\misc\swriter.sh %_DEST%\bin%_EXT%\swriter
+..\%__SRC%\misc\nswrapper.sh %_DEST%\bin%_EXT%\nswrapper
+..\%__SRC%\misc\mozwrapper.sh %_DEST%\bin%_EXT%\mozwrapper
+
+mkdir: %COMMON_DEST%\pck%_EXT%\openoffice_dev
+mkdir: %COMMON_DEST%\pck%_EXT%\openoffice_dev_nologo
+mkdir: %COMMON_DEST%\pck%_EXT%\openoffice_nologo
+mkdir: %COMMON_DEST%\pck%_EXT%\broffice_dev
+mkdir: %COMMON_DEST%\pck%_EXT%\broffice
+mkdir: %COMMON_DEST%\pck%_EXT%\broffice_dev_nologo
+mkdir: %COMMON_DEST%\pck%_EXT%\broffice_nologo
+..\%__SRC%\bin\intro\intro.zip %COMMON_DEST%\pck%_EXT%\intro.zip
+..\%__SRC%\bin\dev\intro.zip %COMMON_DEST%\pck%_EXT%\openoffice_dev\intro.zip
+..\%__SRC%\bin\dev_nologo\intro.zip %COMMON_DEST%\pck%_EXT%\openoffice_dev_nologo\intro.zip
+..\%__SRC%\bin\nologo\intro.zip %COMMON_DEST%\pck%_EXT%\openoffice_nologo\intro.zip
+..\%__SRC%\bin\dev_broffice\intro.zip %COMMON_DEST%\pck%_EXT%\broffice_dev\intro.zip
+..\%__SRC%\bin\broffice\intro.zip %COMMON_DEST%\pck%_EXT%\broffice\intro.zip
+..\%__SRC%\bin\nologo_dev_broffice\intro.zip %COMMON_DEST%\pck%_EXT%\broffice_dev_nologo\intro.zip
+..\%__SRC%\bin\nologo_broffice\intro.zip %COMMON_DEST%\pck%_EXT%\broffice_nologo\intro.zip
+
+..\%__SRC%\bin\guiloader.exe %_DEST%\bin%_EXT%\testtool.exe
+
+..\%__SRC%\bin\guistdio.exe %_DEST%\bin%_EXT%\guistdio.com
+..\%__SRC%\bin\guistdio.exe %_DEST%\bin%_EXT%\crashrep.com
+..\%__SRC%\bin\unopkgio.exe %_DEST%\bin%_EXT%\unopkg.com
+
+..\scripts\ure-link %_DEST%\bin%_EXT%\ure-link
+..\scripts\basis-link %_DEST%\bin%_EXT%\basis-link
+..\scripts\basis-link %_DEST%\bin%_EXT%\c01\basis-link
+..\scripts\basis-link %_DEST%\bin%_EXT%\c05\basis-link
+..\scripts\basis-link %_DEST%\bin%_EXT%\c08\basis-link
+..\scripts\so-basis-link %_DEST%\bin%_EXT%\so\basis-link
+..\scripts\odf-basis-link %_DEST%\bin%_EXT%\odf4ms\basis-link
+
+mkdir: %_DEST%\xml%_EXT%\registry\spool
+mkdir: %_DEST%\xml%_EXT%\registry\spool\org
+mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice
+mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office
+mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office\Jobs
+
+..\%__SRC%\class\*.jar %_DEST%\bin%_EXT%\*.jar
+..\%__SRC%\misc\registry\spool\org\openoffice\Office\Jobs\*.xcu %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office\Jobs
diff --git a/desktop/qa/deployment_misc/makefile.mk b/desktop/qa/deployment_misc/makefile.mk
new file mode 100644
index 000000000000..15faef0dc46e
--- /dev/null
+++ b/desktop/qa/deployment_misc/makefile.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ := ..$/..
+PRJNAME := desktop
+TARGET := qa_deployment_misc
+
+ENABLE_EXCEPTIONS := TRUE
+
+.INCLUDE: settings.mk
+.INCLUDE: $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+
+CFLAGSCXX += $(CPPUNIT_CFLAGS)
+DLLPRE = # no leading "lib" on .so files
+
+SHL1TARGET = $(TARGET)
+SHL1OBJS = $(SLO)$/test_dp_version.obj
+SHL1STDLIBS = $(CPPUNITLIB) $(DEPLOYMENTMISCLIB) $(SALLIB) $(TESTSHL2LIB)
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(SHL1OBJS)
+
+.INCLUDE: target.mk
+
+ALLTAR: test
+
+test .PHONY: $(SHL1TARGETN)
+ $(TESTSHL2) $(SHL1TARGETN)
diff --git a/desktop/qa/deployment_misc/test_dp_version.cxx b/desktop/qa/deployment_misc/test_dp_version.cxx
new file mode 100644
index 000000000000..7b974a8bae73
--- /dev/null
+++ b/desktop/qa/deployment_misc/test_dp_version.cxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "testshl/simpleheader.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+
+#include "../../source/deployment/inc/dp_version.hxx"
+
+namespace {
+
+class Test: public ::CppUnit::TestFixture {
+public:
+ void test();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::test() {
+ struct Data {
+ rtl::OUString version1;
+ rtl::OUString version2;
+ ::dp_misc::Order order;
+ };
+ static Data const data[] = {
+ { rtl::OUString(),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0.0000.00.0")),
+ ::dp_misc::EQUAL },
+ { rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".01")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0.1")),
+ ::dp_misc::EQUAL },
+ { rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("10")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("2")),
+ ::dp_misc::GREATER },
+ { rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("9223372036854775808")),
+ // 2^63
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("9223372036854775807")),
+ ::dp_misc::GREATER }
+ };
+ for (::std::size_t i = 0; i < sizeof data / sizeof (Data); ++i) {
+ CPPUNIT_ASSERT_EQUAL(
+ data[i].order,
+ ::dp_misc::compareVersions(data[i].version1, data[i].version2));
+ static ::dp_misc::Order const reverse[3] = {
+ ::dp_misc::GREATER, ::dp_misc::EQUAL, ::dp_misc::LESS
+ };
+ CPPUNIT_ASSERT_EQUAL(
+ reverse[data[i].order],
+ ::dp_misc::compareVersions(data[i].version2, data[i].version1));
+ }
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "alltests");
+
+}
+
+NOADDITIONAL;
diff --git a/desktop/qa/deployment_misc/version.map b/desktop/qa/deployment_misc/version.map
new file mode 100644
index 000000000000..7321bbca16ad
--- /dev/null
+++ b/desktop/qa/deployment_misc/version.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ registerAllTestFunction;
+
+ local:
+ *;
+};
diff --git a/desktop/registry/data/org/openoffice/Office/Jobs.xcu b/desktop/registry/data/org/openoffice/Office/Jobs.xcu
new file mode 100644
index 000000000000..0572d96a2a63
--- /dev/null
+++ b/desktop/registry/data/org/openoffice/Office/Jobs.xcu
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************ -->
+<oor:component-data oor:name="Jobs" oor:package="org.openoffice.Office" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <node oor:name="Jobs">
+ <node oor:name="ProductRegistration" oor:op="replace">
+ <prop oor:name="Service">
+ <value>com.sun.star.comp.framework.DoRegistrationJob</value>
+ </prop>
+ <node oor:name="Arguments">
+ <prop oor:name="ProductName" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_PRODUCTNAME}</value>
+ </prop>
+ <prop oor:name="ProductVersion" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_PRODUCTVERSION}</value>
+ </prop>
+ <prop oor:name="ProductURN" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_URN}</value>
+ </prop>
+ <prop oor:name="ProductSource" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_SOURCE}</value>
+ </prop>
+ <prop oor:name="ProductParent" oor:op="replace" oor:type="xs:string">
+ <value>${SERVICETAG_PARENTNAME}</value>
+ </prop>
+ <prop oor:name="Vendor" oor:op="replace" oor:type="xs:string">
+ <value>Sun Microsystems, Inc.</value>
+ </prop>
+ <prop oor:name="RegistrationData" oor:op="replace" oor:type="xs:string">
+ <value>$(user)/registration.xml</value>
+ </prop>
+ <prop oor:name="RegistrationURL" oor:op="replace" oor:type="xs:string">
+ <value>${REGISTRATION_HOST}/register/${registry_urn}?product=${REGISTRATION_PRODUCT}&amp;locale=${locale}&amp;cid=${REGISTRATION_CID}</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ <node oor:name="Events">
+ <node oor:name="onRegisterNow" oor:op="fuse">
+ <node oor:name="JobList">
+ <node oor:name="ProductRegistration" oor:op="replace"/>
+ </node>
+ </node>
+ <node oor:name="onRegisterLater" oor:op="fuse">
+ <node oor:name="JobList">
+ <node oor:name="ProductRegistration" oor:op="replace"/>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/desktop/registry/data/org/openoffice/Office/makefile.mk b/desktop/registry/data/org/openoffice/Office/makefile.mk
new file mode 100644
index 000000000000..2ad8441ea3d3
--- /dev/null
+++ b/desktop/registry/data/org/openoffice/Office/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=data_registration
+PACKAGE=org.openoffice.Office
+
+ABSXCSROOT=$(SOLARXMLDIR)
+XCSROOT=..
+DTDDIR=$(ABSXCSROOT)
+XSLDIR=$(ABSXCSROOT)$/processing
+PROCESSOUT=$(MISC)$/$(TARGET)
+PROCESSORDIR=$(SOLARBINDIR)
+
+.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
+
+# --- Files -------------------------------------------------------
+
+.IF "$(BUILD_SPECIAL)"!=""
+
+XCUFILES= \
+ Jobs.xcu
+
+MODULEFILES=
+
+LOCALIZEDFILES=
+
+PACKAGEDIR=$(subst,.,$/ $(PACKAGE))
+SPOOLDIR=$(MISC)$/registry$/spool
+
+MYXCUFILES= \
+ $(SPOOLDIR)$/$(PACKAGEDIR)$/Jobs$/Jobs-registration.xcu
+
+.ELSE # "$(BUILD_SPECIAL)"!=""
+
+dummy:
+ @echo "Nothing to build"
+
+.ENDIF # "$(BUILD_SPECIAL)"!=""
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.ENDIF # L10N_framework
+ALLTAR : $(MYXCUFILES)
+
+$(SPOOLDIR)$/$(PACKAGEDIR)$/Jobs$/Jobs-registration.xcu : $(PROCESSOUT)$/registry$/data$/$/$(PACKAGEDIR)$/Jobs.xcu
+ @-$(MKDIRHIER) $(@:d)
+ @$(COPY) $< $@
+
diff --git a/desktop/scripts/basis-link b/desktop/scripts/basis-link
new file mode 100644
index 000000000000..3af84201e04f
--- /dev/null
+++ b/desktop/scripts/basis-link
@@ -0,0 +1 @@
+Basis \ No newline at end of file
diff --git a/desktop/scripts/makefile.mk b/desktop/scripts/makefile.mk
new file mode 100644
index 000000000000..5c412f818702
--- /dev/null
+++ b/desktop/scripts/makefile.mk
@@ -0,0 +1,67 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=desktop
+TARGET=scripts
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Targets -------------------------------------------------------------
+
+UNIXTEXT= \
+ $(MISC)$/sbase.sh \
+ $(MISC)$/scalc.sh \
+ $(MISC)$/sdraw.sh \
+ $(MISC)$/simpress.sh \
+ $(MISC)$/smaster.sh \
+ $(MISC)$/smath.sh \
+ $(MISC)$/sweb.sh \
+ $(MISC)$/swriter.sh \
+ $(MISC)$/mozwrapper.sh \
+ $(MISC)$/unoinfo.sh \
+ $(MISC)$/unopkg.sh
+
+.IF "$(OS)" != "MACOSX"
+
+ALLTAR: $(MISC)$/soffice.sh-expanded
+
+$(MISC)/soffice.sh-expanded: $(MISC)/soffice.sh
+.IF "$(OS)" == "LINUX" && "$(CPUNAME)" == "POWERPC"
+ $(SED) 's/^#@# //' $< > $@
+.ELSE
+ $(COPY) $< $@
+.ENDIF
+
+UNIXTEXT+= $(MISC)$/soffice.sh
+
+.ENDIF
+
+.INCLUDE : target.mk
diff --git a/desktop/scripts/mozwrapper.sh b/desktop/scripts/mozwrapper.sh
new file mode 100644
index 000000000000..89b6415358be
--- /dev/null
+++ b/desktop/scripts/mozwrapper.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# if mozilla is not found, specify full path here
+MOZILLA=mozilla
+
+if ${MOZILLA} -remote "openURL($1,new-window)" 2>&1 | egrep -si "not running on display"; then
+ ${MOZILLA} $1
+fi
diff --git a/desktop/scripts/odf-basis-link b/desktop/scripts/odf-basis-link
new file mode 100644
index 000000000000..3af84201e04f
--- /dev/null
+++ b/desktop/scripts/odf-basis-link
@@ -0,0 +1 @@
+Basis \ No newline at end of file
diff --git a/desktop/scripts/sbase.sh b/desktop/scripts/sbase.sh
new file mode 100644
index 000000000000..932a535e53bd
--- /dev/null
+++ b/desktop/scripts/sbase.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" -base "$@"
diff --git a/desktop/scripts/scalc.sh b/desktop/scripts/scalc.sh
new file mode 100644
index 000000000000..b1c3eebaff1f
--- /dev/null
+++ b/desktop/scripts/scalc.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" -calc "$@"
diff --git a/desktop/scripts/sdraw.sh b/desktop/scripts/sdraw.sh
new file mode 100644
index 000000000000..fe0338a89394
--- /dev/null
+++ b/desktop/scripts/sdraw.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" -draw "$@"
diff --git a/desktop/scripts/simpress.sh b/desktop/scripts/simpress.sh
new file mode 100644
index 000000000000..20cae509b10a
--- /dev/null
+++ b/desktop/scripts/simpress.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" -impress "$@"
diff --git a/desktop/scripts/smaster.sh b/desktop/scripts/smaster.sh
new file mode 100644
index 000000000000..affd55b265b0
--- /dev/null
+++ b/desktop/scripts/smaster.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" -global "$@"
diff --git a/desktop/scripts/smath.sh b/desktop/scripts/smath.sh
new file mode 100644
index 000000000000..ae4e3670a8d5
--- /dev/null
+++ b/desktop/scripts/smath.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" -math "$@"
diff --git a/desktop/scripts/so-basis-link b/desktop/scripts/so-basis-link
new file mode 100644
index 000000000000..3af84201e04f
--- /dev/null
+++ b/desktop/scripts/so-basis-link
@@ -0,0 +1 @@
+Basis \ No newline at end of file
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh
new file mode 100644
index 000000000000..0215f88d1ff0
--- /dev/null
+++ b/desktop/scripts/soffice.sh
@@ -0,0 +1,135 @@
+#!/bin/sh
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+#
+# STAR_PROFILE_LOCKING_DISABLED=1
+# export STAR_PROFILE_LOCKING_DISABLED
+#
+
+# file locking now enabled by default
+SAL_ENABLE_FILE_LOCKING=1
+export SAL_ENABLE_FILE_LOCKING
+
+# Uncomment the line below if you suspect that OpenGL is not
+# working on your system.
+# SAL_NOOPENGL=true; export SAL_NOOPENGL
+
+# The following is needed on Linux PPC with IBM j2sdk142:
+#@# export JITC_PROCESSOR_TYPE=6
+
+# resolve installation directory
+sd_cwd="`pwd`"
+if [ -h "$0" ] ; then
+ sd_basename=`basename "$0"`
+ sd_script=`ls -l "$0" | sed "s/.*${sd_basename} -> //g"`
+ cd "`dirname "$0"`"
+ cd "`dirname "$sd_script"`"
+else
+ cd "`dirname "$0"`"
+fi
+sd_prog=`pwd`
+cd "$sd_cwd"
+
+sd_binary=`basename "$0"`.bin
+
+#collect all bootstrap variables specified on the command line
+#so that they can be passed as arguments to javaldx later on
+for arg in $@
+do
+ case "$arg" in
+ -env:*) BOOTSTRAPVARS=$BOOTSTRAPVARS" ""$arg";;
+ esac
+done
+
+# pagein
+sd_pagein_args=@pagein-common
+for sd_arg in "$@"; do
+ case ${sd_arg} in
+ -calc)
+ sd_pagein_args="${sd_pagein_args} @pagein-calc"
+ break;
+ ;;
+ -draw)
+ sd_pagein_args="${sd_pagein_args} @pagein-draw"
+ break;
+ ;;
+ -impress)
+ sd_pagein_args="${sd_pagein_args} @pagein-impress"
+ break;
+ ;;
+ -writer)
+ sd_pagein_args="${sd_pagein_args} @pagein-writer"
+ break;
+ ;;
+ esac
+done
+"$sd_prog/../basis-link/program/pagein" -L"$sd_prog/../basis-link/program" \
+ ${sd_pagein_args}
+
+# extend the ld_library_path for java: javaldx checks the sofficerc for us
+if [ -x "$sd_prog/../basis-link/ure-link/bin/javaldx" ] ; then
+ my_path=`"$sd_prog/../basis-link/ure-link/bin/javaldx" $BOOTSTRAPVARS \
+ "-env:INIFILENAME=vnd.sun.star.pathname:$sd_prog/redirectrc"`
+ if [ -n "$my_path" ] ; then
+ LD_LIBRARY_PATH=$my_path${LD_LIBRARY_PATH+:$LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ fi
+fi
+
+unset XENVIRONMENT
+
+# uncomment line below to disable anti aliasing of fonts
+# SAL_ANTIALIAS_DISABLE=true; export SAL_ANTIALIAS_DISABLE
+
+# uncomment line below if you encounter problems starting soffice on your system
+# SAL_NO_XINITTHREADS=true; export SAL_NO_XINITTHREADS
+
+# read database entries for Adabas D
+if [ -f /etc/adabasrc ]; then
+ . /etc/adabasrc
+fi
+
+# execute soffice binary
+"$sd_prog/$sd_binary" "$@" &
+trap 'kill -9 $!' TERM
+wait $!
+sd_ret=$?
+
+while [ $sd_ret -eq 79 -o $sd_ret -eq 81 ]
+do
+ if [ $sd_ret -eq 79 ]; then
+ "$sd_prog/$sd_binary" ""$BOOTSTRAPVARS"" &
+ elif [ $sd_ret -eq 81 ]; then
+ "$sd_prog/$sd_binary" "$@" &
+ fi
+
+ wait $!
+ sd_ret=$?
+done
+
+exit $sd_ret
diff --git a/desktop/scripts/sweb.sh b/desktop/scripts/sweb.sh
new file mode 100644
index 000000000000..6d814e26e8aa
--- /dev/null
+++ b/desktop/scripts/sweb.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" -web "$@"
diff --git a/desktop/scripts/swriter.sh b/desktop/scripts/swriter.sh
new file mode 100644
index 000000000000..34ca9fee30c7
--- /dev/null
+++ b/desktop/scripts/swriter.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cmd=`dirname "$0"`/soffice
+exec "$cmd" -writer "$@"
diff --git a/desktop/scripts/unoinfo.sh b/desktop/scripts/unoinfo.sh
new file mode 100644
index 000000000000..081e414365cf
--- /dev/null
+++ b/desktop/scripts/unoinfo.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+set -e
+
+# resolve installation directory
+if [ -h "$0" ] ; then
+ sd_basename=`basename "$0"`
+ sd_script=`ls -l "$0" | sed "s/.*${sd_basename} -> //g"`
+ cd "`dirname "$0"`"
+ cd "`dirname "$sd_script"`"
+else
+ cd "`dirname "$0"`"
+fi
+sd_prog=`pwd`
+
+case $1 in
+c++)
+ printf '%s' "$sd_prog/../basis-link/ure-link/lib"
+ ;;
+java)
+ printf '0%s\0%s\0%s\0%s\0%s' \
+ "$sd_prog/../basis-link/ure-link/share/java/ridl.jar" \
+ "$sd_prog/../basis-link/ure-link/share/java/jurt.jar" \
+ "$sd_prog/../basis-link/ure-link/share/java/juh.jar" \
+ "$sd_prog/../basis-link/program/classes/unoil.jar" "$sd_prog"
+ ;;
+*)
+ exit 1
+ ;;
+esac
diff --git a/desktop/scripts/unopkg.sh b/desktop/scripts/unopkg.sh
new file mode 100644
index 000000000000..0fe319735c06
--- /dev/null
+++ b/desktop/scripts/unopkg.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+# enable file locking
+SAL_ENABLE_FILE_LOCKING=1
+export SAL_ENABLE_FILE_LOCKING
+
+# resolve installation directory
+sd_cwd="`pwd`"
+if [ -h "$0" ] ; then
+ sd_basename=`basename "$0"`
+ sd_script=`ls -l "$0" | sed "s/.*${sd_basename} -> //g"`
+ cd "`dirname "$0"`"
+ cd "`dirname "$sd_script"`"
+else
+ cd "`dirname "$0"`"
+fi
+sd_prog=`pwd`
+cd "$sd_cwd"
+
+#collect all bootstrap variables specified on the command line
+#so that they can be passed as arguments to javaldx later on
+for arg in $@
+do
+ case "$arg" in
+ -env:*) BOOTSTRAPVARS=$BOOTSTRAPVARS" ""$arg";;
+ esac
+done
+
+# extend the ld_library_path for java: javaldx checks the sofficerc for us
+if [ -x "$sd_prog/../basis-link/ure-link/bin/javaldx" ] ; then
+ my_path=`"$sd_prog/../basis-link/ure-link/bin/javaldx" $BOOTSTRAPVARS \
+ "-env:INIFILENAME=vnd.sun.star.pathname:$sd_prog/redirectrc"`
+ if [ -n "$my_path" ] ; then
+ LD_LIBRARY_PATH=$my_path${LD_LIBRARY_PATH+:$LD_LIBRARY_PATH}
+ export LD_LIBRARY_PATH
+ fi
+fi
+
+unset XENVIRONMENT
+
+# uncomment line below to disable anti aliasing of fonts
+# SAL_ANTIALIAS_DISABLE=true; export SAL_ANTIALIAS_DISABLE
+
+# uncomment line below if you encounter problems starting soffice on your system
+# SAL_NO_XINITTHREADS=true; export SAL_NO_XINITTHREADS
+
+# execute binary
+exec "$sd_prog/unopkg.bin" "$@" \
+ "-env:INIFILENAME=vnd.sun.star.pathname:$sd_prog/redirectrc"
+
diff --git a/desktop/scripts/ure-link b/desktop/scripts/ure-link
new file mode 100644
index 000000000000..dd0ecb6115e8
--- /dev/null
+++ b/desktop/scripts/ure-link
@@ -0,0 +1 @@
+..\URE \ No newline at end of file
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
new file mode 100644
index 000000000000..731ffe85d83b
--- /dev/null
+++ b/desktop/source/app/app.cxx
@@ -0,0 +1,3045 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <memory>
+#include <unistd.h>
+#include "app.hxx"
+#include "desktop.hrc"
+#include "appinit.hxx"
+#include "officeipcthread.hxx"
+#include "cmdlineargs.hxx"
+#include "desktopresid.hxx"
+#include "dispatchwatcher.hxx"
+#include "configinit.hxx"
+#include "lockfile.hxx"
+#include "checkinstall.hxx"
+#include "cmdlinehelp.hxx"
+#include "userinstall.hxx"
+#include "desktopcontext.hxx"
+#include "exithelper.hxx"
+#include "../migration/pages.hxx"
+
+#include <svtools/javacontext.hxx>
+#include <com/sun/star/frame/XSessionManagerListener.hpp>
+#include <com/sun/star/frame/XSynchronousDispatch.hpp>
+#include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
+#include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InstallationIncompleteException.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/task/XRestartManager.hpp>
+#ifndef _COM_SUN_STAR_TASK_XJOBEXECUTOR_HPP_
+#include <com/sun/star/task/XJob.hpp>
+#endif
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/ui/XUIElementFactoryRegistration.hpp>
+#include <com/sun/star/frame/XUIControllerRegistration.hpp>
+
+#include <com/sun/star/java/XJavaVM.hpp>
+#include <tools/testtoolloader.hxx>
+#include <tools/solar.h>
+#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
+#include <toolkit/unohlp.hxx>
+#endif
+#include <vos/security.hxx>
+#include <vos/ref.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/configurationhelper.hxx>
+#ifndef _UTL__HXX_
+#include <unotools/configmgr.hxx>
+#endif
+#include <unotools/configitem.hxx>
+#include <unotools/confignode.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <tools/tempfile.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <osl/module.h>
+#include <osl/file.hxx>
+#include <osl/signal.h>
+#include <rtl/uuid.h>
+#include <unotools/pathoptions.hxx>
+#include <svl/languageoptions.hxx>
+#include <unotools/internaloptions.hxx>
+#include <svtools/miscopt.hxx>
+#include <svtools/menuoptions.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <unotools/syslocale.hxx>
+#include <svl/folderrestriction.hxx>
+#include <unotools/tempfile.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/instance.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/help.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/sfx.hrc>
+#include <ucbhelper/contentbroker.hxx>
+#include <unotools/bootstrap.hxx>
+#include <cppuhelper/bootstrap.hxx>
+
+#include "vos/process.hxx"
+
+#include <svtools/fontsubstconfig.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <svtools/apearcfg.hxx>
+#include <unotools/misccfg.hxx>
+#include <svtools/filter.hxx>
+#include <unotools/regoptions.hxx>
+
+#include "langselect.hxx"
+
+#define DEFINE_CONST_UNICODE(CONSTASCII) UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
+#define U2S(STRING) ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8)
+
+using namespace vos;
+using namespace rtl;
+
+//Gives an ICE with MSVC6
+//namespace css = ::com::sun::star;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+//using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::system;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::container;
+
+namespace css = ::com::sun::star;
+
+ResMgr* desktop::Desktop::pResMgr = 0;
+
+namespace desktop
+{
+
+static SalMainPipeExchangeSignalHandler* pSignalHandler = 0;
+static sal_Bool _bCrashReporterEnabled = sal_True;
+
+static const ::rtl::OUString CFG_PACKAGE_COMMON_HELP ( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Office.Common/Help"));
+static const ::rtl::OUString CFG_PATH_REG ( RTL_CONSTASCII_USTRINGPARAM( "Registration" ));
+static const ::rtl::OUString CFG_ENTRY_REGURL ( RTL_CONSTASCII_USTRINGPARAM( "URL" ));
+static const ::rtl::OUString CFG_ENTRY_TEMPLATEREGURL ( RTL_CONSTASCII_USTRINGPARAM( "TemplateURL" ));
+
+// ----------------------------------------------------------------------------
+
+ResMgr* Desktop::GetDesktopResManager()
+{
+ if ( !Desktop::pResMgr )
+ {
+ String aMgrName = String::CreateFromAscii( "dkt" );
+
+ // Create desktop resource manager and bootstrap process
+ // was successful. Use default way to get language specific message.
+ if ( Application::IsInExecute() )
+ Desktop::pResMgr = ResMgr::CreateResMgr( U2S( aMgrName ));
+
+ if ( !Desktop::pResMgr )
+ {
+ // Use VCL to get the correct language specific message as we
+ // are in the bootstrap process and not able to get the installed
+ // language!!
+/*
+ LanguageType aLanguageType = LANGUAGE_DONTKNOW;
+
+ Desktop::pResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLanguageType );
+ AllSettings as = GetSettings();
+ as.SetUILanguage(aLanguageType);
+ SetSettings(as);
+*/
+ // LanguageSelection langselect;
+ OUString aUILocaleString = LanguageSelection::getLanguageString();
+ sal_Int32 nIndex = 0;
+ OUString aLanguage = aUILocaleString.getToken( 0, '-', nIndex);
+ OUString aCountry = aUILocaleString.getToken( 0, '-', nIndex);
+ OUString aVariant = aUILocaleString.getToken( 0, '-', nIndex);
+
+ ::com::sun::star::lang::Locale aLocale( aLanguage, aCountry, aVariant );
+
+ Desktop::pResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale);
+ AllSettings as = GetSettings();
+ as.SetUILocale(aLocale);
+ SetSettings(as);
+ }
+ }
+
+ return Desktop::pResMgr;
+}
+
+// ----------------------------------------------------------------------------
+// Get a message string securely. There is a fallback string if the resource
+// is not available.
+
+OUString Desktop::GetMsgString( USHORT nId, const OUString& aFaultBackMsg )
+{
+ ResMgr* resMgr = GetDesktopResManager();
+ if ( !resMgr )
+ return aFaultBackMsg;
+ else
+ return OUString( String( ResId( nId, *resMgr )));
+}
+
+OUString MakeStartupErrorMessage(OUString const & aErrorMessage)
+{
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CANNOT_START, *pResMgr))) );
+ else
+ aDiagnosticMessage.appendAscii( "The program cannot be started." );
+
+ aDiagnosticMessage.appendAscii( "\n" );
+
+ aDiagnosticMessage.append( aErrorMessage );
+
+ return aDiagnosticMessage.makeStringAndClear();
+}
+
+OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
+{
+ OUStringBuffer aDiagnosticMessage( 200 );
+
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS, *pResMgr ))) );
+ else
+ aDiagnosticMessage.appendAscii( "The program cannot be started." );
+
+ if ( aInternalErrMsg.getLength() > 0 )
+ {
+ aDiagnosticMessage.appendAscii( "\n\n" );
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_INTERNAL_ERRMSG, *pResMgr ))) );
+ else
+ aDiagnosticMessage.appendAscii( "The following internal error has occured:\n\n" );
+ aDiagnosticMessage.append( aInternalErrMsg );
+ }
+
+ return aDiagnosticMessage.makeStringAndClear();
+}
+
+//=============================================================================
+// shows a simple error box with the given message ... but exits from these process !
+//
+// Fatal errors cant be solved by the process ... nor any recovery can help.
+// Mostly the installation was damaged and must be repaired manually .. or by calling
+// setup again.
+//
+// On the other side we must make sure that no further actions will be possible within
+// the current office process ! No pipe requests, no menu/toolbar/shortuct actions
+// are allowed. Otherwise we will force a "crash inside a crash".
+//
+// Thats why we have to use a special native message box here which does not use yield :-)
+//=============================================================================
+void FatalError(const ::rtl::OUString& sMessage)
+{
+ ::rtl::OUString sProductKey = ::utl::Bootstrap::getProductKey();
+ if ( ! sProductKey.getLength())
+ {
+ ::vos::OStartupInfo aInfo;
+ aInfo.getExecutableFile( sProductKey );
+
+ ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
+ if ( nLastIndex > 0 )
+ sProductKey = sProductKey.copy( nLastIndex+1 );
+ }
+
+ ::rtl::OUStringBuffer sTitle (128);
+ sTitle.append (sProductKey );
+ sTitle.appendAscii (" - Fatal Error");
+
+ Application::ShowNativeErrorBox (sTitle.makeStringAndClear (), sMessage);
+ _exit(ExitHelper::E_FATAL_ERROR);
+}
+
+static bool ShouldSuppressUI(CommandLineArgs* pCmdLine)
+{
+ return pCmdLine->IsInvisible() ||
+ pCmdLine->IsHeadless() ||
+ pCmdLine->IsQuickstart();
+}
+
+CommandLineArgs* Desktop::GetCommandLineArgs()
+{
+ static CommandLineArgs* pArgs = 0;
+ if ( !pArgs )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pArgs )
+ {
+ pArgs = new CommandLineArgs;
+ }
+ }
+
+ return pArgs;
+}
+
+sal_Bool InitConfiguration()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (jb99855) ::InitConfiguration" );
+
+ Reference< XMultiServiceFactory > xProvider( CreateApplicationConfigurationProvider( ) );
+ return xProvider.is();
+}
+
+namespace
+{
+ struct BrandName
+ : public rtl::Static< String, BrandName > {};
+ struct Version
+ : public rtl::Static< String, Version > {};
+ struct AboutBoxVersion
+ : public rtl::Static< String, AboutBoxVersion > {};
+ struct OOOVendor
+ : public rtl::Static< String, OOOVendor > {};
+ struct Extension
+ : public rtl::Static< String, Extension > {};
+ struct XMLFileFormatName
+ : public rtl::Static< String, XMLFileFormatName > {};
+ struct XMLFileFormatVersion
+ : public rtl::Static< String, XMLFileFormatVersion > {};
+ struct WriterCompatibilityVersionOOo11
+ : public rtl::Static< String, WriterCompatibilityVersionOOo11 > {};
+}
+
+void ReplaceStringHookProc( UniString& rStr )
+{
+ static int nAll = 0, nPro = 0;
+
+ nAll++;
+ if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
+ {
+ String &rBrandName = BrandName::get();
+ String &rVersion = Version::get();
+ String &rAboutBoxVersion = AboutBoxVersion::get();
+ String &rExtension = Extension::get();
+ String &rXMLFileFormatName = XMLFileFormatName::get();
+ String &rXMLFileFormatVersion = XMLFileFormatVersion::get();
+
+ if ( !rBrandName.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
+ aRet >>= aTmp;
+ rBrandName = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATNAME );
+ aRet >>= aTmp;
+ rXMLFileFormatName = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATVERSION );
+ aRet >>= aTmp;
+ rXMLFileFormatVersion = 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", rBrandName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
+ rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATNAME", rXMLFileFormatName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATVERSION", rXMLFileFormatVersion );
+ }
+ if ( rStr.SearchAscii( "%OOOVENDOR" ) != STRING_NOTFOUND )
+ {
+ String &rOOOVendor = OOOVendor::get();
+
+ if ( !rOOOVendor.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::OOOVENDOR );
+ aRet >>= aTmp;
+ rOOOVendor = aTmp;
+
+ }
+ rStr.SearchAndReplaceAllAscii( "%OOOVENDOR" ,rOOOVendor );
+ }
+
+ if ( rStr.SearchAscii( "%WRITERCOMPATIBILITYVERSIONOOO11" ) != STRING_NOTFOUND )
+ {
+ String &rWriterCompatibilityVersionOOo11 = WriterCompatibilityVersionOOo11::get();
+ if ( !rWriterCompatibilityVersionOOo11.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::WRITERCOMPATIBILITYVERSIONOOO11 );
+ aRet >>= aTmp;
+ rWriterCompatibilityVersionOOo11 = aTmp;
+ }
+
+ rStr.SearchAndReplaceAllAscii( "%WRITERCOMPATIBILITYVERSIONOOO11",
+ rWriterCompatibilityVersionOOo11 );
+ }
+}
+
+Desktop::Desktop()
+: m_bServicesRegistered( false )
+, m_aBootstrapError( BE_OK )
+, m_pLockfile( NULL )
+{
+ RTL_LOGFILE_TRACE( "desktop (cd100003) ::Desktop::Desktop" );
+}
+
+Desktop::~Desktop()
+{
+}
+
+void Desktop::Init()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" );
+ SetBootstrapStatus(BS_OK);
+
+ // create service factory...
+ Reference < XMultiServiceFactory > rSMgr = CreateApplicationServiceManager();
+ if( rSMgr.is() )
+ {
+ ::comphelper::setProcessServiceFactory( rSMgr );
+ }
+ else
+ {
+ SetBootstrapError( BE_UNO_SERVICEMANAGER );
+ }
+
+ if ( GetBootstrapError() == BE_OK )
+ {
+ // prepare language
+ if ( !LanguageSelection::prepareLanguage() )
+ {
+ if ( LanguageSelection::getStatus() == LanguageSelection::LS_STATUS_CANNOT_DETERMINE_LANGUAGE )
+ SetBootstrapError( BE_LANGUAGE_MISSING );
+ else
+ SetBootstrapError( BE_OFFICECONFIG_BROKEN );
+ }
+ }
+
+ if ( GetBootstrapError() == BE_OK )
+ {
+ CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
+#ifdef UNX
+ // check whether we need to print cmdline help
+ if ( pCmdLineArgs->IsHelp() ) {
+ displayCmdlineHelp();
+ SetBootstrapStatus(BS_TERMINATE);
+ }
+#endif
+ // start ipc thread only for non-remote offices
+ RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) ::OfficeIPCThread::EnableOfficeIPCThread" );
+ OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread();
+ if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR )
+ {
+ SetBootstrapError( BE_PATHINFO_MISSING );
+ }
+ else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE )
+ {
+ // 2nd office startup should terminate after sending cmdlineargs through pipe
+ SetBootstrapStatus(BS_TERMINATE);
+ }
+ else if ( pCmdLineArgs->IsHelp() )
+ {
+ // disable IPC thread in an instance that is just showing a help message
+ OfficeIPCThread::DisableOfficeIPCThread();
+ }
+ pSignalHandler = new SalMainPipeExchangeSignalHandler;
+ }
+}
+
+void Desktop::DeInit()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::DeInit" );
+
+ try {
+ // instead of removing of the configManager just let it commit all the changes
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ utl::ConfigManager::GetConfigManager()->StoreConfigItems();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+
+ // close splashscreen if it's still open
+ CloseSplashScreen();
+ Reference<XMultiServiceFactory> xXMultiServiceFactory(::comphelper::getProcessServiceFactory());
+ DestroyApplicationServiceManager( xXMultiServiceFactory );
+ // nobody should get a destroyd service factory...
+ ::comphelper::setProcessServiceFactory( NULL );
+
+ // clear lockfile
+ if (m_pLockfile != NULL)
+ m_pLockfile->clean();
+
+ OfficeIPCThread::DisableOfficeIPCThread();
+ if( pSignalHandler )
+ DELETEZ( pSignalHandler );
+ } catch (RuntimeException&) {
+ // someone threw an exception during shutdown
+ // this will leave some garbage behind..
+ }
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::DeInit" );
+}
+
+BOOL Desktop::QueryExit()
+{
+ try
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ utl::ConfigManager::GetConfigManager()->StoreConfigItems();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ }
+ catch ( RuntimeException& )
+ {
+ }
+
+ const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
+
+ Reference< ::com::sun::star::frame::XDesktop >
+ xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+
+ Reference < ::com::sun::star::beans::XPropertySet > xPropertySet( xDesktop, UNO_QUERY );
+ if ( xPropertySet.is() )
+ {
+ Any a;
+ a <<= (sal_Bool)sal_True;
+ xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
+ }
+
+ BOOL bExit = ( !xDesktop.is() || xDesktop->terminate() );
+
+
+ if ( !bExit && xPropertySet.is() )
+ {
+ Any a;
+ a <<= (sal_Bool)sal_False;
+ xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
+ }
+ else
+ {
+ try
+ {
+ // it is no problem to call DisableOfficeIPCThread() more than once
+ // it also looks to be threadsafe
+ OfficeIPCThread::DisableOfficeIPCThread();
+ }
+ catch ( RuntimeException& )
+ {
+ }
+
+ if (m_pLockfile != NULL) m_pLockfile->clean();
+ }
+
+ return bExit;
+}
+
+void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
+{
+ if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
+ {
+ sal_Bool bWorkstationInstallation = sal_False;
+ ::rtl::OUString aBaseInstallURL;
+ ::rtl::OUString aUserInstallURL;
+ ::rtl::OUString aProductKey;
+ ::rtl::OUString aTemp;
+ ::vos::OStartupInfo aInfo;
+
+ aInfo.getExecutableFile( aProductKey );
+ sal_uInt32 lastIndex = aProductKey.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ aProductKey = aProductKey.copy( lastIndex+1 );
+
+ aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
+ if ( aTemp.getLength() > 0 )
+ aProductKey = aTemp;
+
+ ::utl::Bootstrap::PathStatus aBaseInstallStatus = ::utl::Bootstrap::locateBaseInstallation( aBaseInstallURL );
+ ::utl::Bootstrap::PathStatus aUserInstallStatus = ::utl::Bootstrap::locateUserInstallation( aUserInstallURL );
+
+ if (( aBaseInstallStatus == ::utl::Bootstrap::PATH_EXISTS &&
+ aUserInstallStatus == ::utl::Bootstrap::PATH_EXISTS ))
+ {
+ if ( aBaseInstallURL != aUserInstallURL )
+ bWorkstationInstallation = sal_True;
+ }
+
+ OUString aMessage;
+ OUStringBuffer aBuffer( 100 );
+ aBuffer.append( aDiagnosticMessage );
+
+ aBuffer.appendAscii( "\n" );
+
+ ErrorBox aBootstrapFailedBox( NULL, WB_OK, aMessage );
+ aBootstrapFailedBox.SetText( aProductKey );
+ aBootstrapFailedBox.Execute();
+ }
+}
+
+// Create a error message depending on bootstrap failure code and an optional file url
+::rtl::OUString Desktop::CreateErrorMsgString(
+ utl::Bootstrap::FailureCode nFailureCode,
+ const ::rtl::OUString& aFileURL )
+{
+ OUString aMsg;
+ OUString aFilePath;
+ sal_Bool bFileInfo = sal_True;
+
+ switch ( nFailureCode )
+ {
+ /// the shared installation directory could not be located
+ case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The installation path is not available." )) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ /// the bootstrap INI file could not be found or read
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
+ }
+ break;
+
+ /// the bootstrap INI is missing a required entry
+ /// the bootstrap INI contains invalid data
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is corrupt." )) );
+ }
+ break;
+
+ /// the version locator INI file could not be found or read
+ case ::utl::Bootstrap::MISSING_VERSION_FILE:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
+ }
+ break;
+
+ /// the version locator INI has no entry for this version
+ case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The main configuration file \"$1\" does not support the current version." )) );
+ }
+ break;
+
+ /// the user installation directory does not exist
+ case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration directory \"$1\" is missing." )) );
+ }
+ break;
+
+ /// some bootstrap data was invalid in unexpected ways
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "An internal failure occurred." )) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
+ {
+ // This needs to be improved, see #i67575#:
+ aMsg = OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Invalid version file entry" ) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ case ::utl::Bootstrap::NO_FAILURE:
+ {
+ OSL_ASSERT(false);
+ }
+ break;
+ }
+
+ if ( bFileInfo )
+ {
+ String aMsgString( aMsg );
+
+ osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
+
+ aMsgString.SearchAndReplaceAscii( "$1", aFilePath );
+ aMsg = aMsgString;
+ }
+
+ return MakeStartupErrorMessage( aMsg );
+}
+
+void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError )
+{
+ if ( aBootstrapError == BE_PATHINFO_MISSING )
+ {
+ OUString aErrorMsg;
+ OUString aBuffer;
+ utl::Bootstrap::Status aBootstrapStatus;
+ utl::Bootstrap::FailureCode nFailureCode;
+
+ aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
+ if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
+ {
+ switch ( nFailureCode )
+ {
+ case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
+ {
+ aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
+ }
+ break;
+
+ /// the bootstrap INI file could not be found or read
+ /// the bootstrap INI is missing a required entry
+ /// the bootstrap INI contains invalid data
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
+ {
+ OUString aBootstrapFileURL;
+
+ utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
+ }
+ break;
+
+ /// the version locator INI file could not be found or read
+ /// the version locator INI has no entry for this version
+ /// the version locator INI entry is not a valid directory URL
+ case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_VERSION_FILE:
+ {
+ OUString aVersionFileURL;
+
+ utl::Bootstrap::locateVersionFile( aVersionFileURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
+ }
+ break;
+
+ /// the user installation directory does not exist
+ case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
+ {
+ OUString aUserInstallationURL;
+
+ utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
+ }
+ break;
+
+ case ::utl::Bootstrap::NO_FAILURE:
+ {
+ OSL_ASSERT(false);
+ }
+ break;
+ }
+
+ HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
+ }
+ }
+ else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
+ {
+ // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
+ // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
+
+ // When UNO is not properly initialized, all kinds of things can fail
+ // and cause the process to crash (e.g., a call to GetMsgString may
+ // crash when somewhere deep within that call Any::operator <= is used
+ // with a PropertyValue, and no binary UNO type description for
+ // PropertyValue is available). To give the user a hint even if
+ // generating and displaying a message box below crashes, print a
+ // hard-coded message on stderr first:
+ fputs(
+ aBootstrapError == BE_UNO_SERVICEMANAGER
+ ? ("The application cannot be started. " "\n"
+ "The component manager is not available." "\n")
+ // STR_BOOTSTRAP_ERR_CANNOT_START, STR_BOOTSTRAP_ERR_NO_SERVICE
+ : ("The application cannot be started. " "\n"
+ "The configuration service is not available." "\n"),
+ // STR_BOOTSTRAP_ERR_CANNOT_START,
+ // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
+ stderr);
+
+ // First sentence. We cannot bootstrap office further!
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ OUString aErrorMsg;
+
+ if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SERVICE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The service manager is not available." )) );
+ else
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration service is not available." )) );
+
+ aDiagnosticMessage.append( aErrorMsg );
+ aDiagnosticMessage.appendAscii( "\n" );
+
+ // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
+ // repair the installation with the setup executable besides the office executable. Now
+ // we have to ask the user to start the setup on CD/installation directory manually!!
+ OUString aStartSetupManually( GetMsgString(
+ STR_ASK_START_SETUP_MANUALLY,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Start setup application to repair the installation from CD, or the folder containing the installation packages." )) ));
+
+ aDiagnosticMessage.append( aStartSetupManually );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+
+ FatalError( aMessage);
+ }
+ else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "A general error occurred while accessing your central configuration." )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if ( aBootstrapError == BE_USERINSTALL_FAILED )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "User installation could not be completed" )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if ( aBootstrapError == BE_LANGUAGE_MISSING )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString(
+ //@@@ FIXME: should use an own resource string => #i36213#
+ STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Language could not be determined." )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage(
+ aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
+ ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS ))
+ {
+ OUString aUserInstallationURL;
+ OUString aUserInstallationPath;
+ OUString aMessage;
+ OUString aErrorMsg;
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
+
+ if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
+ aErrorMsg = GetMsgString(
+ STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "User installation could not be completed due to insufficient free disk space." )) );
+ else
+ aErrorMsg = GetMsgString(
+ STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "User installation could not be processed due to missing access rights." )) );
+
+ osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
+
+ aDiagnosticMessage.append( aErrorMsg );
+ aDiagnosticMessage.append( aUserInstallationPath );
+ aMessage = MakeStartupErrorMessage(
+ aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+
+ return;
+}
+
+
+void Desktop::retrieveCrashReporterState()
+{
+ static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
+ static const ::rtl::OUString CFG_PATH_CRASHREPORTER = ::rtl::OUString::createFromAscii("CrashReporter" );
+ static const ::rtl::OUString CFG_ENTRY_ENABLED = ::rtl::OUString::createFromAscii("Enabled" );
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ sal_Bool bEnabled( sal_True );
+ if ( xSMGR.is() )
+ {
+ css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_CRASHREPORTER,
+ CFG_ENTRY_ENABLED,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ aVal >>= bEnabled;
+ }
+ _bCrashReporterEnabled = bEnabled;
+}
+
+sal_Bool Desktop::isUIOnSessionShutdownAllowed()
+{
+ static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
+ static const ::rtl::OUString CFG_PATH_SESSION = ::rtl::OUString::createFromAscii("SessionShutdown" );
+ static const ::rtl::OUString CFG_ENTRY_UIENABLED = ::rtl::OUString::createFromAscii("DocumentStoreUIEnabled" );
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ sal_Bool bResult = sal_False;
+ if ( xSMGR.is() )
+ {
+ css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_SESSION,
+ CFG_ENTRY_UIENABLED,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ aVal >>= bResult;
+ }
+
+ return bResult;
+}
+
+//-----------------------------------------------
+/** @short check if crash reporter feature is enabled or
+ disabled.
+*/
+sal_Bool Desktop::isCrashReporterEnabled()
+{
+ return _bCrashReporterEnabled;
+}
+
+//-----------------------------------------------
+/** @short check if recovery must be started or not.
+
+ @param bCrashed [boolean ... out!]
+ the office crashed last times.
+ But may be there are no recovery data.
+ Usefull to trigger the error report tool without
+ showing the recovery UI.
+
+ @param bRecoveryDataExists [boolean ... out!]
+ there exists some recovery data.
+
+ @param bSessionDataExists [boolean ... out!]
+ there exists some session data.
+ Because the user may be logged out last time from it's
+ unix session...
+*/
+void impl_checkRecoveryState(sal_Bool& bCrashed ,
+ sal_Bool& bRecoveryDataExists,
+ sal_Bool& bSessionDataExists )
+{
+ static const ::rtl::OUString SERVICENAME_RECOVERYCORE = ::rtl::OUString::createFromAscii("com.sun.star.frame.AutoRecovery");
+ static const ::rtl::OUString PROP_CRASHED = ::rtl::OUString::createFromAscii("Crashed" );
+ static const ::rtl::OUString PROP_EXISTSRECOVERY = ::rtl::OUString::createFromAscii("ExistsRecoveryData" );
+ static const ::rtl::OUString PROP_EXISTSSESSION = ::rtl::OUString::createFromAscii("ExistsSessionData" );
+ static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
+ static const ::rtl::OUString CFG_PATH_RECOVERYINFO = ::rtl::OUString::createFromAscii("RecoveryInfo" );
+
+ bCrashed = sal_False;
+ bRecoveryDataExists = sal_False;
+ bSessionDataExists = sal_False;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xRecovery(
+ xSMGR->createInstance(SERVICENAME_RECOVERYCORE),
+ css::uno::UNO_QUERY_THROW);
+
+ xRecovery->getPropertyValue(PROP_CRASHED ) >>= bCrashed ;
+ xRecovery->getPropertyValue(PROP_EXISTSRECOVERY) >>= bRecoveryDataExists;
+ xRecovery->getPropertyValue(PROP_EXISTSSESSION ) >>= bSessionDataExists ;
+ }
+ catch(const css::uno::Exception&) {}
+}
+
+//-----------------------------------------------
+/* @short start the recovery wizard.
+
+ @param bEmergencySave
+ differs between EMERGENCY_SAVE and RECOVERY
+*/
+sal_Bool impl_callRecoveryUI(sal_Bool bEmergencySave ,
+ sal_Bool bCrashed ,
+ sal_Bool bExistsRecoveryData)
+{
+ static ::rtl::OUString SERVICENAME_RECOVERYUI = ::rtl::OUString::createFromAscii("com.sun.star.comp.svx.RecoveryUI" );
+ static ::rtl::OUString SERVICENAME_URLPARSER = ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" );
+ static ::rtl::OUString COMMAND_EMERGENCYSAVE = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doEmergencySave");
+ static ::rtl::OUString COMMAND_RECOVERY = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doAutoRecovery" );
+ static ::rtl::OUString COMMAND_CRASHREPORT = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doCrashReport" );
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ css::uno::Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
+ xSMGR->createInstance(SERVICENAME_RECOVERYUI),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::util::XURLTransformer > xURLParser(
+ xSMGR->createInstance(SERVICENAME_URLPARSER),
+ css::uno::UNO_QUERY_THROW);
+
+ css::util::URL aURL;
+ if (bEmergencySave)
+ aURL.Complete = COMMAND_EMERGENCYSAVE;
+ else
+ {
+ if (bExistsRecoveryData)
+ aURL.Complete = COMMAND_RECOVERY;
+ else
+ if (bCrashed && Desktop::isCrashReporterEnabled() )
+ aURL.Complete = COMMAND_CRASHREPORT;
+ }
+
+ sal_Bool bRet = sal_False;
+ if ( aURL.Complete.getLength() > 0 )
+ {
+ xURLParser->parseStrict(aURL);
+
+ css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
+ aRet >>= bRet;
+ }
+ return bRet;
+}
+
+/*
+ * Save all open documents so they will be reopened
+ * the next time the application ist started
+ *
+ * returns sal_True if at least one document could be saved...
+ *
+ */
+
+sal_Bool Desktop::_bTasksSaved = sal_False;
+
+sal_Bool Desktop::SaveTasks()
+{
+ return impl_callRecoveryUI(
+ sal_True , // sal_True => force emergency save
+ sal_False, // 2. and 3. param not used if 1. = true!
+ sal_False);
+}
+
+#ifdef MACOSX
+static void DoRestart()
+{
+ oslProcess process;
+ oslProcessError error;
+ OUString sExecutableFile;
+
+ osl_getExecutableFile( &sExecutableFile.pData );
+
+ error = osl_executeProcess(
+ sExecutableFile.pData,
+ NULL,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ &process
+ );
+}
+#endif
+
+USHORT Desktop::Exception(USHORT nError)
+{
+ // protect against recursive calls
+ static BOOL bInException = FALSE;
+
+ sal_uInt16 nOldMode = Application::GetSystemWindowMode();
+ Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
+ Application::SetDefDialogParent( NULL );
+
+ if ( bInException )
+ {
+ String aDoubleExceptionString;
+ Application::Abort( aDoubleExceptionString );
+ }
+
+ bInException = TRUE;
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+
+ // save all modified documents ... if it's allowed doing so.
+ sal_Bool bRestart = sal_False;
+ sal_Bool bAllowRecoveryAndSessionManagement = (
+ ( !pArgs->IsNoRestore() ) && // some use cases of office must work without recovery
+ ( !pArgs->IsHeadless() ) &&
+ ( !pArgs->IsServer() ) &&
+ (( nError & EXC_MAJORTYPE ) != EXC_DISPLAY ) && // recovery cant work without UI ... but UI layer seams to be the reason for this crash
+ ( Application::IsInExecute() ) // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
+ );
+ if ( bAllowRecoveryAndSessionManagement )
+ bRestart = SaveTasks();
+
+ // because there is no method to flush the condiguration data, we must dispose the ConfigManager
+ Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
+ if (xCFGFlush.is())
+ {
+ xCFGFlush->flush();
+ }
+ else
+ {
+ Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
+ if (xCFGDispose.is())
+ xCFGDispose->dispose();
+ }
+
+ switch( nError & EXC_MAJORTYPE )
+ {
+ case EXC_RSCNOTLOADED:
+ {
+ String aResExceptionString;
+ Application::Abort( aResExceptionString );
+ break;
+ }
+
+ case EXC_SYSOBJNOTCREATED:
+ {
+ String aSysResExceptionString;
+ Application::Abort( aSysResExceptionString );
+ break;
+ }
+
+ default:
+ {
+ if (m_pLockfile != NULL) {
+ m_pLockfile->clean();
+ }
+ if( bRestart )
+ {
+ OfficeIPCThread::DisableOfficeIPCThread();
+ if( pSignalHandler )
+ DELETEZ( pSignalHandler );
+#ifdef MACOSX
+ DoRestart();
+#endif
+ _exit( ExitHelper::E_CRASH_WITH_RESTART );
+ }
+ else
+ {
+ Application::Abort( String() );
+ }
+
+ break;
+ }
+ }
+
+ OSL_ASSERT(false); // unreachable
+ return 0;
+}
+
+void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
+{
+ HandleAppEvent( rAppEvent );
+}
+
+void Desktop::Main()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Main" );
+
+ // Remember current context object
+ com::sun::star::uno::ContextLayer layer(
+ com::sun::star::uno::getCurrentContext() );
+
+ BootstrapError eError = GetBootstrapError();
+ if ( eError != BE_OK )
+ {
+ HandleBootstrapErrors( eError );
+ return;
+ }
+
+ BootstrapStatus eStatus = GetBootstrapStatus();
+ if (eStatus == BS_TERMINATE) {
+ return;
+ }
+
+ // Detect desktop environment - need to do this as early as possible
+ com::sun::star::uno::setCurrentContext(
+ new DesktopContext( com::sun::star::uno::getCurrentContext() ) );
+
+ CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
+
+ // setup configuration error handling
+ ConfigurationErrorHandler aConfigErrHandler;
+ if (!ShouldSuppressUI(pCmdLineArgs))
+ aConfigErrHandler.activate();
+
+ ResMgr::SetReadStringHook( ReplaceStringHookProc );
+
+ // Startup screen
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main { OpenSplashScreen" );
+ OpenSplashScreen();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main } OpenSplashScreen" );
+
+ {
+ UserInstall::UserInstallError instErr_fin = UserInstall::finalize();
+ if ( instErr_fin != UserInstall::E_None)
+ {
+ OSL_ENSURE(sal_False, "userinstall failed");
+ if ( instErr_fin == UserInstall::E_NoDiskSpace )
+ HandleBootstrapErrors( BE_USERINSTALL_NOTENOUGHDISKSPACE );
+ else if ( instErr_fin == UserInstall::E_NoWriteAccess )
+ HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS );
+ else
+ HandleBootstrapErrors( BE_USERINSTALL_FAILED );
+ return;
+ }
+ // refresh path information
+ utl::Bootstrap::reloadData();
+ SetSplashScreenProgress(25);
+ }
+
+ Reference< XMultiServiceFactory > xSMgr =
+ ::comphelper::getProcessServiceFactory();
+
+ std::auto_ptr<SvtLanguageOptions> pLanguageOptions;
+ std::auto_ptr<SvtPathOptions> pPathOptions;
+
+ Reference < css::document::XEventListener > xGlobalBroadcaster;
+ try
+ {
+ RegisterServices( xSMgr );
+
+ //SetSplashScreenProgress(15);
+
+#ifndef UNX
+ if ( pCmdLineArgs->IsHelp() ) {
+ displayCmdlineHelp();
+ return;
+ }
+#endif
+
+ // check user installation directory for lockfile so we can be sure
+ // there is no other instance using our data files from a remote host
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main -> Lockfile" );
+ m_pLockfile = new Lockfile;
+ if ( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoLockcheck() && !m_pLockfile->check( Lockfile_execWarning )) {
+ // Lockfile exists, and user clicked 'no'
+ return;
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main <- Lockfile" );
+
+ // check if accessibility is enabled but not working and allow to quit
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ GetEnableATToolSupport" );
+ if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
+ {
+ BOOL bQuitApp;
+
+ if( !InitAccessBridge( true, bQuitApp ) )
+ if( bQuitApp )
+ return;
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} GetEnableATToolSupport" );
+
+ // terminate if requested...
+ if( pCmdLineArgs->IsTerminateAfterInit() ) return;
+
+
+ // Read the common configuration items for optimization purpose
+ if ( !InitializeConfiguration() ) return;
+
+ //SetSplashScreenProgress(20);
+
+ // set static variable to enabled/disable crash reporter
+ retrieveCrashReporterState();
+ if ( !isCrashReporterEnabled() )
+ {
+ osl_setErrorReporting( sal_False );
+ // disable stack trace feature
+ }
+
+ // create title string
+ sal_Bool bCheckOk = sal_False;
+ ::com::sun::star::lang::Locale aLocale;
+ String aMgrName = String::CreateFromAscii( "iso" );
+ ResMgr* pLabelResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale );
+ if ( !pLabelResMgr )
+ {
+ // no "iso" resource -> search for "ooo" resource
+ aMgrName = String::CreateFromAscii( "ooo" );
+ pLabelResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale);
+ }
+ String aTitle = pLabelResMgr ? String( ResId( RID_APPTITLE, *pLabelResMgr ) ) : String();
+ delete pLabelResMgr;
+/*
+ // locale and UI locale in AppSettings are now retrieved from configuration or system directly via SvtSysLocale
+ // no reason to set while starting
+ // set UI language and locale
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ set locale settings" );
+ //LanguageSelection langselect;
+ OUString aUILocaleString = LanguageSelection::getLanguageString();
+ Locale aUILocale = LanguageSelection::IsoStringToLocale(aUILocaleString);
+ LanguageType eLanguage = SvtSysLocale().GetLanguage();
+
+ // #i39040#, do not call anything between GetSettings and SetSettings that might have
+ // a side effect on the settings (like, eg, SvtSysLocaleOptions().GetLocaleLanguageType(),
+ // which changes the MiscSettings !!! )
+ AllSettings aSettings( Application::GetSettings() );
+ aSettings.SetUILocale( aUILocale );
+ aSettings.SetLanguage( eLanguage );
+ Application::SetSettings( aSettings );
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} set locale settings" );
+*/
+
+ // Check for StarOffice/Suite specific extensions runs also with OpenOffice installation sets
+ OUString aTitleString( aTitle );
+ bCheckOk = CheckInstallation( aTitleString );
+ if ( !bCheckOk )
+ return;
+ else
+ aTitle = aTitleString;
+
+#ifdef DBG_UTIL
+ //include version ID in non product builds
+ ::rtl::OUString aDefault;
+ aTitle += DEFINE_CONST_UNICODE(" [");
+ String aVerId( utl::Bootstrap::getBuildIdData( aDefault ));
+ aTitle += aVerId;
+ aTitle += ']';
+#endif
+
+ SetDisplayName( aTitle );
+// SetSplashScreenProgress(30);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create SvtPathOptions and SvtLanguageOptions" );
+ pPathOptions.reset( new SvtPathOptions);
+// SetSplashScreenProgress(40);
+// pLanguageOptions = new SvtLanguageOptions(sal_True);
+// SetSplashScreenProgress(45);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create SvtPathOptions and SvtLanguageOptions" );
+
+ // Check special env variable #111015#
+ std::vector< String > aUnrestrictedFolders;
+ svt::getUnrestrictedFolders( aUnrestrictedFolders );
+
+ if ( aUnrestrictedFolders.size() > 0 )
+ {
+ // Set different working directory. The first entry is
+ // the new work path.
+ String aWorkPath = aUnrestrictedFolders[0];
+ SvtPathOptions().SetWorkPath( aWorkPath );
+ }
+
+ // create service for loadin SFX (still needed in startup)
+ xGlobalBroadcaster = Reference < css::document::XEventListener >
+ ( xSMgr->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.GlobalEventBroadcaster" ) ), UNO_QUERY );
+
+ // initialize test-tool library (if available)
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ tools::InitTestToolLib" );
+ tools::InitTestToolLib();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} tools::InitTestToolLib" );
+
+ // Check if bundled or shared extensions were added /removed
+ // and process those extensions (has to be done before checking
+ // the extension dependencies!
+ SynchronizeExtensionRepositories();
+ bool bAbort = CheckExtensionDependencies();
+ if ( bAbort )
+ return;
+ // First Start Wizard allowed ?
+ if ( ! pCmdLineArgs->IsNoFirstStartWizard())
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ FirstStartWizard" );
+
+ if (IsFirstStartWizardNeeded())
+ {
+ ::utl::RegOptions().removeReminder(); // remove patch registration reminder
+ Reference< XJob > xFirstStartJob( xSMgr->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.comp.desktop.FirstStart" ) ), UNO_QUERY );
+ if (xFirstStartJob.is())
+ {
+ sal_Bool bDone = sal_False;
+ Sequence< NamedValue > lArgs(2);
+ lArgs[0].Name = ::rtl::OUString::createFromAscii("LicenseNeedsAcceptance");
+ lArgs[0].Value <<= LicenseNeedsAcceptance();
+ lArgs[1].Name = ::rtl::OUString::createFromAscii("LicensePath");
+ lArgs[1].Value <<= GetLicensePath();
+
+ xFirstStartJob->execute(lArgs) >>= bDone;
+ if ( !bDone )
+ {
+ return;
+ }
+ }
+ }
+ else if ( RegistrationPage::hasReminderDateCome() )
+ RegistrationPage::executeSingleMode();
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} FirstStartWizard" );
+ }
+
+ // keep a language options instance...
+ pLanguageOptions.reset( new SvtLanguageOptions(sal_True));
+
+ if (xGlobalBroadcaster.is())
+ {
+ css::document::EventObject aEvent;
+ aEvent.EventName = ::rtl::OUString::createFromAscii("OnStartApp");
+ xGlobalBroadcaster->notifyEvent(aEvent);
+ }
+
+ SetSplashScreenProgress(50);
+ // Backing Component
+ sal_Bool bCrashed = sal_False;
+ sal_Bool bExistsRecoveryData = sal_False;
+ sal_Bool bExistsSessionData = sal_False;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ impl_checkRecoveryState" );
+ impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} impl_checkRecoveryState" );
+
+ if (
+ (pCmdLineArgs->IsEmptyOrAcceptOnly() ) &&
+ (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) &&
+ (!bExistsRecoveryData ) &&
+ (!bExistsSessionData ) &&
+ (!Application::AnyInput( INPUT_APPEVENT ) )
+ )
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create BackingComponent" );
+ Reference< XFrame > xDesktopFrame( xSMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
+ if (xDesktopFrame.is())
+ {
+// SetSplashScreenProgress(60);
+ Reference< XFrame > xBackingFrame;
+ Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
+
+ xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
+ if (xBackingFrame.is())
+ xContainerWindow = xBackingFrame->getContainerWindow();
+ if (xContainerWindow.is())
+ {
+ // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank"
+ // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
+ // otherwise documents loaded into this frame will later on miss functionality depending on the style.
+ Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ OSL_ENSURE( pContainerWindow, "Desktop::Main: no implementation access to the frame's container window!" );
+ pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
+
+ SetSplashScreenProgress(75);
+ Sequence< Any > lArgs(1);
+ lArgs[0] <<= xContainerWindow;
+
+ Reference< XController > xBackingComp(
+ xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs),
+ UNO_QUERY);
+// SetSplashScreenProgress(80);
+ if (xBackingComp.is())
+ {
+ Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
+ // Attention: You MUST(!) call setComponent() before you call attachFrame().
+ // Because the backing component set the property "IsBackingMode" of the frame
+ // to true inside attachFrame(). But setComponent() reset this state everytimes ...
+ xBackingFrame->setComponent(xBackingWin, xBackingComp);
+ SetSplashScreenProgress(100);
+ xBackingComp->attachFrame(xBackingFrame);
+ CloseSplashScreen();
+ xContainerWindow->setVisible(sal_True);
+ }
+ }
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create BackingComponent" );
+ }
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& wte )
+ {
+ com::sun::star::uno::Exception te;
+ wte.TargetException >>= te;
+ FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
+ return;
+ }
+ catch ( com::sun::star::uno::Exception& e )
+ {
+ FatalError( MakeStartupErrorMessage(e.Message) );
+ return;
+ }
+ /*
+ catch ( ... )
+ {
+ FatalError( MakeStartupErrorMessage(
+ OUString::createFromAscii(
+ "Unknown error during startup (Office wrapper service).\nInstallation could be damaged.")));
+ return;
+ }
+ */
+// SetSplashScreenProgress(55);
+
+ SvtFontSubstConfig().Apply();
+
+ SvtTabAppearanceCfg aAppearanceCfg;
+ aAppearanceCfg.SetInitialized();
+ aAppearanceCfg.SetApplicationDefaults( this );
+ SvtAccessibilityOptions aOptions;
+ aOptions.SetVCLSettings();
+// SetSplashScreenProgress(60);
+
+ Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
+
+ sal_Bool bTerminateRequested = sal_False;
+
+ // Preload function depends on an initialized sfx application!
+ SetSplashScreenProgress(75);
+
+ sal_Bool bUseSystemFileDialog(sal_True);
+ if ( pCmdLineArgs->IsHeadless() )
+ {
+ // Ensure that we use not the system file dialogs as
+ // headless mode relies on Application::EnableHeadlessMode()
+ // which does only work for VCL dialogs!!
+ SvtMiscOptions aMiscOptions;
+ bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
+ aMiscOptions.SetUseSystemFileDialog( sal_False );
+ }
+
+ // use system window dialogs
+ Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG );
+
+// SetSplashScreenProgress(80);
+
+ if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() &&
+ !pCmdLineArgs->IsNoQuickstart() )
+ InitializeQuickstartMode( xSMgr );
+
+ RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) createInstance com.sun.star.frame.Desktop" );
+ try
+ {
+ Reference< XDesktop > xDesktop( xSMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
+ if ( xDesktop.is() )
+ xDesktop->addTerminateListener( new OfficeIPCThreadController );
+ SetSplashScreenProgress(100);
+ }
+ catch ( com::sun::star::uno::Exception& e )
+ {
+ FatalError( MakeStartupErrorMessage(e.Message) );
+ return;
+ }
+ /*
+ catch ( ... )
+ {
+ FatalError( MakeStartupErrorMessage(
+ OUString::createFromAscii(
+ "Unknown error during startup (TD/Desktop service).\nInstallation could be damaged.")));
+ return;
+ }
+ */
+
+ // Release solar mutex just before we wait for our client to connect
+ int nAcquireCount = 0;
+ ::vos::IMutex& rMutex = Application::GetSolarMutex();
+ if ( rMutex.tryToAcquire() )
+ nAcquireCount = Application::ReleaseSolarMutex() - 1;
+
+ // Post user event to startup first application component window
+ // We have to send this OpenClients message short before execute() to
+ // minimize the risk that this message overtakes type detection contruction!!
+ Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
+
+ // Post event to enable acceptors
+ Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
+
+ // The configuration error handler currently is only for startup
+ aConfigErrHandler.deactivate();
+
+ // Acquire solar mutex just before we enter our message loop
+ if ( nAcquireCount )
+ Application::AcquireSolarMutex( nAcquireCount );
+
+ // call Application::Execute to process messages in vcl message loop
+ RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Application::Execute()" );
+
+ Reference< ::com::sun::star::task::XRestartManager > xRestartManager;
+ try
+ {
+ // The JavaContext contains an interaction handler which is used when
+ // the creation of a Java Virtual Machine fails
+ com::sun::star::uno::ContextLayer layer2(
+ new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) );
+
+ ::comphelper::ComponentContext aContext( xSMgr );
+ xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
+ if ( !xRestartManager.is() || !xRestartManager->isRestartRequested( sal_True ) )
+ Execute();
+ }
+ catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg)
+ {
+ OfficeIPCThread::SetDowning();
+ FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
+ }
+ catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg)
+ {
+ OfficeIPCThread::SetDowning();
+ FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
+ }
+
+ // check whether the shutdown is caused by restart
+ sal_Bool bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
+
+ if (xGlobalBroadcaster.is())
+ {
+ css::document::EventObject aEvent;
+ aEvent.EventName = ::rtl::OUString::createFromAscii("OnCloseApp");
+ xGlobalBroadcaster->notifyEvent(aEvent);
+ }
+
+ delete pResMgr;
+ // Restore old value
+ if ( pCmdLineArgs->IsHeadless() )
+ SvtMiscOptions().SetUseSystemFileDialog( bUseSystemFileDialog );
+
+ // remove temp directory
+ RemoveTemporaryDirectory();
+ // The acceptors in the AcceptorMap must be released (in DeregisterServices)
+ // with the solar mutex unlocked, to avoid deadlock:
+ nAcquireCount = Application::ReleaseSolarMutex();
+ DeregisterServices();
+ Application::AcquireSolarMutex(nAcquireCount);
+ tools::DeInitTestToolLib();
+ // be sure that path/language options gets destroyed before
+ // UCB is deinitialized
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> dispose path/language options" );
+ pLanguageOptions.reset( 0 );
+ pPathOptions.reset( 0 );
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- dispose path/language options" );
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> deinit ucb" );
+ ::ucbhelper::ContentBroker::deinitialize();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- deinit ucb" );
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::Main" );
+ if ( bRestartRequested )
+ {
+#ifdef MACOSX
+ DoRestart();
+#endif
+ // wouldn't the solution be more clean if SalMain returns the exit code to the system?
+ _exit( ExitHelper::E_NORMAL_RESTART );
+ }
+}
+
+IMPL_LINK( Desktop, ImplInitFilterHdl, ConvertData*, pData )
+{
+ return GraphicFilter::GetGraphicFilter()->GetFilterCallback().Call( pData );
+}
+
+sal_Bool Desktop::InitializeConfiguration()
+{
+ sal_Bool bOk = sal_False;
+
+ try
+ {
+ bOk = InitConfiguration();
+ }
+ catch( ::com::sun::star::lang::ServiceNotRegisteredException& )
+ {
+ this->HandleBootstrapErrors( Desktop::BE_UNO_SERVICE_CONFIG_MISSING );
+ }
+ catch( ::com::sun::star::configuration::MissingBootstrapFileException& e )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE,
+ e.BootstrapFileURL ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::configuration::InvalidBootstrapFileException& e )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY,
+ e.BootstrapFileURL ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::configuration::InstallationIncompleteException& )
+ {
+ OUString aVersionFileURL;
+ OUString aMsg;
+ utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
+ if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
+ aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL );
+ else
+ aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL );
+
+ HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg );
+ }
+ catch ( com::sun::star::configuration::backend::BackendAccessException& exception)
+ {
+ // [cm122549] It is assumed in this case that the message
+ // coming from InitConfiguration (in fact CreateApplicationConf...)
+ // is suitable for display directly.
+ FatalError( MakeStartupErrorMessage( exception.Message ) );
+ }
+ catch ( com::sun::star::configuration::backend::BackendSetupException& exception)
+ {
+ // [cm122549] It is assumed in this case that the message
+ // coming from InitConfiguration (in fact CreateApplicationConf...)
+ // is suitable for display directly.
+ FatalError( MakeStartupErrorMessage( exception.Message ) );
+ }
+ catch ( ::com::sun::star::configuration::CannotLoadConfigurationException& )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
+ OUString() ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
+ OUString() ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+
+ return bOk;
+}
+
+sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr )
+{
+ try
+ {
+ // the shutdown icon sits in the systray and allows the user to keep
+ // the office instance running for quicker restart
+ // this will only be activated if -quickstart was specified on cmdline
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) createInstance com.sun.star.office.Quickstart" );
+
+ sal_Bool bQuickstart = GetCommandLineArgs()->IsQuickstart();
+ Sequence< Any > aSeq( 1 );
+ aSeq[0] <<= bQuickstart;
+
+ // Try to instanciate quickstart service. This service is not mandatory, so
+ // do nothing if service is not available
+
+ // #i105753# the following if was invented for performance
+ // unfortunately this broke the QUARTZ behavior which is to always run
+ // in quickstart mode since Mac applications do not usually quit
+ // when the last document closes
+ #ifndef QUARTZ
+ if ( bQuickstart )
+ #endif
+ {
+ Reference < XComponent > xQuickstart( rSMgr->createInstanceWithArguments(
+ DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" ), aSeq ),
+ UNO_QUERY );
+ }
+ return sal_True;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ return sal_False;
+ }
+}
+
+void Desktop::SystemSettingsChanging( AllSettings& rSettings, Window* )
+{
+ if ( !SvtTabAppearanceCfg::IsInitialized () )
+ return;
+
+# define DRAGFULL_OPTION_ALL \
+ ( DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE \
+ | DRAGFULL_OPTION_OBJECTMOVE | DRAGFULL_OPTION_OBJECTSIZE \
+ | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT \
+ | DRAGFULL_OPTION_SCROLL )
+# define DRAGFULL_OPTION_NONE ((sal_uInt32)~DRAGFULL_OPTION_ALL)
+
+ StyleSettings hStyleSettings = rSettings.GetStyleSettings();
+ MouseSettings hMouseSettings = rSettings.GetMouseSettings();
+
+ sal_uInt32 nDragFullOptions = hStyleSettings.GetDragFullOptions();
+
+ SvtTabAppearanceCfg aAppearanceCfg;
+ sal_uInt16 nGet = aAppearanceCfg.GetDragMode();
+ switch ( nGet )
+ {
+ case DragFullWindow:
+ nDragFullOptions |= DRAGFULL_OPTION_ALL;
+ break;
+ case DragFrame:
+ nDragFullOptions &= DRAGFULL_OPTION_NONE;
+ break;
+ case DragSystemDep:
+ default:
+ break;
+ }
+
+ sal_uInt32 nFollow = hMouseSettings.GetFollow();
+ hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MOUSE_FOLLOW_MENU) : (nFollow&~MOUSE_FOLLOW_MENU));
+ rSettings.SetMouseSettings(hMouseSettings);
+
+ BOOL bUseImagesInMenus = hStyleSettings.GetUseImagesInMenus();
+
+ SvtMenuOptions aMenuOpt;
+ nGet = aMenuOpt.GetMenuIconsState();
+ switch ( nGet )
+ {
+ case 0:
+ bUseImagesInMenus = FALSE;
+ break;
+ case 1:
+ bUseImagesInMenus = TRUE;
+ break;
+ case 2:
+ default:
+ break;
+ }
+ hStyleSettings.SetUseImagesInMenus(bUseImagesInMenus);
+
+ sal_uInt16 nTabStyle = hStyleSettings.GetTabControlStyle();
+ nTabStyle &= ~STYLE_TABCONTROL_SINGLELINE;
+ if( aAppearanceCfg.IsSingleLineTabCtrl() )
+ nTabStyle |=STYLE_TABCONTROL_SINGLELINE;
+
+ nTabStyle &= ~STYLE_TABCONTROL_COLOR;
+ if( aAppearanceCfg.IsColoredTabCtrl() )
+ nTabStyle |= STYLE_TABCONTROL_COLOR;
+
+ hStyleSettings.SetTabControlStyle(nTabStyle);
+
+ hStyleSettings.SetDragFullOptions( nDragFullOptions );
+ rSettings.SetStyleSettings ( hStyleSettings );
+}
+
+// ========================================================================
+IMPL_LINK( Desktop, AsyncInitFirstRun, void*, EMPTYARG )
+{
+ DoFirstRunInitializations();
+ return 0L;
+}
+
+// ========================================================================
+
+class ExitTimer : public Timer
+{
+ public:
+ ExitTimer()
+ {
+ SetTimeout(500);
+ Start();
+ }
+ virtual void Timeout()
+ {
+ exit(42);
+ }
+};
+
+IMPL_LINK( Desktop, OpenClients_Impl, void*, EMPTYARG )
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE - DesktopOpenClients_Impl()" );
+
+ OpenClients();
+
+ OfficeIPCThread::SetReady();
+
+ // CloseStartupScreen();
+ CloseSplashScreen();
+
+ CheckFirstRun( );
+
+ // allow ipc interaction
+// OfficeIPCThread::SetReady();
+
+ EnableOleAutomation();
+
+ if (getenv ("OOO_EXIT_POST_STARTUP"))
+ new ExitTimer();
+ return 0;
+}
+
+// enable acceptos
+IMPL_LINK( Desktop, EnableAcceptors_Impl, void*, EMPTYARG )
+{
+ enableAcceptors();
+ return 0;
+}
+
+
+// Registers a COM class factory of the service manager with the windows operating system.
+void Desktop::EnableOleAutomation()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (jl97489) ::Desktop::EnableOleAutomation" );
+#ifdef WNT
+ Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory();
+ xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.bridge.OleApplicationRegistration"));
+ xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.comp.ole.EmbedServer"));
+#endif
+}
+
+sal_Bool Desktop::CheckOEM()
+{
+ Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
+ Reference<XJob> rOemJob(rFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.office.OEMPreloadJob")),
+ UNO_QUERY );
+ Sequence<NamedValue> args;
+ sal_Bool bResult = sal_False;
+ if (rOemJob.is()) {
+ Any aResult = rOemJob->execute(args);
+ aResult >>= bResult;
+ return bResult;
+ } else {
+ return sal_True;
+ }
+}
+
+void Desktop::PreloadModuleData( CommandLineArgs* pArgs )
+{
+ Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
+
+ Sequence < com::sun::star::beans::PropertyValue > args(1);
+ args[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hidden"));
+ args[0].Value <<= sal_True;
+ Reference < XComponentLoader > xLoader( ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY );
+
+ if ( !xLoader.is() )
+ return;
+
+ if ( pArgs->IsWriter() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/swriter"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsCalc() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/scalc"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsDraw() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/sdraw"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsImpress() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/simpress"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+}
+
+void Desktop::PreloadConfigurationData()
+{
+ Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XNameAccess > xNameAccess( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.UICommandDescription" )), UNO_QUERY );
+
+ rtl::OUString aWriterDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ));
+ rtl::OUString aCalcDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ));
+ rtl::OUString aDrawDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ));
+ rtl::OUString aImpressDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ));
+
+ // preload commands configuration
+ if ( xNameAccess.is() )
+ {
+ Any a;
+ Reference< XNameAccess > xCmdAccess;
+
+ try
+ {
+ a = xNameAccess->getByName( aWriterDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ {
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:BasicShapes" ));
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:EditGlossary" ));
+ }
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ try
+ {
+ a = xNameAccess->getByName( aCalcDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:InsertObjectStarMath" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ try
+ {
+ // draw and impress share the same configuration file (DrawImpressCommands.xcu)
+ a = xNameAccess->getByName( aDrawDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:Polygon" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload window state configuration
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.ui.WindowStateConfiguration" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ Any a;
+ Reference< XNameAccess > xWindowAccess;
+ try
+ {
+ a = xNameAccess->getByName( aWriterDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aCalcDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aDrawDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aImpressDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload user interface element factories
+ Sequence< Sequence< css::beans::PropertyValue > > aSeqSeqPropValue;
+ Reference< ::com::sun::star::ui::XUIElementFactoryRegistration > xUIElementFactory(
+ rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.ui.UIElementFactoryManager" )),
+ UNO_QUERY );
+ if ( xUIElementFactory.is() )
+ {
+ try
+ {
+ aSeqSeqPropValue = xUIElementFactory->getRegisteredFactories();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload popup menu controller factories. As all controllers are in the same
+ // configuration file they also get preloaded!
+ Reference< ::com::sun::star::frame::XUIControllerRegistration > xPopupMenuControllerFactory(
+ rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.PopupMenuControllerFactory" )),
+ UNO_QUERY );
+ if ( xPopupMenuControllerFactory.is() )
+ {
+ try
+ {
+ xPopupMenuControllerFactory->hasController(
+ DEFINE_CONST_UNICODE( ".uno:CharFontName" ),
+ OUString() );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload filter configuration
+ Sequence< OUString > aSeq;
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ try
+ {
+ aSeq = xNameAccess->getElementNames();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload type detection configuration
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ try
+ {
+ aSeq = xNameAccess->getElementNames();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+ static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) );
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > xConfigProvider;
+ xConfigProvider = Reference< XMultiServiceFactory > (
+ rFactory->createInstance( sConfigSrvc ),UNO_QUERY );
+
+ if ( xConfigProvider.is() )
+ {
+ // preload writer configuration
+ Sequence< Any > theArgs(1);
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Writer/MailMergeWizard" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // WriterWeb
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.WriterWeb/Content" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload compatibility
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Compatibility/WriterCompatibilityVersion" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload calc configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Calc/Content" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload impress configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI.Effects/UserInterface" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Impress/Layout" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload draw configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Draw/Layout" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload ui configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI/FilterClassification" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload addons configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Addons/AddonUI" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+}
+
+void Desktop::OpenClients()
+{
+
+ // check if a document has been recovered - if there is one of if a document was loaded by cmdline, no default document
+ // should be created
+ Reference < XComponent > xFirst;
+ BOOL bLoaded = FALSE;
+
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+ SvtInternalOptions aInternalOptions;
+
+ Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
+
+ if (!pArgs->IsQuickstart()) {
+ sal_Bool bShowHelp = sal_False;
+ ::rtl::OUStringBuffer aHelpURLBuffer;
+ if (pArgs->IsHelpWriter()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
+ } else if (pArgs->IsHelpCalc()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
+ } else if (pArgs->IsHelpDraw()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
+ } else if (pArgs->IsHelpImpress()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
+ } else if (pArgs->IsHelpBase()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
+ } else if (pArgs->IsHelpBasic()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
+ } else if (pArgs->IsHelpMath()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
+ }
+ if (bShowHelp) {
+ Help *pHelp = Application::GetHelp();
+
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
+ rtl::OUString aTmp;
+ aRet >>= aTmp;
+ aHelpURLBuffer.appendAscii("?Language=");
+ aHelpURLBuffer.append(aTmp);
+#if defined UNX
+ aHelpURLBuffer.appendAscii("&System=UNX");
+#elif defined WNT
+ aHelpURLBuffer.appendAscii("&System=WIN");
+#elif defined MAC
+ aHelpURLBuffer.appendAscii("&System=MAC");
+#elif defined OS2
+ aHelpURLBuffer.appendAscii("&System=OS2");
+#endif
+ pHelp->Start(aHelpURLBuffer.makeStringAndClear(), NULL);
+ return;
+ }
+ }
+ else
+ {
+ OUString aIniName;
+ ::vos::OStartupInfo aInfo;
+
+ aInfo.getExecutableFile( aIniName );
+ sal_uInt32 lastIndex = aIniName.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ {
+ aIniName = aIniName.copy( 0, lastIndex+1 );
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
+#if defined(WNT) || defined(OS2)
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
+#else
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
+#endif
+ }
+
+ rtl::Bootstrap aPerfTuneIniFile( aIniName );
+
+ OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
+ OUString aPreloadData;
+
+ aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "QuickstartPreloadConfiguration" )), aPreloadData, aDefault );
+ if ( aPreloadData.equalsAscii( "1" ))
+ {
+ if ( pArgs->IsWriter() ||
+ pArgs->IsCalc() ||
+ pArgs->IsDraw() ||
+ pArgs->IsImpress() )
+ {
+ PreloadModuleData( pArgs );
+ }
+
+ PreloadConfigurationData();
+ }
+ }
+
+ // Disable AutoSave feature in case "-norestore" or a similare command line switch is set on the command line.
+ // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
+ // But the require that all documents, which are saved as backup should exists inside
+ // memory. May be this mechanism will be inconsistent if the configuration exists ...
+ // but no document inside memory corrspond to this data.
+ // Furter it's not acceptable to recover such documents without any UI. It can
+ // need some time, where the user wont see any results and wait for finishing the office startup ...
+ sal_Bool bAllowRecoveryAndSessionManagement = (
+ ( !pArgs->IsNoRestore() ) &&
+ ( !pArgs->IsHeadless() ) &&
+ ( !pArgs->IsServer() )
+ );
+
+ if ( ! bAllowRecoveryAndSessionManagement )
+ {
+ /*
+ ::comphelper::ConfigurationHelper::writeDirectKey(
+ ::comphelper::getProcessServiceFactory(),
+ ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery"),
+ ::rtl::OUString::createFromAscii("AutoSave"),
+ ::rtl::OUString::createFromAscii("Enabled"),
+ ::com::sun::star::uno::makeAny(sal_False),
+ ::comphelper::ConfigurationHelper::E_STANDARD);
+
+ */
+ try
+ {
+ Reference< XDispatch > xRecovery(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.AutoRecovery")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+
+ Reference< XURLTransformer > xParser(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+
+ css::util::URL aCmd;
+ aCmd.Complete = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/disableRecovery");
+ xParser->parseStrict(aCmd);
+
+ xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ catch(const css::uno::Exception& e)
+ {
+ OUString aMessage = OUString::createFromAscii("Could not disable AutoRecovery.\n")
+ + e.Message;
+ OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ else
+ {
+ sal_Bool bCrashed = sal_False;
+ sal_Bool bExistsRecoveryData = sal_False;
+ sal_Bool bExistsSessionData = sal_False;
+
+ impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
+
+ if ( !getenv ("OOO_DISABLE_RECOVERY") &&
+ ( ! bLoaded ) &&
+ (
+ ( bExistsRecoveryData ) || // => crash with files => recovery
+ ( bCrashed ) // => crash without files => error report
+ )
+ )
+ {
+ try
+ {
+ impl_callRecoveryUI(
+ sal_False , // false => force recovery instead of emergency save
+ bCrashed ,
+ bExistsRecoveryData);
+ /* TODO we cant be shure, that at least one document could be recovered here successfully
+ So we set bLoaded=TRUE to supress opening of the default document.
+ But we should make it more safe. Otherwhise we have an office without an UI ...
+ ...
+ May be we can check the desktop if some documents are existing there.
+ */
+ Reference< XFramesSupplier > xTasksSupplier(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
+ if ( xList->hasElements() )
+ bLoaded = sal_True;
+ }
+ catch(const css::uno::Exception& e)
+ {
+ OUString aMessage = OUString::createFromAscii("Error during recovery\n")
+ + e.Message;
+ OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+
+ Reference< XInitialization > xSessionListener;
+ try
+ {
+ xSessionListener = Reference< XInitialization >(::comphelper::getProcessServiceFactory()->createInstance(
+ OUString::createFromAscii("com.sun.star.frame.SessionListener")), UNO_QUERY_THROW);
+
+ // specifies whether the UI-interaction on Session shutdown is allowed
+ sal_Bool bAllowUI = isUIOnSessionShutdownAllowed();
+ css::beans::NamedValue aProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowUserInteractionOnQuit" ) ),
+ css::uno::makeAny( bAllowUI ) );
+ css::uno::Sequence< css::uno::Any > aArgs( 1 );
+ aArgs[0] <<= aProperty;
+
+ xSessionListener->initialize( aArgs );
+ }
+ catch(const com::sun::star::uno::Exception& e)
+ {
+ OUString aMessage = OUString::createFromAscii("Registration of session listener failed\n")
+ + e.Message;
+ OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+
+ if (
+ ( ! bLoaded ) &&
+ ( bExistsSessionData )
+ )
+ {
+ // session management
+ try
+ {
+ Reference< XSessionManagerListener > r(xSessionListener, UNO_QUERY_THROW);
+ bLoaded = r->doRestore();
+ }
+ catch(const com::sun::star::uno::Exception& e)
+ {
+ OUString aMessage = OUString::createFromAscii("Error in session management\n")
+ + e.Message;
+ OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ }
+
+ OfficeIPCThread::EnableRequests();
+
+ sal_Bool bShutdown( sal_False );
+ if ( !pArgs->IsServer() )
+ {
+ ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
+ aRequest.pcProcessed = NULL;
+
+ pArgs->GetOpenList( aRequest.aOpenList );
+ pArgs->GetViewList( aRequest.aViewList );
+ pArgs->GetStartList( aRequest.aStartList );
+ pArgs->GetPrintList( aRequest.aPrintList );
+ pArgs->GetPrintToList( aRequest.aPrintToList );
+ pArgs->GetPrinterName( aRequest.aPrinterName );
+ pArgs->GetForceOpenList( aRequest.aForceOpenList );
+ pArgs->GetForceNewList( aRequest.aForceNewList );
+
+ if ( aRequest.aOpenList.getLength() > 0 ||
+ aRequest.aViewList.getLength() > 0 ||
+ aRequest.aStartList.getLength() > 0 ||
+ aRequest.aPrintList.getLength() > 0 ||
+ aRequest.aForceOpenList.getLength() > 0 ||
+ aRequest.aForceNewList.getLength() > 0 ||
+ ( aRequest.aPrintToList.getLength() > 0 && aRequest.aPrinterName.getLength() > 0 ))
+ {
+ bLoaded = sal_True;
+
+ if ( pArgs->HasModuleParam() )
+ {
+ SvtModuleOptions aOpt;
+
+ // Support command line parameters to start a module (as preselection)
+ if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
+ else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
+ else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
+ else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
+ }
+
+ // check for printing disabled
+ if( ( aRequest.aPrintList.getLength() || aRequest.aPrintToList.getLength() )
+ && Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
+ {
+ aRequest.aPrintList = rtl::OUString();
+ aRequest.aPrintToList = rtl::OUString();
+ ResMgr* pDtResMgr = GetDesktopResManager();
+ if( pDtResMgr )
+ {
+ ErrorBox aBox( NULL, ResId( EBX_ERR_PRINTDISABLED, *pDtResMgr ) );
+ aBox.Execute();
+ }
+ }
+
+ // Process request
+ bShutdown = OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
+ }
+ }
+
+ // Don't do anything if we have successfully called terminate at desktop
+ if ( bShutdown )
+ return;
+
+ // no default document if a document was loaded by recovery or by command line or if soffice is used as server
+ Reference< XFramesSupplier > xTasksSupplier(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
+ if ( xList->hasElements() || pArgs->IsServer() )
+ return;
+
+ if ( pArgs->IsQuickstart() || pArgs->IsInvisible() || pArgs->IsBean() || Application::AnyInput( INPUT_APPEVENT ) )
+ // soffice was started as tray icon ...
+ return;
+ {
+ OpenDefault();
+ }
+}
+
+void Desktop::OpenDefault()
+{
+
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::OpenDefault" );
+
+ ::rtl::OUString aName;
+ SvtModuleOptions aOpt;
+
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+ if ( pArgs->IsNoDefault() ) return;
+ if ( pArgs->HasModuleParam() )
+ {
+ // Support new command line parameters to start a module
+ if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
+ else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
+ else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
+ else if ( pArgs->IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
+ else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
+ else if ( pArgs->IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_MATH );
+ else if ( pArgs->IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERGLOBAL );
+ else if ( pArgs->IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERWEB );
+ }
+
+ if ( !aName.getLength() )
+ {
+ // Old way to create a default document
+ if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
+ else
+ return;
+ }
+
+ ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
+ aRequest.pcProcessed = NULL;
+ aRequest.aOpenList = aName;
+ OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
+}
+
+
+String GetURL_Impl(
+ const String& rName, boost::optional< rtl::OUString > const & cwdUrl )
+{
+ // if rName is a vnd.sun.star.script URL do not attempt to parse it
+ // as INetURLObj does not handle handle there URLs
+ if (rName.CompareToAscii("vnd.sun.star.script" , 19) == COMPARE_EQUAL)
+ {
+ return rName;
+ }
+
+ // dont touch file urls, those should already be in internal form
+ // they won't get better here (#112849#)
+ if (rName.CompareToAscii("file:" , 5) == COMPARE_EQUAL)
+ {
+ return rName;
+ }
+
+ if ( rName.CompareToAscii("service:" , 8) == COMPARE_EQUAL )
+ {
+ return rName;
+ }
+
+ // Add path seperator to these directory and make given URL (rName) absolute by using of current working directory
+ // Attention: "setFianlSlash()" is neccessary for calling "smartRel2Abs()"!!!
+ // Otherwhise last part will be ignored and wrong result will be returned!!!
+ // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
+ // But if we add a seperator - he doesn't do it anymore.
+ INetURLObject aObj;
+ if (cwdUrl) {
+ aObj.SetURL(*cwdUrl);
+ aObj.setFinalSlash();
+ }
+
+ // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
+ // Otherwise this char won't get encoded and we are not able to load such files later,
+ // see #110156#
+ bool bWasAbsolute;
+ INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED,
+ RTL_TEXTENCODING_UTF8, true );
+ String aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE);
+
+ ::osl::FileStatus aStatus( FileStatusMask_FileURL );
+ ::osl::DirectoryItem aItem;
+ if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
+ ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
+ aFileURL = aStatus.getFileURL();
+
+ return aFileURL;
+}
+
+void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
+{
+ if ( rAppEvent.GetEvent() == "APPEAR" && !GetCommandLineArgs()->IsInvisible() )
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ // find active task - the active task is always a visible task
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFramesSupplier >
+ xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY );
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xTask = xDesktop->getActiveFrame();
+ if ( !xTask.is() )
+ {
+ // get any task if there is no active one
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > xList( xDesktop->getFrames(), ::com::sun::star::uno::UNO_QUERY );
+ if ( xList->getCount()>0 )
+ xList->getByIndex(0) >>= xTask;
+ }
+
+ if ( xTask.is() )
+ {
+ Reference< com::sun::star::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
+ xTop->toFront();
+ }
+ else
+ {
+ // no visible task that could be activated found
+ Reference< XFrame > xBackingFrame;
+ Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xDesktopFrame( xDesktop, UNO_QUERY );
+
+ xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
+ if (xBackingFrame.is())
+ xContainerWindow = xBackingFrame->getContainerWindow();
+ if (xContainerWindow.is())
+ {
+ Sequence< Any > lArgs(1);
+ lArgs[0] <<= xContainerWindow;
+ Reference< XController > xBackingComp(
+ xSMGR->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs),
+ UNO_QUERY);
+ if (xBackingComp.is())
+ {
+ Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
+ // Attention: You MUST(!) call setComponent() before you call attachFrame().
+ // Because the backing component set the property "IsBackingMode" of the frame
+ // to true inside attachFrame(). But setComponent() reset this state everytimes ...
+ xBackingFrame->setComponent(xBackingWin, xBackingComp);
+ xBackingComp->attachFrame(xBackingFrame);
+ xContainerWindow->setVisible(sal_True);
+
+ Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
+ if (pCompWindow)
+ pCompWindow->Update();
+ }
+ }
+ }
+ }
+ else if ( rAppEvent.GetEvent() == "QUICKSTART" && !GetCommandLineArgs()->IsInvisible() )
+ {
+ // If the office has been started the second time its command line arguments are sent through a pipe
+ // connection to the first office. We want to reuse the quickstart option for the first office.
+ // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
+ // application events to do this (they are executed inside main thread)!!!
+ // Don't start quickstart service if the user specified "-invisible" on the command line!
+ sal_Bool bQuickstart( sal_True );
+ Sequence< Any > aSeq( 1 );
+ aSeq[0] <<= bQuickstart;
+
+ Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" )),
+ UNO_QUERY );
+ if ( xQuickstart.is() )
+ xQuickstart->initialize( aSeq );
+ }
+ else if ( rAppEvent.GetEvent() == "ACCEPT" )
+ {
+ // every time an accept parameter is used we create an acceptor
+ // with the corresponding accept-string
+ OUString aAcceptString(rAppEvent.GetData().GetBuffer());
+ createAcceptor(aAcceptString);
+ }
+ else if ( rAppEvent.GetEvent() == "UNACCEPT" )
+ {
+ // try to remove corresponding acceptor
+ OUString aUnAcceptString(rAppEvent.GetData().GetBuffer());
+ destroyAcceptor(aUnAcceptString);
+ }
+ else if ( rAppEvent.GetEvent() == "SaveDocuments" )
+ {
+ Desktop::_bTasksSaved = sal_False;
+ Desktop::_bTasksSaved = SaveTasks();
+ }
+ else if ( rAppEvent.GetEvent() == "OPENHELPURL" )
+ {
+ // start help for a specific URL
+ OUString aHelpURL(rAppEvent.GetData().GetBuffer());
+ Help *pHelp = Application::GetHelp();
+ pHelp->Start(aHelpURL, NULL);
+ }
+ else if ( rAppEvent.GetEvent() == APPEVENT_OPEN_STRING )
+ {
+ OUString aOpenURL(rAppEvent.GetData().GetBuffer());
+
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
+ {
+ ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
+ pCmdLine->getCwdUrl());
+ pDocsRequest->aOpenList = aOpenURL;
+ pDocsRequest->pcProcessed = NULL;
+
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ }
+ else if ( rAppEvent.GetEvent() == APPEVENT_PRINT_STRING )
+ {
+ OUString aPrintURL(rAppEvent.GetData().GetBuffer());
+
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
+ {
+ ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
+ pCmdLine->getCwdUrl());
+ pDocsRequest->aPrintList = aPrintURL;
+ pDocsRequest->pcProcessed = NULL;
+
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ }
+#ifndef UNX
+ else if ( rAppEvent.GetEvent() == "HELP" )
+ {
+ // in non unix version allow showing of cmdline help window
+ displayCmdlineHelp();
+ }
+#endif
+ else if ( rAppEvent.GetEvent() == "SHOWDIALOG" )
+ {
+ // ignore all errors here. It's clicking a menu entry only ...
+ // The user will try it again, in case nothing happens .-)
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >
+ xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY );
+
+ // check provider ... we know it's weak reference only
+ if ( ! xDesktop.is())
+ return;
+
+ css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), css::uno::UNO_QUERY_THROW);
+ css::util::URL aCommand;
+ if( rAppEvent.GetData().EqualsAscii( "PREFERENCES" ) )
+ aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:OptionsTreeDialog" ) );
+ else if( rAppEvent.GetData().EqualsAscii( "ABOUT" ) )
+ aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:About" ) );
+ if( aCommand.Complete.getLength() )
+ {
+ xParser->parseStrict(aCommand);
+
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, rtl::OUString(), 0);
+ if (xDispatch.is())
+ xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+}
+
+void Desktop::OpenSplashScreen()
+{
+ ::rtl::OUString aTmpString;
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ sal_Bool bVisible = sal_False;
+ // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
+ if ( !pCmdLine->IsInvisible() &&
+ !pCmdLine->IsQuickstart() &&
+ !pCmdLine->IsMinimized() &&
+ !pCmdLine->IsNoLogo() &&
+ !pCmdLine->IsTerminateAfterInit() &&
+ !pCmdLine->GetPrintList( aTmpString ) &&
+ !pCmdLine->GetPrintToList( aTmpString ) )
+ {
+ // Determine application name from command line parameters
+ OUString aAppName;
+ if ( pCmdLine->IsWriter() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer" ));
+ else if ( pCmdLine->IsCalc() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc" ));
+ else if ( pCmdLine->IsDraw() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw" ));
+ else if ( pCmdLine->IsImpress() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress" ));
+ else if ( pCmdLine->IsBase() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "base" ));
+ else if ( pCmdLine->IsGlobal() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "global" ));
+ else if ( pCmdLine->IsMath() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math" ));
+ else if ( pCmdLine->IsWeb() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "web" ));
+
+ bVisible = sal_True;
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= bVisible;
+ aSeq[1] <<= aAppName;
+ m_rSplashScreen = Reference<XStatusIndicator>(
+ comphelper::getProcessServiceFactory()->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.office.SplashScreen"),
+ aSeq), UNO_QUERY);
+
+ if(m_rSplashScreen.is())
+ m_rSplashScreen->start(OUString::createFromAscii("SplashScreen"), 100);
+ }
+
+}
+
+void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
+{
+ if(m_rSplashScreen.is())
+ {
+ m_rSplashScreen->setValue(iProgress);
+ }
+}
+
+void Desktop::SetSplashScreenText( const ::rtl::OUString& rText )
+{
+ if( m_rSplashScreen.is() )
+ {
+ m_rSplashScreen->setText( rText );
+ }
+}
+
+void Desktop::CloseSplashScreen()
+{
+ if(m_rSplashScreen.is())
+ {
+ m_rSplashScreen->end();
+ m_rSplashScreen = NULL;
+ }
+}
+
+// ========================================================================
+void Desktop::DoFirstRunInitializations()
+{
+ try
+ {
+ Reference< XJobExecutor > xExecutor( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.task.JobExecutor" ) ), UNO_QUERY );
+ if( xExecutor.is() )
+ xExecutor->trigger( ::rtl::OUString::createFromAscii("onFirstRunInitialization") );
+ }
+ catch(const ::com::sun::star::uno::Exception&)
+ {
+ OSL_ENSURE( sal_False, "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." );
+ }
+}
+
+// ========================================================================
+void Desktop::CheckFirstRun( )
+{
+ const ::rtl::OUString sCommonMiscNodeName = ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Common/Misc" );
+ const ::rtl::OUString sFirstRunNodeName = ::rtl::OUString::createFromAscii( "FirstRun" );
+
+ // --------------------------------------------------------------------
+ // check if this is the first office start
+
+ // for this, open the Common/Misc node where this info is stored
+ ::utl::OConfigurationTreeRoot aCommonMisc = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
+ ::comphelper::getProcessServiceFactory( ),
+ sCommonMiscNodeName,
+ 2,
+ ::utl::OConfigurationTreeRoot::CM_UPDATABLE
+ );
+
+ // read the flag
+ OSL_ENSURE( aCommonMisc.isValid(), "Desktop::CheckFirstRun: could not open the config node needed!" );
+ sal_Bool bIsFirstRun = sal_False;
+ aCommonMisc.getNodeValue( sFirstRunNodeName ) >>= bIsFirstRun;
+
+ if ( !bIsFirstRun )
+ // nothing to do ....
+ return;
+
+ // --------------------------------------------------------------------
+ // it is the first run
+ // this has once been done using a vos timer. this could lead to problems when
+ // the timer would trigger when the app is already going down again, since VCL would
+ // no longer be available. Since the old handler would do a postUserEvent to the main
+ // thread anyway, we can use a vcl timer here to prevent the race contition (#107197#)
+ m_firstRunTimer.SetTimeout(3000); // 3 sec.
+ m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun));
+ m_firstRunTimer.Start();
+
+ // --------------------------------------------------------------------
+ // reset the config flag
+
+ // set the value
+ aCommonMisc.setNodeValue( sFirstRunNodeName, makeAny( (sal_Bool)sal_False ) );
+ // commit the changes
+ aCommonMisc.commit();
+}
+
+}
diff --git a/desktop/source/app/appfirststart.cxx b/desktop/source/app/appfirststart.cxx
new file mode 100644
index 000000000000..2f0d4ab9e538
--- /dev/null
+++ b/desktop/source/app/appfirststart.cxx
@@ -0,0 +1,274 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/datetime.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include "app.hxx"
+
+using rtl::OUString;
+using namespace desktop;
+using namespace com::sun::star::beans;
+
+static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
+
+/* Path of the license. */
+OUString Desktop::GetLicensePath()
+{
+ // license file name
+ static const char *szLicensePath = "/share/readme";
+#if defined(WNT) || defined(OS2)
+ static const char *szWNTLicenseName = "/license";
+ static const char *szWNTLicenseExt = ".txt";
+#else
+ static const char *szUNXLicenseName = "/LICENSE";
+ static const char *szUNXLicenseExt = "";
+#endif
+ static OUString aLicensePath;
+
+ if (aLicensePath.getLength() > 0)
+ return aLicensePath;
+
+ OUString aBaseInstallPath(RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR"));
+ rtl::Bootstrap::expandMacros(aBaseInstallPath);
+
+ // determine the filename of the license to show
+ OUString aLangString;
+ ::com::sun::star::lang::Locale aLocale;
+ OString aMgrName = OString("dkt");
+
+ AllSettings aSettings(Application::GetSettings());
+ aLocale = aSettings.GetUILocale();
+ ResMgr* pLocalResMgr = ResMgr::SearchCreateResMgr(aMgrName, aLocale);
+
+ aLangString = aLocale.Language;
+ if ( aLocale.Country.getLength() != 0 )
+ {
+ aLangString += OUString::createFromAscii("-");
+ aLangString += aLocale.Country;
+ if ( aLocale.Variant.getLength() != 0 )
+ {
+ aLangString += OUString::createFromAscii("-");
+ aLangString += aLocale.Variant;
+ }
+ }
+#if defined(WNT) || defined(OS2)
+ aLicensePath =
+ aBaseInstallPath + OUString::createFromAscii(szLicensePath)
+ + OUString::createFromAscii(szWNTLicenseName)
+ + OUString::createFromAscii("_")
+ + aLangString
+ + OUString::createFromAscii(szWNTLicenseExt);
+#else
+ aLicensePath =
+ aBaseInstallPath + OUString::createFromAscii(szLicensePath)
+ + OUString::createFromAscii(szUNXLicenseName)
+ + OUString::createFromAscii("_")
+ + aLangString
+ + OUString::createFromAscii(szUNXLicenseExt);
+#endif
+ delete pLocalResMgr;
+ return aLicensePath;
+}
+
+/* Check if we need to accept license. */
+sal_Bool Desktop::LicenseNeedsAcceptance()
+{
+ // Don't show a license
+ return sal_False;
+/*
+ sal_Bool bShowLicense = sal_True;
+ sal_Int32 nOpenSourceContext = 0;
+ try
+ {
+ ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::OPENSOURCECONTEXT ) >>= nOpenSourceContext;
+ }
+ catch( const ::com::sun::star::uno::Exception& ) {}
+
+ // open source needs no license
+ if ( nOpenSourceContext > 0 )
+ bShowLicense = sal_False;
+
+ return bShowLicense;
+*/
+}
+
+/* Local function - was the wizard completed already? */
+static sal_Bool impl_isFirstStart()
+{
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"), makeAny(OUString::createFromAscii("org.openoffice.Setup/Office")));
+ theArgs[0] <<= v;
+
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+
+ Any result = pset->getPropertyValue(OUString::createFromAscii("FirstStartWizardCompleted"));
+ sal_Bool bCompleted = sal_False;
+ if ((result >>= bCompleted) && bCompleted)
+ return sal_False; // wizard was already completed
+ else
+ return sal_True;
+ } catch (const Exception&)
+ {
+ return sal_True;
+ }
+}
+
+/* Local function - convert oslDateTime to tools DateTime */
+static DateTime impl_oslDateTimeToDateTime(const oslDateTime& aDateTime)
+{
+ return DateTime(
+ Date(aDateTime.Day, aDateTime.Month, aDateTime.Year),
+ Time(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds));
+}
+
+/* Local function - get DateTime from a string */
+static sal_Bool impl_parseDateTime(const OUString& aString, DateTime& aDateTime)
+{
+ // take apart a canonical literal xsd:dateTime string
+ //CCYY-MM-DDThh:mm:ss(Z)
+
+ OUString aDateTimeString = aString.trim();
+
+ // check length
+ if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
+ return sal_False;
+
+ sal_Int32 nDateLength = 10;
+ sal_Int32 nTimeLength = 8;
+
+ OUString aDateTimeSep = OUString::createFromAscii("T");
+ OUString aDateSep = OUString::createFromAscii("-");
+ OUString aTimeSep = OUString::createFromAscii(":");
+ OUString aUTCString = OUString::createFromAscii("Z");
+
+ OUString aDateString = aDateTimeString.copy(0, nDateLength);
+ OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
+ sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
+ sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
+ nIndex = 0;
+ sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
+ sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
+ sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
+
+ Date tmpDate((USHORT)nDay, (USHORT)nMonth, (USHORT)nYear);
+ Time tmpTime(nHour, nMinute, nSecond);
+ DateTime tmpDateTime(tmpDate, tmpTime);
+ if (aString.indexOf(aUTCString) < 0)
+ tmpDateTime.ConvertToUTC();
+
+ aDateTime = tmpDateTime;
+ return sal_True;
+}
+
+/* Local function - was the license accepted already? */
+static sal_Bool impl_isLicenseAccepted()
+{
+ // If no license will be shown ... it must not be accepted.
+ // So it was accepted "hardly" by the outside installer.
+ // But if the configuration entry "HideEula" will be removed afterwards ..
+ // we have to show the licese page again and user has to accept it here .-)
+ if ( ! Desktop::LicenseNeedsAcceptance() )
+ return sal_True;
+
+ try
+ {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"),
+ makeAny(OUString::createFromAscii("org.openoffice.Setup/Office")));
+ theArgs[0] <<= v;
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+
+ Any result = pset->getPropertyValue(OUString::createFromAscii("LicenseAcceptDate"));
+
+ OUString aAcceptDate;
+ if (result >>= aAcceptDate)
+ {
+ // compare to date of license file
+ OUString aLicenseURL = Desktop::GetLicensePath();
+ osl::DirectoryItem aDirItem;
+ if (osl::DirectoryItem::get(aLicenseURL, aDirItem) != osl::FileBase::E_None)
+ return sal_False;
+ osl::FileStatus aStatus(FileStatusMask_All);
+ if (aDirItem.getFileStatus(aStatus) != osl::FileBase::E_None)
+ return sal_False;
+ TimeValue aTimeVal = aStatus.getModifyTime();
+ oslDateTime aDateTimeVal;
+ if (!osl_getDateTimeFromTimeValue(&aTimeVal, &aDateTimeVal))
+ return sal_False;
+
+ // compare dates
+ DateTime aLicenseDateTime = impl_oslDateTimeToDateTime(aDateTimeVal);
+ DateTime aAcceptDateTime;
+ if (!impl_parseDateTime(aAcceptDate, aAcceptDateTime))
+ return sal_False;
+
+ if ( aAcceptDateTime > aLicenseDateTime )
+ return sal_True;
+ }
+ return sal_False;
+ } catch (const Exception&)
+ {
+ return sal_False;
+ }
+}
+
+/* Check if we need the first start wizard. */
+sal_Bool Desktop::IsFirstStartWizardNeeded()
+{
+ return impl_isFirstStart() || !impl_isLicenseAccepted();
+}
+
diff --git a/desktop/source/app/appinit.cxx b/desktop/source/app/appinit.cxx
new file mode 100644
index 000000000000..97eb3f555f60
--- /dev/null
+++ b/desktop/source/app/appinit.cxx
@@ -0,0 +1,484 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <algorithm>
+
+#include "app.hxx"
+#include "cmdlineargs.hxx"
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#include <com/sun/star/ucb/XContentProviderFactory.hpp>
+#include <uno/current_context.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <osl/file.hxx>
+#include <osl/module.h>
+#include <vos/process.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/bootstrap.hxx>
+#include <comphelper/regpathhelper.hxx>
+#include <tools/debug.hxx>
+#include <tools/tempfile.hxx>
+#include <ucbhelper/configurationkeys.hxx>
+
+#include <cppuhelper/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/rcid.h>
+
+#include <rtl/logfile.hxx>
+#include <rtl/instance.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/tempfile.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/startoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/internaloptions.hxx>
+
+
+#define DEFINE_CONST_OUSTRING(CONSTASCII) OUString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
+
+#define DESKTOP_TEMPDIRNAME "soffice.tmp"
+
+using namespace rtl;
+using namespace vos;
+using namespace desktop;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::ucb;
+
+namespace desktop
+{
+
+// -----------------------------------------------------------------------------
+
+static bool configureUcb(bool bServer, rtl::OUString const & rPortalConnect)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (sb93797) ::configureUcb" );
+ Reference< XMultiServiceFactory >
+ xServiceFactory( comphelper::getProcessServiceFactory() );
+ if (!xServiceFactory.is())
+ {
+ DBG_ERROR("configureUcb(): No XMultiServiceFactory");
+ return false;
+ }
+
+ rtl::OUString aPipe;
+ vos::OSecurity().getUserIdent(aPipe);
+
+ rtl::OUStringBuffer aPortal;
+ if (rPortalConnect.getLength() != 0)
+ {
+ aPortal.append(sal_Unicode(','));
+ aPortal.append(rPortalConnect);
+ }
+
+ Sequence< Any > aArgs(6);
+ aArgs[0]
+ <<= rtl::OUString::createFromAscii(bServer ?
+ UCB_CONFIGURATION_KEY1_SERVER :
+ UCB_CONFIGURATION_KEY1_LOCAL);
+ aArgs[1]
+ <<= rtl::OUString::createFromAscii(UCB_CONFIGURATION_KEY2_OFFICE);
+ aArgs[2] <<= rtl::OUString::createFromAscii("PIPE");
+ aArgs[3] <<= aPipe;
+ aArgs[4] <<= rtl::OUString::createFromAscii("PORTAL");
+ aArgs[5] <<= aPortal.makeStringAndClear();
+
+ bool ret =
+ ::ucbhelper::ContentBroker::initialize( xServiceFactory, aArgs ) != false;
+
+#ifdef GNOME_VFS_ENABLED
+ // register GnomeUCP if necessary
+ ::ucbhelper::ContentBroker* cb = ::ucbhelper::ContentBroker::get();
+ if(cb) {
+ try {
+ Reference< XCurrentContext > xCurrentContext(
+ getCurrentContext());
+ if (xCurrentContext.is())
+ {
+ Any aValue = xCurrentContext->getValueByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "system.desktop-environment" ) )
+ );
+ rtl::OUString aDesktopEnvironment;
+ if ((aValue >>= aDesktopEnvironment)
+ && aDesktopEnvironment.equalsAscii("GNOME"))
+ {
+ Reference<XContentProviderManager> xCPM =
+ cb->getContentProviderManagerInterface();
+#if 0
+ try
+ {
+
+ Reference<XContentProviderFactory> xCPF(
+ xServiceFactory->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.ContentProviderProxyFactory")),
+ UNO_QUERY);
+ if(xCPF.is())
+ xCPM->registerContentProvider(
+ xCPF->createContentProvider(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.GnomeVFSContentProvider"
+ )
+ ),
+ rtl::OUString::createFromAscii(".*"),
+ false);
+ } catch (...)
+ {
+ }
+#else
+
+ // Workaround for P1 #124597#. Instanciate GNOME-VFS-UCP in the thread that initialized
+ // GNOME in order to avoid a deadlock that may occure in case UCP gets initialized from
+ // a different thread. The latter may happen when calling the Office remotely via UNO.
+ // THIS IS NOT A FIX, JUST A WORKAROUND!
+
+ try
+ {
+ Reference<XContentProvider> xCP(
+ xServiceFactory->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.GnomeVFSContentProvider")),
+ UNO_QUERY);
+ if(xCP.is())
+ xCPM->registerContentProvider(
+ xCP,
+ rtl::OUString::createFromAscii(".*"),
+ false);
+ } catch (...)
+ {
+ }
+ }
+#endif
+ }
+ } catch (RuntimeException e) {
+ }
+ }
+#endif // GNOME_VFS_ENABLED
+
+ return ret;;
+}
+
+Reference< XMultiServiceFactory > Desktop::CreateApplicationServiceManager()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createApplicationServiceManager" );
+
+ try
+ {
+ Reference<XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
+ Reference<XMultiServiceFactory> xMS(xComponentContext->getServiceManager(), UNO_QUERY);
+
+ return xMS;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ return Reference< XMultiServiceFactory >();
+}
+
+void Desktop::DestroyApplicationServiceManager( Reference< XMultiServiceFactory >& xSMgr )
+{
+ Reference< XPropertySet > xProps( xSMgr, UNO_QUERY );
+ if ( xProps.is() )
+ {
+ try
+ {
+ Reference< XComponent > xComp;
+ if (xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComp )
+ {
+ xComp->dispose();
+ }
+ }
+ catch ( UnknownPropertyException& )
+ {
+ }
+ }
+}
+
+void Desktop::RegisterServices( Reference< XMultiServiceFactory >& xSMgr )
+{
+ if( !m_bServicesRegistered )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::registerServices" );
+
+ // read command line parameters
+ ::rtl::OUString conDcp;
+ ::rtl::OUString aClientDisplay;
+ ::rtl::OUString aTmpString;
+ sal_Bool bHeadlessMode = sal_False;
+
+ // interpret command line arguments
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+
+ // read accept string from configuration
+ conDcp = SvtStartOptions().GetConnectionURL();
+
+ if ( pCmdLine->GetAcceptString( aTmpString ))
+ conDcp = aTmpString;
+
+ // Headless mode for FAT Office
+ bHeadlessMode = pCmdLine->IsHeadless();
+ if ( bHeadlessMode )
+ Application::EnableHeadlessMode();
+
+ if ( conDcp.getLength() > 0 )
+ {
+ // accept incoming connections (scripting and one rvp)
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (lo119109) desktop::Desktop::createAcceptor()" );
+ createAcceptor(conDcp);
+ }
+
+ // improves parallel processing on Sun ONE Webtop
+ // servicemanager up -> copy user installation
+ if ( pCmdLine->IsServer() )
+ {
+ // Check some mandatory environment states if "-server" is possible. Otherwise ignore
+ // this parameter.
+ Reference< com::sun::star::container::XContentEnumerationAccess > rContent( xSMgr , UNO_QUERY );
+ if( rContent.is() )
+ {
+ OUString sPortalService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.portal.InstallUser" ) );
+ Reference < com::sun::star::container::XEnumeration > rEnum = rContent->createContentEnumeration( sPortalService );
+ if ( !rEnum.is() )
+ {
+ // Reset server parameter so it is ignored in the furthermore startup process
+ pCmdLine->SetBoolParam( CommandLineArgs::CMD_BOOLPARAM_SERVER, sal_False );
+ }
+ }
+ }
+
+ ::rtl::OUString aPortalConnect;
+ bool bServer = (bool)pCmdLine->IsServer();
+
+ pCmdLine->GetPortalConnectString( aPortalConnect );
+ if ( !configureUcb( bServer, aPortalConnect ) )
+ {
+ DBG_ERROR( "Can't configure UCB" );
+ throw com::sun::star::uno::Exception(rtl::OUString::createFromAscii("RegisterServices, configureUcb"), NULL);
+ }
+
+ CreateTemporaryDirectory();
+ m_bServicesRegistered = true;
+ }
+}
+
+namespace
+{
+ struct acceptorMap : public rtl::Static< AcceptorMap, acceptorMap > {};
+ struct CurrentTempURL : public rtl::Static< String, CurrentTempURL > {};
+}
+
+static sal_Bool bAccept = sal_False;
+
+void Desktop::createAcceptor(const OUString& aAcceptString)
+{
+ // check whether the requested acceptor already exists
+ AcceptorMap &rMap = acceptorMap::get();
+ AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
+ if (pIter == rMap.end() ) {
+
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= aAcceptString;
+ aSeq[1] <<= bAccept;
+ Reference<XInitialization> rAcceptor(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString::createFromAscii( "com.sun.star.office.Acceptor" )), UNO_QUERY );
+ if ( rAcceptor.is() ) {
+ try{
+ rAcceptor->initialize( aSeq );
+ rMap.insert(AcceptorMap::value_type(aAcceptString, rAcceptor));
+ } catch (com::sun::star::uno::Exception&) {
+ // no error handling needed...
+ // acceptor just won't come up
+ OSL_ENSURE(sal_False, "Acceptor could not be created.");
+ }
+ } else {
+ // there is already an acceptor with this description
+ OSL_ENSURE(sal_False, "Acceptor already exists.");
+ }
+
+ }
+}
+
+class enable
+{
+ private:
+ Sequence<Any> m_aSeq;
+ public:
+ enable() : m_aSeq(1) {
+ m_aSeq[0] <<= sal_True;
+ }
+ void operator() (const AcceptorMap::value_type& val) {
+ if (val.second.is()) {
+ val.second->initialize(m_aSeq);
+ }
+ }
+};
+
+void Desktop::enableAcceptors()
+{
+ RTL_LOGFILE_CONTEXT(aLog, "desktop (lo119109) Desktop::enableAcceptors");
+ if (!bAccept)
+ {
+ // from now on, all new acceptors are enabled
+ bAccept = sal_True;
+ // enable existing acceptors by calling initialize(true)
+ // on all existing acceptors
+ AcceptorMap &rMap = acceptorMap::get();
+ std::for_each(rMap.begin(), rMap.end(), enable());
+ }
+}
+
+void Desktop::destroyAcceptor(const OUString& aAcceptString)
+{
+ // special case stop all acceptors
+ AcceptorMap &rMap = acceptorMap::get();
+ if (aAcceptString.compareToAscii("all") == 0) {
+ rMap.clear();
+
+ } else {
+ // try to remove acceptor from map
+ AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
+ if (pIter != rMap.end() ) {
+ // remove reference from map
+ // this is the last reference and the acceptor will be destructed
+ rMap.erase(aAcceptString);
+ } else {
+ OSL_ENSURE(sal_False, "Found no acceptor to remove");
+ }
+ }
+}
+
+
+void Desktop::DeregisterServices()
+{
+ // stop all acceptors by clearing the map
+ acceptorMap::get().clear();
+}
+
+void Desktop::CreateTemporaryDirectory()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createTemporaryDirectory" );
+
+ ::rtl::OUString aTempBaseURL;
+ try
+ {
+ SvtPathOptions aOpt;
+ aTempBaseURL = aOpt.GetTempPath();
+ }
+ catch ( RuntimeException& e )
+ {
+ // Catch runtime exception here: We have to add language dependent info
+ // to the exception message. Fallback solution uses hard coded string.
+ OUString aMsg;
+ DesktopResId aResId( STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE );
+ aResId.SetRT( RSC_STRING );
+ if ( aResId.GetResMgr()->IsAvailable( aResId ))
+ aMsg = String( aResId );
+ else
+ aMsg = OUString( RTL_CONSTASCII_USTRINGPARAM( "The path manager is not available.\n" ));
+ e.Message = aMsg + e.Message;
+ throw e;
+ }
+
+ // remove possible old directory and base directory
+ SvtInternalOptions aInternalOpt;
+
+ // set temp base directory
+ sal_Int32 nLength = aTempBaseURL.getLength();
+ if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
+ aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
+
+ String aOldTempURL = aInternalOpt.GetCurrentTempURL();
+ if ( aOldTempURL.Len() > 0 )
+ {
+ // remove old temporary directory
+ ::utl::UCBContentHelper::Kill( aOldTempURL );
+ }
+
+ String aRet;
+ ::rtl::OUString aTempPath( aTempBaseURL );
+
+ // create new current temporary directory
+ ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTempBaseURL, aRet );
+ ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
+ aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
+ if ( !aTempPath.getLength() )
+ {
+ ::osl::File::getTempDirURL( aTempBaseURL );
+
+ nLength = aTempBaseURL.getLength();
+ if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
+ aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
+
+ aTempPath = aTempBaseURL;
+ ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
+ aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
+ }
+
+ // set new current temporary directory
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTempPath, aRet );
+ aInternalOpt.SetCurrentTempURL( aRet );
+ CurrentTempURL::get() = aRet;
+}
+
+void Desktop::RemoveTemporaryDirectory()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::removeTemporaryDirectory" );
+
+ // remove current temporary directory
+ String &rCurrentTempURL = CurrentTempURL::get();
+ if ( rCurrentTempURL.Len() > 0 )
+ {
+ if ( ::utl::UCBContentHelper::Kill( rCurrentTempURL ) )
+ SvtInternalOptions().SetCurrentTempURL( String() );
+ }
+}
+
+} // namespace desktop
diff --git a/desktop/source/app/appinit.hxx b/desktop/source/app/appinit.hxx
new file mode 100644
index 000000000000..c5b48fd4a488
--- /dev/null
+++ b/desktop/source/app/appinit.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_APPINIT_HXX_
+#define _DESKTOP_APPINIT_HXX_
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+namespace desktop
+{
+
+::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > createApplicationServiceManager();
+
+sal_Bool InitializeInstallation( const rtl::OUString& rAppFilename );
+void registerServices( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr );
+void deregisterServices();
+
+void destroyApplicationServiceManager( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr );
+
+void createTemporaryDirectory();
+void removeTemporaryDirectory();
+
+}
+
+#endif
diff --git a/desktop/source/app/appsys.cxx b/desktop/source/app/appsys.cxx
new file mode 100644
index 000000000000..4cff81e3bb54
--- /dev/null
+++ b/desktop/source/app/appsys.cxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "appsys.hxx"
+
+#ifdef WNT
+
+#include <rtl/ustring.hxx>
+#include <tools/solar.h>
+#include <tools/prewin.h>
+#include <winreg.h>
+#include <tools/postwin.h>
+#include <tools/urlobj.hxx>
+
+
+#define U2S(STRING) ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8)
+
+namespace desktop
+{
+
+void FATToVFat_Impl( String& aName )
+{
+ INetURLObject aObj( aName );
+ if ( aObj.GetProtocol() == INET_PROT_FILE )
+ {
+ WIN32_FIND_DATA aData;
+ HANDLE h = FindFirstFile( U2S(aName).getStr(), &aData );
+ if ( h )
+ {
+ // FAT-Kurzname in VFAT-Langname wandeln
+ aObj.removeSegment();
+ aObj.insertName( String::CreateFromAscii( aData.cFileName ) );
+ aName = aObj.PathToFileName();
+ FindClose( h );
+ }
+ }
+}
+
+}
+
+#endif // WNT
+
diff --git a/desktop/source/app/appsys.hxx b/desktop/source/app/appsys.hxx
new file mode 100644
index 000000000000..5d1b06c1bbe7
--- /dev/null
+++ b/desktop/source/app/appsys.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_APPSYS_HXX_
+#define _DESKTOP_APPSYS_HXX_
+
+#include <tools/string.hxx>
+
+namespace desktop
+{
+
+#ifdef WNT
+void FATToVFat_Impl( String& aName );
+#endif
+
+}
+
+#endif // _DESKTOP_APPSYS_HXX_
diff --git a/desktop/source/app/check_ext_deps.cxx b/desktop/source/app/check_ext_deps.cxx
new file mode 100755
index 000000000000..664e63c7f6ca
--- /dev/null
+++ b/desktop/source/app/check_ext_deps.cxx
@@ -0,0 +1,431 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "osl/file.hxx"
+#include "osl/mutex.hxx"
+
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/logfile.hxx>
+#include "cppuhelper/compbase3.hxx"
+
+#include "vcl/wrkwin.hxx"
+#include "vcl/timer.hxx"
+
+#include <unotools/configmgr.hxx>
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/ui/LicenseDialog.hpp"
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+#include "app.hxx"
+
+#include "../deployment/inc/dp_misc.h"
+
+using rtl::OUString;
+using namespace desktop;
+using namespace com::sun::star;
+
+#define UNISTRING(s) OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace
+{
+//For use with XExtensionManager.synchronize
+class SilentCommandEnv
+ : public ::cppu::WeakImplHelper3< ucb::XCommandEnvironment,
+ task::XInteractionHandler,
+ ucb::XProgressHandler >
+{
+ Desktop *mpDesktop;
+ sal_Int32 mnLevel;
+ sal_Int32 mnProgress;
+
+public:
+ SilentCommandEnv( Desktop* pDesktop );
+ virtual ~SilentCommandEnv();
+
+ // 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);
+};
+
+//-----------------------------------------------------------------------------
+SilentCommandEnv::SilentCommandEnv( Desktop* pDesktop )
+{
+ mpDesktop = pDesktop;
+ mnLevel = 0;
+ mnProgress = 25;
+}
+
+//-----------------------------------------------------------------------------
+SilentCommandEnv::~SilentCommandEnv()
+{
+ mpDesktop->SetSplashScreenText( OUString() );
+}
+
+//-----------------------------------------------------------------------------
+Reference<task::XInteractionHandler> SilentCommandEnv::getInteractionHandler()
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//-----------------------------------------------------------------------------
+Reference<ucb::XProgressHandler> SilentCommandEnv::getProgressHandler()
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//-----------------------------------------------------------------------------
+// XInteractionHandler
+void SilentCommandEnv::handle( Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ deployment::LicenseException licExc;
+
+ uno::Any request( xRequest->getRequest() );
+ bool bApprove = true;
+
+ if ( request >>= licExc )
+ {
+ uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ deployment::ui::LicenseDialog::create(
+ xContext, VCLUnoHelper::GetInterface( NULL ),
+ licExc.ExtensionName, licExc.Text ) );
+ sal_Int16 res = xDialog->execute();
+ if ( res == ui::dialogs::ExecutableDialogResults::CANCEL )
+ bApprove = false;
+ else if ( res == ui::dialogs::ExecutableDialogResults::OK )
+ bApprove = true;
+ else
+ {
+ OSL_ASSERT(0);
+ }
+ }
+
+ // We approve everything here
+ uno::Sequence< Reference< task::XInteractionContinuation > > conts( xRequest->getContinuations() );
+ Reference< task::XInteractionContinuation > const * pConts = conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if ( bApprove )
+ {
+ uno::Reference< task::XInteractionApprove > xInteractionApprove( pConts[ pos ], uno::UNO_QUERY );
+ if ( xInteractionApprove.is() )
+ xInteractionApprove->select();
+ }
+ else
+ {
+ uno::Reference< task::XInteractionAbort > xInteractionAbort( pConts[ pos ], uno::UNO_QUERY );
+ if ( xInteractionAbort.is() )
+ xInteractionAbort->select();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// XProgressHandler
+void SilentCommandEnv::push( uno::Any const & rStatus )
+ throw (uno::RuntimeException)
+{
+ OUString sText;
+ mnLevel += 1;
+
+ if ( rStatus.hasValue() && ( rStatus >>= sText) )
+ {
+ if ( mnLevel <= 3 )
+ mpDesktop->SetSplashScreenText( sText );
+ else
+ mpDesktop->SetSplashScreenProgress( ++mnProgress );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SilentCommandEnv::update( uno::Any const & rStatus )
+ throw (uno::RuntimeException)
+{
+ OUString sText;
+ if ( rStatus.hasValue() && ( rStatus >>= sText) )
+ {
+ mpDesktop->SetSplashScreenText( sText );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SilentCommandEnv::pop() throw (uno::RuntimeException)
+{
+ mnLevel -= 1;
+}
+
+} // end namespace
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
+//------------------------------------------------------------------------------
+static sal_Int16 impl_showExtensionDialog( uno::Reference< uno::XComponentContext > &xContext )
+{
+ rtl::OUString sServiceName = UNISTRING("com.sun.star.deployment.ui.UpdateRequiredDialog");
+ uno::Reference< uno::XInterface > xService;
+ sal_Int16 nRet = 0;
+
+ uno::Reference< lang::XMultiComponentFactory > xServiceManager( xContext->getServiceManager() );
+ if( !xServiceManager.is() )
+ throw uno::RuntimeException(
+ UNISTRING( "impl_showExtensionDialog(): unable to obtain service manager from component context" ), uno::Reference< uno::XInterface > () );
+
+ xService = xServiceManager->createInstanceWithContext( sServiceName, xContext );
+ uno::Reference< ui::dialogs::XExecutableDialog > xExecuteable( xService, uno::UNO_QUERY );
+ if ( xExecuteable.is() )
+ nRet = xExecuteable->execute();
+
+ return nRet;
+}
+
+//------------------------------------------------------------------------------
+// Check dependencies of all packages
+//------------------------------------------------------------------------------
+static bool impl_checkDependencies( const uno::Reference< uno::XComponentContext > &xContext )
+{
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+ uno::Reference< deployment::XExtensionManager > xExtensionManager = deployment::ExtensionManager::get( xContext );
+
+ if ( !xExtensionManager.is() )
+ {
+ OSL_ENSURE( 0, "Could not get the Extension Manager!" );
+ return true;
+ }
+
+ try {
+ xAllPackages = xExtensionManager->getAllExtensions( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException & ) { return true; }
+ catch ( ucb::CommandFailedException & ) { return true; }
+ catch ( ucb::CommandAbortedException & ) { return true; }
+ catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+
+ sal_Int32 nMax = 2;
+#ifdef DEBUG
+ nMax = 3;
+#endif
+
+ for ( sal_Int32 i = 0; i < xAllPackages.getLength(); ++i )
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > xPackageList = xAllPackages[i];
+
+ for ( sal_Int32 j = 0; (j<nMax) && (j < xPackageList.getLength()); ++j )
+ {
+ uno::Reference< deployment::XPackage > xPackage = xPackageList[j];
+ if ( xPackage.is() )
+ {
+ 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() );
+ }
+
+ if ( bRegistered )
+ {
+ bool bDependenciesValid = false;
+ try {
+ bDependenciesValid = xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException & ) {}
+ if ( ! bDependenciesValid )
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------------
+// resets the 'check needed' flag (needed, if aborted)
+//------------------------------------------------------------------------------
+static void impl_setNeedsCompatCheck()
+{
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ Sequence< Any > theArgs(1);
+ beans::NamedValue v( OUString::createFromAscii("NodePath"),
+ makeAny( OUString::createFromAscii("org.openoffice.Setup/Office") ) );
+ theArgs[0] <<= v;
+ Reference< beans::XPropertySet > pset = Reference< beans::XPropertySet >(
+ theConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+
+ Any value = makeAny( OUString::createFromAscii("never") );
+
+ pset->setPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID"), value );
+ Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
+ }
+ catch (const Exception&) {}
+}
+
+//------------------------------------------------------------------------------
+static bool impl_check()
+{
+ uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
+
+ bool bDependenciesValid = impl_checkDependencies( xContext );
+
+ short nRet = 0;
+
+ if ( !bDependenciesValid )
+ nRet = impl_showExtensionDialog( xContext );
+
+ if ( nRet == -1 )
+ {
+ impl_setNeedsCompatCheck();
+ return true;
+ }
+ else
+ return false;
+}
+
+//------------------------------------------------------------------------------
+// to check if we need checking the dependencies of the extensions again, we compare
+// the build id of the office with the one of the last check
+//------------------------------------------------------------------------------
+static bool impl_needsCompatCheck()
+{
+ bool bNeedsCheck = false;
+ rtl::OUString aLastCheckBuildID;
+ rtl::OUString aCurrentBuildID( UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) );
+ rtl::Bootstrap::expandMacros( aCurrentBuildID );
+
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ Sequence< Any > theArgs(1);
+ beans::NamedValue v( OUString::createFromAscii("NodePath"),
+ makeAny( OUString::createFromAscii("org.openoffice.Setup/Office") ) );
+ theArgs[0] <<= v;
+ Reference< beans::XPropertySet > pset = Reference< beans::XPropertySet >(
+ theConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+
+ Any result = pset->getPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID") );
+
+ result >>= aLastCheckBuildID;
+ if ( aLastCheckBuildID != aCurrentBuildID )
+ {
+ bNeedsCheck = true;
+ result <<= aCurrentBuildID;
+ pset->setPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID"), result );
+ Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
+ }
+#ifdef DEBUG
+ bNeedsCheck = true;
+#endif
+ }
+ catch (const Exception&) {}
+
+ return bNeedsCheck;
+}
+
+//------------------------------------------------------------------------------
+// Do we need to check the dependencies of the extensions?
+// When there are unresolved issues, we can't continue with startup
+sal_Bool Desktop::CheckExtensionDependencies()
+{
+ sal_Bool bAbort = false;
+
+ if ( impl_needsCompatCheck() )
+ bAbort = impl_check();
+
+ return bAbort;
+}
+
+void Desktop::SynchronizeExtensionRepositories()
+{
+ RTL_LOGFILE_CONTEXT(aLog,"desktop (jl) ::Desktop::SynchronizeExtensionRepositories");
+ dp_misc::syncRepositories( new SilentCommandEnv( this ) );
+}
diff --git a/desktop/source/app/checkinstall.cxx b/desktop/source/app/checkinstall.cxx
new file mode 100644
index 000000000000..bb7258554cfe
--- /dev/null
+++ b/desktop/source/app/checkinstall.cxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "checkinstall.hxx"
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/date.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+
+namespace desktop
+{
+
+sal_Bool CheckInstallation( OUString& rTitle )
+{
+ try
+ {
+ Reference< XMultiServiceFactory > xSMgr = ::comphelper::getProcessServiceFactory();
+ Reference< XExactName > xExactName( xSMgr->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.desktop.Evaluation" ))),
+ UNO_QUERY );
+ if ( xExactName.is() )
+ {
+ try
+ {
+ rTitle = xExactName->getExactName( rTitle );
+ Reference< XMaterialHolder > xMaterialHolder( xExactName, UNO_QUERY );
+ if ( xMaterialHolder.is() )
+ {
+ com::sun::star::util::Date aExpirationDate;
+ Any a = xMaterialHolder->getMaterial();
+ if ( a >>= aExpirationDate )
+ {
+ Date aToday;
+ Date aTimeBombDate( aExpirationDate.Day, aExpirationDate.Month, aExpirationDate.Year );
+ if ( aToday > aTimeBombDate )
+ {
+ InfoBox aInfoBox( NULL, String::CreateFromAscii( "This version has expired" ) );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+ }
+ else
+ {
+ InfoBox aInfoBox( NULL, rTitle );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+ catch ( RuntimeException& )
+ {
+ // Evaluation version expired!
+ return sal_False;
+ }
+ }
+ else
+ {
+ Reference< com::sun::star::container::XContentEnumerationAccess > rContent( xSMgr , UNO_QUERY );
+ if( rContent.is() )
+ {
+ OUString sEvalService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.Evaluation" ) );
+ Reference < com::sun::star::container::XEnumeration > rEnum = rContent->createContentEnumeration( sEvalService );
+ if ( rEnum.is() )
+ {
+ InfoBox aInfoBox( NULL, rTitle );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+ }
+ }
+ catch(Exception)
+ {
+ }
+
+ return sal_True;
+}
+
+} // namespace desktop
diff --git a/desktop/source/app/checkinstall.hxx b/desktop/source/app/checkinstall.hxx
new file mode 100644
index 000000000000..495ea3161bd3
--- /dev/null
+++ b/desktop/source/app/checkinstall.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_CHECKINSTALL_HXX_
+#define _DESKTOP_CHECKINSTALL_HXX_
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+
+namespace desktop
+{
+
+sal_Bool CheckInstallation( rtl::OUString& rTitle );
+
+}
+
+#endif // _DESKTOP_CHECKINSTALL_HXX_
diff --git a/desktop/source/app/cmdlineargs.cxx b/desktop/source/app/cmdlineargs.cxx
new file mode 100644
index 000000000000..0625191ee2ea
--- /dev/null
+++ b/desktop/source/app/cmdlineargs.cxx
@@ -0,0 +1,900 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <cmdlineargs.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustring.hxx>
+#include "rtl/process.h"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uri/XExternalUriReferenceTranslator.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include "tools/getprocessworkingdir.hxx"
+
+#include <svl/documentlockfile.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uri;
+using namespace com::sun::star::uno;
+
+namespace desktop
+{
+
+namespace {
+
+class ExtCommandLineSupplier: public CommandLineArgs::Supplier {
+public:
+ explicit ExtCommandLineSupplier():
+ m_count(rtl_getAppCommandArgCount()),
+ m_index(0)
+ {
+ rtl::OUString url;
+ if (tools::getProcessWorkingDir(&url)) {
+ m_cwdUrl.reset(url);
+ }
+ }
+
+ virtual ~ExtCommandLineSupplier() {}
+
+ virtual boost::optional< rtl::OUString > getCwdUrl() { return m_cwdUrl; }
+
+ virtual bool next(rtl::OUString * argument) {
+ OSL_ASSERT(argument != NULL);
+ if (m_index < m_count) {
+ rtl_getAppCommandArg(m_index++, &argument->pData);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+private:
+ boost::optional< rtl::OUString > m_cwdUrl;
+ sal_uInt32 m_count;
+ sal_uInt32 m_index;
+};
+
+}
+
+static CommandLineArgs::BoolParam aModuleGroupDefinition[] =
+{
+ CommandLineArgs::CMD_BOOLPARAM_WRITER,
+ CommandLineArgs::CMD_BOOLPARAM_CALC,
+ CommandLineArgs::CMD_BOOLPARAM_DRAW,
+ CommandLineArgs::CMD_BOOLPARAM_IMPRESS,
+ CommandLineArgs::CMD_BOOLPARAM_GLOBAL,
+ CommandLineArgs::CMD_BOOLPARAM_MATH,
+ CommandLineArgs::CMD_BOOLPARAM_WEB,
+ CommandLineArgs::CMD_BOOLPARAM_BASE
+};
+
+CommandLineArgs::GroupDefinition CommandLineArgs::m_pGroupDefinitions[ CommandLineArgs::CMD_GRPID_COUNT ] =
+{
+ { 8, aModuleGroupDefinition }
+};
+
+CommandLineArgs::Supplier::Exception::Exception() {}
+
+CommandLineArgs::Supplier::Exception::Exception(Exception const &) {}
+
+CommandLineArgs::Supplier::Exception::~Exception() {}
+
+CommandLineArgs::Supplier::Exception &
+CommandLineArgs::Supplier::Exception::operator =(Exception const &)
+{ return *this; }
+
+CommandLineArgs::Supplier::~Supplier() {}
+
+// intialize class with command line parameters from process environment
+CommandLineArgs::CommandLineArgs()
+{
+ ResetParamValues();
+ ExtCommandLineSupplier s;
+ ParseCommandLine_Impl( s );
+}
+
+CommandLineArgs::CommandLineArgs( Supplier& supplier )
+{
+ ResetParamValues();
+ ParseCommandLine_Impl( supplier );
+}
+
+// ----------------------------------------------------------------------------
+
+void CommandLineArgs::ParseCommandLine_Impl( Supplier& supplier )
+{
+ m_cwdUrl = supplier.getCwdUrl();
+ Reference<XMultiServiceFactory> xMS(comphelper::getProcessServiceFactory(), UNO_QUERY);
+ OSL_ENSURE(xMS.is(), "CommandLineArgs: no ProcessServiceFactory.");
+
+ Reference< XExternalUriReferenceTranslator > xTranslator(
+ xMS->createInstance(
+ OUString::createFromAscii(
+ "com.sun.star.uri.ExternalUriReferenceTranslator")),
+ UNO_QUERY);
+
+ // parse command line arguments
+ sal_Bool bPrintEvent = sal_False;
+ sal_Bool bOpenEvent = sal_True;
+ sal_Bool bViewEvent = sal_False;
+ sal_Bool bStartEvent = sal_False;
+ sal_Bool bPrintToEvent = sal_False;
+ sal_Bool bPrinterName = sal_False;
+ sal_Bool bForceOpenEvent = sal_False;
+ sal_Bool bForceNewEvent = sal_False;
+ sal_Bool bDisplaySpec = sal_False;
+
+ m_eArgumentCount = NONE;
+
+ for (;;)
+ {
+ ::rtl::OUString aArg;
+ if ( !supplier.next( &aArg ) )
+ {
+ break;
+ }
+ // convert file URLs to internal form #112849#
+ if (aArg.indexOf(OUString::createFromAscii("file:"))==0 &&
+ xTranslator.is())
+ {
+ OUString tmp(xTranslator->translateToInternal(aArg));
+ if (tmp.getLength() > 0)
+ aArg = tmp;
+ }
+ String aArgStr = aArg;
+
+ if ( aArg.getLength() > 0 )
+ {
+ m_eArgumentCount = m_eArgumentCount == NONE ? ONE : MANY;
+ if ( !InterpretCommandLineParameter( aArg ))
+ {
+ if ( aArgStr.GetChar(0) == '-' )
+ {
+ // handle this argument as an option
+ if ( aArgStr.EqualsIgnoreCaseAscii( "-n" ))
+ {
+ // force new documents based on the following documents
+ bForceNewEvent = sal_True;
+ bOpenEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bPrintEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-o" ))
+ {
+ // force open documents regards if they are templates or not
+ bForceOpenEvent = sal_True;
+ bOpenEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bPrintEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-pt" ))
+ {
+ // Print to special printer
+ bPrintToEvent = sal_True;
+ bPrinterName = sal_True;
+ bPrintEvent = sal_False;
+ bOpenEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ bForceOpenEvent = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-p" ))
+ {
+ // Print to default printer
+ bPrintEvent = sal_True;
+ bPrintToEvent = sal_False;
+ bOpenEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-view" ))
+ {
+ // open in viewmode
+ bOpenEvent = sal_False;
+ bPrintEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bViewEvent = sal_True;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-show" ))
+ {
+ // open in viewmode
+ bOpenEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_True;
+ bPrintEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-display" ))
+ {
+ // set display
+ bOpenEvent = sal_False;
+ bPrintEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_True;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-language" ))
+ {
+ bOpenEvent = sal_False;
+ bPrintEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+
+ #ifdef MACOSX
+ /* #i84053# ignore -psn on Mac
+ Platform dependent #ifdef here is ugly, however this is currently
+ the only platform dependent parameter. Should more appear
+ we should find a better solution
+ */
+ else if ( aArgStr.CompareToAscii( "-psn", 4 ) == COMPARE_EQUAL )
+ {
+ // finder argument from MacOSX
+ bOpenEvent = sal_False;
+ bPrintEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ #endif
+ }
+ else
+ {
+ if ( bPrinterName && bPrintToEvent )
+ {
+ // first argument after "-pt" this must be the printer name
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTERNAME, aArgStr );
+ bPrinterName = sal_False;
+ }
+ else
+ {
+ // handle this argument as a filename
+ if ( bOpenEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_OPENLIST, aArgStr );
+ else if ( bViewEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_VIEWLIST, aArgStr );
+ else if ( bStartEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_STARTLIST, aArgStr );
+ else if ( bPrintEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTLIST, aArgStr );
+ else if ( bPrintToEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTTOLIST, aArgStr );
+ else if ( bForceNewEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_FORCENEWLIST, aArgStr );
+ else if ( bForceOpenEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_FORCEOPENLIST, aArgStr );
+ else if ( bDisplaySpec ){
+ AddStringListParam_Impl( CMD_STRINGPARAM_DISPLAY, aArgStr );
+ bDisplaySpec = sal_False; // only one display, not a lsit
+ bOpenEvent = sal_True; // set back to standard
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void CommandLineArgs::AddStringListParam_Impl( StringParam eParam, const rtl::OUString& aParam )
+{
+ OSL_ASSERT( eParam >= 0 && eParam < CMD_STRINGPARAM_COUNT );
+ if ( m_aStrParams[eParam].getLength() )
+ m_aStrParams[eParam] += ::rtl::OUString::valueOf( (sal_Unicode)APPEVENT_PARAM_DELIMITER );
+ m_aStrParams[eParam] += aParam;
+ m_aStrSetParams[eParam] = sal_True;
+}
+
+void CommandLineArgs::SetBoolParam_Impl( BoolParam eParam, sal_Bool bValue )
+{
+ OSL_ASSERT( eParam >= 0 && eParam < CMD_BOOLPARAM_COUNT );
+ m_aBoolParams[eParam] = bValue;
+}
+
+sal_Bool CommandLineArgs::InterpretCommandLineParameter( const ::rtl::OUString& aArg )
+{
+ String aArgStr( aArg );
+
+ if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-minimized" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_MINIMIZED, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-invisible" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_INVISIBLE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-norestore" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NORESTORE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-nodefault" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NODEFAULT, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-bean" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_BEAN, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-plugin" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_PLUGIN, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-server" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_SERVER, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-headless" )) == sal_True )
+ {
+ // Headless means also invisibile, so set this parameter to true!
+ SetBoolParam_Impl( CMD_BOOLPARAM_HEADLESS, sal_True );
+ SetBoolParam_Impl( CMD_BOOLPARAM_INVISIBLE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-quickstart" )) == sal_True )
+ {
+#if defined(WNT) || defined(OS2) || defined(QUARTZ)
+ SetBoolParam_Impl( CMD_BOOLPARAM_QUICKSTART, sal_True );
+#endif
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOQUICKSTART, sal_False );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-quickstart=no" )))
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOQUICKSTART, sal_True );
+ SetBoolParam_Impl( CMD_BOOLPARAM_QUICKSTART, sal_False );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-terminate_after_init" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_TERMINATEAFTERINIT, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-nofirststartwizard" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOFIRSTSTARTWIZARD, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-nologo" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOLOGO, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-nolockcheck" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOLOCKCHECK, sal_True );
+ // Workaround for automated testing
+ ::svt::DocumentLockFile::AllowInteraction( sal_False );
+
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-help" ))
+ || aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-h" ))
+ || aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-?" )))
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELP, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpwriter" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPWRITER, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpcalc" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPCALC, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpdraw" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPDRAW, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpimpress" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPIMPRESS, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpbase" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPBASE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpbasic" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPBASIC, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpmath" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPMATH, sal_True );
+ return sal_True;
+ }
+ #ifdef MACOSX
+ /* #i84053# ignore -psn on Mac
+ Platform dependent #ifdef here is ugly, however this is currently
+ the only platform dependent parameter. Should more appear
+ we should find a better solution
+ */
+ else if ( aArg.compareToAscii( "-psn", 4 ) == 0 )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_PSN, sal_True );
+ return sal_True;
+ }
+ #endif
+ else if ( aArgStr.Copy(0, 8).EqualsIgnoreCaseAscii( "-accept=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_ACCEPT, aArgStr.Copy( 8 ) );
+ return sal_True;
+ }
+ else if ( aArgStr.Copy(0, 10).EqualsIgnoreCaseAscii( "-unaccept=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_UNACCEPT, aArgStr.Copy( 10 ) );
+ return sal_True;
+ }
+ else if ( aArgStr.CompareIgnoreCaseToAscii( "-portal," ,
+ RTL_CONSTASCII_LENGTH( "-portal," )) == COMPARE_EQUAL )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_PORTAL, aArgStr.Copy( RTL_CONSTASCII_LENGTH( "-portal," )) );
+ return sal_True;
+ }
+ else if ( aArgStr.Copy( 0, 7 ).EqualsIgnoreCaseAscii( "-userid" ))
+ {
+ if ( aArgStr.Len() > 8 )
+ {
+ rtl::OUString aUserDir = aArgStr;
+ AddStringListParam_Impl(
+ CMD_STRINGPARAM_USERDIR,
+ ::rtl::Uri::decode( aUserDir.copy( 8 ),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ return sal_True;
+ }
+ else if ( aArgStr.Copy( 0, 15).EqualsIgnoreCaseAscii( "-clientdisplay=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_CLIENTDISPLAY, aArgStr.Copy( 15 ) );
+ return sal_True;
+ }
+ else if ( aArgStr.Copy(0, 9).EqualsIgnoreCaseAscii( "-version=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_VERSION, aArgStr.Copy( 9 ) );
+ return sal_True;
+ }
+ else if ( aArgStr.Copy(0, 10).EqualsIgnoreCaseAscii( "-language=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_LANGUAGE, aArgStr.Copy( 10 ) );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-writer" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_WRITER );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_WRITER, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-calc" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_CALC );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_CALC, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-draw" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_DRAW );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_DRAW, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-impress" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_IMPRESS );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_IMPRESS, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-base" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_BASE );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_BASE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-global" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_GLOBAL );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_GLOBAL, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-math" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_MATH );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_MATH, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-web" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_WEB );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_WEB, sal_True );
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool CommandLineArgs::CheckGroupMembers( GroupParamId nGroupId, BoolParam nExcludeMember ) const
+{
+ // Check if at least one bool param out of a group is set. An exclude member can be provided.
+ for ( int i = 0; i < m_pGroupDefinitions[nGroupId].nCount; i++ )
+ {
+ BoolParam nParam = m_pGroupDefinitions[nGroupId].pGroupMembers[i];
+ if ( nParam != nExcludeMember && m_aBoolParams[nParam] )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void CommandLineArgs::ResetParamValues()
+{
+ int i;
+
+ for ( i = 0; i < CMD_BOOLPARAM_COUNT; i++ )
+ m_aBoolParams[i] = sal_False;
+ for ( i = 0; i < CMD_STRINGPARAM_COUNT; i++ )
+ m_aStrSetParams[i] = sal_False;
+ m_eArgumentCount = NONE;
+}
+
+void CommandLineArgs::SetBoolParam( BoolParam eParam, sal_Bool bNewValue )
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+
+ OSL_ASSERT( ( eParam >= 0 && eParam < CMD_BOOLPARAM_COUNT ) );
+ m_aBoolParams[eParam] = bNewValue;
+}
+
+sal_Bool CommandLineArgs::IsMinimized() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_MINIMIZED ];
+}
+
+sal_Bool CommandLineArgs::IsInvisible() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_INVISIBLE ];
+}
+
+sal_Bool CommandLineArgs::IsNoRestore() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NORESTORE ];
+}
+
+sal_Bool CommandLineArgs::IsNoDefault() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NODEFAULT ];
+}
+
+sal_Bool CommandLineArgs::IsBean() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_BEAN ];
+}
+
+sal_Bool CommandLineArgs::IsServer() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_SERVER ];
+}
+
+sal_Bool CommandLineArgs::IsHeadless() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HEADLESS ];
+}
+
+sal_Bool CommandLineArgs::IsQuickstart() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_QUICKSTART ];
+}
+
+sal_Bool CommandLineArgs::IsNoQuickstart() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOQUICKSTART ];
+}
+
+sal_Bool CommandLineArgs::IsTerminateAfterInit() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_TERMINATEAFTERINIT ];
+}
+
+sal_Bool CommandLineArgs::IsNoFirstStartWizard() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOFIRSTSTARTWIZARD ];
+}
+
+sal_Bool CommandLineArgs::IsNoLogo() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOLOGO ];
+}
+
+sal_Bool CommandLineArgs::IsNoLockcheck() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOLOCKCHECK ];
+}
+
+sal_Bool CommandLineArgs::IsHelp() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELP ];
+}
+sal_Bool CommandLineArgs::IsHelpWriter() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPWRITER ];
+}
+
+sal_Bool CommandLineArgs::IsHelpCalc() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPCALC ];
+}
+
+sal_Bool CommandLineArgs::IsHelpDraw() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPDRAW ];
+}
+
+sal_Bool CommandLineArgs::IsHelpImpress() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPIMPRESS ];
+}
+
+sal_Bool CommandLineArgs::IsHelpBase() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPBASE ];
+}
+sal_Bool CommandLineArgs::IsHelpMath() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPMATH ];
+}
+sal_Bool CommandLineArgs::IsHelpBasic() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPBASIC ];
+}
+
+sal_Bool CommandLineArgs::IsWriter() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_WRITER ];
+}
+
+sal_Bool CommandLineArgs::IsCalc() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_CALC ];
+}
+
+sal_Bool CommandLineArgs::IsDraw() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_DRAW ];
+}
+
+sal_Bool CommandLineArgs::IsImpress() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_IMPRESS ];
+}
+
+sal_Bool CommandLineArgs::IsBase() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_BASE ];
+}
+
+sal_Bool CommandLineArgs::IsGlobal() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_GLOBAL ];
+}
+
+sal_Bool CommandLineArgs::IsMath() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_MATH ];
+}
+
+sal_Bool CommandLineArgs::IsWeb() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_WEB ];
+}
+
+sal_Bool CommandLineArgs::HasModuleParam() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_COUNT );
+}
+
+sal_Bool CommandLineArgs::GetPortalConnectString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PORTAL ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PORTAL ];
+}
+
+sal_Bool CommandLineArgs::GetAcceptString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_ACCEPT ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_ACCEPT ];
+}
+
+sal_Bool CommandLineArgs::GetUnAcceptString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_UNACCEPT ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_UNACCEPT ];
+}
+
+sal_Bool CommandLineArgs::GetOpenList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_OPENLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_OPENLIST ];
+}
+
+sal_Bool CommandLineArgs::GetViewList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_VIEWLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_VIEWLIST ];
+}
+
+sal_Bool CommandLineArgs::GetStartList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_STARTLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_STARTLIST ];
+}
+
+sal_Bool CommandLineArgs::GetForceOpenList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_FORCEOPENLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_FORCEOPENLIST ];
+}
+
+sal_Bool CommandLineArgs::GetForceNewList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_FORCENEWLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_FORCENEWLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrintList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrintToList( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTTOLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTTOLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrinterName( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTERNAME ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTERNAME ];
+}
+
+sal_Bool CommandLineArgs::GetLanguage( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_LANGUAGE ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_LANGUAGE ];
+}
+
+sal_Bool CommandLineArgs::IsEmpty() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_eArgumentCount == NONE;
+}
+
+sal_Bool CommandLineArgs::IsEmptyOrAcceptOnly() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+
+ return m_eArgumentCount == NONE ||
+ ( ( m_eArgumentCount == ONE ) && ( m_aStrParams[ CMD_STRINGPARAM_ACCEPT ].getLength() )) ||
+ ( ( m_eArgumentCount == ONE ) && m_aBoolParams[ CMD_BOOLPARAM_PSN ] );
+}
+
+} // namespace desktop
diff --git a/desktop/source/app/cmdlineargs.hxx b/desktop/source/app/cmdlineargs.hxx
new file mode 100644
index 000000000000..615577098c2d
--- /dev/null
+++ b/desktop/source/app/cmdlineargs.hxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_COMMANDLINEARGS_HXX_
+#define _DESKTOP_COMMANDLINEARGS_HXX_
+
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include "boost/optional.hpp"
+
+namespace desktop
+{
+
+class CommandLineArgs
+{
+ public:
+ enum BoolParam // must be zero based!
+ {
+ CMD_BOOLPARAM_MINIMIZED,
+ CMD_BOOLPARAM_INVISIBLE,
+ CMD_BOOLPARAM_NORESTORE,
+ CMD_BOOLPARAM_BEAN,
+ CMD_BOOLPARAM_PLUGIN,
+ CMD_BOOLPARAM_SERVER,
+ CMD_BOOLPARAM_HEADLESS,
+ CMD_BOOLPARAM_QUICKSTART,
+ CMD_BOOLPARAM_NOQUICKSTART,
+ CMD_BOOLPARAM_TERMINATEAFTERINIT,
+ CMD_BOOLPARAM_NOFIRSTSTARTWIZARD,
+ CMD_BOOLPARAM_NOLOGO,
+ CMD_BOOLPARAM_NOLOCKCHECK,
+ CMD_BOOLPARAM_NODEFAULT,
+ CMD_BOOLPARAM_HELP,
+ CMD_BOOLPARAM_WRITER,
+ CMD_BOOLPARAM_CALC,
+ CMD_BOOLPARAM_DRAW,
+ CMD_BOOLPARAM_IMPRESS,
+ CMD_BOOLPARAM_GLOBAL,
+ CMD_BOOLPARAM_MATH,
+ CMD_BOOLPARAM_WEB,
+ CMD_BOOLPARAM_BASE,
+ CMD_BOOLPARAM_HELPWRITER,
+ CMD_BOOLPARAM_HELPCALC,
+ CMD_BOOLPARAM_HELPDRAW,
+ CMD_BOOLPARAM_HELPBASIC,
+ CMD_BOOLPARAM_HELPMATH,
+ CMD_BOOLPARAM_HELPIMPRESS,
+ CMD_BOOLPARAM_HELPBASE,
+ CMD_BOOLPARAM_PSN,
+ CMD_BOOLPARAM_COUNT // must be last element!
+ };
+
+ enum StringParam // must be zero based!
+ {
+ CMD_STRINGPARAM_PORTAL,
+ CMD_STRINGPARAM_ACCEPT,
+ CMD_STRINGPARAM_UNACCEPT,
+ CMD_STRINGPARAM_USERDIR,
+ CMD_STRINGPARAM_CLIENTDISPLAY,
+ CMD_STRINGPARAM_OPENLIST,
+ CMD_STRINGPARAM_VIEWLIST,
+ CMD_STRINGPARAM_STARTLIST,
+ CMD_STRINGPARAM_FORCEOPENLIST,
+ CMD_STRINGPARAM_FORCENEWLIST,
+ CMD_STRINGPARAM_PRINTLIST,
+ CMD_STRINGPARAM_VERSION,
+ CMD_STRINGPARAM_PRINTTOLIST,
+ CMD_STRINGPARAM_PRINTERNAME,
+ CMD_STRINGPARAM_DISPLAY,
+ CMD_STRINGPARAM_LANGUAGE,
+ CMD_STRINGPARAM_COUNT // must be last element!
+ };
+
+ enum GroupParamId
+ {
+ CMD_GRPID_MODULE,
+ CMD_GRPID_COUNT
+ };
+
+ struct Supplier {
+ // Thrown from constructors and next:
+ class Exception {
+ public:
+ Exception();
+ Exception(Exception const &);
+ virtual ~Exception();
+ Exception & operator =(Exception const &);
+ };
+
+ virtual ~Supplier();
+ virtual boost::optional< rtl::OUString > getCwdUrl() = 0;
+ virtual bool next(rtl::OUString * argument) = 0;
+ };
+
+ CommandLineArgs();
+ CommandLineArgs( Supplier& supplier );
+
+ boost::optional< rtl::OUString > getCwdUrl() const { return m_cwdUrl; }
+
+ // generic methods to access parameter
+ void SetBoolParam( BoolParam eParam, sal_Bool bNewValue );
+
+ // Access to bool parameters
+ sal_Bool IsMinimized() const;
+ sal_Bool IsInvisible() const;
+ sal_Bool IsNoRestore() const;
+ sal_Bool IsNoDefault() const;
+ sal_Bool IsBean() const;
+ sal_Bool IsServer() const;
+ sal_Bool IsHeadless() const;
+ sal_Bool IsQuickstart() const;
+ sal_Bool IsNoQuickstart() const;
+ sal_Bool IsTerminateAfterInit() const;
+ sal_Bool IsNoFirstStartWizard() const;
+ sal_Bool IsNoLogo() const;
+ sal_Bool IsNoLockcheck() const;
+ sal_Bool IsHelp() const;
+ sal_Bool IsHelpWriter() const;
+ sal_Bool IsHelpCalc() const;
+ sal_Bool IsHelpDraw() const;
+ sal_Bool IsHelpImpress() const;
+ sal_Bool IsHelpBase() const;
+ sal_Bool IsHelpMath() const;
+ sal_Bool IsHelpBasic() const;
+ sal_Bool IsWriter() const;
+ sal_Bool IsCalc() const;
+ sal_Bool IsDraw() const;
+ sal_Bool IsImpress() const;
+ sal_Bool IsBase() const;
+ sal_Bool IsGlobal() const;
+ sal_Bool IsMath() const;
+ sal_Bool IsWeb() const;
+ sal_Bool HasModuleParam() const;
+
+ // Access to string parameters
+ sal_Bool GetPortalConnectString( ::rtl::OUString& rPara) const;
+ sal_Bool GetAcceptString( ::rtl::OUString& rPara) const;
+ sal_Bool GetUnAcceptString( ::rtl::OUString& rPara) const;
+ sal_Bool GetOpenList( ::rtl::OUString& rPara) const;
+ sal_Bool GetViewList( ::rtl::OUString& rPara) const;
+ sal_Bool GetStartList( ::rtl::OUString& rPara) const;
+ sal_Bool GetForceOpenList( ::rtl::OUString& rPara) const;
+ sal_Bool GetForceNewList( ::rtl::OUString& rPara) const;
+ sal_Bool GetPrintList( ::rtl::OUString& rPara) const;
+ sal_Bool GetPrintToList( ::rtl::OUString& rPara ) const;
+ sal_Bool GetPrinterName( ::rtl::OUString& rPara ) const;
+ sal_Bool GetLanguage( ::rtl::OUString& rPara ) const;
+
+ // Special analyzed states (does not match directly to a command line parameter!)
+ sal_Bool IsPrinting() const;
+ sal_Bool IsEmpty() const;
+ sal_Bool IsEmptyOrAcceptOnly() const;
+
+ private:
+ enum Count { NONE, ONE, MANY };
+
+ struct GroupDefinition
+ {
+ sal_Int32 nCount;
+ BoolParam* pGroupMembers;
+ };
+
+ // no copy and operator=
+ CommandLineArgs( const CommandLineArgs& );
+ CommandLineArgs operator=( const CommandLineArgs& );
+
+ sal_Bool InterpretCommandLineParameter( const ::rtl::OUString& );
+ void ParseCommandLine_Impl( Supplier& supplier );
+ void ResetParamValues();
+ sal_Bool CheckGroupMembers( GroupParamId nGroup, BoolParam nExcludeMember ) const;
+
+ void AddStringListParam_Impl( StringParam eParam, const rtl::OUString& aParam );
+ void SetBoolParam_Impl( BoolParam eParam, sal_Bool bValue );
+
+ boost::optional< rtl::OUString > m_cwdUrl;
+ sal_Bool m_aBoolParams[ CMD_BOOLPARAM_COUNT ]; // Stores boolean parameters
+ rtl::OUString m_aStrParams[ CMD_STRINGPARAM_COUNT ]; // Stores string parameters
+ sal_Bool m_aStrSetParams[ CMD_STRINGPARAM_COUNT ]; // Stores if string parameters are provided on cmdline
+ Count m_eArgumentCount; // Number of Args
+ mutable ::osl::Mutex m_aMutex;
+
+ // static definition for groups where only one member can be true
+ static GroupDefinition m_pGroupDefinitions[ CMD_GRPID_COUNT ];
+};
+
+}
+
+#endif
diff --git a/desktop/source/app/cmdlinehelp.cxx b/desktop/source/app/cmdlinehelp.cxx
new file mode 100644
index 000000000000..c4530e9ce61c
--- /dev/null
+++ b/desktop/source/app/cmdlinehelp.cxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <stdlib.h>
+#ifdef UNX
+#include <stdio.h>
+#endif
+#include <sal/types.h>
+#include <tools/string.hxx>
+#include <vcl/msgbox.hxx>
+#include <rtl/bootstrap.hxx>
+#include <app.hxx>
+
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include "cmdlinehelp.hxx"
+
+namespace desktop
+{
+ // to be able to display the help nicely in a dialog box with propotional font,
+ // we need to split it in chunks...
+ // ___HEAD___
+ // LEFT RIGHT
+ // LEFT RIGHT
+ // LEFT RIGHT
+ // __BOTTOM__
+ // [OK]
+
+ const char *aCmdLineHelp_head =
+ "%PRODUCTNAME %PRODUCTVERSION %PRODUCTEXTENSION %BUILDID\n"\
+ "\n"\
+ "Usage: %CMDNAME [options] [documents...]\n"\
+ "\n"\
+ "Options:\n";
+ const char *aCmdLineHelp_left =
+ "-minimized \n"\
+ "-invisible \n"\
+ "-norestore \n"\
+ "-quickstart \n"\
+ "-nologo \n"\
+ "-nolockcheck \n"\
+ "-nodefault \n"\
+ "-headless \n"\
+ "-help/-h/-? \n"\
+ "-writer \n"\
+ "-calc \n"\
+ "-draw \n"\
+ "-impress \n"\
+ "-base \n"\
+ "-math \n"\
+ "-global \n"\
+ "-web \n"\
+ "-o \n"\
+ "-n \n";
+ const char *aCmdLineHelp_right =
+ "keep startup bitmap minimized.\n"\
+ "no startup screen, no default document and no UI.\n"\
+ "suppress restart/restore after fatal errors.\n"\
+ "starts the quickstart service (only available on windows and OS/2 platform)\n"\
+ "don't show startup screen.\n"\
+ "don't check for remote instances using the installation\n"\
+ "don't start with an empty document\n"\
+ "like invisible but no userinteraction at all.\n"\
+ "show this message and exit.\n"\
+ "create new text document.\n"\
+ "create new spreadsheet document.\n"\
+ "create new drawing.\n"\
+ "create new presentation.\n"\
+ "create new database.\n"\
+ "create new formula.\n"\
+ "create new global document.\n"\
+ "create new HTML document.\n"\
+ "open documents regardless whether they are templates or not.\n"\
+ "always open documents as new files (use as template).\n";
+ const char *aCmdLineHelp_bottom =
+ "-display <display>\n"\
+ " Specify X-Display to use in Unix/X11 versions.\n"
+ "-p <documents...>\n"\
+ " print the specified documents on the default printer.\n"\
+ "-pt <printer> <documents...>\n"\
+ " print the specified documents on the specified printer.\n"\
+ "-view <documents...>\n"\
+ " open the specified documents in viewer-(readonly-)mode.\n"\
+ "-show <presentation>\n"\
+ " open the specified presentation and start it immediately\n"\
+ "-accept=<accept-string>\n"\
+ " Specify an UNO connect-string to create an UNO acceptor through which\n"\
+ " other programs can connect to access the API\n"\
+ "-unaccept=<accept-string>\n"\
+ " Close an acceptor that was created with -accept=<accept-string>\n"\
+ " Use -unnaccept=all to close all open acceptors\n"\
+ "Remaining arguments will be treated as filenames or URLs of documents to open.\n";
+
+ void ReplaceStringHookProc( UniString& rStr );
+
+ void displayCmdlineHelp()
+ {
+ // if you put variables in other chunks don't forget to call the replace routines
+ // for those chunks...
+ String aHelpMessage_head(aCmdLineHelp_head, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_left(aCmdLineHelp_left, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_right(aCmdLineHelp_right, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_bottom(aCmdLineHelp_bottom, RTL_TEXTENCODING_ASCII_US);
+ ReplaceStringHookProc(aHelpMessage_head);
+ ::rtl::OUString aDefault;
+ String aVerId( ::utl::Bootstrap::getBuildIdData( aDefault ));
+ aHelpMessage_head.SearchAndReplaceAscii( "%BUILDID", aVerId );
+ aHelpMessage_head.SearchAndReplaceAscii( "%CMDNAME", String( "soffice", RTL_TEXTENCODING_ASCII_US) );
+#ifdef UNX
+ // on unix use console for output
+ fprintf(stderr, "%s\n", ByteString(aHelpMessage_head,
+ RTL_TEXTENCODING_ASCII_US).GetBuffer());
+ // merge left and right column
+ int n = aHelpMessage_left.GetTokenCount ('\n');
+ ByteString bsLeft(aHelpMessage_left, RTL_TEXTENCODING_ASCII_US);
+ ByteString bsRight(aHelpMessage_right, RTL_TEXTENCODING_ASCII_US);
+ for ( int i = 0; i < n; i++ )
+ {
+ fprintf(stderr, "%s", bsLeft.GetToken(i, '\n').GetBuffer());
+ fprintf(stderr, "%s\n", bsRight.GetToken(i, '\n').GetBuffer());
+ }
+ fprintf(stderr, "%s", ByteString(aHelpMessage_bottom,
+ RTL_TEXTENCODING_ASCII_US).GetBuffer());
+#else
+ // rest gets a dialog box
+ CmdlineHelpDialog aDlg;
+ aDlg.m_ftHead.SetText(aHelpMessage_head);
+ aDlg.m_ftLeft.SetText(aHelpMessage_left);
+ aDlg.m_ftRight.SetText(aHelpMessage_right);
+ aDlg.m_ftBottom.SetText(aHelpMessage_bottom);
+ aDlg.Execute();
+#endif
+ }
+#ifndef UNX
+ CmdlineHelpDialog::CmdlineHelpDialog (void)
+ : ModalDialog( NULL, DesktopResId( DLG_CMDLINEHELP ) )
+ , m_ftHead( this, DesktopResId( TXT_DLG_CMDLINEHELP_HEADER ) )
+ , m_ftLeft( this, DesktopResId( TXT_DLG_CMDLINEHELP_LEFT ) )
+ , m_ftRight( this, DesktopResId( TXT_DLG_CMDLINEHELP_RIGHT ) )
+ , m_ftBottom( this, DesktopResId( TXT_DLG_CMDLINEHELP_BOTTOM ) )
+ , m_btOk( this, DesktopResId( BTN_DLG_CMDLINEHELP_OK ) )
+ {
+ FreeResource();
+ }
+#endif
+}
diff --git a/desktop/source/app/cmdlinehelp.hxx b/desktop/source/app/cmdlinehelp.hxx
new file mode 100644
index 000000000000..4bca6e7e7d1a
--- /dev/null
+++ b/desktop/source/app/cmdlinehelp.hxx
@@ -0,0 +1,23 @@
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#ifndef _SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+
+namespace desktop
+{
+ void displayCmdlineHelp( void );
+#ifndef UNX
+ class CmdlineHelpDialog : public ModalDialog
+ {
+ public:
+ CmdlineHelpDialog ( void );
+
+ FixedText m_ftHead;
+ FixedText m_ftLeft;
+ FixedText m_ftRight;
+ FixedText m_ftBottom;
+ OKButton m_btOk;
+ };
+#endif
+}
diff --git a/desktop/source/app/configinit.cxx b/desktop/source/app/configinit.cxx
new file mode 100644
index 000000000000..bd722a136e8a
--- /dev/null
+++ b/desktop/source/app/configinit.cxx
@@ -0,0 +1,303 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "configinit.hxx"
+
+#include "desktop.hrc"
+#include "app.hxx"
+#include <comphelper/processfactory.hxx>
+#include <uno/current_context.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <stdio.h>
+#include <map>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/CannotConnectException.hpp>
+
+// ----------------------------------------------------------------------------
+
+namespace uno = ::com::sun::star::uno;
+namespace lang = ::com::sun::star::lang;
+namespace configuration = ::com::sun::star::configuration;
+namespace backend = ::com::sun::star::configuration::backend;
+using rtl::OUString;
+using uno::UNO_QUERY;
+using desktop::Desktop;
+
+// ----------------------------------------------------------------------------
+static char const CONFIGURATION_PROVIDER[] = "com.sun.star.configuration.ConfigurationProvider";
+
+static char const CONFIGURATION_ERROR_HANDLER[] = "com.sun.star.configuration.backend.InteractionHandler";
+
+// must be aligned with configmgr/source/misc/configinteractionhandler
+static char const CONFIG_ERROR_HANDLER[] = "configuration.interaction-handler";
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+#define arraysize( arr ) ( sizeof (arr)/sizeof *(arr) )
+
+typedef uno::Reference< lang::XMultiServiceFactory > ConfigurationProvider;
+
+#define OUSTRING( constascii ) OUString( RTL_CONSTASCII_USTRINGPARAM( constascii ) )
+
+#define OU2O( ustr, enc ) rtl::OUStringToOString( (ustr), RTL_TEXTENCODING_ ## enc )
+
+#define k_PROVIDER OUSTRING( CONFIGURATION_PROVIDER )
+#define k_ERRORHANDLER OUSTRING( CONFIGURATION_ERROR_HANDLER )
+// ----------------------------------------------------------------------------
+// Get a message string securely. There is a fallback string if the resource
+// is not available. Adapted from Desktop::GetMsgString()
+
+OUString getMsgString( USHORT nId, char const * aFallBackMsg )
+{
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( !pResMgr || !nId )
+ return OUString::createFromAscii(aFallBackMsg);
+ else
+ return OUString( String(ResId( nId, *pResMgr )));
+}
+// ----------------------------------------------------------------------------
+/** Creates the normal configuration provider.
+
+*/
+static
+ConfigurationProvider createDefaultConfigurationProvider( )
+{
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+
+ OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for CreateApplicationConfigurationProvider");
+
+ ConfigurationProvider xProvider;
+
+ if (xServiceManager.is())
+ {
+
+ xProvider.set( xServiceManager->createInstance(k_PROVIDER), UNO_QUERY);
+ }
+
+ if (!xProvider.is())
+ {
+ OUString const sMsg = OUSTRING("Service \"") + k_PROVIDER +
+ OUSTRING("\" is not available at the service manager.");
+
+ throw lang::ServiceNotRegisteredException(sMsg, xServiceManager);
+ }
+
+ return xProvider;
+}
+// ----------------------------------------------------------------------------
+/// @attention this method must be called from a catch statement!
+static void handleGeneralException(uno::Exception& aException,
+ const rtl::OUString& aMessage)
+{
+ aException.Message = aMessage ;
+ throw ;
+}
+// ----------------------------------------------------------------------------
+
+uno::Reference< lang::XMultiServiceFactory > CreateApplicationConfigurationProvider( )
+{
+ uno::Reference< lang::XMultiServiceFactory > xProvider;
+
+ try
+ {
+ xProvider = createDefaultConfigurationProvider( );
+ }
+ catch (configuration::InvalidBootstrapFileException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_SETTINGS_INCOMPLETE,
+ "The startup settings for your configuration settings are incomplete. "));
+ }
+ catch (backend::CannotConnectException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (backend::BackendSetupException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (configuration::CannotLoadConfigurationException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (uno::Exception & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
+ "A general error occurred while accessing your configuration settings."));
+ }
+
+
+ return xProvider ;
+}
+// ----------------------------------------------------------------------------
+
+
+
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// ConfigurationErrorHandler
+// ----------------------------------------------------------------------------
+
+namespace
+{
+ typedef uno::Reference< uno::XCurrentContext > CurrentContext;
+ class SimpleCurrentContext : public cppu::WeakImplHelper1< uno::XCurrentContext >
+ {
+ CurrentContext m_xChainedContext;
+ public:
+ explicit
+ SimpleCurrentContext(const CurrentContext & xChainedContext)
+ : m_xChainedContext(xChainedContext)
+ {}
+
+ void install() { uno::setCurrentContext(this); }
+ void deinstall() { uno::setCurrentContext(m_xChainedContext); }
+
+ uno::Any getChainedValueByName( OUString const & aName) const
+ {
+ return m_xChainedContext.is()
+ ? m_xChainedContext->getValueByName(aName)
+ : uno::Any();
+ }
+
+ // XCurrentContext
+ virtual uno::Any SAL_CALL
+ getValueByName( OUString const & aName)
+ throw (uno::RuntimeException);
+ };
+
+ uno::Any SAL_CALL
+ SimpleCurrentContext::getValueByName( OUString const & aName)
+ throw (uno::RuntimeException)
+ {
+ return getChainedValueByName(aName);
+ }
+
+}
+
+// ----------------------------------------------------------------------------
+class ConfigurationErrorHandler::Context : public SimpleCurrentContext
+{
+public:
+ Context()
+ : SimpleCurrentContext( uno::getCurrentContext() )
+ {
+ }
+
+ ~Context()
+ {
+ }
+
+ // XCurrentContext
+ virtual uno::Any SAL_CALL
+ getValueByName( OUString const & aName)
+ throw (uno::RuntimeException);
+
+private:
+ InteractionHandler m_xHandler;
+};
+
+//------------------------------------------------------------------------------
+uno::Any SAL_CALL ConfigurationErrorHandler::Context::getValueByName( OUString const & aName)
+ throw (uno::RuntimeException)
+{
+ if ( aName.equalsAscii( CONFIG_ERROR_HANDLER ) )
+ {
+ if ( !m_xHandler.is() )
+ m_xHandler = ConfigurationErrorHandler::getDefaultInteractionHandler();
+ return uno::Any( m_xHandler );
+ }
+ return SimpleCurrentContext::getValueByName( aName );
+}
+
+//------------------------------------------------------------------------------
+ConfigurationErrorHandler::~ConfigurationErrorHandler()
+{
+ deactivate();
+}
+
+//------------------------------------------------------------------------------
+/// installs the handler into the current context
+void ConfigurationErrorHandler::activate()
+{
+ if (!m_pContext)
+ {
+ m_pContext = new Context;
+ m_pContext->acquire();
+ }
+ m_pContext->install();
+}
+
+//------------------------------------------------------------------------------
+/// deinstalls the handler from the current context, restoring the previous context
+void ConfigurationErrorHandler::deactivate()
+{
+ if (m_pContext)
+ {
+ m_pContext->deinstall();
+ m_pContext->release();
+ m_pContext = 0;
+ }
+}
+//------------------------------------------------------------------------------
+
+ConfigurationErrorHandler::InteractionHandler ConfigurationErrorHandler::getDefaultInteractionHandler()
+{
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+
+ OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for ConfigurationErrorHandler");
+
+ InteractionHandler xHandler;
+
+ if (xServiceManager.is())
+ {
+ xHandler.set( xServiceManager->createInstance(k_ERRORHANDLER), UNO_QUERY );
+ }
+
+ return xHandler;
+}
+//------------------------------------------------------------------------------
+
+
+
diff --git a/desktop/source/app/configinit.hxx b/desktop/source/app/configinit.hxx
new file mode 100644
index 000000000000..68df86656bea
--- /dev/null
+++ b/desktop/source/app/configinit.hxx
@@ -0,0 +1,71 @@
+#ifndef _DESKTOP_CONFIGINIT_HXX_
+#define _DESKTOP_CONFIGINIT_HXX_
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <rtl/ustring.hxx>
+
+/** creates a ConfigurationProvider instance
+Important: exceptions thrown from that method will contain a readily
+displayable message.
+
+ @return
+ The default configuration provider for the application or<br/>
+ <NULL/>, if startup was canceled
+
+ @throw com::sun::star::configuration::CannotLoadConfigurationException
+ if the configuration provider can't be created
+
+ @throw com::sun::star::lang::ServiceNotRegisteredException
+ if the ConfigurationProvider service is unknwon
+
+ @throw com::sun::star::lang::WrappedTargetException
+ if the configuration backend could be created,
+ but incurred a failure later
+
+*/
+extern
+com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ CreateApplicationConfigurationProvider( );
+
+//-----------------------------------------------------------------------------
+#include <com/sun/star/task/XInteractionHandler.hpp>
+
+/**
+ sets an InteractionHandler for configuration errors in the current context.
+
+ */
+ class ConfigurationErrorHandler
+ {
+ public:
+ typedef com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > InteractionHandler;
+
+ /// Constructor: Uses the default interaction handler
+ ConfigurationErrorHandler()
+ : m_pContext(0), m_xHandler()
+ {}
+
+ /// Constructor: Uses an externally provided interaction handler
+ ConfigurationErrorHandler(const InteractionHandler & xHandler)
+ : m_pContext(0), m_xHandler( xHandler )
+ {}
+
+ ~ConfigurationErrorHandler();
+
+ static InteractionHandler getDefaultInteractionHandler();
+
+ /// installs the handler into the current context
+ void activate();
+ /// deinstalls the handler from the current context, restoring the previous context
+ void deactivate();
+ private:
+ class Context;
+ Context * m_pContext;
+ InteractionHandler m_xHandler;
+ private:
+ // not implemented - suppress copy
+ ConfigurationErrorHandler(const ConfigurationErrorHandler&);
+ void operator=(const ConfigurationErrorHandler&);
+ };
+
+//-----------------------------------------------------------------------------
+#endif
diff --git a/desktop/source/app/copyright_ascii_ooo.c b/desktop/source/app/copyright_ascii_ooo.c
new file mode 100644
index 000000000000..7439547f62b4
--- /dev/null
+++ b/desktop/source/app/copyright_ascii_ooo.c
@@ -0,0 +1,10 @@
+
+ /*
+ * copyright text to see as text in the soffice binary
+ *
+ */
+
+extern const char copyright_text_1[];
+
+const char copyright_text_1[] = "Copyright © 2000, 2010 Oracle and/or its affiliates, All rights reserved.";
+
diff --git a/desktop/source/app/copyright_ascii_sun.c b/desktop/source/app/copyright_ascii_sun.c
new file mode 100644
index 000000000000..c7de54e98fba
--- /dev/null
+++ b/desktop/source/app/copyright_ascii_sun.c
@@ -0,0 +1,8 @@
+
+ /*
+ * copyright text to see as text in the soffice binary
+ *
+ */
+
+const char copyright_text_1[] = "Copyright © 2000, 2010 Oracle and/or its affiliates, All rights reserved.";
+
diff --git a/desktop/source/app/desktop.hrc b/desktop/source/app/desktop.hrc
new file mode 100644
index 000000000000..9c68d7b9fd2d
--- /dev/null
+++ b/desktop/source/app/desktop.hrc
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_HRC_
+#define _DESKTOP_HRC_
+
+#ifndef _SOLAR_HRC
+#include <svl/solar.hrc>
+#endif
+
+#define RID_DESKTOP_DIALOG_START 2000
+#define RID_FIRSTSTSTART_START 3000
+#define RID_DESKTOP_STRING_START 10000
+
+
+#define INFOBOX_CMDLINEHELP (RID_DESKTOP_DIALOG_START+51)
+#define INFOBOX_EXPIRED (RID_DESKTOP_DIALOG_START+52)
+
+#define QBX_USERDATALOCKED (RID_DESKTOP_DIALOG_START+100)
+
+#define DLG_CMDLINEHELP (RID_DESKTOP_DIALOG_START+101)
+#define TXT_DLG_CMDLINEHELP_HEADER (RID_DESKTOP_DIALOG_START+102)
+#define TXT_DLG_CMDLINEHELP_LEFT (RID_DESKTOP_DIALOG_START+103)
+#define TXT_DLG_CMDLINEHELP_RIGHT (RID_DESKTOP_DIALOG_START+104)
+#define TXT_DLG_CMDLINEHELP_BOTTOM (RID_DESKTOP_DIALOG_START+105)
+#define BTN_DLG_CMDLINEHELP_OK (RID_DESKTOP_DIALOG_START+106)
+
+#define QBX_CONFIG_IMPORTSETTINGS (RID_DESKTOP_DIALOG_START+180)
+
+#define EBX_ERR_PRINTDISABLED (RID_DESKTOP_DIALOG_START+190)
+
+#define STR_RECOVER_QUERY (RID_DESKTOP_STRING_START+0)
+#define STR_RECOVER_TITLE (RID_DESKTOP_STRING_START+1)
+#define STR_RECOVER_PREPARED (RID_DESKTOP_STRING_START+2)
+
+#define STR_BOOTSTRAP_ERR_CANNOT_START (RID_DESKTOP_STRING_START+100)
+#define STR_BOOTSTRAP_ERR_DIR_MISSING (RID_DESKTOP_STRING_START+101)
+#define STR_BOOTSTRAP_ERR_PATH_INVALID (RID_DESKTOP_STRING_START+102)
+#define STR_BOOTSTRAP_ERR_NO_PATH (RID_DESKTOP_STRING_START+103)
+#define STR_BOOTSTRAP_ERR_INTERNAL (RID_DESKTOP_STRING_START+104)
+#define STR_BOOTSTRAP_ERR_FILE_CORRUPT (RID_DESKTOP_STRING_START+105)
+#define STR_BOOTSTRAP_ERR_FILE_MISSING (RID_DESKTOP_STRING_START+106)
+#define STR_BOOTSTRAP_ERR_NO_SUPPORT (RID_DESKTOP_STRING_START+107)
+#define STR_BOOTSTRAP_ERR_LANGUAGE_MISSING (RID_DESKTOP_STRING_START+108)
+
+#define STR_BOOTSTRAP_ERR_NO_SERVICE (RID_DESKTOP_STRING_START+120)
+#define STR_BOOTSTRAP_ERR_NO_CFG_SERVICE (RID_DESKTOP_STRING_START+121)
+#define STR_BOOTSTRAP_ERR_CFG_DATAACCESS (RID_DESKTOP_STRING_START+122)
+#define STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE (RID_DESKTOP_STRING_START+123)
+
+#define STR_ASK_START_SETUP_MANUALLY (RID_DESKTOP_STRING_START+152)
+
+#define STR_INTERNAL_ERRMSG (RID_DESKTOP_STRING_START+161)
+
+#define STR_CONFIG_ERR_SETTINGS_INCOMPLETE (RID_DESKTOP_STRING_START+182)
+#define STR_CONFIG_ERR_CANNOT_CONNECT (RID_DESKTOP_STRING_START+183)
+#define STR_CONFIG_ERR_RIGHTS_MISSING (RID_DESKTOP_STRING_START+184)
+#define STR_CONFIG_ERR_ACCESS_GENERAL (RID_DESKTOP_STRING_START+187)
+#define STR_CONFIG_ERR_NO_WRITE_ACCESS (RID_DESKTOP_STRING_START+188)
+
+#define STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE (RID_DESKTOP_STRING_START+189)
+#define STR_BOOSTRAP_ERR_NOACCESSRIGHTS (RID_DESKTOP_STRING_START+190)
+
+#define STR_TITLE_USERDATALOCKED (RID_DESKTOP_STRING_START+206)
+#define STR_TITLE_EXPIRED (RID_DESKTOP_STRING_START+207)
+
+#endif // _DESKTOP_HRC_
diff --git a/desktop/source/app/desktop.src b/desktop/source/app/desktop.src
new file mode 100644
index 000000000000..2f6897adf80e
--- /dev/null
+++ b/desktop/source/app/desktop.src
@@ -0,0 +1,234 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "desktop.hrc"
+
+
+String STR_RECOVER_QUERY
+{
+ Text [ en-US ] = "Should the file \"$1\" be restored?" ;
+};
+
+String STR_RECOVER_TITLE
+{
+ Text [ en-US ] = "File Recovery" ;
+};
+
+WarningBox STR_RECOVER_PREPARED
+{
+ Message [ en-US ] = "An unrecoverable error has occurred.\n\nAll modified files have been saved and can\nprobably be recovered at program restart." ;
+};
+
+String STR_BOOTSTRAP_ERR_CANNOT_START
+{
+ Text [ en-US ] = "The application cannot be started. ";
+};
+
+String STR_BOOTSTRAP_ERR_DIR_MISSING
+{
+ Text [ en-US ] = "The configuration directory \"$1\" could not be found.";
+};
+
+String STR_BOOTSTRAP_ERR_PATH_INVALID
+{
+ Text [ en-US ] = "The installation path is invalid.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_PATH
+{
+ Text [ en-US ] = "The installation path is not available.";
+};
+
+String STR_BOOTSTRAP_ERR_INTERNAL
+{
+ Text [ en-US ] = "An internal error occurred.";
+};
+
+String STR_BOOTSTRAP_ERR_FILE_CORRUPT
+{
+ Text [ en-US ] = "The configuration file \"$1\" is corrupt.";
+};
+
+String STR_BOOTSTRAP_ERR_FILE_MISSING
+{
+ Text [ en-US ] = "The configuration file \"$1\" was not found.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_SUPPORT
+{
+ Text [ en-US ] = "The configuration file \"$1\" does not support the current version.";
+};
+
+String STR_BOOTSTRAP_ERR_LANGUAGE_MISSING
+{
+ Text [ en-US ] = "The user interface language cannot be determined.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_SERVICE
+{
+ Text [ en-US ] = "The component manager is not available.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
+{
+ Text [ en-US ] = "The configuration service is not available.";
+};
+
+String STR_ASK_START_SETUP_MANUALLY
+{
+ Text [ en-US ] = "Start the setup application to repair the installation from the CD or the folder containing the installation packages.";
+};
+
+String STR_CONFIG_ERR_SETTINGS_INCOMPLETE
+{
+ Text [ en-US ] = "The startup settings for accessing the central configuration are incomplete. ";
+};
+
+String STR_CONFIG_ERR_CANNOT_CONNECT
+{
+ Text [ en-US ] = "A connection to the central configuration could not be established. ";
+};
+
+String STR_CONFIG_ERR_RIGHTS_MISSING
+{
+ Text [ en-US ] = "You cannot access the central configuration because of missing access rights. ";
+};
+
+String STR_CONFIG_ERR_ACCESS_GENERAL
+{
+ Text [ en-US ] = "A general error occurred while accessing your central configuration. ";
+};
+
+String STR_CONFIG_ERR_NO_WRITE_ACCESS
+{
+ Text [ en-US ] = "The changes to your personal settings cannot be stored centrally because of missing access rights. ";
+};
+
+String STR_BOOTSTRAP_ERR_CFG_DATAACCESS
+{
+ Text [ en-US ] = "%PRODUCTNAME cannot be started due to an error in accessing the %PRODUCTNAME configuration data.\n\nPlease contact your system administrator." ;
+};
+
+String STR_INTERNAL_ERRMSG
+{
+ Text [ en-US ] = "The following internal error has occurred: " ;
+};
+
+QueryBox QBX_USERDATALOCKED
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_NO ;
+ Message [ en-US ] = "Either another instance of %PRODUCTNAME is accessing your personal settings or your personal settings are locked.\nSimultaneous access can lead to inconsistencies in your personal settings. Before continuing, you should make sure user '$u' closes %PRODUCTNAME on host '$h'.\n\nDo you really want to continue?";
+};
+
+String STR_TITLE_USERDATALOCKED
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION";
+};
+
+InfoBox INFOBOX_CMDLINEHELP
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message = "";
+};
+
+ModalDialog DLG_CMDLINEHELP
+{
+ Text = "Help Message...";
+ Size = MAP_APPFONT(250, 365);
+ Border = True;
+ SVLook = True;
+ Moveable = True;
+
+ FixedText TXT_DLG_CMDLINEHELP_HEADER
+ {
+ Size = MAP_APPFONT(240, 50);
+ Pos = MAP_APPFONT(5, 5);
+ Text = "HEADER";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_LEFT
+ {
+ Size = MAP_APPFONT(50, 150);
+ Pos = MAP_APPFONT(5, 50);
+ Text = "LEFT";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_RIGHT
+ {
+ Size = MAP_APPFONT(190, 150);
+ Pos = MAP_APPFONT(60, 50);
+ Text = "RIGHT";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_BOTTOM
+ {
+ Size = MAP_APPFONT(240, 145);
+ Pos = MAP_APPFONT(5, 200);
+ Text = "BOTTOM";
+ };
+ OKButton BTN_DLG_CMDLINEHELP_OK
+ {
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Pos = MAP_APPFONT(95, 345);
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+};
+
+ErrorBox EBX_ERR_PRINTDISABLED
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message [ en-US ] = "Printing is disabled. No documents can be printed.";
+};
+
+InfoBox INFOBOX_EXPIRED
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message [ en-US ] = "This Evaluation Version has expired. To find out more about %PRODUCTNAME,\nvisit http://www.oracle.com/us/products/applications/open-office.";
+};
+
+String STR_TITLE_EXPIRED
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION";
+};
+
+String STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE
+{
+ Text [ en-US ] = "The path manager is not available.\n";
+};
+
+String STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE
+{
+ Text [ en-US ] = "%PRODUCTNAME user installation could not be completed due to insufficient free disk space. Please free more disc space at the following location and restart %PRODUCTNAME:\n\n";
+};
+
+String STR_BOOSTRAP_ERR_NOACCESSRIGHTS
+{
+ Text [ en-US ] = "%PRODUCTNAME user installation could not be processed due to missing access rights. Please make sure that you have sufficient access rights for the following location and restart %PRODUCTNAME:\n\n";
+};
+
diff --git a/desktop/source/app/desktopcontext.cxx b/desktop/source/app/desktopcontext.cxx
new file mode 100644
index 000000000000..e516b5eadd46
--- /dev/null
+++ b/desktop/source/app/desktopcontext.cxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "desktopcontext.hxx"
+
+#include <vcl/svapp.hxx>
+#include <svtools/javainteractionhandler.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::task;
+
+namespace desktop
+{
+
+DesktopContext::DesktopContext( const Reference< XCurrentContext > & ctx )
+ : m_xNextContext( ctx )
+{
+}
+
+Any SAL_CALL DesktopContext::getValueByName( const OUString& Name) throw (RuntimeException)
+{
+ Any retVal;
+
+ if ( 0 == Name.compareToAscii( JAVA_INTERACTION_HANDLER_NAME ))
+ {
+ retVal = makeAny( Reference< XInteractionHandler >( new svt::JavaInteractionHandler()) );
+ }
+ else if( m_xNextContext.is() )
+ {
+ // Call next context in chain if found
+ retVal = m_xNextContext->getValueByName( Name );
+ }
+ return retVal;
+}
+
+}
diff --git a/desktop/source/app/desktopcontext.hxx b/desktop/source/app/desktopcontext.hxx
new file mode 100644
index 000000000000..88948e753af5
--- /dev/null
+++ b/desktop/source/app/desktopcontext.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_DESKTOPCONTEXT_HXX_
+#define _DESKTOP_DESKTOPCONTEXT_HXX_
+
+#include <cppuhelper/implbase1.hxx>
+#include <uno/current_context.hxx>
+
+namespace desktop
+{
+ class DesktopContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext >
+ {
+ public:
+ DesktopContext( const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > & ctx);
+
+ // XCurrentContext
+ virtual com::sun::star::uno::Any SAL_CALL getValueByName( const rtl::OUString& Name )
+ throw (com::sun::star::uno::RuntimeException);
+
+ private:
+ com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_xNextContext;
+ };
+}
+
+#endif // _DESKTOP_DESKTOPCONTEXT_HXX_
diff --git a/desktop/source/app/desktopresid.cxx b/desktop/source/app/desktopresid.cxx
new file mode 100644
index 000000000000..90cc8e220fba
--- /dev/null
+++ b/desktop/source/app/desktopresid.cxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "desktopresid.hxx"
+#include "app.hxx"
+
+// -----------------------------------------------------------------------
+namespace desktop
+{
+
+DesktopResId::DesktopResId( USHORT nId ) :
+ ResId( nId, *Desktop::GetDesktopResManager() )
+{
+}
+
+}
diff --git a/desktop/source/app/desktopresid.hxx b/desktop/source/app/desktopresid.hxx
new file mode 100644
index 000000000000..410ca429f5ad
--- /dev/null
+++ b/desktop/source/app/desktopresid.hxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_RESID_HXX_
+#define _DESKTOP_RESID_HXX_
+
+#include <tools/resid.hxx>
+
+namespace desktop
+{
+
+class DesktopResId : public ResId
+{
+ public:
+ DesktopResId( USHORT nId );
+};
+
+}
+
+#endif // _DESKTOP_RESID_HXX_
diff --git a/desktop/source/app/dispatchwatcher.cxx b/desktop/source/app/dispatchwatcher.cxx
new file mode 100644
index 000000000000..db7f3c45964f
--- /dev/null
+++ b/desktop/source/app/dispatchwatcher.cxx
@@ -0,0 +1,514 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "dispatchwatcher.hxx"
+#include <rtl/ustring.hxx>
+#include <tools/string.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/synchronousdispatch.hxx>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/util/CloseVetoException.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+
+#include <tools/urlobj.hxx>
+#include <comphelper/mediadescriptor.hxx>
+
+#include <vector>
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::view;
+
+namespace desktop
+{
+
+String GetURL_Impl(
+ const String& rName, boost::optional< rtl::OUString > const & cwdUrl );
+
+struct DispatchHolder
+{
+ DispatchHolder( const URL& rURL, Reference< XDispatch >& rDispatch ) :
+ aURL( rURL ), xDispatch( rDispatch ) {}
+
+ URL aURL;
+ rtl::OUString cwdUrl;
+ Reference< XDispatch > xDispatch;
+};
+
+Mutex* DispatchWatcher::pWatcherMutex = NULL;
+
+Mutex& DispatchWatcher::GetMutex()
+{
+ if ( !pWatcherMutex )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pWatcherMutex )
+ pWatcherMutex = new osl::Mutex();
+ }
+
+ return *pWatcherMutex;
+}
+
+// Create or get the dispatch watcher implementation. This implementation must be
+// a singleton to prevent access to the framework after it wants to terminate.
+DispatchWatcher* DispatchWatcher::GetDispatchWatcher()
+{
+ static Reference< XInterface > xDispatchWatcher;
+ static DispatchWatcher* pDispatchWatcher = NULL;
+
+ if ( !xDispatchWatcher.is() )
+ {
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( !xDispatchWatcher.is() )
+ {
+ pDispatchWatcher = new DispatchWatcher();
+
+ // We have to hold a reference to ourself forever to prevent our own destruction.
+ xDispatchWatcher = static_cast< cppu::OWeakObject *>( pDispatchWatcher );
+ }
+ }
+
+ return pDispatchWatcher;
+}
+
+
+DispatchWatcher::DispatchWatcher()
+ : m_nRequestCount(0)
+{
+}
+
+
+DispatchWatcher::~DispatchWatcher()
+{
+}
+
+
+sal_Bool DispatchWatcher::executeDispatchRequests( const DispatchList& aDispatchRequestsList, bool bNoTerminate )
+{
+ Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+
+ DispatchList::const_iterator p;
+ std::vector< DispatchHolder > aDispatches;
+ ::rtl::OUString aAsTemplateArg( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate"));
+
+ for ( p = aDispatchRequestsList.begin(); p != aDispatchRequestsList.end(); p++ )
+ {
+ String aPrinterName;
+ const DispatchRequest& aDispatchRequest = *p;
+
+ // create parameter array
+ sal_Int32 nCount = 4;
+ if ( aDispatchRequest.aPreselectedFactory.getLength() )
+ nCount++;
+
+ // we need more properties for a print/print to request
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ nCount++;
+
+ Sequence < PropertyValue > aArgs( nCount );
+
+ // mark request as user interaction from outside
+ aArgs[0].Name = ::rtl::OUString::createFromAscii("Referer");
+ aArgs[0].Value <<= ::rtl::OUString::createFromAscii("private:OpenEvent");
+
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly");
+ aArgs[2].Name = ::rtl::OUString::createFromAscii("OpenNewView");
+ aArgs[3].Name = ::rtl::OUString::createFromAscii("Hidden");
+ aArgs[4].Name = ::rtl::OUString::createFromAscii("Silent");
+ }
+ else
+ {
+ Reference < com::sun::star::task::XInteractionHandler > xInteraction(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.task.InteractionHandler") ),
+ com::sun::star::uno::UNO_QUERY );
+
+ aArgs[1].Name = OUString::createFromAscii( "InteractionHandler" );
+ aArgs[1].Value <<= xInteraction;
+
+ sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
+ aArgs[2].Name = OUString::createFromAscii( "MacroExecutionMode" );
+ aArgs[2].Value <<= nMacroExecMode;
+
+ sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
+ aArgs[3].Name = OUString::createFromAscii( "UpdateDocMode" );
+ aArgs[3].Value <<= nUpdateDoc;
+ }
+
+ if ( aDispatchRequest.aPreselectedFactory.getLength() )
+ {
+ aArgs[nCount-1].Name = ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE();
+ aArgs[nCount-1].Value <<= aDispatchRequest.aPreselectedFactory;
+ }
+
+ String aName( GetURL_Impl( aDispatchRequest.aURL, aDispatchRequest.aCwdUrl ) );
+ ::rtl::OUString aTarget( RTL_CONSTASCII_USTRINGPARAM("_default") );
+
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ // documents opened for printing are opened readonly because they must be opened as a new document and this
+ // document could be open already
+ aArgs[1].Value <<= sal_True;
+
+ // always open a new document for printing, because it must be disposed afterwards
+ aArgs[2].Value <<= sal_True;
+
+ // printing is done in a hidden view
+ aArgs[3].Value <<= sal_True;
+
+ // load document for printing without user interaction
+ aArgs[4].Value <<= sal_True;
+
+ // hidden documents should never be put into open tasks
+ aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") );
+ }
+
+ // load the document ... if they are loadable!
+ // Otherwise try to dispatch it ...
+ Reference < XPrintable > xDoc;
+ if(
+ ( aName.CompareToAscii( ".uno" , 4 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii( "slot:" , 5 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii( "macro:", 6 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii("vnd.sun.star.script", 19) == COMPARE_EQUAL)
+ )
+ {
+ // Attention: URL must be parsed full. Otherwise some detections on it will fail!
+ // It doesnt matter, if parser isn't available. Because; We try loading of URL then ...
+ URL aURL ;
+ aURL.Complete = aName;
+
+ Reference < XDispatch > xDispatcher ;
+ Reference < XDispatchProvider > xProvider ( xDesktop, UNO_QUERY );
+ Reference < XURLTransformer > xParser ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );
+
+ if( xParser.is() == sal_True )
+ xParser->parseStrict( aURL );
+
+ if( xProvider.is() == sal_True )
+ xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
+
+ if( xDispatcher.is() == sal_True )
+ {
+ {
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ // Remember request so we can find it in statusChanged!
+ m_aRequestContainer.insert( DispatchWatcherHashMap::value_type( aURL.Complete, (sal_Int32)1 ) );
+ m_nRequestCount++;
+ }
+
+ // Use local vector to store dispatcher because we have to fill our request container before
+ // we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
+ aDispatches.push_back( DispatchHolder( aURL, xDispatcher ));
+ }
+ }
+ else if ( ( aName.CompareToAscii( "service:" , 8 ) == COMPARE_EQUAL ) )
+ {
+ // TODO: the dispatch has to be done for loadComponentFromURL as well. Please ask AS for more details.
+ URL aURL ;
+ aURL.Complete = aName;
+
+ Reference < XDispatch > xDispatcher ;
+ Reference < XDispatchProvider > xProvider ( xDesktop, UNO_QUERY );
+ Reference < XURLTransformer > xParser ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );
+
+ if( xParser.is() == sal_True )
+ xParser->parseStrict( aURL );
+
+ if( xProvider.is() == sal_True )
+ xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
+
+ if( xDispatcher.is() == sal_True )
+ {
+ try
+ {
+ // We have to be listener to catch errors during dispatching URLs.
+ // Otherwise it would be possible to have an office running without an open
+ // window!!
+ Sequence < PropertyValue > aArgs2(1);
+ aArgs2[0].Name = ::rtl::OUString::createFromAscii("SynchronMode");
+ aArgs2[0].Value <<= sal_True;
+ Reference < XNotifyingDispatch > xDisp( xDispatcher, UNO_QUERY );
+ if ( xDisp.is() )
+ xDisp->dispatchWithNotification( aURL, aArgs2, DispatchWatcher::GetDispatchWatcher() );
+ else
+ xDispatcher->dispatch( aURL, aArgs2 );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ OUString aMsg = OUString::createFromAscii(
+ "Desktop::OpenDefault() IllegalArgumentException while calling XNotifyingDispatch: ");
+ OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ }
+ else
+ {
+ INetURLObject aObj( aName );
+ if ( aObj.GetProtocol() == INET_PROT_PRIVATE )
+ aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_default") );
+
+ // Set "AsTemplate" argument according to request type
+ if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW ||
+ aDispatchRequest.aRequestType == REQUEST_FORCEOPEN )
+ {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc( nIndex+1 );
+ aArgs[nIndex].Name = aAsTemplateArg;
+ if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW )
+ aArgs[nIndex].Value <<= sal_True;
+ else
+ aArgs[nIndex].Value <<= sal_False;
+ }
+
+ // if we are called in viewmode, open document read-only
+ // #95425#
+ if(aDispatchRequest.aRequestType == REQUEST_VIEW) {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc(nIndex+1);
+ aArgs[nIndex].Name = OUString::createFromAscii("ReadOnly");
+ aArgs[nIndex].Value <<= sal_True;
+ }
+
+ // if we are called with -start set Start in mediadescriptor
+ if(aDispatchRequest.aRequestType == REQUEST_START) {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc(nIndex+1);
+ aArgs[nIndex].Name = OUString::createFromAscii("StartPresentation");
+ aArgs[nIndex].Value <<= sal_True;
+ }
+
+ // This is a synchron loading of a component so we don't have to deal with our statusChanged listener mechanism.
+
+ try
+ {
+ xDoc = Reference < XPrintable >( ::comphelper::SynchronousDispatch::dispatch( xDesktop, aName, aTarget, 0, aArgs ), UNO_QUERY );
+ //xDoc = Reference < XPrintable >( xDesktop->loadComponentFromURL( aName, aTarget, 0, aArgs ), UNO_QUERY );
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& iae)
+ {
+ OUString aMsg = OUString::createFromAscii(
+ "Dispatchwatcher IllegalArgumentException while calling loadComponentFromURL: ")
+ + iae.Message;
+ OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ catch (com::sun::star::io::IOException& ioe)
+ {
+ OUString aMsg = OUString::createFromAscii(
+ "Dispatchwatcher IOException while calling loadComponentFromURL: ")
+ + ioe.Message;
+ OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ if ( aDispatchRequest.aRequestType == REQUEST_OPEN ||
+ aDispatchRequest.aRequestType == REQUEST_VIEW ||
+ aDispatchRequest.aRequestType == REQUEST_START ||
+ aDispatchRequest.aRequestType == REQUEST_FORCEOPEN ||
+ aDispatchRequest.aRequestType == REQUEST_FORCENEW )
+ {
+ // request is completed
+ OfficeIPCThread::RequestsCompleted( 1 );
+ }
+ else if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ if ( xDoc.is() )
+ {
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ // create the printer
+ Sequence < PropertyValue > aPrinterArgs( 1 );
+ aPrinterArgs[0].Name = ::rtl::OUString::createFromAscii("Name");
+ aPrinterArgs[0].Value <<= ::rtl::OUString( aDispatchRequest.aPrinterName );
+ xDoc->setPrinter( aPrinterArgs );
+ }
+
+ // print ( also without user interaction )
+ Sequence < PropertyValue > aPrinterArgs( 1 );
+ aPrinterArgs[0].Name = ::rtl::OUString::createFromAscii("Wait");
+ aPrinterArgs[0].Value <<= ( sal_Bool ) sal_True;
+ xDoc->print( aPrinterArgs );
+ }
+ else
+ {
+ // place error message here ...
+ }
+
+ // remove the document
+ try
+ {
+ Reference < XCloseable > xClose( xDoc, UNO_QUERY );
+ if ( xClose.is() )
+ xClose->close( sal_True );
+ else
+ {
+ Reference < XComponent > xComp( xDoc, UNO_QUERY );
+ if ( xComp.is() )
+ xComp->dispose();
+ }
+ }
+ catch ( com::sun::star::util::CloseVetoException& )
+ {
+ }
+
+ // request is completed
+ OfficeIPCThread::RequestsCompleted( 1 );
+ }
+ }
+ }
+
+ if ( aDispatches.size() > 0 )
+ {
+ // Execute all asynchronous dispatches now after we placed them into our request container!
+ Sequence < PropertyValue > aArgs( 2 );
+ aArgs[0].Name = ::rtl::OUString::createFromAscii("Referer");
+ aArgs[0].Value <<= ::rtl::OUString::createFromAscii("private:OpenEvent");
+ aArgs[1].Name = ::rtl::OUString::createFromAscii("SynchronMode");
+ aArgs[1].Value <<= sal_True;
+
+ for ( sal_uInt32 n = 0; n < aDispatches.size(); n++ )
+ {
+ Reference< XDispatch > xDispatch = aDispatches[n].xDispatch;
+ Reference < XNotifyingDispatch > xDisp( xDispatch, UNO_QUERY );
+ if ( xDisp.is() )
+ xDisp->dispatchWithNotification( aDispatches[n].aURL, aArgs, this );
+ else
+ {
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ m_nRequestCount--;
+ aGuard.clear();
+ xDispatch->dispatch( aDispatches[n].aURL, aArgs );
+ }
+ }
+ }
+
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ bool bEmpty = (m_nRequestCount == 0);
+ aGuard.clear();
+
+ // No more asynchronous requests?
+ // The requests are removed from the request container after they called back to this
+ // implementation via statusChanged!!
+ if ( bEmpty && !bNoTerminate /*m_aRequestContainer.empty()*/ )
+ {
+ // We have to check if we have an open task otherwise we have to shutdown the office.
+ Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
+ aGuard.clear();
+
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
+
+ if ( !xList->hasElements() )
+ {
+ // We don't have any task open so we have to shutdown ourself!!
+ Reference< XDesktop > xDesktop2( xTasksSupplier, UNO_QUERY );
+ if ( xDesktop2.is() )
+ return xDesktop2->terminate();
+ }
+ }
+
+ return sal_False;
+}
+
+
+void SAL_CALL DispatchWatcher::disposing( const ::com::sun::star::lang::EventObject& )
+throw(::com::sun::star::uno::RuntimeException)
+{
+}
+
+
+void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException )
+{
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+ sal_Int16 nCount = --m_nRequestCount;
+ aGuard.clear();
+ OfficeIPCThread::RequestsCompleted( 1 );
+/*
+ // Find request in our hash map and remove it as a pending request
+ DispatchWatcherHashMap::iterator pDispatchEntry = m_aRequestContainer.find( rEvent.FeatureURL.Complete ) ;
+ if ( pDispatchEntry != m_aRequestContainer.end() )
+ {
+ m_aRequestContainer.erase( pDispatchEntry );
+ aGuard.clear();
+ OfficeIPCThread::RequestsCompleted( 1 );
+ }
+ else
+ aGuard.clear();
+*/
+ if ( !nCount && !OfficeIPCThread::AreRequestsPending() )
+ {
+ // We have to check if we have an open task otherwise we have to shutdown the office.
+ Reference< XFramesSupplier > xTasksSupplier( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
+
+ if ( !xList->hasElements() )
+ {
+ // We don't have any task open so we have to shutdown ourself!!
+ Reference< XDesktop > xDesktop( xTasksSupplier, UNO_QUERY );
+ if ( xDesktop.is() )
+ xDesktop->terminate();
+ }
+ }
+}
+
+}
+
+
+
+
+
+
+
+
diff --git a/desktop/source/app/dispatchwatcher.hxx b/desktop/source/app/dispatchwatcher.hxx
new file mode 100644
index 000000000000..2b3f1ab54680
--- /dev/null
+++ b/desktop/source/app/dispatchwatcher.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_DISPATCHWATCHER_HXX
+#define _DESKTOP_DISPATCHWATCHER_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#include <com/sun/star/frame/XDispatchResultListener.hpp>
+
+#include "officeipcthread.hxx"
+#include <hash_map>
+#include <vector>
+
+namespace desktop
+{
+
+/*
+ Class for controlls dispatching of command URL through office command line. There
+ are "dangerous" command URLs, that can result in a running office without UI. To prevent
+ this situation the implementation surveile all dispatches and looks for an open task if
+ there is arose a problem. If there is none the office will be shutdown to prevent a
+ running office without UI.
+*/
+
+struct OUStringHashCode
+{
+ size_t operator()( const ::rtl::OUString& sString ) const
+ {
+ return sString.hashCode();
+ }
+};
+
+class DispatchWatcherHashMap : public ::std::hash_map< ::rtl::OUString, sal_Int32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > >
+{
+ public:
+ inline void free()
+ {
+ DispatchWatcherHashMap().swap( *this );
+ }
+};
+
+class DispatchWatcher : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XDispatchResultListener >
+{
+ public:
+ enum RequestType
+ {
+ REQUEST_OPEN,
+ REQUEST_VIEW,
+ REQUEST_START,
+ REQUEST_PRINT,
+ REQUEST_PRINTTO,
+ REQUEST_FORCEOPEN,
+ REQUEST_FORCENEW
+ };
+
+ struct DispatchRequest
+ {
+ DispatchRequest( RequestType aType, const ::rtl::OUString& aFile, boost::optional< rtl::OUString > const & cwdUrl, const ::rtl::OUString& aPrinter, const ::rtl::OUString& aFact ) :
+ aRequestType( aType ), aURL( aFile ), aCwdUrl( cwdUrl ), aPrinterName( aPrinter ), aPreselectedFactory( aFact ) {}
+
+ RequestType aRequestType;
+ rtl::OUString aURL;
+ boost::optional< rtl::OUString > aCwdUrl;
+ rtl::OUString aPrinterName;
+ rtl::OUString aPreselectedFactory;
+ };
+
+ typedef std::vector< DispatchRequest > DispatchList;
+
+ virtual ~DispatchWatcher();
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XDispachResultListener
+ virtual void SAL_CALL dispatchFinished( const com::sun::star::frame::DispatchResultEvent& aEvent ) throw( com::sun::star::uno::RuntimeException );
+
+ // Access function to get a dispatcher watcher reference. There must be a global reference holder
+ static DispatchWatcher* GetDispatchWatcher();
+
+ // execute new dispatch request
+ sal_Bool executeDispatchRequests( const DispatchList& aDispatches, bool bNoTerminate = false );
+
+ private:
+ DispatchWatcher();
+
+ static ::osl::Mutex& GetMutex();
+
+ DispatchWatcherHashMap m_aRequestContainer;
+
+ static ::osl::Mutex* pWatcherMutex;
+
+ sal_Int16 m_nRequestCount;
+};
+
+}
+
+#endif // _DESKTOP_DISPATCHWATCHER_HXX
diff --git a/desktop/source/app/exports.dxp b/desktop/source/app/exports.dxp
new file mode 100644
index 000000000000..9630d7e06768
--- /dev/null
+++ b/desktop/source/app/exports.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
diff --git a/desktop/source/app/langselect.cxx b/desktop/source/app/langselect.cxx
new file mode 100644
index 000000000000..9df8d82a37ff
--- /dev/null
+++ b/desktop/source/app/langselect.cxx
@@ -0,0 +1,558 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "app.hxx"
+#include "langselect.hxx"
+#include "cmdlineargs.hxx"
+#include <stdio.h>
+
+#include <rtl/string.hxx>
+#include <rtl/bootstrap.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/resid.hxx>
+#include <tools/config.hxx>
+#include <i18npool/mslangid.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include "com/sun/star/util/XFlushable.hpp"
+#include <rtl/locale.hxx>
+#include <rtl/instance.hxx>
+#include <osl/process.h>
+#include <osl/file.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+namespace desktop {
+
+static char const SOFFICE_BOOTSTRAP[] = "Bootstrap";
+static char const SOFFICE_STARTLANG[] = "STARTLANG";
+
+sal_Bool LanguageSelection::bFoundLanguage = sal_False;
+OUString LanguageSelection::aFoundLanguage;
+LanguageSelection::LanguageSelectionStatus LanguageSelection::m_eStatus = LS_STATUS_OK;
+
+const OUString LanguageSelection::usFallbackLanguage = OUString::createFromAscii("en-US");
+
+static sal_Bool existsURL( OUString const& sURL )
+{
+ using namespace osl;
+ DirectoryItem aDirItem;
+
+ if (sURL.getLength() != 0)
+ return ( DirectoryItem::get( sURL, aDirItem ) == DirectoryItem::E_None );
+
+ return sal_False;
+}
+
+// locate soffice.ini/.rc file
+static OUString locateSofficeIniFile()
+{
+ OUString aUserDataPath;
+ OUString aSofficeIniFileURL;
+
+ // Retrieve the default file URL for the soffice.ini/rc
+ rtl::Bootstrap().getIniName( aSofficeIniFileURL );
+
+ if ( utl::Bootstrap::locateUserData( aUserDataPath ) == utl::Bootstrap::PATH_EXISTS )
+ {
+ const char CONFIG_DIR[] = "/config";
+
+ sal_Int32 nIndex = aSofficeIniFileURL.lastIndexOf( '/');
+ if ( nIndex > 0 )
+ {
+ OUString aUserSofficeIniFileURL;
+ OUStringBuffer aBuffer( aUserDataPath );
+ aBuffer.appendAscii( CONFIG_DIR );
+ aBuffer.append( aSofficeIniFileURL.copy( nIndex ));
+ aUserSofficeIniFileURL = aBuffer.makeStringAndClear();
+
+ if ( existsURL( aUserSofficeIniFileURL ))
+ return aUserSofficeIniFileURL;
+ }
+ }
+ // Fallback try to use the soffice.ini/rc from program folder
+ return aSofficeIniFileURL;
+}
+
+Locale LanguageSelection::IsoStringToLocale(const OUString& str)
+{
+ Locale l;
+ sal_Int32 index=0;
+ l.Language = str.getToken(0, '-', index);
+ if (index >= 0) l.Country = str.getToken(0, '-', index);
+ if (index >= 0) l.Variant = str.getToken(0, '-', index);
+ return l;
+}
+
+bool LanguageSelection::prepareLanguage()
+{
+ m_eStatus = LS_STATUS_OK;
+ OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ Reference< XLocalizable > theConfigProvider;
+ try
+ {
+ theConfigProvider = Reference< XLocalizable >(theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
+ }
+ catch(const Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ if(!theConfigProvider.is())
+ return false;
+
+ sal_Bool bSuccess = sal_False;
+
+ // #i42730#get the windows 16Bit locale - it should be preferred over the UI language
+ try
+ {
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.System/L10N/", sal_False), UNO_QUERY_THROW);
+ Any aWin16SysLocale = xProp->getPropertyValue(OUString::createFromAscii("SystemLocale"));
+ ::rtl::OUString sWin16SysLocale;
+ aWin16SysLocale >>= sWin16SysLocale;
+ if( sWin16SysLocale.getLength())
+ setDefaultLanguage(sWin16SysLocale);
+ }
+ catch(const Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ // #i32939# use system locale to set document default locale
+ try
+ {
+ OUString usLocale;
+ Reference< XPropertySet > xLocaleProp(getConfigAccess(
+ "org.openoffice.System/L10N", sal_True), UNO_QUERY_THROW);
+ xLocaleProp->getPropertyValue(OUString::createFromAscii("Locale")) >>= usLocale;
+ setDefaultLanguage(usLocale);
+ }
+ catch (Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ // get the selected UI language as string
+ bool bCmdLanguage( false );
+ bool bIniLanguage( false );
+ OUString aEmpty;
+ OUString aLocaleString = getUserUILanguage();
+
+ if ( aLocaleString.getLength() == 0 )
+ {
+ CommandLineArgs* pCmdLineArgs = Desktop::GetCommandLineArgs();
+ if ( pCmdLineArgs )
+ {
+ pCmdLineArgs->GetLanguage(aLocaleString);
+ if (isInstalledLanguage(aLocaleString, sal_False))
+ {
+ bCmdLanguage = true;
+ bFoundLanguage = true;
+ aFoundLanguage = aLocaleString;
+ }
+ else
+ aLocaleString = aEmpty;
+ }
+
+ if ( !bCmdLanguage )
+ {
+ OUString aSOfficeIniURL = locateSofficeIniFile();
+ Config aConfig(aSOfficeIniURL);
+ aConfig.SetGroup( SOFFICE_BOOTSTRAP );
+ OString sLang = aConfig.ReadKey( SOFFICE_STARTLANG );
+ aLocaleString = OUString( sLang.getStr(), sLang.getLength(), RTL_TEXTENCODING_ASCII_US );
+ if (isInstalledLanguage(aLocaleString, sal_False))
+ {
+ bIniLanguage = true;
+ bFoundLanguage = true;
+ aFoundLanguage = aLocaleString;
+ }
+ else
+ aLocaleString = aEmpty;
+ }
+ }
+
+ // user further fallbacks for the UI language
+ if ( aLocaleString.getLength() == 0 )
+ aLocaleString = getLanguageString();
+
+ if ( aLocaleString.getLength() > 0 )
+ {
+ try
+ {
+ // prepare default config provider by localizing it to the selected locale
+ // this will ensure localized configuration settings to be selected accoring to the
+ // UI language.
+ Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
+ // flush any data already written to the configuration (which
+ // currently uses independent caches for different locales and thus
+ // would ignore data written to another cache):
+ Reference< XFlushable >(theConfigProvider, UNO_QUERY_THROW)->
+ flush();
+ theConfigProvider->setLocale(loc);
+
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Setup/L10N/", sal_True), UNO_QUERY_THROW);
+ if ( !bCmdLanguage )
+ {
+ // Store language only
+ xProp->setPropertyValue(OUString::createFromAscii("ooLocale"), makeAny(aLocaleString));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ }
+
+ if ( bIniLanguage )
+ {
+ // Store language only
+ Reference< XPropertySet > xProp2(getConfigAccess("org.openoffice.Office.Linguistic/General/", sal_True), UNO_QUERY_THROW);
+ xProp2->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(aLocaleString));
+ Reference< XChangesBatch >(xProp2, UNO_QUERY_THROW)->commitChanges();
+ }
+
+ MsLangId::setConfiguredSystemUILanguage( MsLangId::convertLocaleToLanguage(loc) );
+
+ OUString sLocale;
+ xProp->getPropertyValue(OUString::createFromAscii("ooSetupSystemLocale")) >>= sLocale;
+ if ( sLocale.getLength() )
+ {
+ loc = LanguageSelection::IsoStringToLocale(sLocale);
+ MsLangId::setConfiguredSystemLanguage( MsLangId::convertLocaleToLanguage(loc) );
+ }
+ else
+ MsLangId::setConfiguredSystemLanguage( MsLangId::getSystemLanguage() );
+
+ bSuccess = sal_True;
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch (Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+
+ }
+ }
+
+ // #i32939# setting of default document locale
+ // #i32939# this should not be based on the UI language
+ setDefaultLanguage(aLocaleString);
+
+ return bSuccess;
+}
+
+void LanguageSelection::setDefaultLanguage(const OUString& sLocale)
+{
+ // #i32939# setting of default document language
+ //
+ // See #i42730# for rules for determining source of settings
+
+ // determine script type of locale
+ LanguageType nLang = MsLangId::convertIsoStringToLanguage(sLocale);
+ sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(nLang);
+
+ switch (nScriptType)
+ {
+ case SCRIPTTYPE_ASIAN:
+ MsLangId::setConfiguredAsianFallback( nLang );
+ break;
+ case SCRIPTTYPE_COMPLEX:
+ MsLangId::setConfiguredComplexFallback( nLang );
+ break;
+ default:
+ MsLangId::setConfiguredWesternFallback( nLang );
+ break;
+ }
+}
+
+OUString LanguageSelection::getUserUILanguage()
+{
+ // check whether the user has selected a specific language
+ OUString aUserLanguage = getUserLanguage();
+ if (aUserLanguage.getLength() > 0 )
+ {
+ if (isInstalledLanguage(aUserLanguage))
+ {
+ // all is well
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+ }
+ else
+ {
+ // selected language is not/no longer installed
+ resetUserLanguage();
+ }
+ }
+
+ return aUserLanguage;
+}
+
+OUString LanguageSelection::getLanguageString()
+{
+ // did we already find a language?
+ if (bFoundLanguage)
+ return aFoundLanguage;
+
+ // check whether the user has selected a specific language
+ OUString aUserLanguage = getUserUILanguage();
+ if (aUserLanguage.getLength() > 0 )
+ return aUserLanguage ;
+
+ // try to use system default
+ aUserLanguage = getSystemLanguage();
+ if (aUserLanguage.getLength() > 0 )
+ {
+ if (isInstalledLanguage(aUserLanguage, sal_False))
+ {
+ // great, system default language is available
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+ }
+ }
+ // fallback 1: en-US
+ OUString usFB = usFallbackLanguage;
+ if (isInstalledLanguage(usFB))
+ {
+ bFoundLanguage = sal_True;
+ aFoundLanguage = usFallbackLanguage;
+ return aFoundLanguage;
+ }
+
+ // fallback didn't work use first installed language
+ aUserLanguage = getFirstInstalledLanguage();
+
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+}
+
+Reference< XNameAccess > LanguageSelection::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
+{
+ Reference< XNameAccess > xNameAccess;
+ try{
+ OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
+ OUString sAccessSrvc;
+ if (bUpdate)
+ sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
+ else
+ sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
+
+ OUString sConfigURL = OUString::createFromAscii(pPath);
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ if (theMSF.is()) {
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
+ theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
+
+ // access the provider
+ Sequence< Any > theArgs(1);
+ theArgs[ 0 ] <<= sConfigURL;
+ xNameAccess = Reference< XNameAccess > (
+ theConfigProvider->createInstanceWithArguments(
+ sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+ }
+ } catch (com::sun::star::uno::Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ }
+ return xNameAccess;
+}
+
+Sequence< OUString > LanguageSelection::getInstalledLanguages()
+{
+ Sequence< OUString > seqLanguages;
+ Reference< XNameAccess > xAccess = getConfigAccess("org.openoffice.Setup/Office/InstalledLocales", sal_False);
+ if (!xAccess.is()) return seqLanguages;
+ seqLanguages = xAccess->getElementNames();
+ return seqLanguages;
+}
+
+// FIXME
+// it's not very clever to handle language fallbacks here, but
+// right now, there is no place that handles those fallbacks globally
+static Sequence< OUString > _getFallbackLocales(const OUString& aIsoLang)
+{
+ Sequence< OUString > seqFallbacks;
+ if (aIsoLang.equalsAscii("zh-HK")) {
+ seqFallbacks = Sequence< OUString >(1);
+ seqFallbacks[0] = OUString::createFromAscii("zh-TW");
+ }
+ return seqFallbacks;
+}
+
+sal_Bool LanguageSelection::isInstalledLanguage(OUString& usLocale, sal_Bool bExact)
+{
+ sal_Bool bInstalled = sal_False;
+ Sequence< OUString > seqLanguages = getInstalledLanguages();
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (usLocale.equals(seqLanguages[i]))
+ {
+ bInstalled = sal_True;
+ break;
+ }
+ }
+
+ if (!bInstalled && !bExact)
+ {
+ // try fallback locales
+ Sequence< OUString > seqFallbacks = _getFallbackLocales(usLocale);
+ for (sal_Int32 j=0; j<seqFallbacks.getLength(); j++)
+ {
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (seqFallbacks[j].equals(seqLanguages[i]))
+ {
+ bInstalled = sal_True;
+ usLocale = seqFallbacks[j];
+ break;
+ }
+ }
+ }
+ }
+
+ if (!bInstalled && !bExact)
+ {
+ // no exact match was found, well try to find a substitute
+ OUString aInstalledLocale;
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (usLocale.indexOf(seqLanguages[i]) == 0)
+ {
+ // requested locale starts with the installed locale
+ // (i.e. installed locale has index 0 in requested locale)
+ bInstalled = sal_True;
+ usLocale = seqLanguages[i];
+ break;
+ }
+ }
+ }
+ return bInstalled;
+}
+
+OUString LanguageSelection::getFirstInstalledLanguage()
+{
+ OUString aLanguage;
+ Sequence< OUString > seqLanguages = getInstalledLanguages();
+ if (seqLanguages.getLength() > 0)
+ aLanguage = seqLanguages[0];
+ return aLanguage;
+}
+
+OUString LanguageSelection::getUserLanguage()
+{
+ OUString aUserLanguage;
+ Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_False));
+ if (xAccess.is())
+ {
+ try
+ {
+ xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ catch ( WrappedTargetException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ }
+ return aUserLanguage;
+}
+
+OUString LanguageSelection::getSystemLanguage()
+{
+ OUString aUserLanguage;
+ Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.System/L10N", sal_False));
+ if (xAccess.is())
+ {
+ try
+ {
+ xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ catch ( WrappedTargetException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ }
+ return aUserLanguage;
+}
+
+
+void LanguageSelection::resetUserLanguage()
+{
+ try
+ {
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_True), UNO_QUERY_THROW);
+ xProp->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(OUString::createFromAscii("")));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch ( Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+}
+
+LanguageSelection::LanguageSelectionStatus LanguageSelection::getStatus()
+{
+ return m_eStatus;
+}
+
+} // namespace desktop
diff --git a/desktop/source/app/langselect.hxx b/desktop/source/app/langselect.hxx
new file mode 100644
index 000000000000..bdf3cd6364de
--- /dev/null
+++ b/desktop/source/app/langselect.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <list>
+#include <sal/types.h>
+#include <tools/string.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/resid.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <svl/languageoptions.hxx>
+
+namespace desktop
+{
+
+class LanguageSelection
+{
+public:
+ enum LanguageSelectionStatus
+ {
+ LS_STATUS_OK,
+ LS_STATUS_CANNOT_DETERMINE_LANGUAGE,
+ LS_STATUS_CONFIGURATIONACCESS_BROKEN
+ };
+
+ static com::sun::star::lang::Locale IsoStringToLocale(const rtl::OUString& str);
+ static rtl::OUString getLanguageString();
+ static bool prepareLanguage();
+ static LanguageSelectionStatus getStatus();
+
+private:
+ static const rtl::OUString usFallbackLanguage;
+ static rtl::OUString aFoundLanguage;
+ static sal_Bool bFoundLanguage;
+ static LanguageSelectionStatus m_eStatus;
+
+ static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >
+ getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate=sal_False);
+ static com::sun::star::uno::Sequence< rtl::OUString > getInstalledLanguages();
+ static sal_Bool isInstalledLanguage(rtl::OUString& usLocale, sal_Bool bExact=sal_False);
+ static rtl::OUString getFirstInstalledLanguage();
+ static rtl::OUString getUserUILanguage();
+ static rtl::OUString getUserLanguage();
+ static rtl::OUString getSystemLanguage();
+ static void resetUserLanguage();
+ static void setDefaultLanguage(const rtl::OUString&);
+};
+
+} //namespace desktop
diff --git a/desktop/source/app/lockfile.cxx b/desktop/source/app/lockfile.cxx
new file mode 100644
index 000000000000..9cc447a6c56b
--- /dev/null
+++ b/desktop/source/app/lockfile.cxx
@@ -0,0 +1,256 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <stdlib.h>
+#include <time.h>
+#ifdef WNT
+#include <tools/prewin.h>
+#include <windows.h>
+#include <tools/postwin.h>
+#endif
+#include <sal/types.h>
+#include <osl/file.hxx>
+#include <osl/socket.hxx>
+#include <osl/security.hxx>
+#include <unotools/bootstrap.hxx>
+#include <tools/string.hxx>
+#include <tools/config.hxx>
+
+#include "lockfile.hxx"
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::utl;
+
+
+namespace desktop {
+
+ // initialize static members...
+ // lock suffix
+ const OUString Lockfile::Suffix()
+ { return OUString::createFromAscii( "/.lock" ); }
+ // values for datafile
+ const ByteString Lockfile::Group()
+ { return ByteString( "Lockdata" ); }
+ const ByteString Lockfile::Userkey()
+ { return ByteString( "User" ); }
+ const ByteString Lockfile::Hostkey()
+ { return ByteString( "Host" ); }
+ const ByteString Lockfile::Stampkey()
+ { return ByteString( "Stamp" ); }
+ const ByteString Lockfile::Timekey()
+ { return ByteString( "Time" ); }
+ const ByteString Lockfile::IPCkey()
+ { return ByteString( "IPCServer" ); }
+
+ Lockfile::Lockfile( bool bIPCserver )
+ :m_bIPCserver(bIPCserver)
+ ,m_bRemove(sal_False)
+ ,m_bIsLocked(sal_False)
+ {
+ // build the file-url to use for the lock
+ OUString aUserPath;
+ utl::Bootstrap::locateUserInstallation( aUserPath );
+ m_aLockname = aUserPath + Suffix();
+
+ // generate ID
+ const int nIdBytes = 16;
+ char tmpId[nIdBytes*2+1];
+ time_t t;
+ srand( (unsigned)(t = time( NULL )) );
+ int tmpByte = 0;
+ for (int i = 0; i<nIdBytes; i++) {
+ tmpByte = rand( ) % 0xFF;
+ sprintf( tmpId+i*2, "%02X", tmpByte ); // #100211# - checked
+ }
+ tmpId[nIdBytes*2]=0x00;
+ m_aId = OUString::createFromAscii( tmpId );
+
+ // generate date string
+ char *tmpTime = ctime( &t );
+ if (tmpTime != NULL) {
+ m_aDate = OUString::createFromAscii( tmpTime );
+ sal_Int32 i = m_aDate.indexOf('\n');
+ if (i > 0)
+ m_aDate = m_aDate.copy(0, i);
+ }
+
+
+ // try to create file
+ File aFile(m_aLockname);
+ if (aFile.open( OpenFlag_Create ) == File::E_EXIST) {
+ m_bIsLocked = sal_True;
+ } else {
+ // new lock created
+ aFile.close( );
+ syncToFile( );
+ m_bRemove = sal_True;
+ }
+ }
+
+ sal_Bool Lockfile::check( fpExecWarning execWarning )
+ {
+
+ if (m_bIsLocked) {
+ // lock existed, ask user what to do
+ if (isStale() ||
+ (execWarning != 0 && (*execWarning)( this ))) {
+ // remove file and create new
+ File::remove( m_aLockname );
+ File aFile(m_aLockname);
+ aFile.open( OpenFlag_Create );
+ aFile.close( );
+ syncToFile( );
+ m_bRemove = sal_True;
+ return sal_True;
+ } else {
+ //leave alone and return false
+ m_bRemove = sal_False;
+ return sal_False;
+ }
+ } else {
+ // lock was created by us
+ return sal_True;
+ }
+ }
+
+ sal_Bool Lockfile::isStale( void ) const
+ {
+ // this checks whether the lockfile was created on the same
+ // host by the same user. Should this be the case it is safe
+ // to assume that it is a stale lockfile which can be overwritten
+ String aLockname = m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup(Group());
+ ByteString aIPCserver = aConfig.ReadKey( IPCkey() );
+ if (! aIPCserver.EqualsIgnoreCaseAscii( "true" ))
+ return false;
+
+ ByteString aHost = aConfig.ReadKey( Hostkey() );
+ ByteString aUser = aConfig.ReadKey( Userkey() );
+ // lockfile from same host?
+ ByteString myHost;
+#ifdef WNT
+ /*
+ prevent windows from connecting to the net to get it's own
+ hostname by using the netbios name
+ */
+ sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1;
+ char* szHost = new char[sz];
+ if (GetComputerName(szHost, (LPDWORD)&sz))
+ myHost = OString(szHost);
+ else
+ myHost = OString("UNKNOWN");
+ delete[] szHost;
+#else
+ oslSocketResult sRes;
+ myHost = OUStringToOString(
+ SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US );
+#endif
+ if (aHost == myHost) {
+ // lockfile by same UID
+ OUString myUserName;
+ Security aSecurity;
+ aSecurity.getUserName( myUserName );
+ ByteString myUser = OUStringToOString( myUserName, RTL_TEXTENCODING_ASCII_US );
+ if (aUser == myUser)
+ return sal_True;
+ }
+ return sal_False;
+ }
+
+ void Lockfile::syncToFile( void ) const
+ {
+ String aLockname = m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup(Group());
+
+ // get information
+ ByteString aHost;
+#ifdef WNT
+ /*
+ prevent windows from connecting to the net to get it's own
+ hostname by using the netbios name
+ */
+ sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1;
+ char* szHost = new char[sz];
+ if (GetComputerName(szHost, (LPDWORD)&sz))
+ aHost = OString(szHost);
+ else
+ aHost = OString("UNKNOWN");
+ delete[] szHost;
+#else
+ oslSocketResult sRes;
+ aHost = OUStringToOString(
+ SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US );
+#endif
+ OUString aUserName;
+ Security aSecurity;
+ aSecurity.getUserName( aUserName );
+ ByteString aUser = OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aTime = OUStringToOString( m_aDate, RTL_TEXTENCODING_ASCII_US );
+ ByteString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US );
+
+ // write information
+ aConfig.WriteKey( Userkey(), aUser );
+ aConfig.WriteKey( Hostkey(), aHost );
+ aConfig.WriteKey( Stampkey(), aStamp );
+ aConfig.WriteKey( Timekey(), aTime );
+ aConfig.WriteKey(
+ IPCkey(),
+ m_bIPCserver ? ByteString("true") : ByteString("false") );
+ aConfig.Flush( );
+ }
+
+ void Lockfile::clean( void )
+ {
+ if ( m_bRemove )
+ {
+ File::remove( m_aLockname );
+ m_bRemove = sal_False;
+ }
+ }
+
+ Lockfile::~Lockfile( void )
+ {
+ // unlock userdata by removing file
+ if ( m_bRemove )
+ File::remove( m_aLockname );
+ }
+}
+
+
+
+
+
+
+
+
+
diff --git a/desktop/source/app/lockfile.hxx b/desktop/source/app/lockfile.hxx
new file mode 100644
index 000000000000..248e44c52160
--- /dev/null
+++ b/desktop/source/app/lockfile.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+/* Information:
+ * This class implements a mechanism to lock a users installation directory,
+ * which is necessesary because instances of staroffice could be running on
+ * different hosts while using the same directory thus causing data
+ * inconsistency.
+ * When an existing lock is detected, the user will be asked whether he wants
+ * to continue anyway, thus removing the lock and replacing it with a new one
+ *
+ * ideas:
+ * - store information about user and host and time in the lockfile and display
+ * these when asking whether to remove the lockfile.
+ * - periodically check the lockfile and warn the user when it gets replaced
+ *
+ */
+
+#include "sal/types.h"
+#include "rtl/ustring.hxx"
+
+class ByteString;
+
+namespace desktop {
+
+ class Lockfile;
+ bool Lockfile_execWarning( Lockfile * that );
+
+ class Lockfile
+ {
+ public:
+
+ // contructs a new lockfile onject
+ Lockfile( bool bIPCserver = true );
+
+ // separating GUI code:
+ typedef bool (* fpExecWarning)( Lockfile * that );
+
+ // checks the lockfile, asks user when lockfile is
+ // found (iff gui) and returns false when we may not continue
+ sal_Bool check( fpExecWarning execWarning );
+
+ // removes the lockfile. should only be called in exceptional situations
+ void clean(void);
+
+ // removes the lockfile
+ ~Lockfile(void);
+
+ private:
+ // data in lockfile
+ static const ByteString Group();
+ static const ByteString Userkey();
+ static const ByteString Hostkey();
+ static const ByteString Stampkey();
+ static const ByteString Timekey();
+ static const ByteString IPCkey();
+ // lockfilename
+ static const rtl::OUString Suffix();
+ bool m_bIPCserver;
+ // full qualified name (file://-url) of the lockfile
+ rtl::OUString m_aLockname;
+ // flag whether the d'tor should delete the lock
+ sal_Bool m_bRemove;
+ sal_Bool m_bIsLocked;
+ // ID
+ rtl::OUString m_aId;
+ rtl::OUString m_aDate;
+ // access to data in file
+ void syncToFile(void) const;
+ sal_Bool isStale(void) const;
+ friend bool Lockfile_execWarning( Lockfile * that );
+
+ };
+
+}
diff --git a/desktop/source/app/lockfile2.cxx b/desktop/source/app/lockfile2.cxx
new file mode 100644
index 000000000000..c155d9e6a3cd
--- /dev/null
+++ b/desktop/source/app/lockfile2.cxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "vcl/msgbox.hxx"
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include "tools/config.hxx"
+#include "lockfile.hxx"
+
+
+namespace desktop {
+
+bool Lockfile_execWarning( Lockfile * that )
+{
+ // read information from lock
+ String aLockname = that->m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup(that->Group());
+ ByteString aHost = aConfig.ReadKey( that->Hostkey() );
+ ByteString aUser = aConfig.ReadKey( that->Userkey() );
+ ByteString aStamp = aConfig.ReadKey( that->Stampkey() );
+ ByteString aTime = aConfig.ReadKey( that->Timekey() );
+
+ // display warning and return response
+ QueryBox aBox( NULL, DesktopResId( QBX_USERDATALOCKED ) );
+ // set box title
+ String aTitle = String( DesktopResId( STR_TITLE_USERDATALOCKED ));
+ aBox.SetText( aTitle );
+ // insert values...
+ String aMsgText = aBox.GetMessText( );
+ aMsgText.SearchAndReplaceAscii(
+ "$u", String( aUser, RTL_TEXTENCODING_ASCII_US) );
+ aMsgText.SearchAndReplaceAscii(
+ "$h", String( aHost, RTL_TEXTENCODING_ASCII_US) );
+ aMsgText.SearchAndReplaceAscii(
+ "$t", String( aTime, RTL_TEXTENCODING_ASCII_US) );
+ aBox.SetMessText(aMsgText);
+ // do it
+ return aBox.Execute( ) == RET_YES;
+}
+
+}
+
diff --git a/desktop/source/app/main.c b/desktop/source/app/main.c
new file mode 100644
index 000000000000..dceaf1a3fba1
--- /dev/null
+++ b/desktop/source/app/main.c
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "sal/config.h"
+
+#include "sal/main.h"
+
+#include "sofficemain.h"
+
+SAL_IMPLEMENT_MAIN() {
+ return soffice_main();
+}
diff --git a/desktop/source/app/makefile.mk b/desktop/source/app/makefile.mk
new file mode 100644
index 000000000000..085d8520e7ad
--- /dev/null
+++ b/desktop/source/app/makefile.mk
@@ -0,0 +1,115 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=dkt
+AUTOSEG=true
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : ../deployment/inc/dp_misc.mk
+
+.IF "$(ENABLE_GNOMEVFS)"=="TRUE"
+CFLAGS+=-DGNOME_VFS_ENABLED
+.ENDIF
+
+# .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
+
+SHL1TARGET = sofficeapp
+SHL1OBJS = \
+ $(SLO)$/app.obj \
+ $(SLO)$/appfirststart.obj \
+ $(SLO)$/appinit.obj \
+ $(SLO)$/appsys.obj \
+ $(SLO)$/checkinstall.obj \
+ $(SLO)$/check_ext_deps.obj \
+ $(SLO)$/cmdlineargs.obj \
+ $(SLO)$/cmdlinehelp.obj \
+ $(SLO)$/configinit.obj \
+ $(SLO)$/desktopcontext.obj \
+ $(SLO)$/desktopresid.obj \
+ $(SLO)$/dispatchwatcher.obj \
+ $(SLO)$/langselect.obj \
+ $(SLO)$/lockfile.obj \
+ $(SLO)$/lockfile2.obj \
+ $(SLO)$/officeipcthread.obj \
+ $(SLO)$/sofficemain.obj \
+ $(SLO)$/userinstall.obj
+
+SHL1LIBS = $(SLB)$/mig.lib
+
+SHL1STDLIBS = \
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(DEPLOYMENTMISCLIB) \
+ $(I18NISOLANGLIB) \
+ $(SALLIB) \
+ $(SFXLIB) \
+ $(SVLLIB) \
+ $(SVTOOLLIB) \
+ $(TKLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(VCLLIB) \
+ $(VOSLIB)
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+OBJFILES = \
+ $(OBJ)$/copyright_ascii_ooo.obj \
+ $(OBJ)$/main.obj
+.IF "$(GUI)" != "OS2"
+OBJFILES += \
+ $(OBJ)$/copyright_ascii_sun.obj
+.ENDIF
+
+SLOFILES = $(SHL1OBJS)
+
+SRS1NAME= desktop
+SRC1FILES= desktop.src
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx
new file mode 100644
index 000000000000..fc74c3fb4504
--- /dev/null
+++ b/desktop/source/app/officeipcthread.cxx
@@ -0,0 +1,996 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "app.hxx"
+#include "officeipcthread.hxx"
+#include "cmdlineargs.hxx"
+#include "dispatchwatcher.hxx"
+#include <memory>
+#include <stdio.h>
+#include <vos/process.hxx>
+#include <unotools/bootstrap.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+#include <unotools/configmgr.hxx>
+#include <osl/thread.hxx>
+#include <rtl/digest.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/instance.hxx>
+#include <osl/conditn.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/strbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#include "osl/file.hxx"
+#include "rtl/process.h"
+#include "tools/getprocessworkingdir.hxx"
+
+using namespace vos;
+using namespace rtl;
+using namespace desktop;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+
+const char *OfficeIPCThread::sc_aTerminationSequence = "InternalIPC::TerminateThread";
+const int OfficeIPCThread::sc_nTSeqLength = 28;
+const char *OfficeIPCThread::sc_aShowSequence = "-tofront";
+const int OfficeIPCThread::sc_nShSeqLength = 5;
+const char *OfficeIPCThread::sc_aConfirmationSequence = "InternalIPC::ProcessingDone";
+const int OfficeIPCThread::sc_nCSeqLength = 27;
+
+namespace { static char const ARGUMENT_PREFIX[] = "InternalIPC::Arguments"; }
+
+// Type of pipe we use
+enum PipeMode
+{
+ PIPEMODE_DONTKNOW,
+ PIPEMODE_CREATED,
+ PIPEMODE_CONNECTED
+};
+
+namespace desktop
+{
+
+namespace {
+
+class Parser: public CommandLineArgs::Supplier {
+public:
+ explicit Parser(rtl::OString const & input): m_input(input) {
+ if (!m_input.match(ARGUMENT_PREFIX) ||
+ m_input.getLength() == RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX))
+ {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ m_index = RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX);
+ switch (m_input[m_index++]) {
+ case '0':
+ break;
+ case '1':
+ {
+ rtl::OUString url;
+ if (!next(&url, false)) {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ m_cwdUrl.reset(url);
+ break;
+ }
+ case '2':
+ {
+ rtl::OUString path;
+ if (!next(&path, false)) {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ rtl::OUString url;
+ if (osl::FileBase::getFileURLFromSystemPath(path, url) ==
+ osl::FileBase::E_None)
+ {
+ m_cwdUrl.reset(url);
+ }
+ break;
+ }
+ default:
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ }
+
+ virtual ~Parser() {}
+
+ virtual boost::optional< rtl::OUString > getCwdUrl() { return m_cwdUrl; }
+
+ virtual bool next(rtl::OUString * argument) { return next(argument, true); }
+
+private:
+ virtual bool next(rtl::OUString * argument, bool prefix) {
+ OSL_ASSERT(argument != NULL);
+ if (m_index < m_input.getLength()) {
+ if (prefix) {
+ if (m_input[m_index] != ',') {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ ++m_index;
+ }
+ rtl::OStringBuffer b;
+ while (m_index < m_input.getLength()) {
+ char c = m_input[m_index];
+ if (c == ',') {
+ break;
+ }
+ ++m_index;
+ if (c == '\\') {
+ if (m_index < m_input.getLength()) {
+ c = m_input[m_index++];
+ switch (c) {
+ case '0':
+ c = '\0';
+ break;
+ case ',':
+ case '\\':
+ break;
+ default:
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ } else {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ }
+ b.append(c);
+ }
+ rtl::OString b2(b.makeStringAndClear());
+ if (!rtl_convertStringToUString(
+ &argument->pData, b2.getStr(), b2.getLength(),
+ RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+ {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ boost::optional< rtl::OUString > m_cwdUrl;
+ rtl::OString m_input;
+ sal_Int32 m_index;
+};
+
+bool addArgument(
+ ByteString * arguments, char prefix, rtl::OUString const & argument)
+{
+ rtl::OString utf8;
+ if (!argument.convertToString(
+ &utf8, RTL_TEXTENCODING_UTF8,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ return false;
+ }
+ *arguments += prefix;
+ for (sal_Int32 i = 0; i < utf8.getLength(); ++i) {
+ char c = utf8[i];
+ switch (c) {
+ case '\0':
+ *arguments += "\\0";
+ break;
+ case ',':
+ *arguments += "\\,";
+ break;
+ case '\\':
+ *arguments += "\\\\";
+ break;
+ default:
+ *arguments += c;
+ break;
+ }
+ }
+ return true;
+}
+
+}
+
+OfficeIPCThread* OfficeIPCThread::pGlobalOfficeIPCThread = 0;
+namespace { struct Security : public rtl::Static<OSecurity, Security> {}; }
+::osl::Mutex* OfficeIPCThread::pOfficeIPCThreadMutex = 0;
+
+
+String CreateMD5FromString( const OUString& aMsg )
+{
+ // PRE: aStr "file"
+ // BACK: Str "ababab....0f" Hexcode String
+
+ rtlDigest handle = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ if ( handle > 0 )
+ {
+ const sal_uInt8* pData = (const sal_uInt8*)aMsg.getStr();
+ sal_uInt32 nSize = ( aMsg.getLength() * sizeof( sal_Unicode ));
+ sal_uInt32 nMD5KeyLen = rtl_digest_queryLength( handle );
+ sal_uInt8* pMD5KeyBuffer = new sal_uInt8[ nMD5KeyLen ];
+
+ rtl_digest_init( handle, pData, nSize );
+ rtl_digest_update( handle, pData, nSize );
+ rtl_digest_get( handle, pMD5KeyBuffer, nMD5KeyLen );
+ rtl_digest_destroy( handle );
+
+ // Create hex-value string from the MD5 value to keep the string size minimal
+ OUStringBuffer aBuffer( nMD5KeyLen * 2 + 1 );
+ for ( sal_uInt32 i = 0; i < nMD5KeyLen; i++ )
+ aBuffer.append( (sal_Int32)pMD5KeyBuffer[i], 16 );
+
+ delete [] pMD5KeyBuffer;
+ return aBuffer.makeStringAndClear();
+ }
+
+ return String();
+}
+
+class ProcessEventsClass_Impl
+{
+public:
+ DECL_STATIC_LINK( ProcessEventsClass_Impl, CallEvent, void* pEvent );
+ DECL_STATIC_LINK( ProcessEventsClass_Impl, ProcessDocumentsEvent, void* pEvent );
+};
+
+IMPL_STATIC_LINK_NOINSTANCE( ProcessEventsClass_Impl, CallEvent, void*, pEvent )
+{
+ // Application events are processed by the Desktop::HandleAppEvent implementation.
+ Desktop::HandleAppEvent( *((ApplicationEvent*)pEvent) );
+ delete (ApplicationEvent*)pEvent;
+ return 0;
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( ProcessEventsClass_Impl, ProcessDocumentsEvent, void*, pEvent )
+{
+ // Documents requests are processed by the OfficeIPCThread implementation
+ ProcessDocumentsRequest* pDocsRequest = (ProcessDocumentsRequest*)pEvent;
+
+ if ( pDocsRequest )
+ {
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ return 0;
+}
+
+void ImplPostForeignAppEvent( ApplicationEvent* pEvent )
+{
+ Application::PostUserEvent( STATIC_LINK( NULL, ProcessEventsClass_Impl, CallEvent ), pEvent );
+}
+
+void ImplPostProcessDocumentsEvent( ProcessDocumentsRequest* pEvent )
+{
+ Application::PostUserEvent( STATIC_LINK( NULL, ProcessEventsClass_Impl, ProcessDocumentsEvent ), pEvent );
+}
+
+OSignalHandler::TSignalAction SAL_CALL SalMainPipeExchangeSignalHandler::signal(TSignalInfo *pInfo)
+{
+ if( pInfo->Signal == osl_Signal_Terminate )
+ OfficeIPCThread::DisableOfficeIPCThread();
+ return (TAction_CallNextHandler);
+}
+
+// ----------------------------------------------------------------------------
+
+// The OfficeIPCThreadController implementation is a bookkeeper for all pending requests
+// that were created by the OfficeIPCThread. The requests are waiting to be processed by
+// our framework loadComponentFromURL function (e.g. open/print request).
+// During shutdown the framework is asking OfficeIPCThreadController about pending requests.
+// If there are pending requests framework has to stop the shutdown process. It is waiting
+// for these requests because framework is not able to handle shutdown and open a document
+// concurrently.
+
+
+// XServiceInfo
+OUString SAL_CALL OfficeIPCThreadController::getImplementationName()
+throw ( RuntimeException )
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.OfficeIPCThreadController" ));
+}
+
+sal_Bool SAL_CALL OfficeIPCThreadController::supportsService( const OUString& )
+throw ( RuntimeException )
+{
+ return sal_False;
+}
+
+Sequence< OUString > SAL_CALL OfficeIPCThreadController::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< OUString > aSeq( 0 );
+ return aSeq;
+}
+
+// XEventListener
+void SAL_CALL OfficeIPCThreadController::disposing( const EventObject& )
+throw( RuntimeException )
+{
+}
+
+// XTerminateListener
+void SAL_CALL OfficeIPCThreadController::queryTermination( const EventObject& )
+throw( TerminationVetoException, RuntimeException )
+{
+ // Desktop ask about pending request through our office ipc pipe. We have to
+ // be sure that no pending request is waiting because framework is not able to
+ // handle shutdown and open a document concurrently.
+
+ if ( OfficeIPCThread::AreRequestsPending() )
+ throw TerminationVetoException();
+ else
+ OfficeIPCThread::SetDowning();
+}
+
+void SAL_CALL OfficeIPCThreadController::notifyTermination( const EventObject& )
+throw( RuntimeException )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+::osl::Mutex& OfficeIPCThread::GetMutex()
+{
+ // Get or create our mutex for thread-saftey
+ if ( !pOfficeIPCThreadMutex )
+ {
+ ::osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pOfficeIPCThreadMutex )
+ pOfficeIPCThreadMutex = new osl::Mutex;
+ }
+
+ return *pOfficeIPCThreadMutex;
+}
+
+void OfficeIPCThread::SetDowning()
+{
+ // We have the order to block all incoming requests. Framework
+ // wants to shutdown and we have to make sure that no loading/printing
+ // requests are executed anymore.
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( pGlobalOfficeIPCThread )
+ pGlobalOfficeIPCThread->mbDowning = true;
+}
+
+static bool s_bInEnableRequests = false;
+
+void OfficeIPCThread::EnableRequests( bool i_bEnable )
+{
+ // switch between just queueing the requests and executing them
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( pGlobalOfficeIPCThread )
+ {
+ s_bInEnableRequests = true;
+ pGlobalOfficeIPCThread->mbRequestsEnabled = i_bEnable;
+ if( i_bEnable )
+ {
+ // hit the compiler over the head
+ ProcessDocumentsRequest aEmptyReq = ProcessDocumentsRequest( boost::optional< rtl::OUString >() );
+ // trigger already queued requests
+ OfficeIPCThread::ExecuteCmdLineRequests( aEmptyReq );
+ }
+ s_bInEnableRequests = false;
+ }
+}
+
+sal_Bool OfficeIPCThread::AreRequestsPending()
+{
+ // Give info about pending requests
+ ::osl::MutexGuard aGuard( GetMutex() );
+ if ( pGlobalOfficeIPCThread )
+ return ( pGlobalOfficeIPCThread->mnPendingRequests > 0 );
+ else
+ return sal_False;
+}
+
+void OfficeIPCThread::RequestsCompleted( int nCount )
+{
+ // Remove nCount pending requests from our internal counter
+ ::osl::MutexGuard aGuard( GetMutex() );
+ if ( pGlobalOfficeIPCThread )
+ {
+ if ( pGlobalOfficeIPCThread->mnPendingRequests > 0 )
+ pGlobalOfficeIPCThread->mnPendingRequests -= nCount;
+ }
+}
+
+OfficeIPCThread::Status OfficeIPCThread::EnableOfficeIPCThread()
+{
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if( pGlobalOfficeIPCThread )
+ return IPC_STATUS_OK;
+
+ ::rtl::OUString aUserInstallPath;
+ ::rtl::OUString aDummy;
+
+ ::vos::OStartupInfo aInfo;
+ OfficeIPCThread* pThread = new OfficeIPCThread;
+
+ pThread->maPipeIdent = OUString( RTL_CONSTASCII_USTRINGPARAM( "SingleOfficeIPC_" ) );
+
+ // The name of the named pipe is created with the hashcode of the user installation directory (without /user). We have to retrieve
+ // this information from a unotools implementation.
+ ::utl::Bootstrap::PathStatus aLocateResult = ::utl::Bootstrap::locateUserInstallation( aUserInstallPath );
+ if ( aLocateResult == ::utl::Bootstrap::PATH_EXISTS || aLocateResult == ::utl::Bootstrap::PATH_VALID)
+ aDummy = aUserInstallPath;
+ else
+ {
+ delete pThread;
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+
+ // Try to determine if we are the first office or not! This should prevent multiple
+ // access to the user directory !
+ // First we try to create our pipe if this fails we try to connect. We have to do this
+ // in a loop because the the other office can crash or shutdown between createPipe
+ // and connectPipe!!
+
+ OUString aIniName;
+
+ aInfo.getExecutableFile( aIniName );
+ sal_uInt32 lastIndex = aIniName.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ {
+ aIniName = aIniName.copy( 0, lastIndex+1 );
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
+#if defined(WNT) || defined(OS2)
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
+#else
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
+#endif
+ }
+
+ ::rtl::Bootstrap aPerfTuneIniFile( aIniName );
+
+ OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
+ OUString aPreloadData;
+
+ aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "FastPipeCommunication" )), aPreloadData, aDefault );
+
+
+ OUString aUserInstallPathHashCode;
+
+ if ( aPreloadData.equalsAscii( "1" ))
+ {
+ sal_Char szBuffer[32];
+ sprintf( szBuffer, "%d", SUPD );
+ aUserInstallPathHashCode = OUString( szBuffer, strlen(szBuffer), osl_getThreadTextEncoding() );
+ }
+ else
+ aUserInstallPathHashCode = CreateMD5FromString( aDummy );
+
+
+ // Check result to create a hash code from the user install path
+ if ( aUserInstallPathHashCode.getLength() == 0 )
+ return IPC_STATUS_BOOTSTRAP_ERROR; // Something completely broken, we cannot create a valid hash code!
+
+ pThread->maPipeIdent = pThread->maPipeIdent + aUserInstallPathHashCode;
+
+ PipeMode nPipeMode = PIPEMODE_DONTKNOW;
+ do
+ {
+ OSecurity &rSecurity = Security::get();
+ // Try to create pipe
+ if ( pThread->maPipe.create( pThread->maPipeIdent.getStr(), OPipe::TOption_Create, rSecurity ))
+ {
+ // Pipe created
+ nPipeMode = PIPEMODE_CREATED;
+ }
+ else if( pThread->maPipe.create( pThread->maPipeIdent.getStr(), OPipe::TOption_Open, rSecurity )) // Creation not successfull, now we try to connect
+ {
+ // Pipe connected to first office
+ nPipeMode = PIPEMODE_CONNECTED;
+ }
+ else
+ {
+ OPipe::TPipeError eReason = pThread->maPipe.getError();
+ if ((eReason == OPipe::E_ConnectionRefused) || (eReason == OPipe::E_invalidError))
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+
+ // Wait for second office to be ready
+ TimeValue aTimeValue;
+ aTimeValue.Seconds = 0;
+ aTimeValue.Nanosec = 10000000; // 10ms
+ osl::Thread::wait( aTimeValue );
+ }
+
+ } while ( nPipeMode == PIPEMODE_DONTKNOW );
+
+ if ( nPipeMode == PIPEMODE_CREATED )
+ {
+ // Seems we are the one and only, so start listening thread
+ pGlobalOfficeIPCThread = pThread;
+ pThread->create(); // starts thread
+ }
+ else
+ {
+ // Seems another office is running. Pipe arguments to it and self terminate
+ pThread->maStreamPipe = pThread->maPipe;
+
+ sal_Bool bWaitBeforeClose = sal_False;
+ ByteString aArguments(RTL_CONSTASCII_STRINGPARAM(ARGUMENT_PREFIX));
+ rtl::OUString cwdUrl;
+ if (!(tools::getProcessWorkingDir(&cwdUrl) &&
+ addArgument(&aArguments, '1', cwdUrl)))
+ {
+ aArguments += '0';
+ }
+ sal_uInt32 nCount = rtl_getAppCommandArgCount();
+ for( sal_uInt32 i=0; i < nCount; i++ )
+ {
+ rtl_getAppCommandArg( i, &aDummy.pData );
+ if( aDummy.indexOf('-',0) != 0 )
+ {
+ bWaitBeforeClose = sal_True;
+ }
+ if (!addArgument(&aArguments, ',', aDummy)) {
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ }
+ // finaly, write the string onto the pipe
+ pThread->maStreamPipe.write( aArguments.GetBuffer(), aArguments.Len() );
+ pThread->maStreamPipe.write( "\0", 1 );
+
+ // wait for confirmation #95361# #95425#
+ ByteString aToken(sc_aConfirmationSequence);
+ char *aReceiveBuffer = new char[aToken.Len()+1];
+ int n = pThread->maStreamPipe.read( aReceiveBuffer, aToken.Len() );
+ aReceiveBuffer[n]='\0';
+
+ delete pThread;
+ if (aToken.CompareTo(aReceiveBuffer)!= COMPARE_EQUAL) {
+ // something went wrong
+ delete[] aReceiveBuffer;
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ } else {
+ delete[] aReceiveBuffer;
+ return IPC_STATUS_2ND_OFFICE;
+ }
+ }
+
+ return IPC_STATUS_OK;
+}
+
+void OfficeIPCThread::DisableOfficeIPCThread()
+{
+ osl::ClearableMutexGuard aMutex( GetMutex() );
+
+ if( pGlobalOfficeIPCThread )
+ {
+ OfficeIPCThread *pOfficeIPCThread = pGlobalOfficeIPCThread;
+ pGlobalOfficeIPCThread = 0;
+
+ // send thread a termination message
+ // this is done so the subsequent join will not hang
+ // because the thread hangs in accept of pipe
+ OPipe Pipe( pOfficeIPCThread->maPipeIdent, OPipe::TOption_Open, Security::get() );
+ //Pipe.send( TERMINATION_SEQUENCE, TERMINATION_LENGTH );
+ if (Pipe.isValid())
+ {
+ Pipe.send( sc_aTerminationSequence, sc_nTSeqLength+1 ); // also send 0-byte
+
+ // close the pipe so that the streampipe on the other
+ // side produces EOF
+ Pipe.close();
+ }
+
+ // release mutex to avoid deadlocks
+ aMutex.clear();
+
+ OfficeIPCThread::SetReady(pOfficeIPCThread);
+
+ // exit gracefully and join
+ pOfficeIPCThread->join();
+ delete pOfficeIPCThread;
+
+
+ }
+}
+
+OfficeIPCThread::OfficeIPCThread() :
+ mbDowning( false ),
+ mbRequestsEnabled( false ),
+ mnPendingRequests( 0 ),
+ mpDispatchWatcher( 0 )
+{
+}
+
+OfficeIPCThread::~OfficeIPCThread()
+{
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ if ( mpDispatchWatcher )
+ mpDispatchWatcher->release();
+ maPipe.close();
+ maStreamPipe.close();
+ pGlobalOfficeIPCThread = 0;
+}
+
+static void AddURLToStringList( const rtl::OUString& aURL, rtl::OUString& aStringList )
+{
+ if ( aStringList.getLength() )
+ aStringList += ::rtl::OUString::valueOf( (sal_Unicode)APPEVENT_PARAM_DELIMITER );
+ aStringList += aURL;
+}
+
+void OfficeIPCThread::SetReady(OfficeIPCThread* pThread)
+{
+ if (pThread == NULL) pThread = pGlobalOfficeIPCThread;
+ if (pThread != NULL)
+ {
+ pThread->cReady.set();
+ }
+}
+
+void SAL_CALL OfficeIPCThread::run()
+{
+ do
+ {
+ OPipe::TPipeError
+ nError = maPipe.accept( maStreamPipe );
+
+
+ if( nError == OStreamPipe::E_None )
+ {
+
+ // #111143# and others:
+ // if we receive a request while the office is displaying some dialog or error during
+ // bootstrap, that dialogs event loop might get events that are dispatched by this thread
+ // we have to wait for cReady to be set by the real main loop.
+ // only reqests that dont dispatch events may be processed before cReady is set.
+ cReady.wait();
+
+ // we might have decided to shutdown while we were sleeping
+ if (!pGlobalOfficeIPCThread) return;
+
+ // only lock the mutex when processing starts, othewise we deadlock when the office goes
+ // down during wait
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ ByteString aArguments;
+ // test byte by byte
+ const int nBufSz = 2048;
+ char pBuf[nBufSz];
+ int nBytes = 0;
+ int nResult = 0;
+ // read into pBuf until '\0' is read or read-error
+ while ((nResult=maStreamPipe.recv( pBuf+nBytes, nBufSz-nBytes))>0) {
+ nBytes += nResult;
+ if (pBuf[nBytes-1]=='\0') {
+ aArguments += pBuf;
+ break;
+ }
+ }
+ // don't close pipe ...
+
+ // #90717# Is this a lookup message from another application? if so, ignore
+ if ( aArguments.Len() == 0 )
+ continue;
+
+ // is this a termination message ? if so, terminate
+ if(( aArguments.CompareTo( sc_aTerminationSequence, sc_nTSeqLength ) == COMPARE_EQUAL ) ||
+ mbDowning ) return;
+ String aEmpty;
+ std::auto_ptr< CommandLineArgs > aCmdLineArgs;
+ try
+ {
+ Parser p( aArguments );
+ aCmdLineArgs.reset( new CommandLineArgs( p ) );
+ }
+ catch ( CommandLineArgs::Supplier::Exception & )
+ {
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ fprintf( stderr, "Error in received command line arguments\n" );
+#endif
+ continue;
+ }
+ CommandLineArgs *pCurrentCmdLineArgs = Desktop::GetCommandLineArgs();
+
+ if ( aCmdLineArgs->IsQuickstart() )
+ {
+ // we have to use application event, because we have to start quickstart service in main thread!!
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "QUICKSTART", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+ // handle request for acceptor
+ sal_Bool bAcceptorRequest = sal_False;
+ OUString aAcceptString;
+ if ( aCmdLineArgs->GetAcceptString(aAcceptString) && Desktop::CheckOEM()) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "ACCEPT", aAcceptString );
+ ImplPostForeignAppEvent( pAppEvent );
+ bAcceptorRequest = sal_True;
+ }
+ // handle acceptor removal
+ OUString aUnAcceptString;
+ if ( aCmdLineArgs->GetUnAcceptString(aUnAcceptString) ) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "UNACCEPT", aUnAcceptString );
+ ImplPostForeignAppEvent( pAppEvent );
+ bAcceptorRequest = sal_True;
+ }
+
+#ifndef UNX
+ // only in non-unix version, we need to handle a -help request
+ // in a running instance in order to display the command line help
+ if ( aCmdLineArgs->IsHelp() ) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty, "HELP", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+#endif
+
+ sal_Bool bDocRequestSent = sal_False;
+ ProcessDocumentsRequest* pRequest = new ProcessDocumentsRequest(
+ aCmdLineArgs->getCwdUrl());
+ cProcessed.reset();
+ pRequest->pcProcessed = &cProcessed;
+
+ // Print requests are not dependent on the -invisible cmdline argument as they are
+ // loaded with the "hidden" flag! So they are always checked.
+ bDocRequestSent |= aCmdLineArgs->GetPrintList( pRequest->aPrintList );
+ bDocRequestSent |= ( aCmdLineArgs->GetPrintToList( pRequest->aPrintToList ) &&
+ aCmdLineArgs->GetPrinterName( pRequest->aPrinterName ) );
+
+ if ( !pCurrentCmdLineArgs->IsInvisible() )
+ {
+ // Read cmdline args that can open/create documents. As they would open a window
+ // they are only allowed if the "-invisible" is currently not used!
+ bDocRequestSent |= aCmdLineArgs->GetOpenList( pRequest->aOpenList );
+ bDocRequestSent |= aCmdLineArgs->GetViewList( pRequest->aViewList );
+ bDocRequestSent |= aCmdLineArgs->GetStartList( pRequest->aStartList );
+ bDocRequestSent |= aCmdLineArgs->GetForceOpenList( pRequest->aForceOpenList );
+ bDocRequestSent |= aCmdLineArgs->GetForceNewList( pRequest->aForceNewList );
+
+ // Special command line args to create an empty document for a given module
+
+ // #i18338# (lo)
+ // we only do this if no document was specified on the command line,
+ // since this would be inconsistent with the the behaviour of
+ // the first process, see OpenClients() (call to OpenDefault()) in app.cxx
+ if ( aCmdLineArgs->HasModuleParam() && Desktop::CheckOEM() && (!bDocRequestSent))
+ {
+ SvtModuleOptions aOpt;
+ SvtModuleOptions::EFactory eFactory = SvtModuleOptions::E_WRITER;
+ if ( aCmdLineArgs->IsWriter() )
+ eFactory = SvtModuleOptions::E_WRITER;
+ else if ( aCmdLineArgs->IsCalc() )
+ eFactory = SvtModuleOptions::E_CALC;
+ else if ( aCmdLineArgs->IsDraw() )
+ eFactory = SvtModuleOptions::E_DRAW;
+ else if ( aCmdLineArgs->IsImpress() )
+ eFactory = SvtModuleOptions::E_IMPRESS;
+ else if ( aCmdLineArgs->IsBase() )
+ eFactory = SvtModuleOptions::E_DATABASE;
+ else if ( aCmdLineArgs->IsMath() )
+ eFactory = SvtModuleOptions::E_MATH;
+ else if ( aCmdLineArgs->IsGlobal() )
+ eFactory = SvtModuleOptions::E_WRITERGLOBAL;
+ else if ( aCmdLineArgs->IsWeb() )
+ eFactory = SvtModuleOptions::E_WRITERWEB;
+
+ if ( pRequest->aOpenList.getLength() )
+ pRequest->aModule = aOpt.GetFactoryName( eFactory );
+ else
+ AddURLToStringList( aOpt.GetFactoryEmptyDocumentURL( eFactory ), pRequest->aOpenList );
+ bDocRequestSent = sal_True;
+ }
+ }
+
+ if (!aCmdLineArgs->IsQuickstart() && Desktop::CheckOEM()) {
+ sal_Bool bShowHelp = sal_False;
+ rtl::OUStringBuffer aHelpURLBuffer;
+ if (aCmdLineArgs->IsHelpWriter()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
+ } else if (aCmdLineArgs->IsHelpCalc()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
+ } else if (aCmdLineArgs->IsHelpDraw()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
+ } else if (aCmdLineArgs->IsHelpImpress()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
+ } else if (aCmdLineArgs->IsHelpBase()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
+ } else if (aCmdLineArgs->IsHelpBasic()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
+ } else if (aCmdLineArgs->IsHelpMath()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
+ }
+ if (bShowHelp) {
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
+ rtl::OUString aTmp;
+ aRet >>= aTmp;
+ aHelpURLBuffer.appendAscii("?Language=");
+ aHelpURLBuffer.append(aTmp);
+#if defined UNX
+ aHelpURLBuffer.appendAscii("&System=UNX");
+#elif defined WNT
+ aHelpURLBuffer.appendAscii("&System=WIN");
+#elif defined MAC
+ aHelpURLBuffer.appendAscii("&System=MAC");
+#elif defined OS2
+ aHelpURLBuffer.appendAscii("&System=OS2");
+#endif
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "OPENHELPURL", aHelpURLBuffer.makeStringAndClear());
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ }
+
+ if ( bDocRequestSent && Desktop::CheckOEM())
+ {
+ // Send requests to dispatch watcher if we have at least one. The receiver
+ // is responsible to delete the request after processing it.
+ if ( aCmdLineArgs->HasModuleParam() )
+ {
+ SvtModuleOptions aOpt;
+
+ // Support command line parameters to start a module (as preselection)
+ if ( aCmdLineArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
+ else if ( aCmdLineArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
+ else if ( aCmdLineArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
+ else if ( aCmdLineArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
+ }
+
+
+ ImplPostProcessDocumentsEvent( pRequest );
+ }
+ else
+ {
+ // delete not used request again
+ delete pRequest;
+ pRequest = NULL;
+ }
+ if (( aArguments.CompareTo( sc_aShowSequence, sc_nShSeqLength ) == COMPARE_EQUAL ) ||
+ aCmdLineArgs->IsEmpty() )
+ {
+ // no document was sent, just bring Office to front
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty, "APPEAR", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+ // we don't need the mutex any longer...
+ aGuard.clear();
+ // wait for processing to finish
+ if (bDocRequestSent)
+ cProcessed.wait();
+ // processing finished, inform the requesting end
+ nBytes = 0;
+ while (
+ (nResult = maStreamPipe.send(sc_aConfirmationSequence+nBytes, sc_nCSeqLength-nBytes))>0 &&
+ ((nBytes += nResult) < sc_nCSeqLength) ) ;
+ // now we can close, don't we?
+ // maStreamPipe.close();
+
+ }
+ else
+ {
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ fprintf( stderr, "Error on accept: %d\n", (int)nError );
+#endif
+ TimeValue tval;
+ tval.Seconds = 1;
+ tval.Nanosec = 0;
+ sleep( tval );
+ }
+ } while( schedule() );
+}
+
+static void AddToDispatchList(
+ DispatchWatcher::DispatchList& rDispatchList,
+ boost::optional< rtl::OUString > const & cwdUrl,
+ const OUString& aRequestList,
+ DispatchWatcher::RequestType nType,
+ const OUString& aParam,
+ const OUString& aFactory )
+{
+ if ( aRequestList.getLength() > 0 )
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = aRequestList.getToken( 0, APPEVENT_PARAM_DELIMITER, nIndex );
+ if ( aToken.getLength() > 0 )
+ rDispatchList.push_back(
+ DispatchWatcher::DispatchRequest( nType, aToken, cwdUrl, aParam, aFactory ));
+ }
+ while ( nIndex >= 0 );
+ }
+}
+
+sal_Bool OfficeIPCThread::ExecuteCmdLineRequests( ProcessDocumentsRequest& aRequest )
+{
+ // protect the dispatch list
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ static DispatchWatcher::DispatchList aDispatchList;
+
+ rtl::OUString aEmpty;
+ // Create dispatch list for dispatch watcher
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aOpenList, DispatchWatcher::REQUEST_OPEN, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aViewList, DispatchWatcher::REQUEST_VIEW, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aStartList, DispatchWatcher::REQUEST_START, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aPrintList, DispatchWatcher::REQUEST_PRINT, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aPrintToList, DispatchWatcher::REQUEST_PRINTTO, aRequest.aPrinterName, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aForceOpenList, DispatchWatcher::REQUEST_FORCEOPEN, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aForceNewList, DispatchWatcher::REQUEST_FORCENEW, aEmpty, aRequest.aModule );
+
+ sal_Bool bShutdown( sal_False );
+
+ if ( pGlobalOfficeIPCThread )
+ {
+ if( ! pGlobalOfficeIPCThread->AreRequestsEnabled() )
+ return bShutdown;
+
+ pGlobalOfficeIPCThread->mnPendingRequests += aDispatchList.size();
+ if ( !pGlobalOfficeIPCThread->mpDispatchWatcher )
+ {
+ pGlobalOfficeIPCThread->mpDispatchWatcher = DispatchWatcher::GetDispatchWatcher();
+ pGlobalOfficeIPCThread->mpDispatchWatcher->acquire();
+ }
+
+ // copy for execute
+ DispatchWatcher::DispatchList aTempList( aDispatchList );
+ aDispatchList.clear();
+
+ aGuard.clear();
+
+ // Execute dispatch requests
+ bShutdown = pGlobalOfficeIPCThread->mpDispatchWatcher->executeDispatchRequests( aTempList, s_bInEnableRequests );
+
+ // set processed flag
+ if (aRequest.pcProcessed != NULL)
+ aRequest.pcProcessed->set();
+ }
+
+ return bShutdown;
+}
+
+}
diff --git a/desktop/source/app/officeipcthread.hxx b/desktop/source/app/officeipcthread.hxx
new file mode 100644
index 000000000000..2cbcab0fce2a
--- /dev/null
+++ b/desktop/source/app/officeipcthread.hxx
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_OFFICEIPCTHREAD_HXX_
+#define _DESKTOP_OFFICEIPCTHREAD_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
+#include <vos/pipe.hxx>
+#include <vos/security.hxx>
+#include <vos/thread.hxx>
+#include <vos/signal.hxx>
+#include <rtl/ustring.hxx>
+#ifndef _CPPUHELPER_WEAKBASE2_HXX_
+#include <cppuhelper/implbase2.hxx>
+#endif
+#include <osl/conditn.hxx>
+#include "boost/optional.hpp"
+
+namespace desktop
+{
+
+class SalMainPipeExchangeSignalHandler : public vos::OSignalHandler
+{
+ virtual TSignalAction SAL_CALL signal(TSignalInfo *pInfo);
+};
+
+// A request for the current office
+// that was given by command line or by IPC pipe communication.
+struct ProcessDocumentsRequest
+{
+ ProcessDocumentsRequest(boost::optional< rtl::OUString > const & cwdUrl):
+ aCwdUrl(cwdUrl), pcProcessed( NULL ) {}
+
+ boost::optional< ::rtl::OUString > aCwdUrl;
+ ::rtl::OUString aModule;
+ ::rtl::OUString aOpenList; // Documents that should be opened in the default way
+ ::rtl::OUString aViewList; // Documents that should be opened in viewmode
+ ::rtl::OUString aStartList; // Documents/Presentations that should be started
+ ::rtl::OUString aPrintList; // Documents that should be printed on default printer
+ ::rtl::OUString aForceOpenList; // Documents that should be forced to open for editing (even templates)
+ ::rtl::OUString aForceNewList; // Documents that should be forced to create a new document
+ ::rtl::OUString aPrinterName; // The printer name that should be used for printing
+ ::rtl::OUString aPrintToList; // Documents that should be printed on the given printer
+ ::osl::Condition *pcProcessed; // pointer condition to be set when the request has been processed
+};
+
+class DispatchWatcher;
+class OfficeIPCThread : public vos::OThread
+{
+ private:
+ static OfficeIPCThread* pGlobalOfficeIPCThread;
+ static ::osl::Mutex* pOfficeIPCThreadMutex;
+
+ vos::OPipe maPipe;
+ vos::OStreamPipe maStreamPipe;
+ rtl::OUString maPipeIdent;
+ bool mbDowning;
+ bool mbRequestsEnabled;
+ int mnPendingRequests;
+ DispatchWatcher* mpDispatchWatcher;
+
+ /* condition to be set when the request has been processed */
+ ::osl::Condition cProcessed;
+
+ /* condition to be set when the main event loop is ready
+ otherwise an error dialogs event loop could eat away
+ requests from a 2nd office */
+ ::osl::Condition cReady;
+
+ static ::osl::Mutex& GetMutex();
+ static const char *sc_aTerminationSequence;
+ static const int sc_nTSeqLength;
+ static const char *sc_aShowSequence;
+ static const int sc_nShSeqLength;
+ static const char *sc_aConfirmationSequence;
+ static const int sc_nCSeqLength;
+
+ OfficeIPCThread();
+
+ protected:
+ /// Working method which should be overridden
+ virtual void SAL_CALL run();
+
+ public:
+ enum Status
+ {
+ IPC_STATUS_OK,
+ IPC_STATUS_2ND_OFFICE,
+ IPC_STATUS_BOOTSTRAP_ERROR
+ };
+
+ virtual ~OfficeIPCThread();
+
+ // controlling pipe communication during shutdown
+ static void SetDowning();
+ static void EnableRequests( bool i_bEnable = true );
+ static sal_Bool AreRequestsPending();
+ static void RequestsCompleted( int n = 1 );
+ static sal_Bool ExecuteCmdLineRequests( ProcessDocumentsRequest& );
+
+ // return FALSE if second office
+ static Status EnableOfficeIPCThread();
+ static void DisableOfficeIPCThread();
+ // start dispatching events...
+ static void SetReady(OfficeIPCThread* pThread = NULL);
+
+ bool AreRequestsEnabled() const { return mbRequestsEnabled && ! mbDowning; }
+};
+
+
+class OfficeIPCThreadController : public ::cppu::WeakImplHelper2<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::frame::XTerminateListener >
+{
+ public:
+ OfficeIPCThreadController() {}
+ virtual ~OfficeIPCThreadController() {}
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XTerminateListener
+ virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent )
+ throw( ::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent )
+ throw( ::com::sun::star::uno::RuntimeException );
+};
+
+}
+
+#endif // _DESKTOP_OFFICEIPCTHREAD_HXX_
diff --git a/desktop/source/app/omutexmember.hxx b/desktop/source/app/omutexmember.hxx
new file mode 100644
index 000000000000..1edb90fec8c6
--- /dev/null
+++ b/desktop/source/app/omutexmember.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 __FRAMEWORK_OMUTEXMEMBER_HXX_
+#define __FRAMEWORK_OMUTEXMEMBER_HXX_
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+/*-************************************************************************************************************//**
+ @short definition of a public mutex member
+ @descr You can use this struct as baseclass to get a public mutex member for right initialization.
+ Don't use it as member. You can't guarantee the right order of initialization of baseclasses then!
+ And some other helper classes share the mutex with an implementation and must have a valid one.
+
+ @seealso See implementation of constructors in derived classes for further informations!
+
+ @devstatus ready
+*//*-*************************************************************************************************************/
+
+struct OMutexMember
+{
+ ::osl::Mutex m_aMutex;
+};
+
+#endif // #ifndef __FRAMEWORK_OMUTEXMEMBER_HXX_
diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
new file mode 100644
index 000000000000..fc06850f237a
--- /dev/null
+++ b/desktop/source/app/sofficemain.cxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "app.hxx"
+
+#include <rtl/logfile.hxx>
+#include <tools/extendapplicationenvironment.hxx>
+
+BOOL SVMain();
+
+// -=-= main() -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+extern "C" int soffice_main()
+{
+ tools::extendApplicationEnvironment();
+
+ RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Main()" );
+
+ desktop::Desktop aDesktop;
+ // This string is used during initialization of the Gtk+ VCL module
+ aDesktop.SetAppName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("soffice")) );
+ SVMain();
+
+ return 0;
+}
diff --git a/desktop/source/app/sofficemain.h b/desktop/source/app/sofficemain.h
new file mode 100644
index 000000000000..97775acd7016
--- /dev/null
+++ b/desktop/source/app/sofficemain.h
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_APP_SOFFICEMAIN_H
+#define INCLUDED_DESKTOP_SOURCE_APP_SOFFICEMAIN_H
+
+#include "sal/config.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+int soffice_main(void);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
diff --git a/desktop/source/app/userinstall.cxx b/desktop/source/app/userinstall.cxx
new file mode 100644
index 000000000000..546a6f0ad13c
--- /dev/null
+++ b/desktop/source/app/userinstall.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "userinstall.hxx"
+#include "langselect.hxx"
+
+#include <stdio.h>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+#include <osl/mutex.hxx>
+#include <osl/process.h>
+#include <osl/diagnose.h>
+#include <vos/security.hxx>
+#include <vos/ref.hxx>
+#include <vos/process.hxx>
+
+#ifndef _TOOLS_RESMGR_HXX_
+#include <tools/resmgr.hxx>
+#endif
+#include <unotools/bootstrap.hxx>
+#include <svl/languageoptions.hxx>
+#ifndef _SVTOOLS_SYSLOCALEOPTIONSOPTIONS_HXX
+#include <unotools/syslocaleoptions.hxx>
+#endif
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <i18npool/mslangid.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+#include "app.hxx"
+
+using namespace rtl;
+using namespace osl;
+using namespace utl;
+using namespace com::sun::star::container;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+
+namespace desktop {
+
+ static UserInstall::UserInstallError create_user_install(OUString&);
+
+ static bool is_user_install()
+ {
+ try
+ {
+ OUString sConfigSrvc(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationProvider" ) );
+ OUString sAccessSrvc(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess" ) );
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF
+ = comphelper::getProcessServiceFactory();
+ Reference< XMultiServiceFactory > theConfigProvider
+ = Reference< XMultiServiceFactory >(
+ theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ // localize the provider to user selection
+// Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW);
+// LanguageType aUserLanguageType = LanguageSelection::getLanguageType();
+// Locale aLocale( MsLangId::convertLanguageToIsoString(aUserLanguageType));
+// localizable->setLocale(aLocale);
+
+ Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW);
+ OUString aUserLanguage = LanguageSelection::getLanguageString();
+ Locale aLocale = LanguageSelection::IsoStringToLocale(aUserLanguage);
+ localizable->setLocale(aLocale);
+
+ Sequence< Any > theArgs(1);
+ NamedValue v;
+ v.Name = OUString::createFromAscii("NodePath");
+ v.Value = makeAny(OUString::createFromAscii("org.openoffice.Setup"));
+ theArgs[0] <<= v;
+ Reference< XHierarchicalNameAccess> hnacc(
+ theConfigProvider->createInstanceWithArguments(
+ sAccessSrvc, theArgs), UNO_QUERY_THROW);
+
+ try
+ {
+ sal_Bool bValue = sal_False;
+ hnacc->getByHierarchicalName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Office/ooSetupInstCompleted" ) ) ) >>= bValue;
+
+ return bValue ? true : false;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ // just return false in this case.
+ }
+ }
+ catch (Exception const & e)
+ {
+ OString msg(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US));
+ OSL_ENSURE(sal_False, msg.getStr());
+ }
+
+ return false;
+ }
+
+ UserInstall::UserInstallError UserInstall::finalize()
+ {
+ OUString aUserInstallPath;
+ utl::Bootstrap::PathStatus aLocateResult =
+ utl::Bootstrap::locateUserInstallation(aUserInstallPath);
+
+ switch (aLocateResult) {
+
+ case utl::Bootstrap::DATA_INVALID:
+ case utl::Bootstrap::DATA_MISSING:
+ case utl::Bootstrap::DATA_UNKNOWN:
+ // cannot find a valid path or path is missing
+ return E_Unknown;
+
+ case utl::Bootstrap::PATH_EXISTS:
+ {
+ // path exists, check if an installation lives there
+ if ( is_user_install() )
+ {
+ return E_None;
+ }
+ // Note: fall-thru intended.
+ }
+ case utl::Bootstrap::PATH_VALID:
+ // found a path but need to create user install
+ return create_user_install(aUserInstallPath);
+ default:
+ return E_Unknown;
+ }
+ }
+
+ static osl::FileBase::RC copy_recursive( const rtl::OUString& srcUnqPath, const rtl::OUString& dstUnqPath)
+ {
+
+ FileBase::RC err;
+ DirectoryItem aDirItem;
+ DirectoryItem::get(srcUnqPath, aDirItem);
+ FileStatus aFileStatus(FileStatusMask_All);
+ aDirItem.getFileStatus(aFileStatus);
+
+ if( aFileStatus.getFileType() == FileStatus::Directory)
+ {
+ // create directory if not already there
+ err = Directory::create( dstUnqPath );
+ if (err == osl::FileBase::E_EXIST)
+ err = osl::FileBase::E_None;
+
+ FileBase::RC next = err;
+ if (err == osl::FileBase::E_None)
+ {
+ // iterate through directory contents
+ Directory aDir( srcUnqPath );
+ aDir.open();
+ while (err == osl::FileBase::E_None &&
+ (next = aDir.getNextItem( aDirItem )) == osl::FileBase::E_None)
+ {
+ aDirItem.getFileStatus(aFileStatus);
+ // generate new src/dst pair and make recursive call
+ rtl::OUString newSrcUnqPath = aFileStatus.getFileURL();
+ rtl::OUString newDstUnqPath = dstUnqPath;
+ rtl::OUString itemname = aFileStatus.getFileName();
+ // append trailing '/' if needed
+ if (newDstUnqPath.lastIndexOf(sal_Unicode('/')) != newDstUnqPath.getLength()-1)
+ newDstUnqPath += rtl::OUString::createFromAscii("/");
+ newDstUnqPath += itemname;
+ // recursion
+ err = copy_recursive(newSrcUnqPath, newDstUnqPath);
+ }
+ aDir.close();
+
+ if ( err != osl::FileBase::E_None )
+ return err;
+ if( next != FileBase::E_NOENT )
+ err = FileBase::E_INVAL;
+ }
+ }
+ else
+ {
+ // copy single file - foldback
+ err = File::copy( srcUnqPath,dstUnqPath );
+ }
+ return err;
+ }
+
+ static const char *pszSrcList[] = {
+ "/presets",
+ NULL
+ };
+ static const char *pszDstList[] = {
+ "/user",
+ NULL
+ };
+
+
+ static UserInstall::UserInstallError create_user_install(OUString& aUserPath)
+ {
+ OUString aBasePath;
+ if (utl::Bootstrap::locateBaseInstallation(aBasePath) != utl::Bootstrap::PATH_EXISTS)
+ return UserInstall::E_InvalidBaseinstall;
+
+ // create the user directory
+ FileBase::RC rc = Directory::createPath(aUserPath);
+ if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) return UserInstall::E_Creation;
+
+ // copy data from shared data directory of base installation
+ for (sal_Int32 i=0; pszSrcList[i]!=NULL && pszDstList[i]!=NULL; i++)
+ {
+ rc = copy_recursive(
+ aBasePath + OUString::createFromAscii(pszSrcList[i]),
+ aUserPath + OUString::createFromAscii(pszDstList[i]));
+ if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST))
+ {
+ if ( rc == FileBase::E_NOSPC )
+ return UserInstall::E_NoDiskSpace;
+ else if ( rc == FileBase::E_ACCES )
+ return UserInstall::E_NoWriteAccess;
+ else
+ return UserInstall::E_Creation;
+ }
+ }
+ try
+ {
+ OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
+ OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"), makeAny(OUString::createFromAscii("org.openoffice.Setup")));
+ //v.Name = OUString::createFromAscii("NodePath");
+ //v.Value = makeAny(OUString::createFromAscii("org.openoffice.Setup"));
+ theArgs[0] <<= v;
+ Reference< XHierarchicalPropertySet> hpset(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ hpset->setHierarchicalPropertyValue(OUString::createFromAscii("Office/ooSetupInstCompleted"), makeAny(sal_True));
+ Reference< XChangesBatch >(hpset, UNO_QUERY_THROW)->commitChanges();
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch (Exception& e)
+ {
+ OString aMsg("create_user_install(): ");
+ aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ return UserInstall::E_Creation;
+ }
+
+ return UserInstall::E_None;
+
+ }
+}
+
+
diff --git a/desktop/source/app/userinstall.hxx b/desktop/source/app/userinstall.hxx
new file mode 100644
index 000000000000..8d6a51cd66be
--- /dev/null
+++ b/desktop/source/app/userinstall.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <sal/types.h>
+#include <rtl/ustring.hxx>
+
+namespace desktop
+{
+
+class UserInstall
+{
+public:
+ enum UserInstallError {
+ E_None, // no error
+ E_Creation, // error while creating user install
+ E_InvalidBaseinstall, // corrupt base installation
+ E_SetupFailed, // external setup did not run correctly
+ E_Configuration, // error while accessing configuration
+ E_License, // License not accepted
+ E_NoDiskSpace, // not enough disk space
+ E_NoWriteAccess, // no write access
+ E_Unknown // unknown error
+ };
+
+ static UserInstallError finalize();
+};
+}
diff --git a/desktop/source/app/version.map b/desktop/source/app/version.map
new file mode 100644
index 000000000000..0ffffcd58635
--- /dev/null
+++ b/desktop/source/app/version.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ soffice_main;
+
+ local:
+ *;
+};
diff --git a/desktop/source/deployment/dp_log.cxx b/desktop/source/deployment/dp_log.cxx
new file mode 100644
index 000000000000..44c5e1efd4ed
--- /dev/null
+++ b/desktop/source/deployment/dp_log.cxx
@@ -0,0 +1,211 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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..d93c5a52c782
--- /dev/null
+++ b/desktop/source/deployment/dp_persmap.cxx
@@ -0,0 +1,253 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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() ) );
+ }
+}
+
+//______________________________________________________________________________
+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, RTL_TEXTENCODING_UTF8 ) );
+ 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..f7ebf66355ba
--- /dev/null
+++ b/desktop/source/deployment/dp_services.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+
+#define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 12
+#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& );
+}
+extern sdecl::ServiceDecl const serviceDecl;
+bool singleton_entries( uno::Reference<registry::XRegistryKey> const& );
+}
+
+namespace dp_log {
+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_info::serviceDecl,
+ dp_manager::serviceDecl) &&
+ dp_manager::factory::singleton_entries( pRegistryKey ) &&
+ dp_info::singleton_entries( pRegistryKey ) &&
+ dp_manager::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_info::serviceDecl,
+ dp_manager::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..65c48d70c92d
--- /dev/null
+++ b/desktop/source/deployment/dp_xml.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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::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 );
+ }
+
+//==============================================================================
+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 );
+}
+
+}
diff --git a/desktop/source/deployment/gui/descedit.cxx b/desktop/source/deployment/gui/descedit.cxx
new file mode 100644
index 000000000000..5df203c60fc9
--- /dev/null
+++ b/desktop/source/deployment/gui/descedit.cxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <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..023551ac360d
--- /dev/null
+++ b/desktop/source/deployment/gui/descedit.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..092b232ce96d
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui.h
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_H
+#define INCLUDED_DP_GUI_H
+
+#include "dp_gui_updatedata.hxx"
+#include "dp_misc.h"
+#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)
+ : m_xPackage( xPackage )
+ {}
+
+ virtual ~SelectedPackage();
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> getPackage() const { return m_xPackage; }
+
+private:
+ SelectedPackage(SelectedPackage &); // not defined
+ void operator =(SelectedPackage &); // not defined
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage;
+};
+
+} // 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 100755
index 000000000000..5f52b042edf3
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui.hrc
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_IMG_SHARED (RID_DEPLOYMENT_GUI_START+62)
+#define RID_IMG_SHARED_HC (RID_DEPLOYMENT_GUI_START+63)
+
+#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_ACCEPT_LICENSE (RID_DEPLOYMENT_GUI_START+89)
+
+#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 RID_STR_ERROR_MISSING_LICENSE (RID_DEPLOYMENT_GUI_START+97)
+
+#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
+
+
+
+#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..ce69797db0a8
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/svmedit2.hxx"
+#include "svl/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..421b00517998
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_AUTOSCROLLEDIT_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_AUTOSCROLLEDIT_HXX
+
+#include "svtools/svmedit2.hxx"
+#include "svl/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..4d554ab4ded9
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_backend.src
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..4c5dfdfc89d4
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.cxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <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..98cb7de7a04f
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..fa7465678326
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.src
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 (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 100755
index 000000000000..15823288ee20
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog.src
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+
+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_ACCEPT_LICENSE
+{
+ Text [ en-US ] = "Accept license for %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:";
+};
+
+String RID_STR_ERROR_MISSING_LICENSE
+{
+ Text [ en-US ] = "This extension is disabled because you haven't accepted the license yet.\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 3*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 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 100755
index 000000000000..87f70e449b9d
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.cxx
@@ -0,0 +1,1776 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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_gui_extensioncmdqueue.hxx"
+#include "dp_misc.h"
+#include "dp_update.hxx"
+#include "dp_identifier.hxx"
+
+#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 <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 TOP_OFFSET 5
+#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;
+ }
+};
+
+//------------------------------------------------------------------------------
+// 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 ) );
+ SetButtonStatus( GetEntryData( 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 );
+}
+
+// -----------------------------------------------------------------------
+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 )
+{
+ bool bShowOptionBtn = true;
+
+ pEntry->m_bHasButtons = false;
+ 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 );
+ bShowOptionBtn = false;
+ }
+
+ if ( ( !pEntry->m_bUser || ( pEntry->m_eState == NOT_AVAILABLE ) || pEntry->m_bMissingDeps )
+ && !pEntry->m_bMissingLic )
+ m_pEnableBtn->Hide();
+ else
+ {
+ m_pEnableBtn->Enable( !pEntry->m_bLocked );
+ m_pEnableBtn->Show();
+ pEntry->m_bHasButtons = true;
+ }
+
+ if ( pEntry->m_bHasOptions && bShowOptionBtn )
+ {
+ m_pOptionsBtn->Enable( pEntry->m_bHasOptions );
+ m_pOptionsBtn->Show();
+ pEntry->m_bHasButtons = true;
+ }
+ else
+ m_pOptionsBtn->Hide();
+
+ if ( pEntry->m_bUser || pEntry->m_bShared )
+ {
+ m_pRemoveBtn->Enable( !pEntry->m_bLocked );
+ m_pRemoveBtn->Show();
+ pEntry->m_bHasButtons = true;
+ }
+ else
+ m_pRemoveBtn->Hide();
+}
+
+// -----------------------------------------------------------------------
+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_xPackage, true );
+ break;
+ case CMD_DISABLE: m_pParent->enablePackage( GetEntryData( nPos )->m_xPackage, false );
+ break;
+ case CMD_UPDATE: m_pParent->updatePackage( GetEntryData( nPos )->m_xPackage );
+ break;
+ case CMD_REMOVE: m_pParent->removePackage( 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 );
+
+ if ( pEntry->m_bMissingLic )
+ m_pParent->acceptLicense( pEntry->m_xPackage );
+ else
+ {
+ const bool bEnable( pEntry->m_eState != REGISTERED );
+ m_pParent->enablePackage( 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_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::XPackage > &xPackage )
+{
+ if ( xPackage->getRepositoryName().equals( OUSTR("shared") ) )
+ return true;
+ else
+ return false;
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::continueOnSharedExtension( const uno::Reference< deployment::XPackage > &xPackage,
+ Window *pParent,
+ const USHORT nResID,
+ bool &bHadWarning )
+{
+ if ( !bHadWarning && IsSharedPkgMgr( xPackage ) )
+ {
+ 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::setGetExtensionsURL( const ::rtl::OUString &rURL )
+{
+ m_aGetExtensions.SetURL( rURL );
+}
+
+//------------------------------------------------------------------------------
+long ExtMgrDialog::addPackageToList( const uno::Reference< deployment::XPackage > &xPackage,
+ bool bLicenseMissing )
+{
+ m_aUpdateBtn.Enable( true );
+ return m_pExtensionBox->addEntry( xPackage, bLicenseMissing );
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::prepareChecking()
+{
+ m_pExtensionBox->prepareChecking();
+}
+
+//------------------------------------------------------------------------------
+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::XPackage > &xPackage,
+ bool bEnable )
+{
+ if ( !xPackage.is() )
+ return false;
+
+ if ( bEnable )
+ {
+ if ( ! continueOnSharedExtension( xPackage, this, RID_WARNINGBOX_ENABLE_SHARED_EXTENSION, m_bEnableWarning ) )
+ return false;
+ }
+ else
+ {
+ if ( ! continueOnSharedExtension( xPackage, this, RID_WARNINGBOX_DISABLE_SHARED_EXTENSION, m_bDisableWarning ) )
+ return false;
+ }
+
+ m_pManager->getCmdQueue()->enableExtension( xPackage, bEnable );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::removePackage( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return false;
+
+ if ( !IsSharedPkgMgr( xPackage ) || m_bDeleteWarning )
+ {
+ if ( ! removeExtensionWarn( xPackage->getDisplayName() ) )
+ return false;
+ }
+
+ if ( ! continueOnSharedExtension( xPackage, this, RID_WARNINGBOX_REMOVE_SHARED_EXTENSION, m_bDeleteWarning ) )
+ return false;
+
+ m_pManager->getCmdQueue()->removeExtension( xPackage );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::updatePackage( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return false;
+
+ // get the extension with highest version
+ uno::Sequence<uno::Reference<deployment::XPackage> > seqExtensions =
+ m_pManager->getExtensionManager()->getExtensionsWithSameIdentifier(
+ dp_misc::getIdentifier(xPackage), xPackage->getName(), uno::Reference<ucb::XCommandEnvironment>());
+ uno::Reference<deployment::XPackage> extension =
+ dp_misc::getExtensionWithHighestVersion(seqExtensions);
+ OSL_ASSERT(extension.is());
+ std::vector< css::uno::Reference< css::deployment::XPackage > > vEntries;
+ vEntries.push_back(extension);
+
+ m_pManager->getCmdQueue()->checkForUpdates( vEntries );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::acceptLicense( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return false;
+
+ m_pManager->getCmdQueue()->acceptLicense( xPackage );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< OUString > ExtMgrDialog::raiseAddPicker()
+{
+ 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(
+ m_pManager->getExtensionManager()->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::Sequence< OUString > aFileList = raiseAddPicker();
+
+ 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;
+ Rectangle aControlRegion( Point( 0, 0 ), m_aProgressBar.GetSizePixel() );
+ Rectangle aNativeControlRegion, aNativeContentRegion;
+ if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) ) != FALSE )
+ {
+ nProgressHeight = aNativeControlRegion.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,
+ bool bLicenseMissing )
+{
+ // We will only add entries to the list with unsatisfied dependencies
+ if ( !bLicenseMissing && !checkDependencies( xPackage ) )
+ {
+ m_bHasLockedEntries |= m_pManager->isReadOnly( xPackage );
+ m_aUpdateBtn.Enable( true );
+ return m_pExtensionBox->addEntry( xPackage );
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::prepareChecking()
+{
+ m_pExtensionBox->prepareChecking();
+}
+
+//------------------------------------------------------------------------------
+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::XPackage > &xPackage,
+ bool bEnable )
+{
+ m_pManager->getCmdQueue()->enableExtension( 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< uno::Reference< deployment::XPackage > > vUpdateEntries;
+ sal_Int32 nCount = m_pExtensionBox->GetEntryCount();
+
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( i );
+ vUpdateEntries.push_back( pEntry->m_xPackage );
+ }
+
+ aGuard.clear();
+
+ m_pManager->getCmdQueue()->checkForUpdates( 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;
+ Rectangle aControlRegion( Point( 0, 0 ), m_aProgressBar.GetSizePixel() );
+ Rectangle aNativeControlRegion, aNativeContentRegion;
+ if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) ) != FALSE )
+ {
+ nProgressHeight = aNativeControlRegion.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_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 100755
index 000000000000..f0a85cce98c0
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.hxx
@@ -0,0 +1,266 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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/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 > &xPackage,
+ bool bLicenseMissing = false ) = 0;
+
+ virtual void prepareChecking() = 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::XPackage > &);
+ static bool continueOnSharedExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &,
+ 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 );
+ virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &,
+ bool bLicenseMissing = false );
+ 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::XPackage > &xPackage );
+ bool updatePackage(const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ bool acceptLicense(const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ virtual void prepareChecking();
+ virtual void checkEntries();
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker();
+};
+
+//==============================================================================
+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 > &,
+ bool bLicenseMissing = false );
+ bool enablePackage( 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::XPackage > &xPackage );
+
+ virtual void prepareChecking();
+ virtual void checkEntries();
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker();
+
+ 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..7c47365999a0
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.src
@@ -0,0 +1,252 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+
+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 = "lock_16.png"; };
+};
+
+Image RID_IMG_LOCKED_HC
+{
+ ImageBitmap = Bitmap { File = "lock_16_h.png"; };
+};
+
+Image RID_IMG_SHARED
+{
+ ImageBitmap = Bitmap { File = "shared_16.png"; };
+};
+
+Image RID_IMG_SHARED_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 100755
index 000000000000..8bd8a6191201
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
@@ -0,0 +1,1212 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/NamedValue.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/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/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 "comphelper/processfactory.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( OUString const & sVersion )
+{
+ return ( sVersion.getLength() == 0 ) ? OUString( RTL_CONSTASCII_USTRINGPARAM( "0" ) ) : sVersion;
+}
+
+OUString getVersion( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ return getVersion( rPackage->getVersion());
+}
+}
+
+
+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, ACCEPT_LICENSE };
+
+ E_CMD_TYPE m_eCmdType;
+ bool m_bWarnUser;
+ OUString m_sExtensionURL;
+ OUString m_sRepository;
+ uno::Reference< deployment::XPackage > m_xPackage;
+ std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList;
+
+ ExtensionCmd( const E_CMD_TYPE eCommand,
+ const OUString &rExtensionURL,
+ const OUString &rRepository,
+ const bool bWarnUser )
+ : m_eCmdType( eCommand ),
+ m_bWarnUser( bWarnUser ),
+ m_sExtensionURL( rExtensionURL ),
+ m_sRepository( rRepository ) {};
+ 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<uno::Reference<deployment::XPackage > > &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 OUString &rExtensionURL,
+ const OUString &rRepository,
+ const bool bWarnUser );
+ void removeExtension( const uno::Reference< deployment::XPackage > &rPackage );
+ void enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
+ const bool bEnable );
+ void checkForUpdates( const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList );
+ void acceptLicense( const uno::Reference< deployment::XPackage > &rPackage );
+ void stop();
+ 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 OUString &rPackageURL,
+ const OUString &rRepository,
+ const bool bWarnUser );
+ void _removeExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ 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<uno::Reference<deployment::XPackage > > &vExtensionList );
+ void _acceptLicense( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage );
+
+ 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;
+ const OUString m_sAcceptLicense;
+ 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::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 >>= licExc)
+ {
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ deployment::ui::LicenseDialog::create(
+ m_xContext, VCLUnoHelper::GetInterface( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL ),
+ licExc.ExtensionName, 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::compareVersions(
+ verExc.NewVersion, verExc.Deployed->getVersion() ))
+ {
+ 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.Deployed.is() );
+ bool bEqualNames = verExc.NewDisplayName.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.NewDisplayName);
+ s.SearchAndReplaceAllAscii( "$OLDNAME", verExc.Deployed->getDisplayName());
+ s.SearchAndReplaceAllAscii( "$NEW", getVersion(verExc.NewVersion) );
+ 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.displayName );
+ }
+ 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_sAcceptLicense( DialogHelper::getResourceString( RID_STR_ACCEPT_LICENSE ) ),
+ m_eInput( NONE ),
+ m_bTerminated( false ),
+ m_bStopped( false ),
+ m_bWorking( false )
+{
+ OSL_ASSERT( pDialogHelper );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::addExtension( const ::rtl::OUString &rExtensionURL,
+ const ::rtl::OUString &rRepository,
+ 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, rExtensionURL, rRepository, bWarnUser ) );
+
+ m_queue.push( pEntry );
+ m_eInput = START;
+ m_wakeup.set();
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::removeExtension( 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 ( rPackage.is() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::REMOVE, rPackage ) );
+
+ m_queue.push( pEntry );
+ m_eInput = START;
+ m_wakeup.set();
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::acceptLicense( 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 ( rPackage.is() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::ACCEPT_LICENSE, 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<uno::Reference<deployment::XPackage > > &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::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_sExtensionURL, pEntry->m_sRepository, pEntry->m_bWarnUser );
+ break;
+ case ExtensionCmd::REMOVE :
+ _removeExtension( currentCmdEnv, 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;
+ case ExtensionCmd::ACCEPT_LICENSE :
+ _acceptLicense( currentCmdEnv, pEntry->m_xPackage );
+ 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 OUString &rPackageURL,
+ const OUString &rRepository,
+ 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< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sAddingPackages, OUSTR("%EXTENSION_NAME"), sName );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xExtMgr->addExtension(rPackageURL, uno::Sequence<beans::NamedValue>(),
+ rRepository, xAbortChannel, rCmdEnv.get() );
+ }
+ 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::XPackage > &xPackage )
+{
+ uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sRemovingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ OUString id( dp_misc::getIdentifier( xPackage ) );
+ try
+ {
+ xExtMgr->removeExtension( id, xPackage->getName(), xPackage->getRepositoryName(), xAbortChannel, rCmdEnv.get() );
+ }
+ catch ( deployment::DeploymentException & )
+ {}
+ catch ( ucb::CommandFailedException & )
+ {}
+ 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<uno::Reference<deployment::XPackage > > &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< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sEnablingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xExtMgr->enableExtension( xPackage, 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< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sDisablingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xExtMgr->disableExtension( xPackage, xAbortChannel, rCmdEnv.get() );
+ if ( m_pDialogHelper )
+ m_pDialogHelper->updatePackageInfo( xPackage );
+ }
+ catch ( ::ucb::CommandAbortedException & )
+ {}
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_acceptLicense( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return;
+
+ uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
+ uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sAcceptLicense, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xExtMgr->checkPrerequisitesAndEnable( xPackage, 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 ::rtl::OUString & extensionURL,
+ const ::rtl::OUString & repository,
+ const bool bWarnUser )
+{
+ m_thread->addExtension( extensionURL, repository, bWarnUser );
+}
+
+void ExtensionCmdQueue::removeExtension( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ m_thread->removeExtension( rPackage );
+}
+
+void ExtensionCmdQueue::enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
+ const bool bEnable )
+{
+ m_thread->enableExtension( rPackage, bEnable );
+}
+
+void ExtensionCmdQueue::checkForUpdates( const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
+{
+ m_thread->checkForUpdates( vExtensionList );
+}
+
+void ExtensionCmdQueue::acceptLicense( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ m_thread->acceptLicense( rPackage );
+}
+
+void ExtensionCmdQueue::syncRepositories( const uno::Reference< uno::XComponentContext > &xContext )
+{
+ dp_misc::syncRepositories( new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) );
+}
+
+void ExtensionCmdQueue::stop()
+{
+ m_thread->stop();
+}
+
+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 100755
index 000000000000..7ac00e2740d4
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 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 ::rtl::OUString &rExtensionURL,
+ const ::rtl::OUString &rRepository,
+ const bool bWarnUser );
+ void removeExtension( 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< ::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage > > &vList );
+ void acceptLicense( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage );
+ static void syncRepositories( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext );
+ /**
+ This call does not block. It signals the internal thread
+ that it should install the remaining extensions and then terminate.
+ */
+ void stop();
+
+ 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 100755
index 000000000000..24b47aa223e3
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
@@ -0,0 +1,1210 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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) )
+
+#define USER_PACKAGE_MANAGER OUSTR("user")
+#define SHARED_PACKAGE_MANAGER OUSTR("shared")
+#define BUNDLED_PACKAGE_MANAGER OUSTR("bundled")
+
+using namespace ::com::sun::star;
+
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+// struct Entry_Impl
+//------------------------------------------------------------------------------
+Entry_Impl::Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage,
+ const PackageState eState, const bool bReadOnly ) :
+ m_bActive( false ),
+ m_bLocked( bReadOnly ),
+ m_bHasOptions( false ),
+ m_bUser( false ),
+ m_bShared( false ),
+ m_bNew( false ),
+ m_bChecked( false ),
+ m_bMissingDeps( false ),
+ m_bHasButtons( false ),
+ m_bMissingLic( false ),
+ m_eState( eState ),
+ m_pPublisher( NULL ),
+ m_xPackage( xPackage )
+{
+ 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;
+
+ 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 )
+ {
+ sal_Int32 nCompare = m_xPackage->getRepositoryName().compareTo( pEntry->m_xPackage->getRepositoryName() );
+ 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_aSharedImage( DialogHelper::getResId( RID_IMG_SHARED ) ),
+ m_aSharedImageHC( DialogHelper::getResId( RID_IMG_SHARED_HC ) ),
+ 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 );
+ if ( aText.getLength() )
+ aText += OUSTR("\n");
+ 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;
+
+ if ( m_vEntries[ nPos ]->m_bHasButtons )
+ m_nActiveHeight = aTextHeight + m_nExtraHeight;
+ else
+ m_nActiveHeight = aTextHeight + 2;
+}
+
+//------------------------------------------------------------------------------
+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_bAdjustActive = true;
+ }
+ }
+
+ if ( IsReallyVisible() )
+ {
+ m_bNeedsRecalc = true;
+ 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_WIDTH ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
+ DrawImage( Point( aPos.X()+((ICON_WIDTH-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
+ else
+ DrawImage( aPos, Size( ICON_WIDTH, 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 )
+ {
+ long nExtraHeight = 0;
+
+ if ( pEntry->m_bHasButtons )
+ nExtraHeight = m_nExtraHeight;
+
+ DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - 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_bUser )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SMALL_ICON_SIZE), TOP_OFFSET );
+ if ( pEntry->m_bLocked )
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aLockedImageHC : m_aLockedImage );
+ else
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aSharedImageHC : m_aSharedImage );
+ }
+ if ( ( pEntry->m_eState == AMBIGUOUS ) || pEntry->m_bMissingDeps || pEntry->m_bMissingLic )
+ {
+ 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,
+ bool bLicenseMissing )
+{
+ long nPos = 0;
+ PackageState eState = m_pManager->getPackageState( xPackage );
+ bool bLocked = m_pManager->isReadOnly( xPackage );
+
+ TEntry_Impl pEntry( new Entry_Impl( xPackage, eState, bLocked ) );
+ xPackage->addEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ if ( m_vEntries.empty() )
+ {
+ m_vEntries.push_back( pEntry );
+ }
+ else
+ {
+ if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
+ {
+ m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
+ }
+ else if ( !m_bInCheckMode )
+ {
+ OSL_ENSURE( 0, "ExtensionBox_Impl::addEntry(): Will not add duplicate entries" );
+ }
+ }
+
+ pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ pEntry->m_bUser = xPackage->getRepositoryName().equals( USER_PACKAGE_MANAGER );
+ pEntry->m_bShared = xPackage->getRepositoryName().equals( SHARED_PACKAGE_MANAGER );
+ pEntry->m_bNew = m_bInCheckMode;
+ pEntry->m_bMissingLic = bLicenseMissing;
+
+ if ( bLicenseMissing )
+ pEntry->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_MISSING_LICENSE );
+
+ //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 == REGISTERED )
+ (*iIndex)->m_bMissingLic = false;
+
+ if ( eState == AMBIGUOUS )
+ (*iIndex)->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else if ( ! (*iIndex)->m_bMissingLic )
+ (*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()
+{
+ m_bInCheckMode = true;
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ (*iIndex)->m_bChecked = false;
+ (*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 )
+ {
+ (*iIndex)->m_bChecked = true;
+ bNeedsUpdate = true;
+ nPos = iIndex-m_vEntries.begin();
+ if ( (*iIndex)->m_bNew )
+ { // add entry to list and correct active pos
+ if ( nNewPos == - 1)
+ nNewPos = nPos;
+ if ( nPos <= m_nActive )
+ m_nActive += 1;
+ iIndex++;
+ }
+ else
+ { // remove entry from list
+ if ( nPos < m_nActive )
+ m_nActive -= 1;
+ else if ( ( nPos == m_nActive ) && ( nPos == (long) m_vEntries.size() - 1 ) )
+ m_nActive -= 1;
+ m_vRemovedEntries.push_back( *iIndex );
+ m_vEntries.erase( iIndex );
+ iIndex = m_vEntries.begin() + nPos;
+ }
+ }
+ else
+ 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)GetSettings().GetStyleSettings().GetHighContrastMode();
+}
+
+//------------------------------------------------------------------------------
+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 100755
index 000000000000..762f50296690
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx
@@ -0,0 +1,270 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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 <boost/shared_ptr.hpp>
+
+namespace dp_gui {
+
+#define SMALL_ICON_SIZE 16
+#define TOP_OFFSET 5
+#define ICON_HEIGHT 42
+#define ICON_WIDTH 47
+#define ICON_OFFSET 72
+#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 :1;
+ bool m_bLocked :1;
+ bool m_bHasOptions :1;
+ bool m_bUser :1;
+ bool m_bShared :1;
+ bool m_bNew :1;
+ bool m_bChecked :1;
+ bool m_bMissingDeps :1;
+ bool m_bHasButtons :1;
+ bool m_bMissingLic :1;
+ 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;
+
+ Entry_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ const PackageState eState, const bool bReadOnly );
+ ~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_aSharedImage;
+ Image m_aSharedImageHC;
+ 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,
+ bool bLicenseMissing = false );
+ 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();
+ 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 100755
index 000000000000..29bedf1b229f
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_service.cxx
@@ -0,0 +1,376 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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"
+#include "dp_gui_extensioncmdqueue.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 OOOVendor
+ : public rtl::Static< String, OOOVendor > {};
+ 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();
+ String &rOOOVendor = OOOVendor::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;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::OOOVENDOR );
+ aRet >>= aTmp;
+ rOOOVendor = 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( "%OOOVENDOR", rOOOVendor );
+ 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);
+ ExtensionCmdQueue::syncRepositories( m_xComponentContext );
+ }
+ }
+ 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..4fa94c5ca17c
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_shared.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..740f598499fe
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_system.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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..dfdbbdfc0831
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_system.hxx
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 100755
index 000000000000..d0347c7cbf4e
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx
@@ -0,0 +1,531 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+
+#include "vos/mutex.hxx"
+
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include "com/sun/star/beans/XPropertySet.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"
+#include "dp_update.hxx"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+#define USER_PACKAGE_MANAGER OUSTR("user")
+#define SHARED_PACKAGE_MANAGER OUSTR("shared")
+#define BUNDLED_PACKAGE_MANAGER OUSTR("bundled")
+
+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 ),
+ m_pExecuteCmdQueue( NULL )
+{
+ m_xExtensionManager = deployment::ExtensionManager::get( xContext );
+ m_xExtensionManager->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& )
+ {}
+
+ if ( dp_misc::office_is_running() )
+ {
+ // the registration should be done after the construction has been ended
+ // otherwise an exception prevents object creation, but it is registered as a listener
+ m_xDesktop.set( xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.frame.Desktop"), xContext ), uno::UNO_QUERY );
+ if ( m_xDesktop.is() )
+ m_xDesktop->addTerminateListener( this );
+ }
+}
+
+//------------------------------------------------------------------------------
+TheExtensionManager::~TheExtensionManager()
+{
+ if ( m_pUpdReqDialog )
+ delete m_pUpdReqDialog;
+ if ( m_pExtMgrDialog )
+ delete m_pExtMgrDialog;
+ if ( m_pExecuteCmdQueue )
+ delete m_pExecuteCmdQueue;
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::createDialog( const bool bCreateUpdDlg )
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+
+ if ( bCreateUpdDlg )
+ {
+ if ( !m_pUpdReqDialog )
+ {
+ m_pUpdReqDialog = new UpdateRequiredDialog( NULL, this );
+ delete m_pExecuteCmdQueue;
+ m_pExecuteCmdQueue = new ExtensionCmdQueue( (DialogHelper*) m_pUpdReqDialog, this, m_xContext );
+ createPackageList();
+ }
+ }
+ else if ( !m_pExtMgrDialog )
+ {
+ m_pExtMgrDialog = new ExtMgrDialog( m_pParent, this );
+ delete m_pExecuteCmdQueue;
+ m_pExecuteCmdQueue = 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< uno::Reference< deployment::XPackage > > vEntries;
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+
+ try {
+ xAllPackages = m_xExtensionManager->getAllExtensions( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ } catch ( deployment::DeploymentException & ) {
+ return false;
+ } catch ( ucb::CommandFailedException & ) {
+ return false;
+ } catch ( ucb::CommandAbortedException & ) {
+ return false;
+ } catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+
+ for ( sal_Int32 i = 0; i < xAllPackages.getLength(); ++i )
+ {
+ uno::Reference< deployment::XPackage > xPackage = dp_misc::getExtensionWithHighestVersion(xAllPackages[i]);
+ OSL_ASSERT(xPackage.is());
+ if ( xPackage.is() )
+ {
+ vEntries.push_back( xPackage );
+ }
+ }
+
+ m_pExecuteCmdQueue->checkForUpdates( vEntries );
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::installPackage( const OUString &rPackageURL, bool bWarnUser )
+{
+ if ( rPackageURL.getLength() == 0 )
+ return false;
+
+ createDialog( false );
+
+ bool bInstall = true;
+ bool bInstallForAll = false;
+
+ // DV! missing function is read only repository from extension manager
+ if ( !bWarnUser && ! m_xExtensionManager->isReadOnlyRepository( SHARED_PACKAGE_MANAGER ) )
+ bInstall = getDialogHelper()->installForAllUsers( bInstallForAll );
+
+ if ( !bInstall )
+ return false;
+
+ if ( bInstallForAll )
+ m_pExecuteCmdQueue->addExtension( rPackageURL, SHARED_PACKAGE_MANAGER, false );
+ else
+ m_pExecuteCmdQueue->addExtension( rPackageURL, USER_PACKAGE_MANAGER, 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();
+ }
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::createPackageList()
+{
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+
+ try {
+ xAllPackages = m_xExtensionManager->getAllExtensions( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ } catch ( deployment::DeploymentException & ) {
+ return;
+ } catch ( ucb::CommandFailedException & ) {
+ return;
+ } catch ( ucb::CommandAbortedException & ) {
+ return;
+ } catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+
+ for ( sal_Int32 i = 0; i < xAllPackages.getLength(); ++i )
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > xPackageList = xAllPackages[i];
+
+ for ( sal_Int32 j = 0; j < xPackageList.getLength(); ++j )
+ {
+ uno::Reference< deployment::XPackage > xPackage = xPackageList[j];
+ if ( xPackage.is() )
+ {
+ PackageState eState = getPackageState( xPackage );
+ getDialogHelper()->addPackageToList( xPackage );
+ // When the package is enabled, we can stop here, otherwise we have to look for
+ // another version of this package
+ if ( ( eState == REGISTERED ) || ( eState == NOT_AVAILABLE ) )
+ break;
+ }
+ }
+ }
+
+ uno::Sequence< uno::Reference< deployment::XPackage > > xNoLicPackages;
+ xNoLicPackages = m_xExtensionManager->getExtensionsWithUnacceptedLicenses( SHARED_PACKAGE_MANAGER,
+ uno::Reference< ucb::XCommandEnvironment >() );
+ for ( sal_Int32 i = 0; i < xNoLicPackages.getLength(); ++i )
+ {
+ uno::Reference< deployment::XPackage > xPackage = xNoLicPackages[i];
+ if ( xPackage.is() )
+ {
+ getDialogHelper()->addPackageToList( xPackage, true );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+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;
+ }
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::isReadOnly( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ if ( m_xExtensionManager.is() && xPackage.is() )
+ {
+ return m_xExtensionManager->isReadOnlyRepository( xPackage->getRepositoryName() );
+ }
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+// 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 )
+{
+ getDialogHelper()->prepareChecking();
+ createPackageList();
+ 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 100755
index 000000000000..094e25e249b7
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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/XExtensionManager.hpp"
+#include "com/sun/star/deployment/ExtensionManager.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::Reference< ::com::sun::star::deployment::XExtensionManager > m_xExtensionManager;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xNameAccessNodes;
+
+ Window *m_pParent;
+ ExtMgrDialog *m_pExtMgrDialog;
+ UpdateRequiredDialog *m_pUpdReqDialog;
+ ExtensionCmdQueue *m_pExecuteCmdQueue;
+
+ ::rtl::OUString m_sGetExtensionsURL;
+
+ void createPackageList();
+
+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; }
+ ExtensionCmdQueue* getCmdQueue() const { return m_pExecuteCmdQueue; }
+
+ void SetText( const ::rtl::OUString &rTitle );
+ void Show();
+ void ToTop( USHORT nFlags );
+ bool Close();
+ bool isVisible();
+
+ //-----------------
+ bool checkUpdates( bool showUpdateOnly, bool parentVisible );
+ 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::XExtensionManager > getExtensionManager() const { return m_xExtensionManager; }
+ bool isReadOnly( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+
+ //-----------------
+ 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..24055fae72f6
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_thread.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <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..ffcc2a5ddc54
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_thread.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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_updatedata.hxx b/desktop/source/deployment/gui/dp_gui_updatedata.hxx
new file mode 100644
index 000000000000..76eb8af31e8e
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedata.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 XPackage;
+}}}}
+namespace com { namespace sun { namespace star { namespace xml { namespace dom {
+ class XNode;
+}}}}}
+
+
+namespace dp_gui {
+
+struct UpdateData
+{
+ UpdateData( ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > const & aExt):
+ bIsShared(false), aInstalledPackage(aExt){};
+
+ //When entries added to the listbox then there can be one for the user update and one
+ //for the shared update. However, both list entries will contain the same UpdateData.
+ //isShared is used to indicate which one is used for the shared entry.
+ bool bIsShared;
+
+ //The currently installed extension which is going to be updated. If the extension exist in
+ //multiple repositories then it is the one with the highest version.
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > aInstalledPackage;
+
+ //The version of the update
+ ::rtl::OUString updateVersion;
+
+ //For online update
+ // ======================
+ // The content of the update information.
+ //Only if aUpdateInfo is set then there is an online update available with a better version
+ //than any of the currently installed extensions with the same identifier.
+ ::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;
+
+ //For local update
+ //=====================
+ //The locale extension which is used as update for the user or shared repository.
+ //If set then the data for the online update (aUpdateInfo, sLocalURL, sWebsiteURL)
+ //are to be ignored.
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage >
+ aUpdateSource;
+};
+}
+
+#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..b27cd8da81fe
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx
@@ -0,0 +1,1301 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/XExtensionManager.hpp"
+#include "com/sun/star/deployment/ExtensionManager.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_update.hxx"
+
+#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;
+ // 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< css::uno::Reference< css::deployment::XPackage > > & 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,
+ rtl::OUString const & theVersion);
+
+ css::uno::Reference< css::deployment::XPackage > package;
+ rtl::OUString version;
+ //Indicates that the extension provides its own update URLs.
+ //If this is true, then we must not use the default update
+ //URL to find the update information.
+ bool bProvidesOwnUpdate;
+ css::uno::Reference< css::xml::dom::XNode > info;
+ UpdateDialog::DisabledUpdate disableUpdate;
+ dp_gui::UpdateData updateData;
+ };
+
+ // A multimap in case an extension is installed in "user", "shared" or "bundled"
+ typedef std::map< rtl::OUString, Entry > Map;
+
+ virtual ~Thread();
+
+ virtual void execute();
+#if 0
+ void handleGeneralError(css::uno::Any const & exception) const;
+#endif
+ 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 getOwnUpdateInformation(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ Map * map);
+
+ ::rtl::OUString getUpdateDisplayString(
+ dp_gui::UpdateData const & data, ::rtl::OUString const & version = ::rtl::OUString()) const;
+
+ void prepareUpdateData(
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & updateInfo,
+ UpdateDialog::DisabledUpdate & out_du,
+ dp_gui::UpdateData & out_data) const;
+
+ bool update(
+ UpdateDialog::DisabledUpdate const & du,
+ dp_gui::UpdateData const & data) const;
+
+ css::uno::Reference< css::uno::XComponentContext > m_context;
+ UpdateDialog & m_dialog;
+ std::vector< css::uno::Reference< css::deployment::XPackage > > m_vExtensionList;
+ css::uno::Reference< css::deployment::XUpdateInformationProvider > m_updateInformation;
+ css::uno::Reference< css::task::XInteractionHandler > m_xInteractionHdl;
+
+ // 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< css::uno::Reference< css::deployment::XPackage > > &vExtensionList):
+ m_context(context),
+ m_dialog(dialog),
+ m_vExtensionList(vExtensionList),
+ m_updateInformation(
+ css::deployment::UpdateInformationProvider::create(context)),
+ m_stop(false)
+{
+ if( m_context.is() )
+ {
+ css::uno::Reference< css::lang::XMultiComponentFactory > xServiceManager( m_context->getServiceManager() );
+
+ if( xServiceManager.is() )
+ {
+ m_xInteractionHdl = css::uno::Reference< css::task::XInteractionHandler > (
+ xServiceManager->createInstanceWithContext( OUSTR( "com.sun.star.task.InteractionHandler" ), m_context),
+ css::uno::UNO_QUERY );
+ if ( m_xInteractionHdl.is() )
+ m_updateInformation->setInteractionHandler( m_xInteractionHdl );
+ }
+ }
+}
+
+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,
+ rtl::OUString const & theVersion):
+
+ package(thePackage),
+ version(theVersion),
+ bProvidesOwnUpdate(false),
+ updateData(thePackage)
+{
+}
+
+UpdateDialog::Thread::~Thread()
+{
+ if ( m_xInteractionHdl.is() )
+ m_updateInformation->setInteractionHandler( css::uno::Reference< css::task::XInteractionHandler > () );
+}
+
+void UpdateDialog::Thread::execute()
+{
+ {
+ vos::OGuard g( Application::GetSolarMutex() );
+ if ( m_stop ) {
+ return;
+ }
+ }
+ css::uno::Reference<css::deployment::XExtensionManager> extMgr =
+ css::deployment::ExtensionManager::get(m_context);
+
+ std::vector<std::pair<css::uno::Reference<css::deployment::XPackage>, css::uno::Any > > errors;
+
+ dp_misc::UpdateInfoMap updateInfoMap = dp_misc::getOnlineUpdateInfos(
+ m_context, extMgr, m_updateInformation, &m_vExtensionList, errors);
+
+ typedef std::vector<std::pair<css::uno::Reference<css::deployment::XPackage>,
+ css::uno::Any> >::const_iterator ITERROR;
+ for (ITERROR ite = errors.begin(); ite != errors.end(); ite ++)
+ handleSpecificError(ite->first, ite->second);
+
+ for (dp_misc::UpdateInfoMap::iterator i(updateInfoMap.begin()); i != updateInfoMap.end(); i++)
+ {
+ dp_misc::UpdateInfo const & info = i->second;
+ UpdateData updateData(info.extension);
+ DisabledUpdate disableUpdate;
+ //determine if online updates meet the requirements
+ prepareUpdateData(info.info, disableUpdate, updateData);
+
+ //determine if the update is installed in the user or shared repository
+ rtl::OUString sOnlineVersion;
+ if (info.info.is())
+ sOnlineVersion = info.version;
+ rtl::OUString sVersionUser;
+ rtl::OUString sVersionShared;
+ rtl::OUString sVersionBundled;
+ css::uno::Sequence< css::uno::Reference< css::deployment::XPackage> > extensions;
+ try {
+ extensions = extMgr->getExtensionsWithSameIdentifier(
+ dp_misc::getIdentifier(info.extension), info.extension->getName(),
+ css::uno::Reference<css::ucb::XCommandEnvironment>());
+ } catch (css::lang::IllegalArgumentException& ) {
+ OSL_ASSERT(0);
+ }
+ OSL_ASSERT(extensions.getLength() == 3);
+ if (extensions[0].is() )
+ sVersionUser = extensions[0]->getVersion();
+ if (extensions[1].is() )
+ sVersionShared = extensions[1]->getVersion();
+ if (extensions[2].is() )
+ sVersionBundled = extensions[2]->getVersion();
+
+ bool bSharedReadOnly = extMgr->isReadOnlyRepository(OUSTR("shared"));
+
+ dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
+ bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
+ dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
+ bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
+
+ css::uno::Reference<css::deployment::XPackage> updateSource;
+ if (sourceUser != dp_misc::UPDATE_SOURCE_NONE)
+ {
+ if (sourceUser == dp_misc::UPDATE_SOURCE_SHARED)
+ {
+ updateData.aUpdateSource = extensions[1];
+ updateData.updateVersion = extensions[1]->getVersion();
+ }
+ else if (sourceUser == dp_misc::UPDATE_SOURCE_BUNDLED)
+ {
+ updateData.aUpdateSource = extensions[2];
+ updateData.updateVersion = extensions[2]->getVersion();
+ }
+ if (!update(disableUpdate, updateData))
+ return;
+ }
+
+ if (sourceShared != dp_misc::UPDATE_SOURCE_NONE)
+ {
+ if (sourceShared == dp_misc::UPDATE_SOURCE_BUNDLED)
+ {
+ updateData.aUpdateSource = extensions[2];
+ updateData.updateVersion = extensions[2]->getVersion();
+ }
+ updateData.bIsShared = true;
+ if (!update(disableUpdate, updateData))
+ return;
+ }
+ }
+
+
+ vos::OGuard g(Application::GetSolarMutex());
+ if (!m_stop) {
+ m_dialog.checkingDone();
+ }
+}
+#if 0
+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);
+ }
+}
+#endif
+//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);
+ }
+}
+
+::rtl::OUString UpdateDialog::Thread::getUpdateDisplayString(
+ dp_gui::UpdateData const & data, ::rtl::OUString const & version) const
+{
+ OSL_ASSERT(data.aInstalledPackage.is());
+ rtl::OUStringBuffer b(data.aInstalledPackage->getDisplayName());
+ b.append(static_cast< sal_Unicode >(' '));
+ {
+ vos::OGuard g( Application::GetSolarMutex() );
+ if(!m_stop)
+ b.append(m_dialog.m_version);
+ }
+ b.append(static_cast< sal_Unicode >(' '));
+ if (version.getLength())
+ b.append(version);
+ else
+ b.append(data.updateVersion);
+
+ if (data.sWebsiteURL.getLength())
+ {
+ b.append(static_cast< sal_Unicode >(' '));
+ {
+ vos::OGuard g( Application::GetSolarMutex() );
+ if(!m_stop)
+ b.append(m_dialog.m_browserbased);
+ }
+ }
+ return b.makeStringAndClear();
+}
+
+/** out_data will only be filled if all dependencies are ok.
+ */
+void UpdateDialog::Thread::prepareUpdateData(
+ css::uno::Reference< css::xml::dom::XNode > const & updateInfo,
+ UpdateDialog::DisabledUpdate & out_du,
+ dp_gui::UpdateData & out_data) const
+{
+ if (!updateInfo.is())
+ return;
+ 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));
+
+ out_du.aUpdateInfo = updateInfo;
+ out_du.unsatisfiedDependencies.realloc(ds.getLength());
+ for (sal_Int32 i = 0; i < ds.getLength(); ++i) {
+ out_du.unsatisfiedDependencies[i] = dp_misc::Dependencies::getErrorText(ds[i]);
+ }
+
+ const ::boost::optional< ::rtl::OUString> updateWebsiteURL(infoset.getLocalizedUpdateWebsiteURL());
+
+ out_du.name = getUpdateDisplayString(out_data, infoset.getVersion());
+
+ if (out_du.unsatisfiedDependencies.getLength() == 0)
+ {
+ out_data.aUpdateInfo = updateInfo;
+ out_data.updateVersion = infoset.getVersion();
+ if (updateWebsiteURL)
+ out_data.sWebsiteURL = *updateWebsiteURL;
+ }
+}
+
+bool UpdateDialog::Thread::update(
+ UpdateDialog::DisabledUpdate const & du,
+ dp_gui::UpdateData const & data) const
+{
+ bool ret = false;
+ if (du.unsatisfiedDependencies.getLength() == 0)
+ {
+ vos::OGuard g(Application::GetSolarMutex());
+ if (!m_stop) {
+ m_dialog.addEnabledUpdate(getUpdateDisplayString(data), data);
+ }
+ ret = !m_stop;
+ } else {
+ vos::OGuard g(Application::GetSolarMutex());
+ if (!m_stop) {
+ m_dialog.addDisabledUpdate(du);
+ }
+ ret = !m_stop;
+ }
+ return ret;
+}
+
+// UpdateDialog ----------------------------------------------------------
+UpdateDialog::UpdateDialog(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ Window * parent,
+ const std::vector<css::uno::Reference< css::deployment::XPackage > > &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_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);
+
+ m_xExtensionManager = css::deployment::ExtensionManager::get( context );
+
+ 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();
+
+ 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
+}
+#if 0
+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
+}
+#endif
+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);
+ return showDescription(infoset.getLocalizedPublisherNameAndURL(),
+ infoset.getLocalizedReleaseNotesURL());
+}
+
+bool UpdateDialog::showDescription(css::uno::Reference< css::deployment::XPackage > const & aExtension)
+{
+ OSL_ASSERT(aExtension.is());
+ css::beans::StringPair pubInfo = aExtension->getPublisherInfo();
+ return showDescription(std::make_pair(pubInfo.First, pubInfo.Second),
+ OUSTR(""));
+}
+
+bool UpdateDialog::showDescription(std::pair< rtl::OUString, rtl::OUString > const & pairPublisher,
+ rtl::OUString const & sReleaseNotes)
+{
+ rtl::OUString sPub = pairPublisher.first;
+ rtl::OUString sURL = pairPublisher.second;
+
+ if ( sPub.getLength() == 0 && sURL.getLength() == 0 && sReleaseNotes.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 ( sReleaseNotes.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( sReleaseNotes );
+ }
+ 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;
+}
+
+bool UpdateDialog::isReadOnly( const css::uno::Reference< css::deployment::XPackage > &xPackage ) const
+{
+ if ( m_xExtensionManager.is() && xPackage.is() )
+ {
+ return m_xExtensionManager->isReadOnlyRepository( xPackage->getRepositoryName() );
+ }
+ else
+ 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)
+ {
+ if (m_enabledUpdates[pos].aUpdateSource.is())
+ bInserted = showDescription(m_enabledUpdates[pos].aUpdateSource);
+ else
+ 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);
+ }
+ 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->aInstalledPackage.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(isReadOnly(i->aInstalledPackage) == 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(
+ OUSTR( "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..32c317cb8735
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 XExtensionManager;
+ class XPackage; }
+ 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 vExtensionList
+ check for updates for the contained extensions. There must only be one extension with
+ a particular identifier. If one extension is installed in several repositories, then the
+ one with the highest version must be used, because it contains the latest known update
+ information.
+ */
+ UpdateDialog(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & context,
+ Window * parent,
+ const std::vector< com::sun::star::uno::Reference<
+ com::sun::star::deployment::XPackage > > & 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);
+#if 0
+ void addGeneralError(rtl::OUString const & message);
+#endif
+ void addSpecificError(UpdateDialog::SpecificError const & data);
+
+ void checkingDone();
+
+ void enableOk();
+
+ void initDescription();
+ void clearDescription();
+ bool showDescription(::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage > const & aExtension);
+ bool showDescription(std::pair< rtl::OUString, rtl::OUString > const & pairPublisher,
+ rtl::OUString const & sReleaseNotes);
+ bool showDescription( ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & aUpdateInfo);
+ bool showDescription( const String& rDescription, bool bWithPublisher );
+ bool isReadOnly( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+
+ 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_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;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > m_xExtensionManager;
+
+ 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..325d98c88d48
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.src
@@ -0,0 +1,265 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..067a703ec413
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx
@@ -0,0 +1,756 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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/beans/NamedValue.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/XExtensionManager.hpp"
+#include "com/sun/star/deployment/ExtensionManager.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_xExtensionManager = css::deployment::ExtensionManager::get( xCtx );
+
+ 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;
+
+ if (!curData.aUpdateInfo.is() || curData.aUpdateSource.is())
+ continue;
+ //We assume that m_aVecUpdateData contains only information about extensions which
+ //can be downloaded directly.
+ OSL_ASSERT(curData.sWebsiteURL.getLength() == 0);
+
+ //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> xExtension;
+ UpdateData & curData = *i;
+ cssu::Exception exc;
+ try
+ {
+ cssu::Reference< css::task::XAbortChannel > xAbortChannel(
+ curData.aInstalledPackage->createAbortChannel() );
+ {
+ vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ m_abort = xAbortChannel;
+ }
+ if (!curData.aUpdateSource.is() && curData.sLocalURL.getLength())
+ {
+ css::beans::NamedValue prop(OUSTR("EXTENSION_UPDATE"), css::uno::makeAny(OUSTR("1")));
+ if (!curData.bIsShared)
+ xExtension = m_dialog.getExtensionManager()->addExtension(
+ curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
+ OUSTR("user"), xAbortChannel, m_updateCmdEnv.get());
+ else
+ xExtension = m_dialog.getExtensionManager()->addExtension(
+ curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
+ OUSTR("shared"), xAbortChannel, m_updateCmdEnv.get());
+ }
+ else if (curData.aUpdateSource.is())
+ {
+ OSL_ASSERT(curData.aUpdateSource.is());
+ //I am not sure if we should obtain the install properties and pass them into
+ //add extension. Currently it contains only "SUPPRESS_LICENSE". So it it could happen
+ //that a license is displayed when updating from the shared repository, although the
+ //shared extension was installed using "SUPPRESS_LICENSE".
+ css::beans::NamedValue prop(OUSTR("EXTENSION_UPDATE"), css::uno::makeAny(OUSTR("1")));
+ if (!curData.bIsShared)
+ xExtension = m_dialog.getExtensionManager()->addExtension(
+ curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
+ OUSTR("user"), xAbortChannel, m_updateCmdEnv.get());
+ else
+ xExtension = m_dialog.getExtensionManager()->addExtension(
+ curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
+ OUSTR("shared"), 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 (!xExtension.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..c0e64a8028e8
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 deployment {
+ class XExtensionManager;
+}}}}
+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);
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > getExtensionManager() const
+ { return m_xExtensionManager; }
+
+ rtl::Reference< Thread > m_thread;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xComponentContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > m_xExtensionManager;
+ //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..d77dd256582c
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.src
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 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..878521ad6dd2
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_versionboxes.src
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..9698e257b953
--- /dev/null
+++ b/desktop/source/deployment/gui/license_dialog.cxx
@@ -0,0 +1,330 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/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 "svl/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 & sExtensionName,
+ 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 & sExtensionName,
+ 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 (GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ // 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_ftHead.SetText(m_ftHead.GetText() + OUString('\n') + sExtensionName);
+
+ 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_sExtensionName, 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_sExtensionName, 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..bb4a6b6646c8
--- /dev/null
+++ b/desktop/source/deployment/gui/license_dialog.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 m_sExtensionName;
+ 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..52092a077a4b
--- /dev/null
+++ b/desktop/source/deployment/gui/makefile.mk
@@ -0,0 +1,109 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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_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 = $(SOLARENV)/src/component.map
+
+SHL1STDLIBS = \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(I18NISOLANGLIB) \
+ $(TKLIB) \
+ $(VCLLIB) \
+ $(SVTOOLLIB) \
+ $(SVLLIB) \
+ $(SVXLIB) \
+ $(SVXCORELIB) \
+ $(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..75dbd942a7cd
--- /dev/null
+++ b/desktop/source/deployment/inc/db.hxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 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..13be1e8612fb
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_dependencies.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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) 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..37e616bb1a0b
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_descriptioninfoset.hxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 {
+
+struct DESKTOP_DEPLOYMENTMISC_DLLPUBLIC SimpleLicenseAttributes
+{
+ ::rtl::OUString acceptBy;
+ //Attribute suppress-on-update. Default is false.
+ bool suppressOnUpdate;
+ //Attribute suppress-if-required. Default is false.
+ bool suppressIfRequired;
+};
+
+
+/**
+ 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 attributes of the simple-license element
+
+ As long as there is a simple-license element, the function will return
+ the structure. If it does not exist, then the optional object is uninitialized.
+ */
+ ::boost::optional<SimpleLicenseAttributes> getSimpleLicenseAttributes() 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;
+
+ bool hasDescription() 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;
+};
+
+inline bool DescriptionInfoset::hasDescription() const
+{
+ return m_element.is();
+}
+
+/** creates a DescriptionInfoset object.
+
+ The argument sExtensionFolderURL is a file URL to extension folder containing
+ the description.xml.
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+DescriptionInfoset getDescriptionInfoset(::rtl::OUString const & sExtensionFolderURL);
+}
+
+#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..6fc49c30085c
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_identifier.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..b6116b9a1266
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_interact.h
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..61e3fcc45418
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc.h
@@ -0,0 +1,179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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/ucb/XCommandEnvironment.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 makeRcTerm( ::rtl::OUString const & url );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString expandUnoRcUrl( ::rtl::OUString const & url );
+
+//==============================================================================
+
+/** appends a relative path to a url.
+
+ The relative path must already be correctly encoded for use in an URL.
+ If the URL starts with vnd.sun.star.expand then the relative path will
+ be again encoded for use in an "expand" URL.
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString makeURL(
+ ::rtl::OUString const & baseURL, ::rtl::OUString const & relPath );
+
+
+/** appends a relative path to a url.
+
+ This is the same as makeURL, but the relative Path must me a segment
+ of an system path.
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString makeURLAppendSysPathSegment(
+ ::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 );
+
+//==============================================================================
+
+/** 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);
+
+/** registers or revokes shared or bundled extensions which have been
+ recently added or removed.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void syncRepositories(::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment> const & xCmdEnv);
+
+}
+
+#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..829a6bb96bbf
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc.mk
@@ -0,0 +1,42 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+# 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..ef34ef06872c
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc_api.hxx
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..bb3f58269e62
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_persmap.h
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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();
+
+ 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..95853746bef2
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_platform.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..7dcdd7df7fbb
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_resource.h
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..03144388e8a8
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_ucb.h
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_UCB_H
+#define INCLUDED_DP_UCB_H
+
+#include <list>
+#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 );
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+bool readProperties( ::std::list< ::std::pair< ::rtl::OUString, ::rtl::OUString> > & out_result,
+ ::ucbhelper::Content & ucb_content);
+
+
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_update.hxx b/desktop/source/deployment/inc/dp_update.hxx
new file mode 100755
index 000000000000..01511b1f2d21
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_update.hxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_UPDATE_HXX
+#define INCLUDED_DP_UPDATE_HXX
+
+
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XExtensionManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+
+#include "rtl/ustrbuf.hxx"
+#include "dp_misc_api.hxx"
+
+#include <map>
+#include <vector>
+
+namespace dp_misc {
+
+/** 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();
+
+enum UPDATE_SOURCE
+{
+ UPDATE_SOURCE_NONE,
+ UPDATE_SOURCE_SHARED,
+ UPDATE_SOURCE_BUNDLED,
+ UPDATE_SOURCE_ONLINE
+};
+
+/* determine if an update is available which is installed in the
+ user repository.
+
+ If the return value is UPDATE_SOURCE_NONE, then no update is
+ available, otherwise the return value determine from which the
+ repository the update is used.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+UPDATE_SOURCE isUpdateUserExtension(
+ bool bReadOnlyShared,
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion);
+
+/* determine if an update is available which is installed in the
+ shared repository.
+
+ If the return value is UPDATE_SOURCE_NONE, then no update is
+ available, otherwise the return value determine from which the
+ repository the update is used.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+UPDATE_SOURCE isUpdateSharedExtension(
+ bool bReadOnlyShared,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion);
+
+/* determines the extension with the highest identifier and returns it
+
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage>
+getExtensionWithHighestVersion(
+ ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage> > const & seqExtensionsWithSameId);
+
+
+struct UpdateInfo
+{
+ UpdateInfo( ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> const & ext);
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage> extension;
+//version of the update
+ ::rtl::OUString version;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > info;
+};
+
+typedef std::map< ::rtl::OUString, UpdateInfo > UpdateInfoMap;
+
+/*
+ @param extensionList
+ List of extension for which online update information are to be obtained. If NULL, then
+ for update information are obtained for all installed extension. There may be only one extension
+ with a particular identifier contained in the list. If one extension is installed
+ in several repositories, then the one with the highest version must be used, because it contains
+ the more recent URLs for getting the update information (if at all).
+ @param out_errors
+ the first member of the pair is the extension and the second the exception that was produced
+ when processing the extension.
+
+ @return
+ A map of UpdateInfo instances. If the parameter extensionList was given, then the map contains
+ at only information for those extensions.
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+UpdateInfoMap getOnlineUpdateInfos(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const &xContext,
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager> const & xExtMgr,
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XUpdateInformationProvider > const & updateInformation,
+ std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > > const * extensionList,
+ ::std::vector< ::std::pair< ::com::sun::star::uno::Reference<
+ ::com::sun::star::deployment::XPackage>, ::com::sun::star::uno::Any> > & out_errors);
+
+/* retunrs the highest version from the provided arguments.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString getHighestVersion(
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion);
+
+}
+
+#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..c459333f97a9
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_version.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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);
+}
+
+#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..300051bd1512
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_xml.h
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 );
+
+}
+
+#endif
diff --git a/desktop/source/deployment/makefile.mk b/desktop/source/deployment/makefile.mk
new file mode 100644
index 000000000000..6d83a5c1004b
--- /dev/null
+++ b/desktop/source/deployment/makefile.mk
@@ -0,0 +1,112 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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 = $(SOLARENV)/src/component.map
+
+SHL1LIBS = \
+ $(SLB)$/deployment_manager.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) \
+ $(UNOTOOLSLIB) \
+ $(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..8f6b6b82c0b7
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_activepackages.cxx
@@ -0,0 +1,206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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);
+ sal_Int32 i3 = value.indexOf(separator, i2 + 1);
+
+ if (i3 < 0)
+ {
+ //Before ActivePackages::Data::version was added
+ d.mediaType = ::rtl::OUString(
+ value.getStr() + i2 + 1, value.getLength() - i2 - 1,
+ RTL_TEXTENCODING_UTF8);
+ }
+ else
+ {
+ sal_Int32 i4 = value.indexOf(separator, i3 + 1);
+ d.mediaType = ::rtl::OUString(
+ value.getStr() + i2 + 1, i3 - i2 -1, RTL_TEXTENCODING_UTF8);
+ d.version = ::rtl::OUString(
+ value.getStr() + i3 + 1, i4 - i3 - 1,
+ RTL_TEXTENCODING_UTF8);
+ d.failedPrerequisites = ::rtl::OUString(
+ value.getStr() + i4 + 1, value.getLength() - i4 - 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));
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(data.version, RTL_TEXTENCODING_UTF8));
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(data.failedPrerequisites, 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..7d9c7e32cfb4
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_activepackages.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 {
+ Data(): failedPrerequisites(::rtl::OUString::valueOf((sal_Int32)0))
+ {}
+ /* name of the temporary file (shared, user extension) or the name of
+ the folder of the bundled extension.
+ It does not contain the trailing '_' of the folder.
+ UTF-8 encoded
+ */
+ ::rtl::OUString temporaryName;
+ /* The file name (shared, user) or the folder name (bundled)
+ If the key is the file name, then file name is not encoded.
+ If the key is the idendifier then the file name is UTF-8 encoded.
+ */
+ ::rtl::OUString fileName;
+ ::rtl::OUString mediaType;
+ ::rtl::OUString version;
+ /* If this string contains the value according to
+ com::sun::star::deployment::Prerequisites or "0". That is, if
+ the value is > 0 then
+ the call to XPackage::checkPrerequisites failed.
+ In this case the extension must not be registered.
+ */
+ ::rtl::OUString failedPrerequisites;
+ };
+
+ 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_commandenvironments.cxx b/desktop/source/deployment/manager/dp_commandenvironments.cxx
new file mode 100644
index 000000000000..c2801ba1d965
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_commandenvironments.cxx
@@ -0,0 +1,286 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "dp_commandenvironments.hxx"
+
+namespace deployment = com::sun::star::deployment;
+namespace lang = com::sun::star::lang;
+namespace task = com::sun::star::task;
+namespace ucb = com::sun::star::ucb;
+namespace uno = com::sun::star::uno;
+namespace css = com::sun::star;
+
+#define OUSTR(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+
+namespace dp_manager {
+
+BaseCommandEnv::BaseCommandEnv()
+{
+}
+
+BaseCommandEnv::BaseCommandEnv(
+ Reference< task::XInteractionHandler> const & handler)
+ : m_forwardHandler(handler)
+{
+}
+
+BaseCommandEnv::~BaseCommandEnv()
+{
+}
+// XCommandEnvironment
+//______________________________________________________________________________
+Reference<task::XInteractionHandler> BaseCommandEnv::getInteractionHandler()
+throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//______________________________________________________________________________
+Reference<ucb::XProgressHandler> BaseCommandEnv::getProgressHandler()
+throw (uno::RuntimeException)
+{
+ return this;
+}
+
+void BaseCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & /*xRequest*/ )
+ throw (uno::RuntimeException)
+{
+}
+
+void BaseCommandEnv::handle_(bool approve, bool abort,
+ Reference< task::XInteractionRequest> const & xRequest )
+{
+ if (approve == false && abort == false)
+ {
+ //not handled so far -> forwarding
+ if (m_forwardHandler.is())
+ m_forwardHandler->handle(xRequest);
+ else
+ return; //cannot handle
+ }
+ else
+ {
+ // select:
+ uno::Sequence< Reference< task::XInteractionContinuation > > conts(
+ xRequest->getContinuations() );
+ Reference< task::XInteractionContinuation > const * pConts =
+ conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ 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) {
+ 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 BaseCommandEnv::push( uno::Any const & /*Status*/ )
+throw (uno::RuntimeException)
+{
+}
+
+
+void BaseCommandEnv::update( uno::Any const & /*Status */)
+throw (uno::RuntimeException)
+{
+}
+
+void BaseCommandEnv::pop() throw (uno::RuntimeException)
+{
+}
+//==============================================================================
+
+TmpRepositoryCommandEnv::TmpRepositoryCommandEnv()
+{
+}
+
+TmpRepositoryCommandEnv::TmpRepositoryCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler):
+ BaseCommandEnv(handler)
+{
+}
+// XInteractionHandler
+void TmpRepositoryCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+ deployment::VersionException verExc;
+ deployment::LicenseException licExc;
+ deployment::InstallException instExc;
+
+ bool approve = false;
+ bool abort = false;
+
+ if ((request >>= verExc)
+ || (request >>= licExc)
+ || (request >>= instExc))
+ {
+ approve = true;
+ }
+
+ handle_(approve, abort, xRequest);
+}
+//================================================================================
+
+LicenseCommandEnv::LicenseCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler,
+ bool bSuppressLicense,
+ OUString const & repository):
+ BaseCommandEnv(handler), m_repository(repository),
+ m_bSuppressLicense(bSuppressLicense)
+{
+}
+// XInteractionHandler
+void LicenseCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+
+ deployment::LicenseException licExc;
+
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= licExc)
+ {
+ if (m_bSuppressLicense
+ || m_repository.equals(OUSTR("bundled"))
+ || licExc.AcceptBy.equals(OUSTR("admin")))
+ {
+ //always approve in bundled case, because we do not support
+ //showing licenses anyway.
+ //The "admin" already accepted the license when installing the
+ // shared extension
+ approve = true;
+ }
+ }
+
+ handle_(approve, abort, xRequest);
+}
+
+//================================================================================
+//================================================================================
+
+NoLicenseCommandEnv::NoLicenseCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler):
+ BaseCommandEnv(handler)
+{
+}
+// XInteractionHandler
+void NoLicenseCommandEnv::handle(
+ Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+
+ deployment::LicenseException licExc;
+
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= licExc)
+ {
+ approve = true;
+ }
+ handle_(approve, abort, xRequest);
+}
+
+
+// NoExceptionCommandEnv::NoExceptionCommandEnv(
+// css::uno::Reference< css::task::XInteractionHandler> const & handler,
+// css::uno::Type const & type):
+// BaseCommandEnv(handler),
+// m_type(type)
+// {
+// }
+// // XInteractionHandler
+// void NoExceptionCommandEnv::handle(
+// Reference< task::XInteractionRequest> const & xRequest )
+// throw (uno::RuntimeException)
+// {
+// uno::Any request( xRequest->getRequest() );
+// OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+
+// deployment::LicenseException licExc;
+
+// bool approve = false;
+// bool abort = false;
+
+// if (request.getValueType() == m_type)
+// {
+// approve = true;
+// }
+// handle_(approve, abort, xRequest);
+// }
+
+
+
+} // namespace dp_manager
+
+
diff --git a/desktop/source/deployment/manager/dp_commandenvironments.hxx b/desktop/source/deployment/manager/dp_commandenvironments.hxx
new file mode 100644
index 000000000000..aa21f8281c72
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_commandenvironments.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_COMMANDENVIRONMENTS_HXX
+#define INCLUDED_DP_COMMANDENVIRONMENTS_HXX
+
+
+#include "cppuhelper/compbase3.hxx"
+//#include "cppuhelper/implbase2.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/uno/Type.hxx"
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_manager {
+
+
+
+/**
+ This command environment is to be used when an extension is temporarily
+ stored in the "tmp" repository. It prevents all kind of user interaction.
+ */
+class BaseCommandEnv
+ : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
+ css::task::XInteractionHandler,
+ css::ucb::XProgressHandler >
+{
+protected:
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::task::XInteractionHandler> m_forwardHandler;
+
+ void handle_(bool approve, bool abort,
+ css::uno::Reference< css::task::XInteractionRequest> const & xRequest );
+public:
+ virtual ~BaseCommandEnv();
+ BaseCommandEnv();
+ BaseCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler);
+
+ // 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);
+
+ // 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);
+};
+
+class TmpRepositoryCommandEnv : public BaseCommandEnv
+{
+public:
+ TmpRepositoryCommandEnv();
+ TmpRepositoryCommandEnv(css::uno::Reference< css::task::XInteractionHandler> const & handler);
+
+// XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+
+};
+
+/** this class is for use in XPackageManager::synchronize.
+
+ It handles particular license cases.
+ */
+class LicenseCommandEnv : public BaseCommandEnv
+{
+private:
+ ::rtl::OUString m_repository;
+ bool m_bSuppressLicense;
+public:
+ LicenseCommandEnv(){};
+ LicenseCommandEnv(
+ css::uno::Reference< css::task::XInteractionHandler> const & handler,
+ bool bSuppressLicense,
+ ::rtl::OUString const & repository);
+
+// XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+
+};
+
+/** this class is for use in XPackageManager::checkPrerequisites
+
+ It always prohibits a license interaction
+ */
+class NoLicenseCommandEnv : public BaseCommandEnv
+{
+
+public:
+ NoLicenseCommandEnv(){};
+ NoLicenseCommandEnv(css::uno::Reference< css::task::XInteractionHandler> const & handler);
+
+// XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+
+};
+
+// class NoExceptionCommandEnv : public BaseCommandEnv
+// {
+// css::uno::Type m_type;
+// public:
+// NoExceptionCommandEnv::NoExceptionCommandEnv(){};
+// NoExceptionCommandEnv::NoExceptionCommandEnv(
+// css::uno::Reference< css::task::XInteractionHandler> const & handler,
+// css::uno::Type const & type);
+
+// // XInteractionHandler
+// virtual void SAL_CALL handle(
+// css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+// throw (css::uno::RuntimeException);
+
+// };
+
+}
+
+
+
+
+#endif
+
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx
new file mode 100644
index 000000000000..de9d97db2b48
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx
@@ -0,0 +1,1361 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/implbase1.hxx>
+
+#include "comphelper/servicedecl.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "rtl/bootstrap.hxx"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/deployment/XExtensionManager.hpp"
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/deployment/XPackageManagerFactory.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/beans/Optional.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/beans/Ambiguous.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/util/XModifyBroadcaster.hpp"
+#include "comphelper/sequence.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "osl/diagnose.h"
+#include "dp_interact.h"
+#include "dp_resource.h"
+#include "dp_ucb.h"
+#include "dp_identifier.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_extensionmanager.hxx"
+#include "dp_commandenvironments.hxx"
+#include "dp_properties.hxx"
+#include "boost/bind.hpp"
+
+#include <list>
+#include <hash_map>
+#include <algorithm>
+
+namespace deploy = com::sun::star::deployment;
+namespace lang = com::sun::star::lang;
+namespace registry = com::sun::star::registry;
+namespace task = com::sun::star::task;
+namespace ucb = com::sun::star::ucb;
+namespace uno = com::sun::star::uno;
+namespace beans = com::sun::star::beans;
+namespace util = com::sun::star::util;
+namespace css = com::sun::star;
+
+
+//#define OUSTR(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+
+namespace {
+
+struct CompIdentifiers
+{
+ bool operator() (::std::vector<Reference<deploy::XPackage> > const & a,
+ ::std::vector<Reference<deploy::XPackage> > const & b)
+ {
+
+ if (getName(a).compareTo(getName(b)) < 0)
+ return true;
+ return false;
+ }
+
+ OUString getName(::std::vector<Reference<deploy::XPackage> > const & a);
+};
+
+OUString CompIdentifiers::getName(::std::vector<Reference<deploy::XPackage> > const & a)
+{
+ OSL_ASSERT(a.size() == 3);
+ //get the first non-null reference
+ Reference<deploy::XPackage> extension;
+ ::std::vector<Reference<deploy::XPackage> >::const_iterator it = a.begin();
+ for (; it != a.end(); it++)
+ {
+ if (it->is())
+ {
+ extension = *it;
+ break;
+ }
+ }
+ OSL_ASSERT(extension.is());
+ return extension->getDisplayName();
+}
+
+void writeLastModified(OUString & url, Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ //Write the lastmodified file
+ try {
+ ::rtl::Bootstrap::expandMacros(url);
+ ::ucbhelper::Content ucbStamp(url, xCmdEnv );
+ dp_misc::erase_path( url, xCmdEnv );
+ ::rtl::OString stamp("1" );
+ Reference<css::io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
+ stamp.getLength() ) ) );
+ ucbStamp.writeStream( xData, true /* replace existing */ );
+ }
+ catch(...)
+ {
+ uno::Any exc(::cppu::getCaughtException());
+ throw deploy::DeploymentException(
+ OUSTR("Failed to update") + url, 0, exc);
+ }
+}
+} //end namespace
+
+namespace dp_manager {
+
+
+
+//------------------------------------------------------------------------------
+
+//ToDo: bundled extension
+ExtensionManager::ExtensionManager( Reference< uno::XComponentContext > const& xContext) :
+ ::cppu::WeakComponentImplHelper1< css::deployment::XExtensionManager >(getMutex()),
+ m_xContext( xContext )
+{
+ Reference<deploy::XPackageManagerFactory> xPackageManagerFactory(
+ deploy::thePackageManagerFactory::get(m_xContext));
+ m_userRepository = xPackageManagerFactory->getPackageManager(OUSTR("user"));
+ m_sharedRepository = xPackageManagerFactory->getPackageManager(OUSTR("shared"));
+ m_bundledRepository = xPackageManagerFactory->getPackageManager(OUSTR("bundled"));
+ m_tmpRepository = xPackageManagerFactory->getPackageManager(OUSTR("tmp"));
+
+ m_repositoryNames.push_back(OUSTR("user"));
+ m_repositoryNames.push_back(OUSTR("shared"));
+ m_repositoryNames.push_back(OUSTR("bundled"));
+}
+
+//------------------------------------------------------------------------------
+
+ExtensionManager::~ExtensionManager()
+{
+}
+
+Reference<task::XAbortChannel> ExtensionManager::createAbortChannel()
+ throw (uno::RuntimeException)
+{
+ return new dp_misc::AbortChannel;
+}
+
+css::uno::Reference<css::deployment::XPackageManager>
+ExtensionManager::getPackageManager(::rtl::OUString const & repository)
+ throw (css::lang::IllegalArgumentException)
+{
+ Reference<deploy::XPackageManager> xPackageManager;
+ if (repository.equals(OUSTR("user")))
+ xPackageManager = m_userRepository;
+ else if (repository.equals(OUSTR("shared")))
+ xPackageManager = m_sharedRepository;
+ else if (repository.equals(OUSTR("bundled")))
+ xPackageManager = m_bundledRepository;
+ else
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+ return xPackageManager;
+}
+
+
+/*
+ Enters the XPackage objects into a map. They must be all from the
+ same repository. The value type of the map is a vector, where each vector
+ represents an extension with a particular identifier. The first member
+ is represents the user extension, the second the shared extension and the
+ third the bundled extension.
+ */
+void ExtensionManager::addExtensionsToMap(
+ id2extensions & mapExt,
+ uno::Sequence<Reference<deploy::XPackage> > const & seqExt,
+ OUString const & repository)
+{
+ //Determine the index in the vector where these extensions are to be
+ //added.
+ ::std::list<OUString>::const_iterator citNames =
+ m_repositoryNames.begin();
+ int index = 0;
+ for (;citNames != m_repositoryNames.end(); citNames++, index++)
+ {
+ if (citNames->equals(repository))
+ break;
+ }
+
+ for (int i = 0; i < seqExt.getLength(); i++)
+ {
+ Reference<deploy::XPackage> const & xExtension = seqExt[i];
+ OUString id = dp_misc::getIdentifier(xExtension);
+ id2extensions::iterator ivec = mapExt.find(id);
+ if (ivec == mapExt.end())
+ {
+ ::std::vector<Reference<deploy::XPackage> > vec(3);
+ vec[index] = xExtension;
+ mapExt[id] = vec;
+ }
+ else
+ {
+ ivec->second[index] = xExtension;
+ }
+ }
+}
+
+/*
+ returns a list containing extensions with the same identifier from
+ all repositories (user, shared, bundled) If one repository does not
+ have this extension, then the list contains an empty Referenc. The list
+ is ordered according to the priority of the repostories:
+ 1. user
+ 2. shared
+ 3. bundled
+
+ The number of elements is always three, unless the number of repository
+ changes.
+ */
+::std::list<Reference<deploy::XPackage> >
+ ExtensionManager::getExtensionsWithSameId(
+ OUString const & identifier, OUString const & fileName,
+ Reference< ucb::XCommandEnvironment> const & /*xCmdEnv*/)
+
+{
+ ::std::list<Reference<deploy::XPackage> > extensionList;
+ try
+ { //will throw an exception if the extension does not exist
+ extensionList.push_back(m_userRepository->getDeployedPackage(
+ identifier, fileName, Reference<ucb::XCommandEnvironment>()));
+ } catch(lang::IllegalArgumentException &)
+ {
+ extensionList.push_back(Reference<deploy::XPackage>());
+ }
+ try
+ {
+ extensionList.push_back(m_sharedRepository->getDeployedPackage(
+ identifier, fileName, Reference<ucb::XCommandEnvironment>()));
+ } catch (lang::IllegalArgumentException &)
+ {
+ extensionList.push_back(Reference<deploy::XPackage>());
+ }
+ try
+ {
+ extensionList.push_back(m_bundledRepository->getDeployedPackage(
+ identifier, fileName, Reference<ucb::XCommandEnvironment>()));
+ } catch (lang::IllegalArgumentException &)
+ {
+ extensionList.push_back(Reference<deploy::XPackage>());
+ }
+ OSL_ASSERT(extensionList.size() == 3);
+ return extensionList;
+}
+
+uno::Sequence<Reference<deploy::XPackage> >
+ExtensionManager::getExtensionsWithSameIdentifier(
+ OUString const & identifier,
+ OUString const & fileName,
+ Reference< ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (
+ deploy::DeploymentException,
+ ucb::CommandFailedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ ::std::list<Reference<deploy::XPackage> > listExtensions =
+ getExtensionsWithSameId(
+ identifier, fileName, xCmdEnv);
+ sal_Bool bHasExtension = false;
+
+ //throw an IllegalArgumentException if there is no extension at all.
+ typedef ::std::list<Reference<deploy::XPackage> >::const_iterator CIT;
+ for (CIT i = listExtensions.begin(); i != listExtensions.end(); i++)
+ bHasExtension |= i->is();
+ if (!bHasExtension)
+ throw lang::IllegalArgumentException(
+ OUSTR("Could not find extension: ") + identifier + OUSTR(", ") + fileName,
+ static_cast<cppu::OWeakObject*>(this), -1);
+
+ return comphelper::containerToSequence<
+ Reference<deploy::XPackage>,
+ ::std::list<Reference<deploy::XPackage> >
+ > (listExtensions);
+ }
+ catch (deploy::DeploymentException & )
+ {
+ throw;
+ }
+ catch ( ucb::CommandFailedException & )
+ {
+ throw;
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ throw;
+ }
+ catch (...)
+ {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception during getExtensionsWithSameIdentifier"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+
+
+bool ExtensionManager::isUserDisabled(
+ OUString const & identifier, OUString const & fileName)
+{
+ ::std::list<Reference<deploy::XPackage> > listExtensions;
+
+ try {
+ listExtensions = getExtensionsWithSameId(identifier, fileName);
+ } catch (lang::IllegalArgumentException & ) {
+ }
+ OSL_ASSERT(listExtensions.size() == 3);
+
+ return isUserDisabled( ::comphelper::containerToSequence<
+ Reference<deploy::XPackage>,
+ ::std::list<Reference<deploy::XPackage> >
+ > (listExtensions));
+}
+
+bool ExtensionManager::isUserDisabled(
+ uno::Sequence<Reference<deploy::XPackage> > const & seqExtSameId)
+{
+ OSL_ASSERT(seqExtSameId.getLength() == 3);
+ Reference<deploy::XPackage> const & userExtension = seqExtSameId[0];
+ if (userExtension.is())
+ {
+ beans::Optional<beans::Ambiguous<sal_Bool> > reg =
+ userExtension->isRegistered(Reference<task::XAbortChannel>(),
+ Reference<ucb::XCommandEnvironment>());
+ //If the value is ambiguous is than we assume that the extension
+ //is enabled, but something went wrong during enabling. We do not
+ //automatically disable user extensions.
+ if (reg.IsPresent &&
+ ! reg.Value.IsAmbiguous && ! reg.Value.Value)
+ return true;
+ }
+ return false;
+}
+
+/*
+ This method determines the active extension (XPackage.registerPackage) with a
+ particular identifier.
+
+ The parameter bUserDisabled determines if the user extension is disabled.
+
+ When the user repository contains an extension with the given identifier and
+ it is not disabled by the user, then it is always registered. Otherwise an
+ extension is only registered when there is no registered extension in one of
+ the repositories with a higher priority. That is, if the extension is from
+ the shared repository and an active extension with the same identifer is in
+ the user repository, then the extension is not registered. Similarly a
+ bundled extension is not registered if there is an active extension with the
+ same identifier in the shared or user repository.
+*/
+void ExtensionManager::activateExtension(
+ OUString const & identifier, OUString const & fileName,
+ bool bUserDisabled,
+ bool bStartup,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ ::std::list<Reference<deploy::XPackage> > listExtensions;
+ try {
+ listExtensions = getExtensionsWithSameId(identifier, fileName);
+ } catch (lang::IllegalArgumentException &) {
+ }
+ OSL_ASSERT(listExtensions.size() == 3);
+
+ activateExtension(
+ ::comphelper::containerToSequence<
+ Reference<deploy::XPackage>,
+ ::std::list<Reference<deploy::XPackage> >
+ > (listExtensions),
+ bUserDisabled, bStartup, xAbortChannel, xCmdEnv);
+
+ fireModified();
+}
+
+void ExtensionManager::activateExtension(
+ uno::Sequence<Reference<deploy::XPackage> > const & seqExt,
+ bool bUserDisabled,
+ bool bStartup,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ bool bActive = false;
+ sal_Int32 len = seqExt.getLength();
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ Reference<deploy::XPackage> const & aExt = seqExt[i];
+ if (aExt.is())
+ {
+ //get the registration value of the current iteration
+ beans::Optional<beans::Ambiguous<sal_Bool> > optReg =
+ aExt->isRegistered(xAbortChannel, xCmdEnv);
+ //If nothing can be registered then break
+ if (!optReg.IsPresent)
+ break;
+
+ //Check if this is a disabled user extension,
+ if (i == 0 && bUserDisabled)
+ {
+ aExt->revokePackage(xAbortChannel, xCmdEnv);
+ continue;
+ }
+
+ //If we have already determined an active extension then we must
+ //make sure to unregister all extensions with the same id in
+ //repositories with a lower priority
+ if (bActive)
+ {
+ aExt->revokePackage(xAbortChannel, xCmdEnv);
+ }
+ else
+ {
+ //This is the first extension in the ordered list, which becomes
+ //the active extension
+ bActive = true;
+ //Register if not already done.
+ //reregister if the value is ambiguous, which indicates that
+ //something went wrong during last registration.
+ aExt->registerPackage(bStartup, xAbortChannel, xCmdEnv);
+ }
+ }
+ }
+}
+
+Reference<deploy::XPackage> ExtensionManager::backupExtension(
+ OUString const & identifier, OUString const & fileName,
+ Reference<deploy::XPackageManager> const & xPackageManager,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ Reference<deploy::XPackage> xBackup;
+ Reference<ucb::XCommandEnvironment> tmpCmdEnv(
+ new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
+ Reference<deploy::XPackage> xOldExtension;
+ xOldExtension = xPackageManager->getDeployedPackage(
+ identifier, fileName, tmpCmdEnv);
+
+ if (xOldExtension.is())
+ {
+ xBackup = m_tmpRepository->addPackage(
+ xOldExtension->getURL(), uno::Sequence<beans::NamedValue>(),
+ OUString(), Reference<task::XAbortChannel>(), tmpCmdEnv);
+
+ OSL_ENSURE(xBackup.is(), "Failed to backup extension");
+ }
+ return xBackup;
+}
+
+//The supported package types are actually determined by the registry. However
+//creating a registry
+//(desktop/source/deployment/registry/dp_registry.cxx:PackageRegistryImpl) will
+//create all the backends, so that the registry can obtain from them the package
+//types. Creating the registry will also set up the registry folder containing
+//all the subfolders for the respective backends.
+//Because all repositories support the same backends, we can just delegate this
+//call to one of the repositories.
+uno::Sequence< Reference<deploy::XPackageTypeInfo> >
+ExtensionManager::getSupportedPackageTypes()
+ throw (uno::RuntimeException)
+{
+ return m_userRepository->getSupportedPackageTypes();
+}
+
+// Only add to shared and user repository
+Reference<deploy::XPackage> ExtensionManager::addExtension(
+ OUString const & url, uno::Sequence<beans::NamedValue> const & properties,
+ OUString const & repository,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ Reference<deploy::XPackage> xNewExtension;
+ //Determine the repository to use
+ Reference<deploy::XPackageManager> xPackageManager;
+ if (repository.equals(OUSTR("user")))
+ xPackageManager = m_userRepository;
+ else if (repository.equals(OUSTR("shared")))
+ xPackageManager = m_sharedRepository;
+ else
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+ ::osl::MutexGuard guard(getMutex());
+ Reference<deploy::XPackage> xTmpExtension =
+ getTempExtension(url, xAbortChannel, xCmdEnv);
+ const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
+ const OUString sFileName = xTmpExtension->getName();
+ const OUString sDisplayName = xTmpExtension->getDisplayName();
+ const OUString sVersion = xTmpExtension->getVersion();
+ dp_misc::DescriptionInfoset info(dp_misc::getDescriptionInfoset(xTmpExtension->getURL()));
+ const ::boost::optional<dp_misc::SimpleLicenseAttributes> licenseAttributes =
+ info.getSimpleLicenseAttributes();
+ Reference<deploy::XPackage> xOldExtension;
+ Reference<deploy::XPackage> xExtensionBackup;
+
+ uno::Any excOccurred1;
+ uno::Any excOccurred2;
+ bool bUserDisabled = false;
+ try
+ {
+ bUserDisabled = isUserDisabled(sIdentifier, sFileName);
+ try
+ {
+ xOldExtension = xPackageManager->getDeployedPackage(
+ sIdentifier, sFileName, xCmdEnv);
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ }
+ bool bCanInstall = false;
+ try
+ {
+ if (xOldExtension.is())
+ {
+ //throws a CommandFailedException if the user cancels
+ //the action.
+ checkUpdate(sVersion, sDisplayName,xOldExtension, xCmdEnv);
+ }
+ else
+ {
+ //throws a CommandFailedException if the user cancels
+ //the action.
+ checkInstall(sDisplayName, xCmdEnv);
+ }
+ //Prevent showing the license if requested.
+ Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv);
+ ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>());
+ if (licenseAttributes && licenseAttributes->suppressIfRequired
+ && props.isSuppressedLicense())
+ _xCmdEnv = Reference<ucb::XCommandEnvironment>(
+ new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler()));
+
+ bCanInstall = xTmpExtension->checkPrerequisites(
+ xAbortChannel, _xCmdEnv, xOldExtension.is() || props.isExtensionUpdate()) == 0 ? true : false;
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred1 = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during addExtension, url: ")
+ + url, static_cast<OWeakObject*>(this), excOccurred1);
+ excOccurred1 <<= exc;
+ }
+
+ if (bCanInstall)
+ {
+ if (xOldExtension.is())
+ {
+ xOldExtension->revokePackage(xAbortChannel, xCmdEnv);
+ //save the old user extension in case the user aborts
+ //store the extension in the tmp repository, this will overwrite
+ //xTmpPackage (same identifier). Do not let the user abort or
+ //interact
+ Reference<ucb::XCommandEnvironment> tmpCmdEnv(
+ new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
+ //importing the old extension in the tmp repository will remove
+ //the xTmpExtension
+ xTmpExtension = 0;
+ xExtensionBackup = m_tmpRepository->importExtension(
+ xOldExtension, Reference<task::XAbortChannel>(),
+ tmpCmdEnv);
+ }
+ xNewExtension = xPackageManager->addPackage(
+ url, properties, OUString(), xAbortChannel, xCmdEnv);
+ //If we add a user extension and there is already one which was
+ //disabled by a user, then the newly installed one is enabled. If we
+ //add to another repository then the user extension remains
+ //disabled.
+ bool bUserDisabled2 = bUserDisabled;
+ if (repository.equals(OUSTR("user")))
+ bUserDisabled2 = false;
+ activateExtension(
+ dp_misc::getIdentifier(xNewExtension),
+ xNewExtension->getName(), bUserDisabled2, false, xAbortChannel, xCmdEnv);
+ fireModified();
+ }
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred2 = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred2 = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during addExtension, url: ")
+ + url, static_cast<OWeakObject*>(this), excOccurred2);
+ excOccurred2 <<= exc;
+ }
+
+ if (excOccurred2.hasValue())
+ {
+ //It does not matter what exception is thrown. We try to
+ //recover the original status.
+ //If the user aborted installation then a ucb::CommandAbortedException
+ //is thrown.
+ //Use a private AbortChannel so the user cannot interrupt.
+ try
+ {
+ Reference<ucb::XCommandEnvironment> tmpCmdEnv(
+ new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
+ if (xExtensionBackup.is())
+ {
+ Reference<deploy::XPackage> xRestored =
+ xPackageManager->importExtension(
+ xExtensionBackup, Reference<task::XAbortChannel>(),
+ tmpCmdEnv);
+ }
+ activateExtension(
+ sIdentifier, sFileName, bUserDisabled, false,
+ Reference<task::XAbortChannel>(), tmpCmdEnv);
+ if (xTmpExtension.is() || xExtensionBackup.is())
+ m_tmpRepository->removePackage(
+ sIdentifier, OUString(), xAbortChannel, xCmdEnv);
+ fireModified();
+ }
+ catch (...)
+ {
+ }
+ ::cppu::throwException(excOccurred2);
+ }
+ if (xTmpExtension.is() || xExtensionBackup.is())
+ m_tmpRepository->removePackage(
+ sIdentifier,OUString(), xAbortChannel, xCmdEnv);
+
+ if (excOccurred1.hasValue())
+ ::cppu::throwException(excOccurred1);
+
+ return xNewExtension;
+}
+
+void ExtensionManager::removeExtension(
+ OUString const & identifier, OUString const & fileName,
+ OUString const & repository,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ uno::Any excOccurred1;
+ Reference<deploy::XPackage> xExtensionBackup;
+ Reference<deploy::XPackageManager> xPackageManager;
+ bool bUserDisabled = false;
+ ::osl::MutexGuard guard(getMutex());
+ try
+ {
+//Determine the repository to use
+ if (repository.equals(OUSTR("user")))
+ xPackageManager = m_userRepository;
+ else if (repository.equals(OUSTR("shared")))
+ xPackageManager = m_sharedRepository;
+ else
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+
+ bUserDisabled = isUserDisabled(identifier, fileName);
+ //Backup the extension, in case the user cancels the action
+ xExtensionBackup = backupExtension(
+ identifier, fileName, xPackageManager, xCmdEnv);
+
+ //revoke the extension if it is active
+ Reference<deploy::XPackage> xOldExtension =
+ xPackageManager->getDeployedPackage(
+ identifier, fileName, xCmdEnv);
+ xOldExtension->revokePackage(xAbortChannel, xCmdEnv);
+
+ xPackageManager->removePackage(
+ identifier, fileName, xAbortChannel, xCmdEnv);
+ activateExtension(identifier, fileName, bUserDisabled, false,
+ xAbortChannel, xCmdEnv);
+ fireModified();
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred1 = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred1 = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during removeEtension"),
+ static_cast<OWeakObject*>(this), excOccurred1);
+ excOccurred1 <<= exc;
+ }
+
+ if (excOccurred1.hasValue())
+ {
+ //User aborted installation, restore the previous situation.
+ //Use a private AbortChannel so the user cannot interrupt.
+ try
+ {
+ Reference<ucb::XCommandEnvironment> tmpCmdEnv(
+ new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
+ if (xExtensionBackup.is())
+ {
+ Reference<deploy::XPackage> xRestored =
+ xPackageManager->importExtension(
+ xExtensionBackup, Reference<task::XAbortChannel>(),
+ tmpCmdEnv);
+ activateExtension(
+ identifier, fileName, bUserDisabled, false,
+ Reference<task::XAbortChannel>(),
+ tmpCmdEnv);
+
+ m_tmpRepository->removePackage(
+ dp_misc::getIdentifier(xExtensionBackup),
+ xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
+ fireModified();
+ }
+ }
+ catch (...)
+ {
+ }
+ ::cppu::throwException(excOccurred1);
+ }
+
+ if (xExtensionBackup.is())
+ m_tmpRepository->removePackage(
+ dp_misc::getIdentifier(xExtensionBackup),
+ xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
+}
+
+// Only enable extensions from shared and user repository
+void ExtensionManager::enableExtension(
+ Reference<deploy::XPackage> const & extension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard guard(getMutex());
+ bool bUserDisabled = false;
+ uno::Any excOccurred;
+ try
+ {
+ if (!extension.is())
+ return;
+ OUString repository = extension->getRepositoryName();
+ if (!repository.equals(OUSTR("user")))
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+
+ bUserDisabled = isUserDisabled(dp_misc::getIdentifier(extension),
+ extension->getName());
+
+ activateExtension(dp_misc::getIdentifier(extension),
+ extension->getName(), false, false,
+ xAbortChannel, xCmdEnv);
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during enableExtension"),
+ static_cast<OWeakObject*>(this), excOccurred);
+ excOccurred <<= exc;
+ }
+
+ if (excOccurred.hasValue())
+ {
+ try
+ {
+ activateExtension(dp_misc::getIdentifier(extension),
+ extension->getName(), bUserDisabled, false,
+ xAbortChannel, xCmdEnv);
+ }
+ catch (...)
+ {
+ }
+ ::cppu::throwException(excOccurred);
+ }
+}
+
+/**
+ */
+sal_Int32 ExtensionManager::checkPrerequisitesAndEnable(
+ Reference<deploy::XPackage> const & extension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ if (!extension.is())
+ return 0;
+ ::osl::MutexGuard guard(getMutex());
+ sal_Int32 ret = 0;
+ Reference<deploy::XPackageManager> mgr =
+ getPackageManager(extension->getRepositoryName());
+ ret = mgr->checkPrerequisites(extension, xAbortChannel, xCmdEnv);
+ if (ret)
+ {
+ //There are some unfulfilled prerequisites, try to revoke
+ extension->revokePackage(xAbortChannel, xCmdEnv);
+ }
+ const OUString id(dp_misc::getIdentifier(extension));
+ activateExtension(id, extension->getName(),
+ isUserDisabled(id, extension->getName()), false,
+ xAbortChannel, xCmdEnv);
+ return ret;
+ }
+ catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any excOccurred = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during disableExtension"),
+ static_cast<OWeakObject*>(this), excOccurred);
+ throw exc;
+ }
+}
+
+
+void ExtensionManager::disableExtension(
+ Reference<deploy::XPackage> const & extension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard guard(getMutex());
+ uno::Any excOccurred;
+ bool bUserDisabled = false;
+ try
+ {
+ if (!extension.is())
+ return;
+ const OUString repository( extension->getRepositoryName());
+ if (!repository.equals(OUSTR("user")))
+ throw lang::IllegalArgumentException(
+ OUSTR("No valid repository name provided."),
+ static_cast<cppu::OWeakObject*>(this), 0);
+
+ const OUString id(dp_misc::getIdentifier(extension));
+ bUserDisabled = isUserDisabled(id, extension->getName());
+
+ activateExtension(id, extension->getName(), true, false,
+ xAbortChannel, xCmdEnv);
+ }
+ catch (deploy::DeploymentException& ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (ucb::CommandFailedException & ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (ucb::CommandAbortedException & ) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (lang::IllegalArgumentException &) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (uno::RuntimeException &) {
+ excOccurred = ::cppu::getCaughtException();
+ } catch (...) {
+ excOccurred = ::cppu::getCaughtException();
+ deploy::DeploymentException exc(
+ OUSTR("Extension Manager: exception during disableExtension"),
+ static_cast<OWeakObject*>(this), excOccurred);
+ excOccurred <<= exc;
+ }
+
+ if (excOccurred.hasValue())
+ {
+ try
+ {
+ activateExtension(dp_misc::getIdentifier(extension),
+ extension->getName(), bUserDisabled, false,
+ xAbortChannel, xCmdEnv);
+ }
+ catch (...)
+ {
+ }
+ ::cppu::throwException(excOccurred);
+ }
+}
+
+uno::Sequence< Reference<deploy::XPackage> >
+ ExtensionManager::getDeployedExtensions(
+ OUString const & repository,
+ Reference<task::XAbortChannel> const &xAbort,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return getPackageManager(repository)->getDeployedPackages(
+ xAbort, xCmdEnv);
+}
+
+Reference<deploy::XPackage>
+ ExtensionManager::getDeployedExtension(
+ OUString const & repository,
+ OUString const & identifier,
+ OUString const & filename,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return getPackageManager(repository)->getDeployedPackage(
+ identifier, filename, xCmdEnv);
+}
+
+uno::Sequence< uno::Sequence<Reference<deploy::XPackage> > >
+ ExtensionManager::getAllExtensions(
+ Reference<task::XAbortChannel> const & xAbort,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ id2extensions mapExt;
+
+ uno::Sequence<Reference<deploy::XPackage> > userExt =
+ m_userRepository->getDeployedPackages(xAbort, xCmdEnv);
+ addExtensionsToMap(mapExt, userExt, OUSTR("user"));
+ uno::Sequence<Reference<deploy::XPackage> > sharedExt =
+ m_sharedRepository->getDeployedPackages(xAbort, xCmdEnv);
+ addExtensionsToMap(mapExt, sharedExt, OUSTR("shared"));
+ uno::Sequence<Reference<deploy::XPackage> > bundledExt =
+ m_bundledRepository->getDeployedPackages(xAbort, xCmdEnv);
+ addExtensionsToMap(mapExt, bundledExt, OUSTR("bundled"));
+
+ //copy the values of the map to a vector for sorting
+ ::std::vector< ::std::vector<Reference<deploy::XPackage> > >
+ vecExtensions;
+ id2extensions::const_iterator mapIt = mapExt.begin();
+ for (;mapIt != mapExt.end(); mapIt++)
+ vecExtensions.push_back(mapIt->second);
+
+ //sort the element according to the identifier
+ ::std::sort(vecExtensions.begin(), vecExtensions.end(), CompIdentifiers());
+
+ ::std::vector< ::std::vector<Reference<deploy::XPackage> > >::const_iterator
+ citVecVec = vecExtensions.begin();
+ sal_Int32 j = 0;
+ uno::Sequence< uno::Sequence<Reference<deploy::XPackage> > > seqSeq(vecExtensions.size());
+ for (;citVecVec != vecExtensions.end(); citVecVec++, j++)
+ {
+ seqSeq[j] = comphelper::containerToSequence(*citVecVec);
+ }
+ return seqSeq;
+
+ } catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception during enableExtension"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+//only to be called from unopkg!!!
+void ExtensionManager::reinstallDeployedExtensions(
+ OUString const & repository,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException, ucb::CommandAbortedException,
+ lang::IllegalArgumentException, uno::RuntimeException)
+{
+ try
+ {
+ Reference<deploy::XPackageManager>
+ xPackageManager = getPackageManager(repository);
+
+ ::osl::MutexGuard guard(getMutex());
+ xPackageManager->reinstallDeployedPackages(xAbortChannel, xCmdEnv);
+ //We must sync here, otherwise we will get exceptions when extensions
+ //are removed.
+ dp_misc::syncRepositories(xCmdEnv);
+ const uno::Sequence< Reference<deploy::XPackage> > extensions(
+ xPackageManager->getDeployedPackages(xAbortChannel, xCmdEnv));
+
+ for ( sal_Int32 pos = 0; pos < extensions.getLength(); ++pos )
+ {
+ try
+ {
+ const OUString id = dp_misc::getIdentifier(extensions[ pos ]);
+ const OUString fileName = extensions[ pos ]->getName();
+ OSL_ASSERT(id.getLength());
+ activateExtension(id, fileName, false, false, xAbortChannel, xCmdEnv );
+ }
+ catch (lang::DisposedException &)
+ {
+ }
+ }
+ } catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception during enableExtension"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+sal_Bool ExtensionManager::synchronize(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deploy::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ try
+ {
+ sal_Bool bModified = sal_False;
+
+ ::osl::MutexGuard guard(getMutex());
+ String sSynchronizingShared(StrSyncRepository::get());
+ sSynchronizingShared.SearchAndReplaceAllAscii( "%NAME", OUSTR("shared"));
+ dp_misc::ProgressLevel progressShared(xCmdEnv, sSynchronizingShared);
+ bModified = m_sharedRepository->synchronize(xAbortChannel, xCmdEnv);
+ progressShared.update(OUSTR("\n\n"));
+
+ String sSynchronizingBundled(StrSyncRepository::get());
+ sSynchronizingBundled.SearchAndReplaceAllAscii( "%NAME", OUSTR("bundled"));
+ dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled);
+ bModified |= m_bundledRepository->synchronize(xAbortChannel, xCmdEnv);
+ progressBundled.update(OUSTR("\n\n"));
+
+ try
+ {
+ const uno::Sequence<uno::Sequence<Reference<deploy::XPackage> > >
+ seqSeqExt = getAllExtensions(xAbortChannel, xCmdEnv);
+ for (sal_Int32 i = 0; i < seqSeqExt.getLength(); i++)
+ {
+ uno::Sequence<Reference<deploy::XPackage> > const & seqExt =
+ seqSeqExt[i];
+ activateExtension(seqExt, isUserDisabled(seqExt), true,
+ xAbortChannel, xCmdEnv);
+ }
+ }
+ catch (...)
+ {
+ //We catch the exception, so we can write the lastmodified file
+ //so we will no repeat this everytime OOo starts.
+ OSL_ENSURE(0, "Extensions Manager: synchronize");
+ }
+ OUString lastSyncBundled(RTL_CONSTASCII_USTRINGPARAM(
+ "$BUNDLED_EXTENSIONS_USER/lastsynchronized"));
+ writeLastModified(lastSyncBundled, xCmdEnv);
+ OUString lastSyncShared(RTL_CONSTASCII_USTRINGPARAM(
+ "$SHARED_EXTENSIONS_USER/lastsynchronized"));
+ writeLastModified(lastSyncShared, xCmdEnv);
+ return bModified;
+ } catch (deploy::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any exc = ::cppu::getCaughtException();
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: exception in synchronize"),
+ static_cast<OWeakObject*>(this), exc);
+ }
+}
+
+// Notify the user when a new extension is to be installed. This is only the
+// case when one uses the system integration to install an extension (double
+// clicking on .oxt file etc.)). The function must only be called if there is no
+// extension with the same identifier already deployed. Then the checkUpdate
+// function will inform the user that the extension is about to be installed In
+// case the user cancels the installation a CommandFailed exception is
+// thrown.
+void ExtensionManager::checkInstall(
+ OUString const & displayName,
+ Reference<ucb::XCommandEnvironment> const & cmdEnv)
+{
+ uno::Any request(
+ deploy::InstallException(
+ OUSTR("Extension ") + displayName +
+ OUSTR(" is about to be installed."),
+ static_cast<OWeakObject *>(this), displayName));
+ bool approve = false, abort = false;
+ if (! dp_misc::interactContinuation(
+ request, task::XInteractionApprove::static_type(),
+ cmdEnv, &approve, &abort ))
+ {
+ OSL_ASSERT( !approve && !abort );
+ throw deploy::DeploymentException(
+ dp_misc::getResourceString(RID_STR_ERROR_WHILE_ADDING) + displayName,
+ static_cast<OWeakObject *>(this), request );
+ }
+ if (abort || !approve)
+ throw ucb::CommandFailedException(
+ dp_misc::getResourceString(RID_STR_ERROR_WHILE_ADDING) + displayName,
+ static_cast<OWeakObject *>(this), request );
+}
+
+/* The function will make the user interaction in case there is an extension
+installed with the same id. This function may only be called if there is already
+an extension.
+*/
+void ExtensionManager::checkUpdate(
+ OUString const & newVersion,
+ OUString const & newDisplayName,
+ Reference<deploy::XPackage> const & oldExtension,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ // package already deployed, interact --force:
+ uno::Any request(
+ (deploy::VersionException(
+ dp_misc::getResourceString(
+ RID_STR_PACKAGE_ALREADY_ADDED ) + newDisplayName,
+ static_cast<OWeakObject *>(this), newVersion, newDisplayName,
+ oldExtension ) ) );
+ bool replace = false, abort = false;
+ if (! dp_misc::interactContinuation(
+ request, task::XInteractionApprove::static_type(),
+ xCmdEnv, &replace, &abort )) {
+ OSL_ASSERT( !replace && !abort );
+ throw deploy::DeploymentException(
+ dp_misc::getResourceString(
+ RID_STR_ERROR_WHILE_ADDING) + newDisplayName,
+ static_cast<OWeakObject *>(this), request );
+ }
+ if (abort || !replace)
+ throw ucb::CommandFailedException(
+ dp_misc::getResourceString(
+ RID_STR_PACKAGE_ALREADY_ADDED) + newDisplayName,
+ static_cast<OWeakObject *>(this), request );
+}
+
+Reference<deploy::XPackage> ExtensionManager::getTempExtension(
+ OUString const & url,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & /*xCmdEnv*/)
+
+{
+ Reference<ucb::XCommandEnvironment> tmpCmdEnvA(new TmpRepositoryCommandEnv());
+ Reference<deploy::XPackage> xTmpPackage = m_tmpRepository->addPackage(
+ url, uno::Sequence<beans::NamedValue>(),OUString(), xAbortChannel, tmpCmdEnvA);
+ if (!xTmpPackage.is())
+ {
+ throw deploy::DeploymentException(
+ OUSTR("Extension Manager: Failed to create temporary XPackage for url: ") + url,
+ static_cast<OWeakObject*>(this), uno::Any());
+
+ }
+ return xTmpPackage;
+}
+
+uno::Sequence<Reference<deploy::XPackage> > SAL_CALL
+ExtensionManager::getExtensionsWithUnacceptedLicenses(
+ OUString const & repository,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (deploy::DeploymentException,
+ uno::RuntimeException)
+{
+ Reference<deploy::XPackageManager>
+ xPackageManager = getPackageManager(repository);
+ ::osl::MutexGuard guard(getMutex());
+ return xPackageManager->getExtensionsWithUnacceptedLicenses(xCmdEnv);
+}
+
+sal_Bool ExtensionManager::isReadOnlyRepository(::rtl::OUString const & repository)
+ throw (uno::RuntimeException)
+{
+ return getPackageManager(repository)->isReadOnly();
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<ExtensionManager> servicePIP;
+extern sdecl::ServiceDecl const serviceDecl(
+ servicePIP,
+ // a private one:
+ "com.sun.star.comp.deployment.ExtensionManager",
+ "com.sun.star.comp.deployment.ExtensionManager");
+
+//------------------------------------------------------------------------------
+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
+ OUSTR("/UNO/SINGLETONS/"
+ "com.sun.star.deployment.ExtensionManager") ) );
+ 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;
+ }
+}
+
+// XModifyBroadcaster
+//______________________________________________________________________________
+void ExtensionManager::addModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (uno::RuntimeException)
+{
+ check();
+ rBHelper.addListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+void ExtensionManager::removeModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (uno::RuntimeException)
+{
+ check();
+ rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
+}
+
+void ExtensionManager::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed) {
+ throw lang::DisposedException(
+ OUSTR("ExtensionManager instance has already been disposed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+}
+
+void ExtensionManager::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))) );
+ }
+}
+
+} // namespace dp_manager
+
+
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.hxx b/desktop/source/deployment/manager/dp_extensionmanager.hxx
new file mode 100644
index 000000000000..64cada7da3ac
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx
@@ -0,0 +1,307 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_EXTENSIONMANAGER_H
+#define INCLUDED_DP_EXTENSIONMANAGER_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 "ucbhelper/content.hxx"
+#include "com/sun/star/deployment/XPackageRegistry.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "osl/mutex.hxx"
+#include <list>
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_manager {
+
+typedef ::std::hash_map<
+ ::rtl::OUString,
+ ::std::vector<css::uno::Reference<css::deployment::XPackage> >,
+ ::rtl::OUStringHash > id2extensions;
+
+
+class ExtensionManager : private ::dp_misc::MutexHolder,
+ public ::cppu::WeakComponentImplHelper1< css::deployment::XExtensionManager >
+{
+public:
+ ExtensionManager( css::uno::Reference< css::uno::XComponentContext >const& xContext);
+ virtual ~ExtensionManager();
+
+ static css::uno::Sequence< ::rtl::OUString > getServiceNames();
+ static ::rtl::OUString getImplName();
+
+ void check();
+ void fireModified();
+
+public:
+
+// 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);
+
+//XExtensionManager
+ 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 addExtension(
+ ::rtl::OUString const & url,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ ::rtl::OUString const & repository,
+ 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 removeExtension(
+ ::rtl::OUString const & identifier,
+ ::rtl::OUString const & filename,
+ ::rtl::OUString const & repository,
+ 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 enableExtension(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ 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 disableExtension(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ 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_Int32 SAL_CALL checkPrerequisitesAndEnable(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ 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 css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
+ SAL_CALL getDeployedExtensions(
+ ::rtl::OUString const & repository,
+ css::uno::Reference<css::task::XAbortChannel> const &,
+ 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 css::uno::Reference< css::deployment::XPackage>
+ SAL_CALL getDeployedExtension(
+ ::rtl::OUString const & repository,
+ ::rtl::OUString const & identifier,
+ ::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);
+
+ virtual css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> >
+ SAL_CALL getExtensionsWithSameIdentifier(
+ ::rtl::OUString const & identifier,
+ ::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);
+
+ virtual css::uno::Sequence< css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > >
+ SAL_CALL getAllExtensions(
+ css::uno::Reference<css::task::XAbortChannel> const &,
+ 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 reinstallDeployedExtensions(
+ ::rtl::OUString const & repository,
+ 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 synchronize(
+ 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 css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > SAL_CALL
+ getExtensionsWithUnacceptedLicenses(
+ ::rtl::OUString const & repository,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (css::deployment::DeploymentException,
+ css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isReadOnlyRepository(::rtl::OUString const & repository)
+ throw (css::uno::RuntimeException);
+
+private:
+
+ struct StrSyncRepository : public ::dp_misc::StaticResourceString<
+ StrSyncRepository, RID_STR_SYNCHRONIZING_REPOSITORY> {};
+
+ struct ExtensionInfos
+ {
+ ::rtl::OUString identifier;
+ ::rtl::OUString fileName;
+ ::rtl::OUString displayName;
+ ::rtl::OUString version;
+ };
+
+ css::uno::Reference< css::uno::XComponentContext> m_xContext;
+
+ css::uno::Reference<css::deployment::XPackageManager> m_userRepository;
+ css::uno::Reference<css::deployment::XPackageManager> m_sharedRepository;
+ css::uno::Reference<css::deployment::XPackageManager> m_bundledRepository;
+ css::uno::Reference<css::deployment::XPackageManager> m_tmpRepository;
+
+ /* contains the names of all repositories (except tmp) in order of there
+ priority. That is, the first element is "user" follod by "shared" and
+ then "bundled"
+ */
+ ::std::list< ::rtl::OUString > m_repositoryNames;
+
+ bool isUserDisabled(::rtl::OUString const & identifier,
+ ::rtl::OUString const & filename);
+
+ bool isUserDisabled(
+ css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExtSameId);
+
+ void activateExtension(
+ ::rtl::OUString const & identifier,
+ ::rtl::OUString const & fileName,
+ bool bUserDisabled, bool bStartup,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ void activateExtension(
+ css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExt,
+ bool bUserDisabled, bool bStartup,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+
+
+ ::std::list<css::uno::Reference<css::deployment::XPackage> >
+ getExtensionsWithSameId(::rtl::OUString const & identifier,
+ ::rtl::OUString const & fileName,
+ css::uno::Reference< css::ucb::XCommandEnvironment> const & xCmdEnv =
+ css::uno::Reference< css::ucb::XCommandEnvironment>());
+
+ css::uno::Reference<css::deployment::XPackage> backupExtension(
+ ::rtl::OUString const & identifier, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ void checkInstall(
+ ::rtl::OUString const & displayName,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & cmdEnv);
+
+ void checkUpdate(
+ ::rtl::OUString const & newVersion,
+ ::rtl::OUString const & newDisplayName,
+ css::uno::Reference<css::deployment::XPackage> const & oldExtension,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ css::uno::Reference<css::deployment::XPackage> getTempExtension(
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+
+ void addExtensionsToMap(
+ id2extensions & mapExt,
+ css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > const & seqExt,
+ ::rtl::OUString const & repository);
+
+ css::uno::Reference<css::deployment::XPackageManager>
+ getPackageManager(::rtl::OUString const & repository)
+ throw (css::lang::IllegalArgumentException);
+};
+
+}
+
+
+
+
+#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..4cc43a8386d8
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_informationprovider.cxx
@@ -0,0 +1,393 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/UpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageInformationProvider.hpp"
+#include "com/sun/star/deployment/ExtensionManager.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"
+#include "dp_update.hxx"
+
+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 rtl::OUString& repository,
+ const rtl::OUString& _sExtensionId );
+
+ uno::Reference< deployment::XUpdateInformationProvider > mxUpdateInformation;
+};
+
+//------------------------------------------------------------------------------
+
+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 rtl::OUString & repository,
+ const rtl::OUString& _rExtensionId )
+{
+ rtl::OUString aLocationURL;
+ uno::Reference<deployment::XExtensionManager> xManager =
+ deployment::ExtensionManager::get(mxContext);
+
+ if ( xManager.is() )
+ {
+ const uno::Sequence< uno::Reference< deployment::XPackage > > packages(
+ xManager->getDeployedExtensions(
+ repository,
+ 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 )
+{
+ rtl::OUString aLocationURL = getPackageLocation( UNISTRING("user"), _sExtensionId );
+
+ if ( aLocationURL.getLength() == 0 )
+ {
+ aLocationURL = getPackageLocation( UNISTRING("shared"), _sExtensionId );
+ }
+ if ( aLocationURL.getLength() == 0 )
+ {
+ aLocationURL = getPackageLocation( UNISTRING("bundled"), _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 > > aList;
+
+ uno::Reference<deployment::XExtensionManager> extMgr =
+ deployment::ExtensionManager::get(mxContext);
+
+ if (!extMgr.is())
+ {
+ OSL_ASSERT(0);
+ return aList;
+ }
+ std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
+ dp_misc::UpdateInfoMap updateInfoMap;
+ if (_sExtensionId.getLength())
+ {
+ std::vector<uno::Reference<deployment::XPackage> > vecExtensions;
+ uno::Reference<deployment::XPackage> extension;
+ try
+ {
+ extension = dp_misc::getExtensionWithHighestVersion(
+ extMgr->getExtensionsWithSameIdentifier(
+ _sExtensionId, _sExtensionId, uno::Reference<css_ucb::XCommandEnvironment>()));
+ vecExtensions.push_back(extension);
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ OSL_ASSERT(0);
+ }
+ updateInfoMap = dp_misc::getOnlineUpdateInfos(
+ mxContext, extMgr, mxUpdateInformation, &vecExtensions, errors);
+ }
+ else
+ {
+ updateInfoMap = dp_misc::getOnlineUpdateInfos(
+ mxContext, extMgr, mxUpdateInformation, NULL, errors);
+ }
+
+ int nCount = 0;
+ for (dp_misc::UpdateInfoMap::iterator i(updateInfoMap.begin()); i != updateInfoMap.end(); i++)
+ {
+ dp_misc::UpdateInfo const & info = i->second;
+
+ rtl::OUString sOnlineVersion;
+ if (info.info.is())
+ {
+ // check, if there are unsatisfied dependencies and ignore this online update
+ dp_misc::DescriptionInfoset infoset(mxContext, info.info);
+ uno::Sequence< uno::Reference< xml::dom::XElement > >
+ ds( dp_misc::Dependencies::check( infoset ) );
+ if ( ! ds.getLength() )
+ sOnlineVersion = info.version;
+ }
+
+ rtl::OUString sVersionUser;
+ rtl::OUString sVersionShared;
+ rtl::OUString sVersionBundled;
+ uno::Sequence< uno::Reference< deployment::XPackage> > extensions;
+ try {
+ extensions = extMgr->getExtensionsWithSameIdentifier(
+ dp_misc::getIdentifier(info.extension), info.extension->getName(),
+ uno::Reference<css_ucb::XCommandEnvironment>());
+ } catch (lang::IllegalArgumentException& ) {
+ OSL_ASSERT(0);
+ }
+ OSL_ASSERT(extensions.getLength() == 3);
+ if (extensions[0].is() )
+ sVersionUser = extensions[0]->getVersion();
+ if (extensions[1].is() )
+ sVersionShared = extensions[1]->getVersion();
+ if (extensions[2].is() )
+ sVersionBundled = extensions[2]->getVersion();
+
+ bool bSharedReadOnly = extMgr->isReadOnlyRepository(OUSTR("shared"));
+
+ dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
+ bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
+ dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
+ bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
+
+ rtl::OUString updateVersionUser;
+ rtl::OUString updateVersionShared;
+ if (sourceUser != dp_misc::UPDATE_SOURCE_NONE)
+ updateVersionUser = dp_misc::getHighestVersion(
+ rtl::OUString(), sVersionShared, sVersionBundled, sOnlineVersion);
+ if (sourceShared != dp_misc::UPDATE_SOURCE_NONE)
+ updateVersionShared = dp_misc::getHighestVersion(
+ rtl::OUString(), rtl::OUString(), sVersionBundled, sOnlineVersion);
+ rtl::OUString updateVersion;
+ if (dp_misc::compareVersions(updateVersionUser, updateVersionShared) == dp_misc::GREATER)
+ updateVersion = updateVersionUser;
+ else
+ updateVersion = updateVersionShared;
+ if (updateVersion.getLength())
+ {
+
+ rtl::OUString aNewEntry[2];
+ aNewEntry[0] = i->first;
+ aNewEntry[1] = updateVersion;
+ aList.realloc( ++nCount );
+ aList[ nCount-1 ] = ::uno::Sequence< rtl::OUString >( aNewEntry, 2 );
+ }
+ }
+ return aList;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL PackageInformationProvider::getExtensionList()
+ throw ( uno::RuntimeException )
+{
+ const uno::Reference<deployment::XExtensionManager> mgr =
+ deployment::ExtensionManager::get(mxContext);
+
+ if (!mgr.is())
+ return uno::Sequence< uno::Sequence< rtl::OUString > >();
+
+ const uno::Sequence< uno::Sequence< uno::Reference<deployment::XPackage > > >
+ allExt = mgr->getAllExtensions(
+ uno::Reference< task::XAbortChannel >(),
+ static_cast < XCommandEnvironment *> (this) );
+
+ uno::Sequence< uno::Sequence< rtl::OUString > > retList;
+
+ sal_Int32 cAllIds = allExt.getLength();
+ retList.realloc(cAllIds);
+
+ for (sal_Int32 i = 0; i < cAllIds; i++)
+ {
+ //The inner sequence contains extensions with the same identifier from
+ //all the different repositories, that is user, share, bundled.
+ const uno::Sequence< uno::Reference< deployment::XPackage > > &
+ seqExtension = allExt[i];
+ sal_Int32 cExt = seqExtension.getLength();
+ OSL_ASSERT(cExt == 3);
+ for (sal_Int32 j = 0; j < cExt; j++)
+ {
+ //ToDo according to the old code the first found extenions is used
+ //even if another one with the same id has a better version.
+ uno::Reference< deployment::XPackage > const & xExtension( seqExtension[j] );
+ if (xExtension.is())
+ {
+ rtl::OUString aNewEntry[2];
+ aNewEntry[0] = dp_misc::getIdentifier(xExtension);
+ aNewEntry[1] = xExtension->getVersion();
+ retList[i] = ::uno::Sequence< rtl::OUString >( aNewEntry, 2 );
+ break;
+ }
+ }
+ }
+ return retList;
+}
+
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+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..44bc4d469f2f
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.cxx
@@ -0,0 +1,1673 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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 "osl/security.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 "svl/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/deployment/Prerequisites.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/ucb/UnsupportedCommandException.hpp"
+#include "boost/bind.hpp"
+#include "tools/urlobj.hxx"
+
+#include "osl/file.hxx"
+#include <vector>
+#include <list>
+#include "dp_descriptioninfoset.hxx"
+#include "dp_commandenvironments.hxx"
+#include "dp_properties.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_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 );
+ }
+};
+
+
+namespace {
+OUString getExtensionFolder(OUString const & parentFolder,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ ::ucbhelper::Content tempFolder(
+ parentFolder, xCmdEnv );
+ Reference<sdbc::XResultSet> xResultSet(
+ tempFolder.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
+
+ OUString title;
+ while (xResultSet->next())
+ {
+ title = Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(1 /* Title */ ) ;
+ break;
+ }
+ return title;
+}
+}
+//______________________________________________________________________________
+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(
+ Sequence<css::beans::NamedValue>(),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 );
+ m_registrationData_expanded = expandUnoRcUrl(m_registrationData);
+ if (!m_readOnly)
+ create_folder( 0, m_activePackages_expanded, xCmdEnv, true);
+
+ OUString dbName;
+ if (m_context.equals(OUSTR("user")))
+ dbName = m_activePackages_expanded + OUSTR(".db");
+ else
+ {
+ //Create the extension data base in the user installation
+ create_folder( 0, m_registrationData_expanded, xCmdEnv, true);
+ dbName = m_registrationData_expanded + OUSTR("/extensions.db");
+ }
+ //The data base can always be written because it it always in the user installation
+ m_activePackagesDB.reset(
+ new ActivePackages( dbName, false ) );
+
+ if (! m_readOnly && ! m_context.equals(OUSTR("bundled")))
+ {
+ // 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;
+ ::std::vector<OUString> removedEntries;
+ while (xResultSet->next())
+ {
+ OUString title(
+ Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(
+ 1 /* Title */ ) );
+
+ const char extensionRemoved[] = "removed";
+ if (title.endsWithAsciiL(
+ extensionRemoved, sizeof(extensionRemoved) - 1))
+ {
+ //save the file name withouth the "removed" part
+ sal_Int32 index = title.lastIndexOfAsciiL(
+ extensionRemoved, sizeof(extensionRemoved) - 1);
+ OUString remFile = title.copy(0, index);
+ removedEntries.push_back(::rtl::Uri::encode(
+ remFile, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ {
+ tempEntries.push_back( ::rtl::Uri::encode(
+ title, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ }
+
+ bool bShared = m_context.equals(OUSTR("shared")) ? true : false;
+ 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())
+ {
+ const OUString url(
+ makeURL(m_activePackages_expanded, tempEntry ) );
+
+ //In case of shared extensions, new entries are regarded as
+ //added extensions if there is no xxx.tmpremoved file.
+ if (bShared)
+ {
+ if (::std::find(removedEntries.begin(), removedEntries.end(), tempEntry) ==
+ removedEntries.end())
+ {
+ continue;
+ }
+ else
+ {
+ //Make sure only the same user removes the extension, who
+ //previously unregistered it. This is avoid races if multiple instances
+ //of OOo are running which all have write access to the shared installation.
+ //For example, a user removes the extension, but keeps OOo
+ //running. Parts of the extension may still be loaded and used by OOo.
+ //Therefore the extension is only deleted the next time the extension manager is
+ //run after restarting OOo. While OOo is still running, another user starts OOo
+ //which would deleted the extension files. If the same user starts another
+ //instance of OOo then the lock file will prevent this.
+ OUString aUserName;
+ ::osl::Security aSecurity;
+ aSecurity.getUserName( aUserName );
+ ucbhelper::Content remFileContent(
+ url + OUSTR("removed"), Reference<XCommandEnvironment>());
+ ::rtl::ByteSequence data = dp_misc::readFile(remFileContent);
+ ::rtl::OString osData(reinterpret_cast<const sal_Char*>(data.getConstArray()),
+ data.getLength());
+ OUString sData = ::rtl::OStringToOUString(
+ osData, RTL_TEXTENCODING_UTF8);
+ if (!sData.equals(aUserName))
+ continue;
+ }
+ }
+ // temp entry not needed anymore:
+ erase_path( url + OUSTR("_"),
+ Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ erase_path( url, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ //delete the xxx.tmpremoved file
+ erase_path(url + OUSTR("removed"),
+ Reference<XCommandEnvironment>(), false);
+ }
+ }
+ }
+ }
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::initRegistryBackends()
+{
+ if (m_registryCache.getLength() > 0)
+ create_folder( 0, m_registryCache,
+ Reference<XCommandEnvironment>(), false);
+ m_xRegistry.set( ::dp_registry::create(
+ m_context, m_registryCache, false,
+ 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_registrationData = OUSTR(
+ "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
+ 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_registrationData = OUSTR(
+ "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER");
+ that->m_registryCache = OUSTR(
+ "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/registry");
+ logFile = OUSTR(
+ "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/log.txt");
+ stampURL = OUSTR(
+ "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/stamp.sys");
+ }
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") )) {
+ that->m_activePackages = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
+ that->m_registrationData = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER");
+ that->m_registryCache = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/registry");
+ logFile = OUSTR(
+ "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/log.txt");
+ //No stamp file. We assume that bundled is always readonly. It must not be
+ //modified from ExtensionManager but only by the installer
+ }
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("tmp") )) {
+ that->m_activePackages = OUSTR(
+ "vnd.sun.star.expand:$TMP_EXTENSIONS/extensions");
+ that->m_registrationData = OUSTR(
+ "vnd.sun.star.expand:$TMP_EXTENSIONS");
+ that->m_registryCache = OUSTR(
+ "vnd.sun.star.expand:$TMP_EXTENSIONS/registry");
+ stampURL = OUSTR(
+ "vnd.sun.star.expand:$TMP_EXTENSIONS/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 {
+ //There is no stampURL for the bundled folder
+ if (stampURL.getLength() > 0)
+ {
+#define CURRENT_STAMP "1"
+ try {
+ //The osl file API does not allow to find out if one can write
+ //into a folder. Therefore we try to write a file. Then we delete
+ //it, so that it does not hinder uninstallation of OOo
+ // probe writing:
+ ::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 */ );
+ that->m_readOnly = false;
+ erase_path( stampURL, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ try {
+ erase_path( stampURL, xCmdEnv );
+ } catch (...)
+ {
+ }
+ throw;
+ }
+ catch (Exception &) {
+ 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 ) );
+ }
+
+ 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(), false, 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(
+ Sequence<beans::NamedValue> const & properties,
+ 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;
+ if (!sourceContent.isFolder())
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
+ buf.append( ::rtl::Uri::encode( sourceContent.getURL(),
+ rtl_UriCharClassRegName,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ {
+ //Folder. No need to unzip, just copy
+ buf.append(sourceContent.getURL());
+ }
+ 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:
+ //bundled extensions should only be added by the synchronizeAddedExtensions
+ //functions. Moreover, there is no "temporary folder" for bundled extensions.
+ OSL_ASSERT(!m_context.equals(OUSTR("bundled")));
+ OUString sFolderUrl = makeURLAppendSysPathSegment(destFolderContent.getURL(), title);
+ DescriptionInfoset info =
+ dp_misc::getDescriptionInfoset(sFolderUrl);
+ dbData->temporaryName = tempEntry;
+ dbData->fileName = title;
+ dbData->mediaType = mediaType;
+ dbData->version = info.getVersion();
+
+ //No write the properties file next to the extension
+ ExtensionProperties props(sFolderUrl, properties, xCmdEnv);
+ props.write();
+ return destFolder;
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::insertToActivationLayerDB(
+ OUString const & id, ActivePackages::Data const & dbData )
+{
+ //access to the database must be guarded. See removePackage
+ const ::osl::MutexGuard guard( getMutex() );
+ 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::isInstalled(
+ Reference<deployment::XPackage> const & package)
+{
+ OUString id(dp_misc::getIdentifier(package));
+ OUString fn(package->getName());
+ bool bInstalled = false;
+ if (m_activePackagesDB->has( id, fn ))
+ {
+ bInstalled = true;
+ }
+ return bInstalled;
+}
+
+// XPackageManager
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::importExtension(
+ Reference<deployment::XPackage> const & extension,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ CommandAbortedException, lang::IllegalArgumentException,
+ RuntimeException)
+{
+ return addPackage(extension->getURL(), Sequence<beans::NamedValue>(),
+ OUString(), xAbortChannel, xCmdEnv_);
+}
+
+/* The function adds an extension but does not register it!!!
+ It may not do any user interaction. This is done in XExtensionManager::addExtension
+*/
+Reference<deployment::XPackage> PackageManagerImpl::addPackage(
+ OUString const & url,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ 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(
+ properties, mediaType, sourceContent, title, &dbData );
+
+
+ // bind activation package:
+ //Because every shared/user 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, false, OUString(), xCmdEnv );
+
+ OSL_ASSERT( xPackage.is() );
+ if (xPackage.is())
+ {
+ bool install = false;
+ try
+ {
+ OUString const id = dp_misc::getIdentifier( xPackage );
+
+ ::osl::MutexGuard g(m_addMutex);
+ if (isInstalled(xPackage))
+ {
+ //Do not guard the complete function with the getMutex
+ removePackage(id, xPackage->getName(), xAbortChannel,
+ xCmdEnv);
+ }
+ install = true;
+ insertToActivationLayerDB(id, dbData);
+ }
+ catch (...)
+ {
+ deletePackageFromCache( xPackage, destFolder );
+ throw;
+ }
+ if (!install)
+ {
+ deletePackageFromCache( xPackage, destFolder );
+ }
+ //ToDo: We should notify only if the extension is registered
+ 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, ::rtl::OUString const & fileName,
+ Reference<task::XAbortChannel> const & /*xAbortChannel*/,
+ 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 {
+ Reference<deployment::XPackage> xPackage;
+ {
+ const ::osl::MutexGuard guard(getMutex());
+ //Check if this extension exist and throw an IllegalArgumentException
+ //if it does not
+ //If the files of the extension are already removed, or there is a
+ //different extension at the same place, for example after updating the
+ //extension, then the returned object is that which uses the database data.
+ xPackage = getDeployedPackage_(id, fileName, xCmdEnv );
+
+
+ //Because the extension is only removed the next time the extension
+ //manager runs after restarting OOo, we need to indicate that a
+ //shared extension was "deleted". When a user starts OOo, then it
+ //will check if something changed in the shared repository. Based on
+ //the flag file it will then recognize, that the extension was
+ //deleted and can then update the extnesion database of the shared
+ //extensions in the user installation.
+ if ( xPackage.is() && !m_readOnly && !xPackage->isRemoved() && m_context.equals(OUSTR("shared")))
+ {
+ ActivePackages::Data val;
+ m_activePackagesDB->get( & val, id, fileName);
+ OSL_ASSERT(val.temporaryName.getLength());
+ OUString url(makeURL(m_activePackages_expanded,
+ val.temporaryName + OUSTR("removed")));
+ ::ucbhelper::Content contentRemoved(url, xCmdEnv );
+ OUString aUserName;
+ ::osl::Security aSecurity;
+ aSecurity.getUserName( aUserName );
+
+ ::rtl::OString stamp = ::rtl::OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8);
+ Reference<css::io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
+ stamp.getLength() ) ) );
+ contentRemoved.writeStream( xData, true /* replace existing */ );
+ }
+ m_activePackagesDB->erase( id, fileName ); // to be removed upon next start
+ }
+ try_dispose( xPackage );
+
+ 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 );
+ //The bundled extensions are not contained in an additional folder
+ //with a unique name. data.temporaryName contains already the
+ //UTF8 encoded folder name. See PackageManagerImpl::synchronize
+ if (!m_context.equals(OUSTR("bundled")))
+ {
+ 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) );
+ }
+ }
+ Reference<deployment::XPackage> xExtension;
+ try
+ {
+ //Ignore extensions where XPackage::checkPrerequisites failed.
+ //They must not be usable for this user.
+ if (data.failedPrerequisites.equals(OUSTR("0")))
+ {
+ xExtension = m_xRegistry->bindPackage(
+ getDeployPath( data ), data.mediaType, false, OUString(), xCmdEnv );
+ }
+ }
+ catch (deployment::InvalidRemovedParameterException& e)
+ {
+ xExtension = e.Extension;
+ }
+ return xExtension;
+}
+
+//______________________________________________________________________________
+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 )
+ {
+ if (! iPos->second.failedPrerequisites.equals(OUSTR("0")))
+ continue;
+ 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 );
+ }
+}
+
+//______________________________________________________________________________
+
+
+//ToDo: the function must not call registerPackage, do this in
+//XExtensionManager.reinstallDeployedExtensions
+void PackageManagerImpl::reinstallDeployedPackages(
+ Reference<task::XAbortChannel> const & /*xAbortChannel*/,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ check();
+ 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();
+
+ //registering is done by the ExtensionManager service.
+ }
+ 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;
+}
+bool PackageManagerImpl::synchronizeRemovedExtensions(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+{
+
+ //find all which are in the extension data base but which
+ //are removed already.
+ OSL_ASSERT(!m_context.equals(OUSTR("user")));
+ bool bModified = false;
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+
+ typedef ActivePackages::Entries::const_iterator ITActive;
+ bool bShared = m_context.equals(OUSTR("shared"));
+
+ for (ITActive i = id2temp.begin(); i != id2temp.end(); i++)
+ {
+ try
+ {
+ //Get the URL to the extensions folder, first make the url for the
+ //shared repository including the temporary name
+ OUString url = makeURL(m_activePackages, i->second.temporaryName);
+ if (bShared)
+ url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
+
+ bool bRemoved = false;
+ //Check if the URL to the extension is still the same
+ ::ucbhelper::Content contentExtension;
+
+ if (!create_ucb_content(
+ &contentExtension, url,
+ Reference<XCommandEnvironment>(), false))
+ {
+ bRemoved = true;
+ }
+
+ //The folder is in the extension database, but it can still be deleted.
+ //look for the xxx.tmpremoved file
+ //There can also be the case that a different extension was installed
+ //in a "temp" folder with name that is already used.
+ if (!bRemoved && bShared)
+ {
+ ::ucbhelper::Content contentRemoved;
+
+ if (create_ucb_content(
+ &contentRemoved,
+ m_activePackages_expanded + OUSTR("/") +
+ i->second.temporaryName + OUSTR("removed"),
+ Reference<XCommandEnvironment>(), false))
+ {
+ bRemoved = true;
+ }
+ }
+
+ if (!bRemoved)
+ {
+ //There may be another extensions at the same place
+ dp_misc::DescriptionInfoset infoset =
+ dp_misc::getDescriptionInfoset(url);
+ OSL_ENSURE(infoset.hasDescription(),
+ "Extension Manager: bundled and shared extensions "
+ "must have an identifer and a version");
+ if (infoset.hasDescription() &&
+ infoset.getIdentifier() &&
+ (! i->first.equals(*(infoset.getIdentifier()))
+ || ! i->second.version.equals(infoset.getVersion())))
+ {
+ bRemoved = true;
+ }
+
+ }
+ if (bRemoved)
+ {
+ Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
+ url, i->second.mediaType, true, i->first, xCmdEnv );
+ OSL_ASSERT(xPackage.is()); //Even if the files are removed, we must get the object.
+ xPackage->revokePackage(xAbortChannel, xCmdEnv);
+ removePackage(xPackage->getIdentifier().Value, xPackage->getName(),
+ xAbortChannel, xCmdEnv);
+ bModified |= true;
+ }
+ }
+ catch( uno::Exception & )
+ {
+ OSL_ASSERT(0);
+ }
+ }
+ return bModified;
+}
+
+
+bool PackageManagerImpl::synchronizeAddedExtensions(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ bool bModified = false;
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+ //check if the folder exist at all. The shared extension folder
+ //may not exist for a normal user.
+ if (!create_ucb_content(
+ NULL, m_activePackages_expanded, Reference<css::ucb::XCommandEnvironment>(), false))
+ return bModified;
+ ::ucbhelper::Content tempFolder(
+ m_activePackages_expanded, xCmdEnv );
+
+ Reference<sdbc::XResultSet> xResultSet(
+ tempFolder.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
+
+ while (xResultSet->next())
+ {
+ try
+ {
+ OUString title(
+ Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(
+ 1 /* Title */ ) );
+ //The temporary folders of user and shared have an '_' at then end.
+ //But the name in ActivePackages.temporaryName is saved without.
+ OUString title2 = title;
+ bool bNotBundled = !m_context.equals(OUSTR("bundled"));
+ if (bNotBundled)
+ {
+ OSL_ASSERT(title2[title2.getLength() -1] == '_');
+ title2 = title2.copy(0, title2.getLength() -1);
+ }
+ OUString titleEncoded = ::rtl::Uri::encode(
+ title2, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8);
+
+ //It it sufficient to check for the folder name, because when the administor
+ //installed the extension it was already checked if there is one with the
+ //same identifier.
+ const MatchTempDir match(titleEncoded);
+ if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
+ id2temp.end())
+ {
+
+ // The folder was not found in the data base, so it must be
+ // an added extension
+ OUString url(m_activePackages_expanded + OUSTR("/") + titleEncoded);
+ OUString sExtFolder;
+ if (bNotBundled) //that is, shared
+ {
+ //Check if the extension was not "deleted" already which is indicated
+ //by a xxx.tmpremoved file
+ ::ucbhelper::Content contentRemoved;
+ if (create_ucb_content(&contentRemoved, url + OUSTR("removed"),
+ Reference<XCommandEnvironment>(), false))
+ continue;
+ sExtFolder = getExtensionFolder(
+ m_activePackages_expanded +
+ OUString(OUSTR("/")) + titleEncoded + OUSTR("_"), xCmdEnv);
+ url = makeURLAppendSysPathSegment(m_activePackages_expanded, title);
+ url = makeURLAppendSysPathSegment(url, sExtFolder);
+ }
+ Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
+ url, OUString(), false, OUString(), xCmdEnv );
+ if (xPackage.is())
+ {
+ //Prepare the database entry
+ ActivePackages::Data dbData;
+
+ dbData.temporaryName = titleEncoded;
+ if (bNotBundled)
+ dbData.fileName = sExtFolder;
+ else
+ dbData.fileName = title;
+ dbData.mediaType = xPackage->getPackageType()->getMediaType();
+ dbData.version = xPackage->getVersion();
+ OSL_ENSURE(dbData.version.getLength() > 0,
+ "Extension Manager: bundled and shared extensions must have "
+ "an identifier and a version");
+
+ OUString id = dp_misc::getIdentifier( xPackage );
+
+ //We provide a special command environment that will prevent
+ //showing a license if simple-licens/@accept-by = "admin"
+ //It will also prevent showing the license for bundled extensions
+ //which is not supported.
+ OSL_ASSERT(!m_context.equals(OUSTR("user")));
+
+ // shall the license be suppressed?
+ DescriptionInfoset info =
+ dp_misc::getDescriptionInfoset(url);
+ ::boost::optional<dp_misc::SimpleLicenseAttributes>
+ attr = info.getSimpleLicenseAttributes();
+ ExtensionProperties props(url,xCmdEnv);
+ bool bNoLicense = false;
+ if (attr && attr->suppressIfRequired && props.isSuppressedLicense())
+ bNoLicense = true;
+
+ Reference<ucb::XCommandEnvironment> licCmdEnv(
+ new LicenseCommandEnv(xCmdEnv->getInteractionHandler(),
+ bNoLicense, m_context));
+ sal_Int32 failedPrereq = xPackage->checkPrerequisites(
+ xAbortChannel, licCmdEnv, false);
+ //Remember that this failed. For example, the user
+ //could have declined the license. Then the next time the
+ //extension folder is investigated we do not want to
+ //try to install the extension again.
+ dbData.failedPrerequisites = OUString::valueOf(failedPrereq);
+ insertToActivationLayerDB(id, dbData);
+ bModified |= true;
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ OSL_ASSERT(0);
+ }
+ }
+ return bModified;
+}
+
+sal_Bool PackageManagerImpl::synchronize(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ check();
+ bool bModified = false;
+ if (m_context.equals(OUSTR("user")))
+ return bModified;
+ bModified |=
+ synchronizeRemovedExtensions(xAbortChannel, xCmdEnv);
+ bModified |= synchronizeAddedExtensions(xAbortChannel, xCmdEnv);
+
+ return bModified;
+}
+
+Sequence< Reference<deployment::XPackage> > PackageManagerImpl::getExtensionsWithUnacceptedLicenses(
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (deployment::DeploymentException, RuntimeException)
+{
+ ::std::vector<Reference<deployment::XPackage> > vec;
+
+ try
+ {
+ const ::osl::MutexGuard guard( getMutex() );
+ // clean up activation layer, scan for zombie temp dirs:
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+
+ ActivePackages::Entries::const_iterator i = id2temp.begin();
+ bool bShared = m_context.equals(OUSTR("shared"));
+
+ for (; i != id2temp.end(); i++ )
+ {
+ //Get the database entry
+ ActivePackages::Data const & dbData = i->second;
+ sal_Int32 failedPrereq = dbData.failedPrerequisites.toInt32();
+ //If the installation failed for other reason then the license then we
+ //ignore it.
+ if (failedPrereq ^= deployment::Prerequisites::LICENSE)
+ continue;
+
+ //Prepare the URL to the extension
+ OUString url = makeURL(m_activePackages, i->second.temporaryName);
+ if (bShared)
+ url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName);
+
+ Reference<deployment::XPackage> p = m_xRegistry->bindPackage(
+ url, OUString(), false, OUString(), xCmdEnv );
+
+ if (p.is())
+ vec.push_back(p);
+
+ }
+ return ::comphelper::containerToSequence(vec);
+ }
+ catch (deployment::DeploymentException &)
+ {
+ throw;
+ }
+ catch (RuntimeException&)
+ {
+ throw;
+ }
+ catch (...)
+ {
+ Any exc = ::cppu::getCaughtException();
+ deployment::DeploymentException de(
+ OUSTR("PackageManagerImpl::getExtensionsWithUnacceptedLicenses"),
+ static_cast<OWeakObject*>(this), exc);
+ exc <<= de;
+ ::cppu::throwException(exc);
+ }
+
+ return ::comphelper::containerToSequence(vec);
+}
+
+sal_Int32 PackageManagerImpl::checkPrerequisites(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ 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)
+{
+ try
+ {
+ if (!extension.is())
+ return 0;
+ if (!m_context.equals(extension->getRepositoryName()))
+ throw lang::IllegalArgumentException(
+ OUSTR("PackageManagerImpl::checkPrerequisites: extension is not"
+ " from this repository."), 0, 0);
+
+ ActivePackages::Data dbData;
+ OUString id = dp_misc::getIdentifier(extension);
+ if (m_activePackagesDB->get( &dbData, id, OUString()))
+ {
+ //If the license was already displayed, then do not show it again
+ Reference<ucb::XCommandEnvironment> _xCmdEnv = xCmdEnv;
+ sal_Int32 prereq = dbData.failedPrerequisites.toInt32();
+ if ( !(prereq & deployment::Prerequisites::LICENSE))
+ _xCmdEnv = new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler());
+
+ sal_Int32 failedPrereq = extension->checkPrerequisites(
+ xAbortChannel, _xCmdEnv, false);
+ dbData.failedPrerequisites = OUString::valueOf(failedPrereq);
+ insertToActivationLayerDB(id, dbData);
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("PackageManagerImpl::checkPrerequisites: unknown extension"),
+ 0, 0);
+
+ }
+ return 0;
+ }
+ catch (deployment::DeploymentException& ) {
+ throw;
+ } catch (ucb::CommandFailedException & ) {
+ throw;
+ } catch (ucb::CommandAbortedException & ) {
+ throw;
+ } catch (lang::IllegalArgumentException &) {
+ throw;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (...) {
+ uno::Any excOccurred = ::cppu::getCaughtException();
+ deployment::DeploymentException exc(
+ OUSTR("PackageManagerImpl::checkPrerequisites: exception "),
+ static_cast<OWeakObject*>(this), excOccurred);
+ throw exc;
+ }
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+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..8fe0f662011b
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.h
@@ -0,0 +1,294 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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_registrationData;
+ ::rtl::OUString m_registrationData_expanded;
+ ::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(
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ ::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 isInstalled(
+ css::uno::Reference<css::deployment::XPackage> const & package);
+
+ bool synchronizeRemovedExtensions(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ bool synchronizeAddedExtensions(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ 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( true )
+ {}
+
+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,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ ::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);
+
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL importExtension(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ 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 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);
+
+ virtual ::sal_Bool SAL_CALL synchronize(
+ 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 css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > SAL_CALL
+ getExtensionsWithUnacceptedLicenses(
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
+ throw (css::deployment::DeploymentException,
+ css::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL checkPrerequisites(
+ css::uno::Reference<css::deployment::XPackage> const & extension,
+ 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);
+ };
+
+//______________________________________________________________________________
+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..6131cc381abf
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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)
+#define RID_STR_SYNCHRONIZING_REPOSITORY (RID_DEPLOYMENT_MANAGER_START+5)
+#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..7d38b880c37a
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.src
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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: ";
+};
+
+String RID_STR_SYNCHRONIZING_REPOSITORY
+{
+ Text [ en-US ] = "Synchronizing repository for %NAME extensions";
+};
diff --git a/desktop/source/deployment/manager/dp_managerfac.cxx b/desktop/source/deployment/manager/dp_managerfac.cxx
new file mode 100644
index 000000000000..f6fde6b07d60
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_managerfac.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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;
+ Reference<deployment::XPackageManager> m_xBundledMgr;
+ 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();
+ m_xBundledMgr.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 if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") ))
+ m_xBundledMgr = 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/dp_properties.cxx b/desktop/source/deployment/manager/dp_properties.cxx
new file mode 100644
index 000000000000..df579944c6e4
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_properties.cxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+ *
+ * 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 "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "xmlscript/xml_helper.hxx"
+#include "ucbhelper/content.hxx"
+#include <list>
+
+#include "dp_ucb.h"
+#include "rtl/ustrbuf.hxx"
+#include "dp_properties.hxx"
+
+namespace lang = com::sun::star::lang;
+namespace task = com::sun::star::task;
+namespace ucb = com::sun::star::ucb;
+namespace uno = com::sun::star::uno;
+namespace css = com::sun::star;
+
+#define OUSTR(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+using ::com::sun::star::uno::Reference;
+using ::rtl::OUString;
+
+#define PROP_SUPPRESS_LICENSE "SUPPRESS_LICENSE"
+#define PROP_EXTENSION_UPDATE "EXTENSION_UPDATE"
+
+namespace dp_manager {
+
+//Reading the file
+ExtensionProperties::ExtensionProperties(
+ OUString const & urlExtension,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv) :
+ m_xCmdEnv(xCmdEnv)
+{
+ m_propFileUrl = urlExtension + OUSTR("properties");
+
+ ::std::list< ::std::pair< OUString, OUString> > props;
+ if (! dp_misc::create_ucb_content(NULL, m_propFileUrl, 0, false))
+ return;
+
+ ::ucbhelper::Content contentProps(m_propFileUrl, m_xCmdEnv);
+ dp_misc::readProperties(props, contentProps);
+
+ typedef ::std::list< ::std::pair< OUString, OUString> >::const_iterator CI;
+ for (CI i = props.begin(); i != props.end(); i++)
+ {
+ if (i->first.equals(OUSTR(PROP_SUPPRESS_LICENSE)))
+ m_prop_suppress_license = i->second;
+ }
+}
+
+//Writing the file
+ExtensionProperties::ExtensionProperties(
+ OUString const & urlExtension,
+ uno::Sequence<css::beans::NamedValue> const & properties,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv) :
+ m_xCmdEnv(xCmdEnv)
+{
+ m_propFileUrl = urlExtension + OUSTR("properties");
+
+ for (sal_Int32 i = 0; i < properties.getLength(); i++)
+ {
+ css::beans::NamedValue const & v = properties[i];
+ if (v.Name.equals(OUSTR(PROP_SUPPRESS_LICENSE)))
+ {
+ m_prop_suppress_license = getPropertyValue(v);
+ }
+ else if (v.Name.equals(OUSTR(PROP_EXTENSION_UPDATE)))
+ {
+ m_prop_extension_update = getPropertyValue(v);
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("Extension Manager: unknown property"), 0, -1);
+ }
+ }
+}
+
+OUString ExtensionProperties::getPropertyValue(css::beans::NamedValue const & v)
+{
+ OUString value(OUSTR("0"));
+ if (v.Value >>= value)
+ {
+ if (value.equals(OUSTR("1")))
+ value = OUSTR("1");
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("Extension Manager: wrong property value"), 0, -1);
+ }
+ return value;
+}
+void ExtensionProperties::write()
+{
+ ::ucbhelper::Content contentProps(m_propFileUrl, m_xCmdEnv);
+ ::rtl::OUStringBuffer buf;
+
+ if (m_prop_suppress_license)
+ {
+ buf.append(OUSTR(PROP_SUPPRESS_LICENSE));
+ buf.append(OUSTR("="));
+ buf.append(*m_prop_suppress_license);
+ }
+
+ ::rtl::OString stamp = ::rtl::OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
+ Reference<css::io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
+ stamp.getLength() ) ) );
+ contentProps.writeStream( xData, true /* replace existing */ );
+}
+
+bool ExtensionProperties::isSuppressedLicense()
+{
+ bool ret = false;
+ if (m_prop_suppress_license)
+ {
+ if (m_prop_suppress_license->equals(OUSTR("1")))
+ ret = true;
+ }
+ return ret;
+}
+
+bool ExtensionProperties::isExtensionUpdate()
+{
+ bool ret = false;
+ if (m_prop_extension_update)
+ {
+ if (m_prop_extension_update->equals(OUSTR("1")))
+ ret = true;
+ }
+ return ret;
+}
+
+} // namespace dp_manager
+
+
diff --git a/desktop/source/deployment/manager/dp_properties.hxx b/desktop/source/deployment/manager/dp_properties.hxx
new file mode 100644
index 000000000000..97fc8b8c5394
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_properties.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: 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_PROPERTIES_HXX
+#define INCLUDED_DP_PROPERTIES_HXX
+
+
+
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "boost/optional.hpp"
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_manager {
+
+
+
+/**
+
+ */
+class ExtensionProperties
+{
+protected:
+ ::rtl::OUString m_propFileUrl;
+ const css::uno::Reference<css::ucb::XCommandEnvironment> m_xCmdEnv;
+ ::boost::optional< ::rtl::OUString> m_prop_suppress_license;
+ ::boost::optional< ::rtl::OUString> m_prop_extension_update;
+
+ ::rtl::OUString getPropertyValue(css::beans::NamedValue const & v);
+public:
+
+ virtual ~ExtensionProperties() {};
+ ExtensionProperties(::rtl::OUString const & urlExtension,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ ExtensionProperties(::rtl::OUString const & urlExtension,
+ css::uno::Sequence<css::beans::NamedValue> const & properties,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+
+ void write();
+
+ bool isSuppressedLicense();
+
+ bool isExtensionUpdate();
+};
+}
+
+
+
+
+#endif
+
diff --git a/desktop/source/deployment/manager/makefile.mk b/desktop/source/deployment/manager/makefile.mk
new file mode 100644
index 000000000000..4dc6405e34bf
--- /dev/null
+++ b/desktop/source/deployment/manager/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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 \
+ $(SLO)$/dp_extensionmanager.obj \
+ $(SLO)$/dp_commandenvironments.obj \
+ $(SLO)$/dp_properties.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..a394731921c8
--- /dev/null
+++ b/desktop/source/deployment/misc/db.cxx
@@ -0,0 +1,272 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <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..9534f166f2f0
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_dependencies.cxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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";
+
+bool satisfiesMinimalVersion(::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) != ::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")))
+ {
+ ::rtl::OUString v(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version")
+ ":Version:OOOBaseVersion}"));
+ ::rtl::Bootstrap::expandMacros(v);
+ sat =
+ ::dp_misc::compareVersions(
+ v,
+ 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 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..b4132db61f03
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_descriptioninfoset.cxx
@@ -0,0 +1,864 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "dp_descriptioninfoset.hxx"
+
+#include "dp_resource.h"
+#include "sal/config.h"
+
+#include "comphelper/sequence.hxx"
+#include "comphelper/makesequence.hxx"
+#include "comphelper/processfactory.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/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "ucbhelper/content.hxx"
+
+namespace {
+
+namespace css = ::com::sun::star;
+using css::uno::Reference;
+using ::rtl::OUString;
+
+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 >());
+ }
+}
+
+/**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);
+};
+
+ExtensionDescription::ExtensionDescription(
+ const Reference<css::uno::XComponentContext>& xContext,
+ const OUString& installDir,
+ const 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.
+ OUString sDescriptionUri(installDir + OUSTR("/description.xml"));
+ 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
+ Reference<css::io::XInputStream> xIn;
+ try
+ { //throws com.sun.star.ucb.InteractiveAugmentedIOException
+ xIn = descContent.openStream();
+ }
+ catch (css::uno::Exception& )
+ {
+ if ( ! static_cast<FileDoesNotExistFilter*>(xFilter.get())->exist())
+ throw NoDescriptionException();
+ throw;
+ }
+ if (!xIn.is())
+ {
+ throw css::uno::Exception(
+ OUSTR("Could not get XInputStream for description.xml of extension ") +
+ sDescriptionUri, 0);
+ }
+
+ //get root node of description.xml
+ Reference<css::xml::dom::XDocumentBuilder> xDocBuilder(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.dom.DocumentBuilder"),
+ xContext ), css::uno::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 css::uno::Exception(
+ OUSTR("Service com.sun.star.xml.dom.DocumentBuilder is not namespace aware."), 0);
+ }
+
+ Reference<css::xml::dom::XDocument> xDoc = xDocBuilder->parse(xIn);
+ if (!xDoc.is())
+ {
+ throw css::uno::Exception(sDescriptionUri + OUSTR(" contains data which cannot be parsed. "), 0);
+ }
+
+ //check for proper root element and namespace
+ Reference<css::xml::dom::XElement> xRoot = xDoc->getDocumentElement();
+ if (!xRoot.is())
+ {
+ throw css::uno::Exception(
+ sDescriptionUri + OUSTR(" contains no root element."), 0);
+ }
+
+ if ( ! xRoot->getTagName().equals(OUSTR("description")))
+ {
+ throw css::uno::Exception(
+ sDescriptionUri + OUSTR(" does not contain the root element <description>."), 0);
+ }
+
+ m_xRoot = Reference<css::xml::dom::XNode>(
+ xRoot, css::uno::UNO_QUERY_THROW);
+ OUString nsDescription = xRoot->getNamespaceURI();
+
+ //check if this namespace is supported
+ if ( ! nsDescription.equals(OUSTR("http://openoffice.org/extensions/description/2006")))
+ {
+ throw css::uno::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, Reference< css::uno::XInterface >(), a);
+ }
+}
+
+ExtensionDescription::~ExtensionDescription()
+{
+}
+
+//======================================================================
+FileDoesNotExistFilter::FileDoesNotExistFilter(
+ const Reference< css::ucb::XCommandEnvironment >& xCmdEnv):
+ m_bExist(true), m_xCommandEnv(xCmdEnv)
+{}
+
+FileDoesNotExistFilter::~FileDoesNotExistFilter()
+{
+};
+
+bool FileDoesNotExistFilter::exist()
+{
+ return m_bExist;
+}
+ // XCommandEnvironment
+Reference<css::task::XInteractionHandler >
+ FileDoesNotExistFilter::getInteractionHandler() throw (css::uno::RuntimeException)
+{
+ return static_cast<css::task::XInteractionHandler*>(this);
+}
+
+Reference<css::ucb::XProgressHandler >
+ FileDoesNotExistFilter::getProgressHandler() throw (css::uno::RuntimeException)
+{
+ return m_xCommandEnv.is()
+ ? m_xCommandEnv->getProgressHandler()
+ : 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(
+ Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Any request( xRequest->getRequest() );
+
+ css::ucb::InteractiveAugmentedIOException ioexc;
+ if ((request>>= ioexc) && ioexc.Code == css::ucb::IOErrorCode_NOT_EXISTING )
+ {
+ m_bExist = false;
+ return;
+ }
+ Reference<css::task::XInteractionHandler> xInteraction;
+ if (m_xCommandEnv.is()) {
+ xInteraction = m_xCommandEnv->getInteractionHandler();
+ }
+ if (xInteraction.is()) {
+ xInteraction->handle(xRequest);
+ }
+}
+
+}
+
+namespace dp_misc {
+
+DescriptionInfoset getDescriptionInfoset(OUString const & sExtensionFolderURL)
+{
+ Reference< css::xml::dom::XNode > root;
+ Reference<css::uno::XComponentContext> context =
+ comphelper_getProcessComponentContext();
+ OSL_ASSERT(context.is());
+ try {
+ root =
+ ExtensionDescription(
+ context, sExtensionFolderURL,
+ Reference< css::ucb::XCommandEnvironment >()).
+ getRootElement();
+ } catch (NoDescriptionException &) {
+ } catch (css::deployment::DeploymentException & e) {
+ throw css::uno::RuntimeException(
+ (OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.deployment.DeploymentException: ")) +
+ e.Message), 0);
+ }
+ return DescriptionInfoset(context, root);
+}
+
+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 >();
+}
+
+::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);
+
+}
+
+::boost::optional<SimpleLicenseAttributes>
+DescriptionInfoset::getSimpleLicenseAttributes() const
+{
+ //Check if the node exist
+ css::uno::Reference< css::xml::dom::XNode > n;
+ if (m_element.is()) {
+ try {
+ n = m_xpath->selectSingleNode(m_element,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license/@accept-by")));
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ if (n.is())
+ {
+ SimpleLicenseAttributes attributes;
+ attributes.acceptBy =
+ getNodeValueFromExpression(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license/@accept-by")));
+
+ ::boost::optional< ::rtl::OUString > suppressOnUpdate = getOptionalValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license/@suppress-on-update")));
+ if (suppressOnUpdate)
+ attributes.suppressOnUpdate = (*suppressOnUpdate).trim().equalsIgnoreAsciiCase(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true")));
+ else
+ attributes.suppressOnUpdate = false;
+
+ ::boost::optional< ::rtl::OUString > suppressIfRequired = getOptionalValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license/@suppress-if-required")));
+ if (suppressIfRequired)
+ attributes.suppressIfRequired = (*suppressIfRequired).trim().equalsIgnoreAsciiCase(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true")));
+ else
+ attributes.suppressIfRequired = false;
+
+ return ::boost::optional<SimpleLicenseAttributes>(attributes);
+ }
+ }
+ return ::boost::optional<SimpleLicenseAttributes>();
+}
+
+::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..9659bc6759fd
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_identifier.cxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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..36e7fd037ccf
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_interact.cxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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..fe3490903043
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_misc.cxx
@@ -0,0 +1,625 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "dp_misc.h"
+#include "dp_version.hxx"
+#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/task/XInteractionHandler.hpp"
+#include "com/sun/star/bridge/UnoUrlResolver.hpp"
+#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/task/XRestartManager.hpp"
+#include "boost/scoped_array.hpp"
+#include "boost/shared_ptr.hpp"
+#include <comphelper/processfactory.hxx>
+
+#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();
+}
+
+
+//Returns true if the Folder was more recently modified then
+//the lastsynchronized file. That is the repository needs to
+//be synchronized.
+bool compareExtensionFolderWithLastSynchronizedFile(
+ OUString const & folderURL, OUString const & fileURL)
+{
+ bool bNeedsSync = false;
+ ::osl::DirectoryItem itemExtFolder;
+ ::osl::File::RC err1 =
+ ::osl::DirectoryItem::get(folderURL, itemExtFolder);
+ //If it does not exist, then there is nothing to be done
+ if (err1 == ::osl::File::E_NOENT)
+ {
+ return false;
+ }
+ else if (err1 != ::osl::File::E_None)
+ {
+ OSL_ENSURE(0, "Cannot access extension folder");
+ return true; //sync just in case
+ }
+
+ //If last synchronized does not exist, then OOo is started for the first time
+ ::osl::DirectoryItem itemFile;
+ ::osl::File::RC err2 = ::osl::DirectoryItem::get(fileURL, itemFile);
+ if (err2 == ::osl::File::E_NOENT)
+ {
+ return true;
+
+ }
+ else if (err2 != ::osl::File::E_None)
+ {
+ OSL_ENSURE(0, "Cannot access file lastsynchronized");
+ return true; //sync just in case
+ }
+
+ //compare the modification time of the extension folder and the last
+ //modified file
+ ::osl::FileStatus statFolder(FileStatusMask_ModifyTime);
+ ::osl::FileStatus statFile(FileStatusMask_ModifyTime);
+ if (itemExtFolder.getFileStatus(statFolder) == ::osl::File::E_None)
+ {
+ if (itemFile.getFileStatus(statFile) == ::osl::File::E_None)
+ {
+ TimeValue timeFolder = statFolder.getModifyTime();
+ TimeValue timeFile = statFile.getModifyTime();
+
+ if (timeFile.Seconds < timeFolder.Seconds)
+ bNeedsSync = true;
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ bNeedsSync = true;
+ }
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ bNeedsSync = true;
+ }
+ return bNeedsSync;
+}
+
+bool needToSyncRepostitory(OUString const & name)
+{
+ OUString folder;
+ OUString file;
+ if (name.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled"))))
+ {
+ folder = OUString(
+ RTL_CONSTASCII_USTRINGPARAM("$BUNDLED_EXTENSIONS"));
+ file = OUString (
+ RTL_CONSTASCII_USTRINGPARAM(
+ "$BUNDLED_EXTENSIONS_USER/lastsynchronized"));
+ }
+ else if (name.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("shared"))))
+ {
+ folder = OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "$UNO_SHARED_PACKAGES_CACHE/uno_packages"));
+ file = OUString (
+ RTL_CONSTASCII_USTRINGPARAM(
+ "$SHARED_EXTENSIONS_USER/lastsynchronized"));
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ return true;
+ }
+ ::rtl::Bootstrap::expandMacros(folder);
+ ::rtl::Bootstrap::expandMacros(file);
+ return compareExtensionFolderWithLastSynchronizedFile(
+ folder, file);
+}
+
+
+} // 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 makeURLAppendSysPathSegment( OUString const & baseURL, OUString const & relPath_ )
+{
+ OUString segment = relPath_;
+ OSL_ASSERT(segment.indexOf(static_cast<sal_Unicode>('/')) == -1);
+
+ ::rtl::Uri::encode(
+ segment, rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8);
+ return makeURL(baseURL, segment);
+}
+
+
+
+//==============================================================================
+OUString expandUnoRcTerm( OUString const & term_ )
+{
+ OUString term(term_);
+ UnoRc::get()->expandMacrosFrom( term );
+ return term;
+}
+
+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;
+}
+
+//==============================================================================
+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 );
+ }
+ }
+}
+
+#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);
+ return value.trim();
+ }
+#else
+ char buf[1024];
+ rtl_zeroMemory(buf, 1024);
+ // read one char less so that the last char in buf is always zero
+ if (fgets(buf, 1024, stdin) != NULL)
+ {
+ OUString value = ::rtl::OStringToOUString(::rtl::OString(buf), osl_getThreadTextEncoding());
+ return value.trim();
+ }
+#endif
+ return OUString();
+}
+
+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
+}
+
+void syncRepositories(Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ Reference<deployment::XExtensionManager> xExtensionManager;
+ //synchronize shared before bundled otherewise there are
+ //more revoke and registration calls.
+ sal_Bool bModified = false;
+ if (needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("shared")))
+ || needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled"))))
+ {
+ xExtensionManager =
+ deployment::ExtensionManager::get(
+ comphelper_getProcessComponentContext());
+
+ if (xExtensionManager.is())
+ {
+ bModified = xExtensionManager->synchronize(
+ Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ }
+
+ if (bModified)
+ {
+ Reference<task::XRestartManager> restarter(
+ comphelper_getProcessComponentContext()->getValueByName(
+ OUSTR( "/singletons/com.sun.star.task.OfficeRestartManager") ), UNO_QUERY );
+ if (restarter.is())
+ {
+ restarter->requestRestart(xCmdEnv.is() == sal_True ? xCmdEnv->getInteractionHandler() :
+ Reference<task::XInteractionHandler>());
+ }
+ }
+}
+
+
+
+}
diff --git a/desktop/source/deployment/misc/dp_misc.hrc b/desktop/source/deployment/misc/dp_misc.hrc
new file mode 100644
index 000000000000..55fabac5c5b5
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_misc.hrc
@@ -0,0 +1,33 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..0d341122af16
--- /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 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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..ac28b6816708
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_platform.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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_KFREEBSD_X86 "kfreebsd_x86"
+#define PLATFORM_KFREEBSD_X86_64 "kfreebsd_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_M68K "linux_m68k"
+#define PLATFORM_LINUX_S390 "linux_s390"
+#define PLATFORM_LINUX_S390x "linux_s390x"
+#define PLATFORM_LINUX_HPPA "linux_hppa"
+#define PLATFORM_LINUX_ALPHA "linux_alpha"
+
+
+
+#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_KFREEBSD_X86)))
+ ret = checkOSandCPU(OUSTR("kFreeBSD"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_KFREEBSD_X86_64)))
+ ret = checkOSandCPU(OUSTR("kFreeBSD"), 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_M68K)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("M68K"));
+ 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_LINUX_HPPA)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("HPPA"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_ALPHA)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("ALPHA"));
+ 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..10ee436ff60c
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_resource.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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..795a492aa0d5
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_ucb.cxx
@@ -0,0 +1,320 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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/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;
+ const Any title( ::rtl::Uri::decode( url.copy( slash + 1 ),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 ) );
+ const Sequence<ContentInfo> infos(
+ parentContent.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;
+}
+
+bool readProperties( ::std::list< ::std::pair< ::rtl::OUString, ::rtl::OUString> > & out_result,
+ ::ucbhelper::Content & ucb_content )
+{
+ // read whole file:
+ ::rtl::ByteSequence bytes( readFile( ucb_content ) );
+ OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()),
+ bytes.getLength(), RTL_TEXTENCODING_UTF8);
+ sal_Int32 pos = 0;
+
+ for (;;)
+ {
+
+ ::rtl::OUStringBuffer buf;
+ sal_Int32 start = pos;
+
+ bool bEOF = false;
+ pos = file.indexOf( LF, pos );
+ if (pos < 0) { // EOF
+ buf.append( file.copy( start ) );
+ bEOF = true;
+ }
+ else
+ {
+ if (pos > 0 && file[ pos - 1 ] == CR)
+ // consume extra CR
+ buf.append( file.copy( start, pos - start - 1 ) );
+ else
+ buf.append( file.copy( start, pos - start ) );
+ pos++;
+ }
+ OUString aLine = buf.makeStringAndClear();
+
+ sal_Int32 posEqual = aLine.indexOf('=');
+ if (posEqual > 0 && (posEqual + 1) < aLine.getLength())
+ {
+ OUString name = aLine.copy(0, posEqual);
+ OUString value = aLine.copy(posEqual + 1);
+ out_result.push_back(::std::make_pair(name, value));
+ }
+
+ if (bEOF)
+ break;
+ }
+ return false;
+}
+
+}
diff --git a/desktop/source/deployment/misc/dp_update.cxx b/desktop/source/deployment/misc/dp_update.cxx
new file mode 100755
index 000000000000..52011f1f0ca0
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_update.cxx
@@ -0,0 +1,397 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "dp_update.hxx"
+#include "dp_version.hxx"
+#include "dp_identifier.hxx"
+#include "dp_descriptioninfoset.hxx"
+
+#include "rtl/bootstrap.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+using ::rtl::OString;
+
+
+namespace dp_misc {
+namespace {
+
+int determineHighestVersion(
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion)
+{
+ int index = 0;
+ OUString greatest = userVersion;
+ if (dp_misc::compareVersions(sharedVersion, greatest) == dp_misc::GREATER)
+ {
+ index = 1;
+ greatest = sharedVersion;
+ }
+ if (dp_misc::compareVersions(bundledVersion, greatest) == dp_misc::GREATER)
+ {
+ index = 2;
+ greatest = bundledVersion;
+ }
+ if (dp_misc::compareVersions(onlineVersion, greatest) == dp_misc::GREATER)
+ {
+ index = 3;
+ }
+ return index;
+}
+
+Sequence< Reference< xml::dom::XElement > >
+getUpdateInformation( Reference<deployment::XUpdateInformationProvider > const & updateInformation,
+ Sequence< OUString > const & urls,
+ OUString const & identifier,
+ uno::Any & out_error)
+{
+ try {
+ return updateInformation->getUpdateInformation(urls, identifier);
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (ucb::CommandFailedException & e) {
+ out_error = e.Reason;
+ } catch (ucb::CommandAbortedException &) {
+ } catch (uno::Exception & e) {
+ out_error = uno::makeAny(e);
+ }
+ return
+ Sequence<Reference< xml::dom::XElement > >();
+}
+
+//Put in anonymous namespace
+
+void getOwnUpdateInfos(
+ Reference<uno::XComponentContext> const & xContext,
+ Reference<deployment::XUpdateInformationProvider > const & updateInformation,
+ UpdateInfoMap& inout_map, std::vector<std::pair<Reference<deployment::XPackage>, uno::Any> > & out_errors,
+ bool & out_allFound)
+{
+ bool allHaveOwnUpdateInformation = true;
+ for (UpdateInfoMap::iterator i = inout_map.begin(); i != inout_map.end(); i++)
+ {
+ OSL_ASSERT(i->second.extension.is());
+ Sequence<OUString> urls(i->second.extension->getUpdateInformationURLs());
+ if (urls.getLength())
+ {
+ const OUString id = dp_misc::getIdentifier(i->second.extension);
+ uno::Any anyError;
+ //It is unclear from the idl if there can be a null reference returned.
+ //However all valid information should be the same
+ Sequence<Reference< xml::dom::XElement > >
+ infos(getUpdateInformation(updateInformation, urls, id, anyError));
+ if (anyError.hasValue())
+ out_errors.push_back(std::make_pair(i->second.extension, anyError));
+
+ for (sal_Int32 j = 0; j < infos.getLength(); ++j)
+ {
+ dp_misc::DescriptionInfoset infoset(
+ xContext,
+ Reference< xml::dom::XNode >(infos[j], UNO_QUERY_THROW));
+ if (!infoset.hasDescription())
+ continue;
+ boost::optional< OUString > id2(infoset.getIdentifier());
+ if (!id2)
+ continue;
+ OSL_ASSERT(*id2 == id);
+ if (*id2 == id)
+ {
+ i->second.version = infoset.getVersion();
+ i->second.info = Reference< xml::dom::XNode >(
+ infos[j], UNO_QUERY_THROW);
+ }
+ break;
+ }
+ }
+ else
+ {
+ allHaveOwnUpdateInformation &= false;
+ }
+ }
+ out_allFound = allHaveOwnUpdateInformation;
+}
+
+void getDefaultUpdateInfos(
+ Reference<uno::XComponentContext> const & xContext,
+ Reference<deployment::XUpdateInformationProvider > const & updateInformation,
+ UpdateInfoMap& inout_map,
+ std::vector<std::pair<Reference<deployment::XPackage>, uno::Any> > & out_errors)
+{
+ const rtl::OUString sDefaultURL(dp_misc::getExtensionDefaultUpdateURL());
+ OSL_ASSERT(sDefaultURL.getLength());
+
+ Any anyError;
+ Sequence< Reference< xml::dom::XElement > >
+ infos(
+ getUpdateInformation(
+ updateInformation,
+ Sequence< OUString >(&sDefaultURL, 1), OUString(), anyError));
+ if (anyError.hasValue())
+ out_errors.push_back(std::make_pair(Reference<deployment::XPackage>(), anyError));
+ for (sal_Int32 i = 0; i < infos.getLength(); ++i)
+ {
+ Reference< xml::dom::XNode > node(infos[i], UNO_QUERY_THROW);
+ dp_misc::DescriptionInfoset infoset(xContext, node);
+ boost::optional< OUString > id(infoset.getIdentifier());
+ if (!id) {
+ continue;
+ }
+ UpdateInfoMap::iterator j = inout_map.find(*id);
+ if (j != inout_map.end())
+ {
+ //skip those extension which provide its own update urls
+ if (j->second.extension->getUpdateInformationURLs().getLength())
+ continue;
+ OUString v(infoset.getVersion());
+ //look for the highest version in the online repository
+ if (dp_misc::compareVersions(v, j->second.version) ==
+ dp_misc::GREATER)
+ {
+ j->second.version = v;
+ j->second.info = node;
+ }
+ }
+ }
+}
+
+
+} // anon namespace
+
+
+OUString getExtensionDefaultUpdateURL()
+{
+ ::rtl::OUString sUrl(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version")
+ ":Version:ExtensionUpdateURL}"));
+ ::rtl::Bootstrap::expandMacros(sUrl);
+ return sUrl;
+}
+
+/* returns the index of the greatest version, starting with 0
+
+ */
+UPDATE_SOURCE isUpdateUserExtension(
+ bool bReadOnlyShared,
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion)
+{
+ UPDATE_SOURCE retVal = UPDATE_SOURCE_NONE;
+ if (bReadOnlyShared)
+ {
+ if (userVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ userVersion, sharedVersion, bundledVersion, onlineVersion);
+ if (index == 1)
+ retVal = UPDATE_SOURCE_SHARED;
+ else if (index == 2)
+ retVal = UPDATE_SOURCE_BUNDLED;
+ else if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+ }
+ else if (sharedVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ OUString(), sharedVersion, bundledVersion, onlineVersion);
+ if (index == 2)
+ retVal = UPDATE_SOURCE_BUNDLED;
+ else if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+
+ }
+ else if (bundledVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ OUString(), OUString(), bundledVersion, onlineVersion);
+ if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+ }
+ }
+ else
+ {
+ if (userVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ userVersion, sharedVersion, bundledVersion, onlineVersion);
+ if (index == 1)
+ retVal = UPDATE_SOURCE_SHARED;
+ else if (index == 2)
+ retVal = UPDATE_SOURCE_BUNDLED;
+ else if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+ }
+ }
+
+ return retVal;
+}
+
+UPDATE_SOURCE isUpdateSharedExtension(
+ bool bReadOnlyShared,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion)
+{
+ if (bReadOnlyShared)
+ return UPDATE_SOURCE_NONE;
+ UPDATE_SOURCE retVal = UPDATE_SOURCE_NONE;
+
+ if (sharedVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ OUString(), sharedVersion, bundledVersion, onlineVersion);
+ if (index == 2)
+ retVal = UPDATE_SOURCE_BUNDLED;
+ else if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+ }
+ else if (bundledVersion.getLength())
+ {
+ int index = determineHighestVersion(
+ OUString(), OUString(), bundledVersion, onlineVersion);
+ if (index == 3)
+ retVal = UPDATE_SOURCE_ONLINE;
+ }
+ return retVal;
+}
+
+Reference<deployment::XPackage>
+getExtensionWithHighestVersion(
+ Sequence<Reference<deployment::XPackage> > const & seqExt)
+{
+ if (seqExt.getLength() == 0)
+ return Reference<deployment::XPackage>();
+
+ Reference<deployment::XPackage> greatest;
+ sal_Int32 len = seqExt.getLength();
+
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ if (!greatest.is())
+ {
+ greatest = seqExt[i];
+ continue;
+ }
+ Reference<deployment::XPackage> const & current = seqExt[i];
+ //greatest has a value
+ if (! current.is())
+ continue;
+
+ if (dp_misc::compareVersions(current->getVersion(), greatest->getVersion()) == dp_misc::GREATER)
+ greatest = current;
+ }
+ return greatest;
+}
+
+UpdateInfo::UpdateInfo( Reference< deployment::XPackage> const & ext):
+extension(ext)
+{
+}
+
+
+
+UpdateInfoMap getOnlineUpdateInfos(
+ Reference<uno::XComponentContext> const &xContext,
+ Reference<deployment::XExtensionManager> const & xExtMgr,
+ Reference<deployment::XUpdateInformationProvider > const & updateInformation,
+ std::vector<Reference<deployment::XPackage > > const * extensionList,
+ std::vector<std::pair< Reference<deployment::XPackage>, uno::Any> > & out_errors)
+{
+ OSL_ASSERT(xExtMgr.is());
+ UpdateInfoMap infoMap;
+ if (!xExtMgr.is())
+ return infoMap;
+
+ if (!extensionList)
+ {
+ const uno::Sequence< uno::Sequence< Reference<deployment::XPackage > > > seqAllExt = xExtMgr->getAllExtensions(
+ Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>());
+
+ //fill the UpdateInfoMap. key = extension identifier, value = UpdateInfo
+ for (int pos = seqAllExt.getLength(); pos --; )
+ {
+ uno::Sequence<Reference<deployment::XPackage> > const & seqExt = seqAllExt[pos];
+
+ Reference<deployment::XPackage> extension = getExtensionWithHighestVersion(seqExt);
+ OSL_ASSERT(extension.is());
+
+ std::pair<UpdateInfoMap::iterator, bool> insertRet = infoMap.insert(
+ UpdateInfoMap::value_type(
+ dp_misc::getIdentifier(extension), UpdateInfo(extension)));
+ OSL_ASSERT(insertRet.second == true);
+ }
+ }
+ else
+ {
+ typedef std::vector<Reference<deployment::XPackage > >::const_iterator CIT;
+ for (CIT i = extensionList->begin(); i != extensionList->end(); i++)
+ {
+ OSL_ASSERT(i->is());
+ std::pair<UpdateInfoMap::iterator, bool> insertRet = infoMap.insert(
+ UpdateInfoMap::value_type(
+ dp_misc::getIdentifier(*i), UpdateInfo(*i)));
+ OSL_ASSERT(insertRet.second == true);
+ }
+ }
+
+ //Now find the update information for the extensions which provide their own
+ //URLs to update information.
+ bool allInfosObtained = false;
+ getOwnUpdateInfos(xContext, updateInformation, infoMap, out_errors, allInfosObtained);
+
+ if (!allInfosObtained)
+ getDefaultUpdateInfos(xContext, updateInformation, infoMap, out_errors);
+ return infoMap;
+}
+OUString getHighestVersion(
+ ::rtl::OUString const & userVersion,
+ ::rtl::OUString const & sharedVersion,
+ ::rtl::OUString const & bundledVersion,
+ ::rtl::OUString const & onlineVersion)
+{
+ int index = determineHighestVersion(userVersion, sharedVersion, bundledVersion, onlineVersion);
+ switch (index)
+ {
+ case 0: return userVersion;
+ case 1: return sharedVersion;
+ case 2: return bundledVersion;
+ case 3: return onlineVersion;
+ default: OSL_ASSERT(0);
+ }
+
+ return OUString();
+}
+} //namespace dp_misc
diff --git a/desktop/source/deployment/misc/dp_version.cxx b/desktop/source/deployment/misc/dp_version.cxx
new file mode 100644
index 000000000000..c0da0533b54c
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_version.cxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/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;
+}
+
+
+}
diff --git a/desktop/source/deployment/misc/makefile.mk b/desktop/source/deployment/misc/makefile.mk
new file mode 100644
index 000000000000..3e4bd68cb4c0
--- /dev/null
+++ b/desktop/source/deployment/misc/makefile.mk
@@ -0,0 +1,95 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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 \
+ $(SLO)$/dp_update.obj
+
+SHL1STDLIBS = \
+ $(BERKELEYLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(XMLSCRIPTLIB) \
+ $(COMPHELPERLIB)
+.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_compbackenddb.cxx b/desktop/source/deployment/registry/component/dp_compbackenddb.cxx
new file mode 100644
index 000000000000..898e7c931f6d
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_compbackenddb.cxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "rtl/string.h"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+
+#include "dp_compbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/component-registry/2010"
+#define NS_PREFIX "comp"
+#define ROOT_ELEMENT_NAME "component-backend-db"
+#define KEY_ELEMENT_NAME "component"
+
+namespace dp_registry {
+namespace backend {
+namespace component {
+
+ComponentBackendDb::ComponentBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+OUString ComponentBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ComponentBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ComponentBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ComponentBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+void ComponentBackendDb::addEntry(::rtl::OUString const & url, Data const & data)
+{
+ try{
+ Reference<css::xml::dom::XNode> componentNode = writeKeyElement(url);
+ writeSimpleElement(OUSTR("java-type-library"),
+ OUString::valueOf((sal_Bool) data.javaTypeLibrary),
+ componentNode);
+
+ writeSimpleList(
+ data.implementationNames,
+ OUSTR("implementation-names"),
+ OUSTR("name"),
+ componentNode);
+
+ writeVectorOfPair(
+ data.singletons,
+ OUSTR("singletons"),
+ OUSTR("item"),
+ OUSTR("key"),
+ OUSTR("value"),
+ componentNode);
+
+ save();
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+ComponentBackendDb::Data ComponentBackendDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ ComponentBackendDb::Data retData;
+ Reference<css::xml::dom::XNode> aNode = getKeyElement(url);
+ if (aNode.is())
+ {
+ bool bJava = readSimpleElement(OUSTR("java-type-library"), aNode)
+ .equals(OUSTR("true")) ? true : false;
+ retData.javaTypeLibrary = bJava;
+
+ retData.implementationNames =
+ readList(
+ aNode,
+ OUSTR("implementation-names"),
+ OUSTR("name"));
+
+ retData.singletons =
+ readVectorOfPair(
+ aNode,
+ OUSTR("singletons"),
+ OUSTR("item"),
+ OUSTR("key"),
+ OUSTR("value"));
+ }
+ return retData;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+} // namespace bundle
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/component/dp_compbackenddb.hxx b/desktop/source/deployment/registry/component/dp_compbackenddb.hxx
new file mode 100644
index 000000000000..b9a5ed737b7c
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_compbackenddb.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_COMPBACKENDDB_HXX
+#define INCLUDED_DP_COMPBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "rtl/string.hxx"
+#include <vector>
+#include <list>
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace xml { namespace dom {
+ class XDocument;
+ class XNode;
+ }}
+ namespace xml { namespace xpath {
+ class XXPathAPI;
+ }}
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace component {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ The format looks like this:
+
+<?xml version="1.0"?>
+<component-backend-db xmlns="http://openoffice.org/extensionmanager/component-registry/2010">
+ <component url="vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages/5CD5.tmp_/leaves1.oxt/extensionoptions.jar">
+ <name>FileName</name>
+ <java-type-library>true</java-type-library>
+ <implementation-names>
+ <name>com.sun.star.comp.extensionoptions.OptionsEventHandler$_OptionsEventHandler</name>
+ ...
+ </implementation-names>
+ <singletons>
+ <item>
+ <key>com.sun.star.java.theJavaVirtualMachine</key>
+ <value>com.sun.star.java.JavaVirtualMachine</value>
+ </item>
+ ...
+ </singletons>
+ </component>
+
+ <component ...>
+ ...
+</component-backend-db>
+ */
+class ComponentBackendDb: public dp_registry::backend::BackendDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+ virtual ::rtl::OUString getNSPrefix();
+ virtual ::rtl::OUString getRootElementName();
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+ struct Data
+ {
+ Data(): javaTypeLibrary(false) {};
+
+ ::std::list< ::rtl::OUString> implementationNames;
+ /* every singleton has a key and a value
+ */
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString> >singletons;
+ bool javaTypeLibrary;
+ };
+
+public:
+
+ ComponentBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+ void addEntry(::rtl::OUString const & url, Data const & data);
+
+ Data getEntry(::rtl::OUString const & url);
+
+
+};
+
+
+
+}
+}
+}
+#endif
+
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..e0844c227669
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.cxx
@@ -0,0 +1,1586 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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 "svl/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>
+#include "dp_compbackenddb.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 component {
+namespace {
+
+typedef ::std::list<OUString> t_stringlist;
+typedef ::std::vector< ::std::pair<OUString, OUString> > t_stringpairvec;
+
+#define IMPLEMENTATION_NAME "com.sun.star.comp.deployment.component.PackageRegistryBackend"
+
+/** 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;
+ ComponentBackendDb::Data m_registeredComponentsDb;
+
+ enum reg {
+ REG_UNINIT, REG_VOID, REG_REGISTERED, REG_NOT_REGISTERED, REG_MAYBE_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,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ const Reference<registry::XSimpleRegistry> getRDB() const;
+
+ //Provides the read-only registry (e.g. not the one based on the duplicated
+ //rdb files
+ const Reference<registry::XSimpleRegistry> getRDB_RO() const;
+
+ public:
+ ComponentPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ OUString const & loader, bool bRemoved,
+ OUString const & identifier);
+ };
+ 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,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ TypelibraryPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool jarFile, bool bRemoved,
+ OUString const & identifier);
+ };
+ 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,
+ sal_Bool bRemoved, OUString const & identifier,
+ 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;
+
+ //URLs of the read-only rdbs (e.g. not the ones of the duplicated files)
+ OUString m_commonRDB_RO;
+ OUString m_nativeRDB_RO;
+
+ std::auto_ptr<ComponentBackendDb> m_backendDb;
+
+ void addDataToDb(OUString const & url, ComponentBackendDb::Data const & data);
+ void deleteDataFromDb(OUString const & url);
+ ComponentBackendDb::Data readDataFromDb(OUString const & url);
+
+
+ //These rdbs are for writing new service entries. The rdb files are copies
+ //which are created when services are added or removed.
+ Reference<registry::XSimpleRegistry> m_xCommonRDB;
+ Reference<registry::XSimpleRegistry> m_xNativeRDB;
+
+ //These rdbs are created on the read-only rdbs which are already used
+ //by UNO since the startup of the current session.
+ Reference<registry::XSimpleRegistry> m_xCommonRDB_RO;
+ Reference<registry::XSimpleRegistry> m_xNativeRDB_RO;
+
+
+ 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();
+
+ //Creates the READ ONLY registries (m_xCommonRDB_RO,m_xNativeRDB_RO)
+ void initServiceRdbFiles_RO();
+};
+
+//______________________________________________________________________________
+
+BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ OUString const & loader, bool bRemoved,
+ OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_loader( loader ),
+ m_registered( REG_UNINIT )
+{
+ if (bRemoved)
+ {
+ m_registeredComponentsDb = getMyBackend()->readDataFromDb(url);
+ }
+}
+
+
+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.
+ //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257
+ {
+ 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;
+}
+
+//Returns the read only RDB.
+const Reference<registry::XSimpleRegistry>
+BackendImpl::ComponentPackageImpl::getRDB_RO() const
+{
+ BackendImpl * that = getMyBackend();
+
+ if (m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") ))
+ return that->m_xNativeRDB_RO;
+ else
+ return that->m_xCommonRDB_RO;
+}
+
+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;
+
+ ::ucbhelper::Content cacheDir( getCachePath(), xCmdEnv );
+ ::ucbhelper::Content oldRDB;
+ // switch common rdb:
+ if (m_commonRDB_RO.getLength() > 0)
+ {
+ create_ucb_content(
+ &oldRDB, makeURL( getCachePath(), m_commonRDB_RO),
+ xCmdEnv, false /* no throw */ );
+ }
+ m_commonRDB = m_commonRDB_RO.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_RO.getLength() > 0)
+ {
+ create_ucb_content(
+ &oldRDB, makeURL(getCachePath(), m_nativeRDB_RO),
+ xCmdEnv, false /* no throw */ );
+ }
+ const OUString plt_rdb( getPlatformString() + OUSTR(".rdb") );
+ const OUString plt_rdb_( getPlatformString() + OUSTR("_.rdb") );
+ m_nativeRDB = m_nativeRDB_RO.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 );
+ false, true);
+ }
+ 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 );
+ false, true);
+ }
+}
+
+void BackendImpl::initServiceRdbFiles_RO()
+{
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ // common rdb for java, native rdb for shared lib components
+ if (m_commonRDB_RO.getLength() > 0)
+ {
+ m_xCommonRDB_RO.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext), UNO_QUERY_THROW);
+ m_xCommonRDB_RO->open(
+ makeURL(expandUnoRcUrl(getCachePath()), m_commonRDB_RO),
+ sal_True, //read-only
+ sal_True); // create data source if necessary
+ }
+ if (m_nativeRDB_RO.getLength() > 0)
+ {
+ m_xNativeRDB_RO.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext), UNO_QUERY_THROW);
+ m_xNativeRDB_RO->open(
+ makeURL(expandUnoRcUrl(getCachePath()), m_nativeRDB_RO),
+ sal_True, //read-only
+ sal_True); // create data source if necessary
+ }
+}
+
+//______________________________________________________________________________
+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
+ {
+ //do this before initServiceRdbFiles_RO, because it determines
+ //m_commonRDB and m_nativeRDB
+ unorc_verify_init( xCmdEnv );
+
+ initServiceRdbFiles_RO();
+
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ComponentBackendDb(getComponentContext(), dbFile));
+ }
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, ComponentBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+void BackendImpl::deleteDataFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+ComponentBackendDb::Data BackendImpl::readDataFromDb(OUString const & url)
+{
+ ComponentBackendDb::Data data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ 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"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ 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"),
+ bRemoved, identifier);
+ }
+ if (value.EqualsIgnoreCaseAscii("Java")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xJavaComponentTypeInfo,
+ OUSTR("com.sun.star.loader.Java2"),
+ bRemoved, identifier);
+ }
+ if (value.EqualsIgnoreCaseAscii("Python")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xPythonComponentTypeInfo,
+ OUSTR("com.sun.star.loader.Python"),
+ bRemoved, identifier);
+ }
+ }
+ }
+ }
+ 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 */, bRemoved, identifier);
+ }
+ if (value.EqualsIgnoreCaseAscii("Java")) {
+ return new BackendImpl::TypelibraryPackageImpl(
+ this, url, name, m_xJavaTypelibTypeInfo,
+ true /* jar */, bRemoved, identifier);
+ }
+ }
+ }
+ }
+ }
+ 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)
+ {
+ if (create_ucb_content(
+ 0, expandUnoRcTerm(token), xCmdEnv,
+ false /* no throw */ ))
+ {
+ //The jar file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the unorc
+ //After running XExtensionManager::synchronize, the unorc is
+ //cleaned up
+ m_jar_typelibs.push_back( token );
+ }
+ }
+ }
+ 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 );
+ if (create_ucb_content(
+ 0, expandUnoRcTerm(token), xCmdEnv,
+ false /* no throw */ ))
+ {
+ //The RDB file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the unorc.
+ //After running XExtensionManager::synchronize, the unorc is
+ //cleaned up
+ m_rdb_typelibs.push_back( token );
+ }
+ }
+ }
+ 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_RO = 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_RO = 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;
+
+ buf.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN="));
+ OUString sOrigin = dp_misc::makeRcTerm(m_cachePath);
+ ::rtl::OString osOrigin = ::rtl::OUStringToOString(sOrigin, RTL_TEXTENCODING_UTF8);
+ buf.append(osOrigin);
+ 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 we duplicated the common or native rdb then we must use those urls
+ //otherwise we use those of the original files. That is, m_commonRDB_RO and
+ //m_nativeRDB_RO;
+ OUString sCommonRDB(m_commonRDB.getLength() > 0 ? m_commonRDB : m_commonRDB_RO);
+ OUString sNativeRDB(m_nativeRDB.getLength() > 0 ? m_nativeRDB : m_nativeRDB_RO);
+
+ if (sCommonRDB.getLength() > 0 || sNativeRDB.getLength() > 0)
+ {
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") );
+ buf.append( ::rtl::OUStringToOString(
+ sCommonRDB, RTL_TEXTENCODING_ASCII_US ) );
+ if (sNativeRDB.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("ORIGIN="));
+ buf2.append(osOrigin);
+ buf2.append(LF);
+ buf2.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") );
+ buf2.append( ::rtl::OUStringToOString(
+ sNativeRDB, 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;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::addToUnoRc( bool jarFile, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( dp_misc::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( dp_misc::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( dp_misc::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;
+ bool bAmbiguousComponentName = false;
+ const Reference<registry::XSimpleRegistry> xRDB( getRDB_RO() );
+ 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;
+ }
+ else
+ {
+ //try to match only the file name
+ OUString thisUrl(getURL());
+ OUString thisFileName(thisUrl.copy(thisUrl.lastIndexOf('/')));
+
+ OUString locationFileName(location.copy(location.lastIndexOf('/')));
+ if (locationFileName.equalsIgnoreAsciiCase(thisFileName))
+ bAmbiguousComponentName = true;
+ }
+ }
+ }
+ if (pos >= 0)
+ m_registered = REG_REGISTERED;
+ else if (bAmbiguousComponentName)
+ m_registered = REG_MAYBE_REGISTERED;
+ }
+ }
+
+ //Different extensions can use the same service implementations. Then the extensions
+ //which was installed last will overwrite the one from the other extension. That is
+ //the registry will contain the path (the location) of the library or jar of the
+ //second extension. In this case isRegistered called for the lib of the first extension
+ //would return "not registered". That would mean that during uninstallation
+ //XPackage::registerPackage is not called, because it just was not registered. This is,
+ //however, necessary for jar files. Registering and unregistering update
+ //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
+ //Therefore, we will return always "is ambiguous" if the path of this component cannot
+ //be found in the registry and if there is another path and both have the same file name (but
+ //the rest of the path is different).
+ //If the caller cannot precisely determine that this package was registered, then it must
+ //call registerPackage.
+ sal_Bool bAmbiguous = m_registered == REG_VOID // REG_VOID == we are in the progress of unregistration
+ || m_registered == REG_MAYBE_REGISTERED;
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ m_registered == REG_REGISTERED, bAmbiguous) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::ComponentPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool startup,
+ ::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;
+ if (m_bRemoved)
+ isJavaTypelib = m_registeredComponentsDb.javaTypeLibrary;
+ else
+ isJavaTypelib = java &&
+ !jarManifestHeaderPresent( url, OUSTR("UNO-Type-Path"), xCmdEnv );
+
+ ComponentBackendDb::Data data;
+ data.javaTypeLibrary = isJavaTypelib;
+ if (doRegisterPackage)
+ {
+ Reference <uno::XComponentContext> context(that->getComponentContext());
+ if (! startup)
+ {
+ context.set(
+ that->getObject( url ), UNO_QUERY );
+
+ if (! context.is()) {
+ context.set(
+ that->insertObject( url, raise_uno_process(
+ that->getComponentContext(),
+ abortChannel ) ),
+ UNO_QUERY_THROW );
+ }
+ }
+
+ const Reference<registry::XSimpleRegistry> xServicesRDB( getRDB() );
+ const Reference<registry::XImplementationRegistration> xImplReg(
+ context->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.ImplementationRegistration"),
+ context ), UNO_QUERY_THROW );
+
+ xImplReg->registerImplementation( m_loader, url, xServicesRDB );
+ //only write to unorc if registration was successful.
+ //It may fail if there is no suitable java.
+ if (isJavaTypelib)
+ {
+ that->addToUnoRc( java, url, xCmdEnv );
+ data.javaTypeLibrary = true;
+ }
+
+ t_stringlist implNames;
+ t_stringpairvec singletons;
+ const Reference<loader::XImplementationLoader> xLoader(
+ getComponentInfo( &implNames, &singletons, context ) );
+ data.implementationNames = implNames;
+ data.singletons = singletons;
+
+ if (!startup)
+ {
+ // 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;
+ getMyBackend()->addDataToDb(url, data);
+ }
+ else // revokePackage()
+ {
+ // set to VOID during revocation process:
+ m_registered = REG_VOID;
+
+ //get the remote context. If it does not exist then use the local one
+ Reference<XComponentContext> xContext(
+ that->getObject( url ), UNO_QUERY );
+ bool bRemoteContext = false;
+ if (!xContext.is())
+ xContext = that->getComponentContext();
+ else
+ bRemoteContext = true;
+
+ t_stringlist implNames;
+ t_stringpairvec singletons;
+ if (m_bRemoved)
+ {
+ implNames = m_registeredComponentsDb.implementationNames;
+ singletons = m_registeredComponentsDb.singletons;
+ }
+ else
+ {
+ getComponentInfo( &implNames, &singletons, xContext );
+ }
+
+ if (!startup)
+ {
+ // 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 (bRemoteContext)
+ that->releaseObject( url );
+
+ m_registered = REG_NOT_REGISTERED;
+ getMyBackend()->deleteDataFromDb(url);
+ }
+}
+
+//##############################################################################
+BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool jarFile, bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_jarFile( jarFile )
+{
+}
+
+// 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,
+ bool /*startup*/,
+ ::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,
+ IMPLEMENTATION_NAME,
+ 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..53085a48d185
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..36f2a1cc4a5c
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.src
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..b7ee5c203cd5
--- /dev/null
+++ b/desktop/source/deployment/registry/component/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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 \
+ $(SLO)$/dp_compbackenddb.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..9ea6e8227340
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.cxx
@@ -0,0 +1,783 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+
+//TODO: Large parts of this file were copied from dp_component.cxx; those parts
+// should be consolidated.
+
+#include "dp_configuration.hrc"
+#include "dp_backend.h"
+#include "dp_persmap.h"
+#include "dp_ucb.h"
+#include "rtl/string.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/memory.h"
+#include "osl/file.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "svl/inettype.hxx"
+#include "com/sun/star/configuration/Update.hpp"
+#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 <list>
+#include <memory>
+
+#include "dp_configurationbackenddb.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 configuration {
+namespace {
+
+typedef ::std::list<OUString> t_stringlist;
+
+//==============================================================================
+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,
+ bool startup,
+ ::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, bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_isSchema( isSchema )
+ {}
+ };
+ friend class PackageImpl;
+
+ t_stringlist m_xcs_files;
+ t_stringlist m_xcu_files;
+ t_stringlist & getFiles( bool xcs ) {
+ return xcs ? m_xcs_files : m_xcu_files;
+ }
+
+ bool m_configmgrini_inited;
+ bool m_configmgrini_modified;
+ std::auto_ptr<ConfigurationBackendDb> m_backendDb;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
+ OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ ::std::auto_ptr<PersistentMap> m_registeredPackages;
+ // for backwards compatibility
+
+ virtual void SAL_CALL disposing();
+
+ const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+ void configmgrini_verify_init(
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ void configmgrini_flush( Reference<XCommandEnvironment> const & xCmdEnv );
+
+ bool addToConfigmgrIni( bool isSchema, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ bool removeFromConfigmgrIni( bool isSchema, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void addDataToDb(OUString const & url, ConfigurationBackendDb::Data const & data);
+ ::boost::optional<ConfigurationBackendDb::Data> readDataFromDb(OUString const & url);
+ void deleteDataFromDb(OUString const & url);
+ ::std::list<OUString> getAllIniEntries();
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+
+ using PackageRegistryBackend::disposing;
+};
+
+//______________________________________________________________________________
+void BackendImpl::disposing()
+{
+ try {
+ configmgrini_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 );
+ }
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_configmgrini_inited( false ),
+ m_configmgrini_modified( false ),
+ 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;
+
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ if (transientMode())
+ {
+ //TODO
+ }
+ else
+ {
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ConfigurationBackendDb(getComponentContext(), dbFile));
+ //clean up data folders which are no longer used.
+ //This must not be done in the same process where the help files
+ //are still registers. Only after revoking and restarting OOo the folders
+ //can be removed. This works now, because the extension manager is a singleton
+ //and the backends are only create once per process.
+ ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
+ deleteUnusedFolders(OUString(), folders);
+
+
+ configmgrini_verify_init( xCmdEnv );
+ m_registeredPackages.reset(
+ new PersistentMap(
+ makeURL( getCachePath(), OUSTR("registered_packages.db") ),
+ false ) );
+ }
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, ConfigurationBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+::boost::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
+ OUString const & url)
+{
+ ::boost::optional<ConfigurationBackendDb::Data> data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+void BackendImpl::deleteDataFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+::std::list<OUString> BackendImpl::getAllIniEntries()
+{
+ if (m_backendDb.get())
+ return m_backendDb->getAllIniEntries();
+ else
+ return ::std::list<OUString>();
+}
+
+
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ 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"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>();
+ }
+
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.configuration-data"))
+ {
+ return new PackageImpl(
+ this, url, name, m_xConfDataTypeInfo, false /* data file */,
+ bRemoved, identifier);
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.configuration-schema")) {
+ return new PackageImpl(
+ this, url, name, m_xConfSchemaTypeInfo, true /* schema file */,
+ bRemoved, identifier);
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+void BackendImpl::configmgrini_verify_init(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ const ::osl::MutexGuard guard( getMutex() );
+ if (! m_configmgrini_inited)
+ {
+ // common rc:
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content(
+ &ucb_content,
+ makeURL( getCachePath(), OUSTR("configmgr.ini") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ OUString line;
+ if (readLine( &line, OUSTR("SCHEMA="), ucb_content,
+ RTL_TEXTENCODING_UTF8 ))
+ {
+ sal_Int32 index = sizeof ("SCHEMA=") - 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 */ )) {
+ //The file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the configmgrini.
+ //After running XExtensionManager::synchronize, the configmgrini is
+ //cleaned up
+ m_xcs_files.push_back( token );
+ }
+ }
+ }
+ while (index >= 0);
+ }
+ if (readLine( &line, OUSTR("DATA="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ sal_Int32 index = sizeof ("DATA=") - 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 */ )) {
+ //The file may not exist anymore if a shared or bundled
+ //extension was removed, but it can still be in the configmgrini.
+ //After running XExtensionManager::synchronize, the configmgrini is
+ //cleaned up
+ m_xcu_files.push_back( token );
+ }
+ else
+ {
+ //Check if it was removed. Only when the file contained %origin, so that
+ //a new file was writen in the user installation (e.g. $BUNDLED_EXTENSIONS_USER)
+ //See also ConfigurationBackendDb.iniEntry
+ ::std::list<OUString> iniEntries = getAllIniEntries();
+ if (::std::find(iniEntries.begin(), iniEntries.end(), token)
+ != iniEntries.end())
+ m_xcu_files.push_back( token );
+ else
+ OSL_ENSURE(0, "Extension manager: Invalid configmgr.ini entry.");
+ }
+ }
+ }
+ while (index >= 0);
+ }
+ }
+ m_configmgrini_modified = false;
+ m_configmgrini_inited = true;
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::configmgrini_flush(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ if (!m_configmgrini_inited || !m_configmgrini_modified)
+ return;
+
+ ::rtl::OStringBuffer buf;
+ if (! m_xcs_files.empty())
+ {
+ t_stringlist::const_iterator iPos( m_xcs_files.begin() );
+ t_stringlist::const_iterator const iEnd( m_xcs_files.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("SCHEMA=") );
+ 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_xcu_files.empty())
+ {
+ t_stringlist::const_iterator iPos( m_xcu_files.begin() );
+ t_stringlist::const_iterator const iEnd( m_xcu_files.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("DATA=") );
+ 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);
+ }
+
+ // write configmgr.ini:
+ 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("configmgr.ini") ), xCmdEnv );
+ ucb_content.writeStream( xData, true /* replace existing */ );
+
+ m_configmgrini_modified = false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::addToConfigmgrIni( bool isSchema, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ configmgrini_verify_init( xCmdEnv );
+ t_stringlist & rSet = getFiles(isSchema);
+ if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
+ rSet.push_front( rcterm ); // prepend to list, thus overriding
+ // write immediately:
+ m_configmgrini_modified = true;
+ configmgrini_flush( xCmdEnv );
+ return true;
+ }
+ else
+ return false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::removeFromConfigmgrIni(
+ bool isSchema, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( dp_misc::makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ configmgrini_verify_init( xCmdEnv );
+ t_stringlist & rSet = getFiles(isSchema);
+ t_stringlist::iterator i(std::find(rSet.begin(), rSet.end(), rcterm));
+ if (i == rSet.end() && !isSchema)
+ {
+ //in case the xcu contained %origin% then the configmr.ini contains the
+ //url to the file in the user installation (e.g. $BUNDLED_EXTENSIONS_USER)
+ ::boost::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
+ if (data)
+ i = std::find(rSet.begin(), rSet.end(), data->iniEntry);
+ }
+ if (i == rSet.end()) {
+ return false;
+ }
+ rSet.erase(i);
+ // write immediately:
+ m_configmgrini_modified = true;
+ configmgrini_flush( xCmdEnv );
+ return true;
+}
+
+//##############################################################################
+
+// 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();
+ const rtl::OUString url(getURL());
+
+ bool bReg = false;
+ if (that->readDataFromDb(getURL()))
+ bReg = true;
+ if (!bReg)
+ //fallback for user extension registered in berkeley DB
+ bReg = that->m_registeredPackages->has(
+ rtl::OUStringToOString( url, RTL_TEXTENCODING_UTF8 ));
+
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true, beans::Ambiguous<sal_Bool>( bReg, false ) );
+}
+
+//------------------------------------------------------------------------------
+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();
+}
+
+//______________________________________________________________________________
+OUString replaceOrigin(
+ OUString const & url, OUString const & destFolder, Reference< XCommandEnvironment > const & xCmdEnv, bool & out_replaced)
+{
+ // 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)
+ return url;
+ if (write_pos < filtered.getLength())
+ filtered.realloc( write_pos );
+ rtl::OUString newUrl(url);
+ if (destFolder.getLength())
+ {
+ //get the file name of the xcu and add it to the url of the temporary folder
+ sal_Int32 i = url.lastIndexOf('/');
+ newUrl = destFolder + url.copy(i);
+ }
+
+ ucbhelper::Content(newUrl, xCmdEnv).writeStream(
+ xmlscript::createInputStream(filtered), true);
+ out_replaced = true;
+ return newUrl;
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ OUString url( getURL() );
+
+ if (doRegisterPackage)
+ {
+ ConfigurationBackendDb::Data data;
+ if (!m_isSchema)
+ {
+ const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
+ bool out_replaced = false;
+ url = replaceOrigin(url, sModFolder, xCmdEnv, out_replaced);
+ if (out_replaced)
+ data.dataUrl = sModFolder;
+ else
+ deleteTempFolder(sModFolder);
+ }
+ //No need for live-deployment for bundled extension, because OOo
+ //restarts after installation
+ if (that->m_eContext != CONTEXT_BUNDLED
+ && !startup)
+ {
+ if (m_isSchema)
+ {
+ com::sun::star::configuration::Update::get(
+ that->m_xComponentContext)->insertExtensionXcsFile(
+ that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
+ }
+ else
+ {
+ com::sun::star::configuration::Update::get(
+ that->m_xComponentContext)->insertExtensionXcuFile(
+ that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
+ }
+ }
+ that->addToConfigmgrIni( m_isSchema, url, xCmdEnv );
+ data.iniEntry = dp_misc::makeRcTerm(url);
+ that->addDataToDb(getURL(), data);
+ }
+ else // revoke
+ {
+ if (!that->removeFromConfigmgrIni(m_isSchema, url, xCmdEnv)) {
+ t_string2string_map entries(
+ that->m_registeredPackages->getEntries());
+ for (t_string2string_map::iterator i(entries.begin());
+ i != entries.end(); ++i)
+ {
+ //If the xcu file was installed before the configmgr was chaned
+ //to use the configmgr.ini, one needed to rebuild to whole directory
+ //structur containing the xcu, xcs files from all extensions. Now,
+ //we just add all other xcu/xcs files to the configmgr.ini instead of
+ //rebuilding the directory structure.
+ rtl::OUString url2(
+ rtl::OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
+ ConfigurationBackendDb::Data data;
+ if (url2 != url) {
+ bool schema = i->second.equalsIgnoreAsciiCase(
+ "vnd.sun.star.configuration-schema");
+ OUString url_replaced(url2);
+ if (!schema)
+ {
+ const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
+ bool out_replaced = false;
+ url_replaced = replaceOrigin(
+ url2, sModFolder, xCmdEnv, out_replaced);
+ if (out_replaced)
+ data.dataUrl = sModFolder;
+ else
+ deleteTempFolder(sModFolder);
+ }
+ that->addToConfigmgrIni(schema, url_replaced, xCmdEnv);
+ that->addDataToDb(url2, data);
+ }
+ that->m_registeredPackages->erase(i->first);
+ }
+ ::ucbhelper::Content(
+ makeURL( that->getCachePath(), OUSTR("registry") ),
+ xCmdEnv ).executeCommand(
+ OUSTR("delete"), Any( true /* delete physically */ ) );
+ }
+ that->deleteDataFromDb(getURL());
+
+ //TODO: revoking at runtime, possible, sensible?
+ }
+}
+
+} // 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..01e1905228b3
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.hrc
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..7ff749b18459
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.src
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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/dp_configurationbackenddb.cxx b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx
new file mode 100644
index 000000000000..845ba88cb813
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * 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 "rtl/string.h"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+
+#include "dp_configurationbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/configuration-registry/2010"
+#define NS_PREFIX "conf"
+#define ROOT_ELEMENT_NAME "configuration-backend-db"
+#define KEY_ELEMENT_NAME "configuration"
+
+namespace dp_registry {
+namespace backend {
+namespace configuration {
+
+ConfigurationBackendDb::ConfigurationBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+OUString ConfigurationBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ConfigurationBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ConfigurationBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ConfigurationBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+
+void ConfigurationBackendDb::addEntry(::rtl::OUString const & url, Data const & data)
+{
+ try{
+ Reference<css::xml::dom::XNode> helpNode
+ = writeKeyElement(url);
+
+ writeSimpleElement(OUSTR("data-url"), data.dataUrl, helpNode);
+ writeSimpleElement(OUSTR("ini-entry"), data.iniEntry, helpNode);
+ save();
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in configuration backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+::boost::optional<ConfigurationBackendDb::Data>
+ConfigurationBackendDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ ConfigurationBackendDb::Data retData;
+ Reference<css::xml::dom::XNode> aNode = getKeyElement(url);
+ if (aNode.is())
+ {
+ retData.dataUrl = readSimpleElement(OUSTR("data-url"), aNode);
+ retData.iniEntry = readSimpleElement(OUSTR("ini-entry"), aNode);
+ }
+ else
+ {
+ return ::boost::optional<Data>();
+ }
+ return ::boost::optional<Data>(retData);
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in configuration backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::list<OUString> ConfigurationBackendDb::getAllDataUrls()
+{
+ try
+ {
+ ::std::list<OUString> listRet;
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sPrefix = getNSPrefix();
+ OUString sExpression(
+ sPrefix + OUSTR(":configuration/") + sPrefix + OUSTR(":data-url/text()"));
+ Reference<css::xml::dom::XNodeList> nodes =
+ xpathApi->selectNodeList(root, sExpression);
+ if (nodes.is())
+ {
+ sal_Int32 length = nodes->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ listRet.push_back(nodes->item(i)->getNodeValue());
+ }
+ return listRet;
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in configuration backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::list<OUString> ConfigurationBackendDb::getAllIniEntries()
+{
+ return getOneChildFromAllEntries(OUSTR("ini-entry"));
+}
+
+
+
+} // namespace configuration
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx
new file mode 100644
index 000000000000..1b6c4f8973a4
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configurationbackenddb.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * 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_CONFIGURATIONBACKENDDB_HXX
+#define INCLUDED_DP_CONFIGURATIONBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "rtl/string.hxx"
+#include <list>
+#include "boost/optional.hpp"
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace configuration {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ */
+class ConfigurationBackendDb: public dp_registry::backend::BackendDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+
+ virtual ::rtl::OUString getNSPrefix();
+
+ virtual ::rtl::OUString getRootElementName();
+
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+ struct Data
+ {
+ /* the URL to the folder containing the xcu or xcs files which contained
+ %origin%
+ */
+ ::rtl::OUString dataUrl;
+ /* the URL of the xcu or xcs file which is written in to the configmgr.ini
+ */
+ ::rtl::OUString iniEntry;
+ };
+
+public:
+
+ ConfigurationBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+ void addEntry(::rtl::OUString const & url, Data const & data);
+
+ ::boost::optional<Data> getEntry(::rtl::OUString const & url);
+ ::std::list< ::rtl::OUString> getAllDataUrls();
+ ::std::list< ::rtl::OUString> getAllIniEntries();
+};
+
+
+
+}
+}
+}
+#endif
+
diff --git a/desktop/source/deployment/registry/configuration/makefile.mk b/desktop/source/deployment/registry/configuration/makefile.mk
new file mode 100644
index 000000000000..9bcbd50d4230
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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 \
+ $(SLO)$/dp_configurationbackenddb.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..d781ba9e40ef
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_backend.cxx
@@ -0,0 +1,807 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "dp_backend.h"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "rtl/bootstrap.hxx"
+#include "osl/file.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/deployment/InvalidRemovedParameterException.hpp"
+#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
+#include "com/sun/star/ucb/IOErrorCode.hpp"
+#include "com/sun/star/beans/StringPair.hpp"
+#include "com/sun/star/sdbc/XResultSet.hpp"
+#include "com/sun/star/sdbc/XRow.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.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("bundled") ))
+ m_eContext = CONTEXT_BUNDLED;
+ else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("tmp") ))
+ m_eContext = CONTEXT_TMP;
+ 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, sal_Bool bRemoved,
+ OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::InvalidRemovedParameterException,
+ ucb::CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ check();
+
+ t_string2ref::const_iterator const iFind( m_bound.find( url ) );
+ if (iFind != m_bound.end())
+ {
+ Reference<deployment::XPackage> xPackage( iFind->second );
+ if (xPackage.is())
+ {
+ if (mediaType.getLength() &&
+ mediaType != xPackage->getPackageType()->getMediaType())
+ throw lang::IllegalArgumentException
+ (OUSTR("XPackageRegistry::bindPackage: media type does not match"),
+ static_cast<OWeakObject*>(this), 1);
+ if (xPackage->isRemoved() != bRemoved)
+ throw deployment::InvalidRemovedParameterException(
+ OUSTR("XPackageRegistry::bindPackage: bRemoved parameter does not match"),
+ static_cast<OWeakObject*>(this), xPackage->isRemoved(), xPackage);
+ return xPackage;
+ }
+ }
+
+ guard.clear();
+
+ Reference<deployment::XPackage> xNewPackage;
+ try {
+ xNewPackage = bindPackage_( url, mediaType, bRemoved,
+ identifier, 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_string2ref::iterator, bool > insertion(
+ m_bound.insert( t_string2ref::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;
+}
+
+OUString PackageRegistryBackend::createFolder(
+ OUString const & relUrl,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ OUString sDataFolder = makeURL(getCachePath(), relUrl);
+ //make sure the folder exist
+ ucbhelper::Content dataContent;
+ ::dp_misc::create_folder(&dataContent, sDataFolder, xCmdEnv);
+
+ OUString sDataFolderURL = dp_misc::expandUnoRcUrl(sDataFolder);
+
+ OUString tempEntry;
+ if (::osl::File::createTempFile(
+ &sDataFolderURL, 0, &tempEntry ) != ::osl::File::E_None)
+ throw RuntimeException(
+ OUSTR("::osl::File::createTempFile() failed!"), 0 );
+ tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
+ OUString destFolder= makeURL(sDataFolder, tempEntry) + OUSTR("_");
+ ::ucbhelper::Content destFolderContent;
+ dp_misc::create_folder( &destFolderContent, destFolder, xCmdEnv );
+
+ return destFolder;
+}
+
+void PackageRegistryBackend::deleteTempFolder(
+ OUString const & folderUrl)
+{
+ OSL_ASSERT(folderUrl.getLength()
+ && folderUrl[folderUrl.getLength() - 1] == '_');
+ if (folderUrl.getLength()
+ && folderUrl[folderUrl.getLength() - 1] == '_')
+ {
+ const OUString tempFile = folderUrl.copy(0, folderUrl.getLength() - 1);
+ erase_path( folderUrl, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ erase_path( tempFile, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ }
+}
+
+void PackageRegistryBackend::deleteUnusedFolders(
+ OUString const & relUrl,
+ ::std::list< OUString> const & usedFolders)
+{
+ try
+ {
+ const OUString sDataFolder = makeURL(getCachePath(), relUrl);
+ ::ucbhelper::Content tempFolder(
+ sDataFolder, Reference<ucb::XCommandEnvironment>());
+ Reference<sdbc::XResultSet> xResultSet(
+ tempFolder.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
+ // get all temp directories:
+ ::std::vector<OUString> tempEntries;
+
+ char tmp[] = ".tmp";
+
+ while (xResultSet->next())
+ {
+ OUString title(
+ Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(
+ 1 /* Title */ ) );
+
+ if (title.endsWithAsciiL(tmp, sizeof(tmp) - 1))
+ tempEntries.push_back(
+ makeURLAppendSysPathSegment(sDataFolder, title));
+ }
+
+ for ( ::std::size_t pos = 0; pos < tempEntries.size(); ++pos )
+ {
+ //usedFolders contains the urls to the folders which have
+ //a trailing underscore
+ const OUString tempFolderName = tempEntries[ pos ] + OUSTR("_");
+
+ if (::std::find( usedFolders.begin(), usedFolders.end(), tempFolderName ) ==
+ usedFolders.end())
+ {
+ deleteTempFolder(tempFolderName);
+ }
+ }
+ }
+ catch (ucb::InteractiveAugmentedIOException& e)
+ {
+ //In case the folder containing all the data folder does not
+ //exist yet, we ignore the exception
+ if (e.Code != ucb::IOErrorCode_NOT_EXISTING)
+ throw e;
+ }
+
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+Package::~Package()
+{
+}
+
+//______________________________________________________________________________
+Package::Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url,
+ OUString const & rName,
+ OUString const & displayName,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved,
+ OUString const & identifier)
+ : t_PackageBase( getMutex() ),
+ m_myBackend( myBackend ),
+ m_url( url ),
+ m_name( rName ),
+ m_displayName( displayName ),
+ m_xPackageType( xPackageType ),
+ m_bRemoved(bRemoved),
+ m_identifier(identifier)
+{
+ if (m_bRemoved)
+ {
+ //We use the last segment of the URL
+ OSL_ASSERT(m_name.getLength() == 0);
+ OUString name = m_url;
+ rtl::Bootstrap::expandMacros(name);
+ sal_Int32 index = name.lastIndexOf('/');
+ if (index != -1 && index < name.getLength())
+ m_name = name.copy(index + 1);
+ }
+}
+
+//______________________________________________________________________________
+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_Int32 Package::checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >&,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >&,
+ sal_Bool)
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return 0;
+}
+
+//______________________________________________________________________________
+::sal_Bool Package::checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& )
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ 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)
+{
+ if (m_bRemoved)
+ return beans::Optional<OUString>(true, m_identifier);
+
+ return beans::Optional<OUString>();
+}
+
+//______________________________________________________________________________
+OUString Package::getVersion() throw (
+ deployment::ExtensionRemovedException,
+ RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return OUString();
+}
+
+//______________________________________________________________________________
+OUString Package::getURL() throw (RuntimeException)
+{
+ return m_url;
+}
+
+//______________________________________________________________________________
+OUString Package::getDisplayName() throw (
+ deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return m_displayName;
+}
+
+//______________________________________________________________________________
+OUString Package::getDescription() throw (
+ deployment::ExtensionRemovedException,RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return OUString();
+}
+
+//______________________________________________________________________________
+Sequence<OUString> Package::getUpdateInformationURLs() throw (
+ deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return Sequence<OUString>();
+}
+
+//______________________________________________________________________________
+css::beans::StringPair Package::getPublisherInfo() throw (
+ deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ css::beans::StringPair aEmptyPair;
+ return aEmptyPair;
+}
+
+//______________________________________________________________________________
+uno::Reference< css::graphic::XGraphic > Package::getIcon( sal_Bool /*bHighContrast*/ )
+ throw (deployment::ExtensionRemovedException, RuntimeException )
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ 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 (deployment::ExtensionRemovedException,
+ CommandFailedException, CommandAbortedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ ::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,
+ bool startup,
+ 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 = isRemoved() ? getName() : getDisplayName();
+ ProgressLevel progress(
+ xCmdEnv,
+ (doRegisterPackage
+ ? PackageRegistryBackend::StrRegisteringPackage::get()
+ : PackageRegistryBackend::StrRevokingPackage::get())
+ + displayName );
+ processPackage_( guard,
+ doRegisterPackage,
+ startup,
+ 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(
+ sal_Bool startup,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::ExtensionRemovedException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ processPackage_impl( true /* register */, startup, 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 */, false, xAbortChannel, xCmdEnv );
+
+}
+
+PackageRegistryBackend * Package::getMyBackend() const
+{
+ PackageRegistryBackend * pBackend = 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<Package *>(this)));
+ }
+ return pBackend;
+}
+OUString Package::getRepositoryName()
+ throw (RuntimeException)
+{
+ PackageRegistryBackend * backEnd = getMyBackend();
+ return backEnd->getContext();
+}
+
+beans::Optional< OUString > Package::getRegistrationDataURL()
+ throw (deployment::ExtensionRemovedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return beans::Optional<OUString>();
+}
+
+sal_Bool Package::isRemoved()
+ throw (RuntimeException)
+{
+ return m_bRemoved;
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+Package::TypeInfo::~TypeInfo()
+{
+}
+
+// XPackageTypeInfo
+//______________________________________________________________________________
+OUString Package::TypeInfo::getMediaType() throw (RuntimeException)
+{
+ return m_mediaType;
+}
+
+//______________________________________________________________________________
+OUString Package::TypeInfo::getDescription()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ return getShortDescription();
+}
+
+//______________________________________________________________________________
+OUString Package::TypeInfo::getShortDescription()
+ throw (deployment::ExtensionRemovedException, 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_backenddb.cxx b/desktop/source/deployment/registry/dp_backenddb.cxx
new file mode 100644
index 000000000000..14b4f2374c5b
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_backenddb.cxx
@@ -0,0 +1,649 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "rtl/string.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "osl/file.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "com/sun/star/io/XActiveDataSource.hpp"
+#include "com/sun/star/io/XActiveDataControl.hpp"
+#include "dp_ucb.h"
+#include "dp_misc.h"
+#include "ucbhelper/content.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "dp_backenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+
+namespace dp_registry {
+namespace backend {
+
+BackendDb::BackendDb(
+ Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url):
+ m_xContext(xContext)
+{
+ m_urlDb = dp_misc::expandUnoRcUrl(url);
+}
+
+void BackendDb::save()
+{
+ const Reference<css::io::XActiveDataSource> xDataSource(m_doc,css::uno::UNO_QUERY_THROW);
+ ::rtl::ByteSequence bytes;
+ xDataSource->setOutputStream(::xmlscript::createOutputStream(&bytes));
+ const Reference<css::io::XActiveDataControl> xDataControl(m_doc,css::uno::UNO_QUERY_THROW);
+ xDataControl->start();
+
+ const Reference<css::io::XInputStream> xData(
+ ::xmlscript::createInputStream(bytes));
+ ::ucbhelper::Content ucbDb(m_urlDb, 0);
+ ucbDb.writeStream(xData, true /*replace existing*/);
+}
+
+css::uno::Reference<css::xml::dom::XDocument> BackendDb::getDocument()
+{
+ if (!m_doc.is())
+ {
+ const Reference<css::xml::dom::XDocumentBuilder> xDocBuilder(
+ m_xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.dom.DocumentBuilder"),
+ m_xContext ), css::uno::UNO_QUERY);
+ if (!xDocBuilder.is())
+ throw css::uno::RuntimeException(
+ OUSTR(" Could not create service com.sun.star.xml.dom.DocumentBuilder"), 0);
+
+ ::osl::DirectoryItem item;
+ ::osl::File::RC err = ::osl::DirectoryItem::get(m_urlDb, item);
+ if (err == ::osl::File::E_None)
+ {
+ m_doc = xDocBuilder->parseURI(m_urlDb);
+ }
+ else if (err == ::osl::File::E_NOENT)
+ {
+ //Create a new document and insert some basic stuff
+ m_doc = xDocBuilder->newDocument();
+ const Reference<css::xml::dom::XElement> rootNode =
+ m_doc->createElementNS(getDbNSName(), getNSPrefix() +
+ OUSTR(":") + getRootElementName());
+
+ m_doc->appendChild(Reference<css::xml::dom::XNode>(
+ rootNode, UNO_QUERY_THROW));
+ save();
+ }
+ else
+ throw css::uno::RuntimeException(
+ OUSTR("Extension manager could not access database file:" )
+ + m_urlDb, 0);
+
+ if (!m_doc.is())
+ throw css::uno::RuntimeException(
+ OUSTR("Extension manager could not get root node of data base file: ")
+ + m_urlDb, 0);
+ }
+
+ return m_doc;
+}
+
+Reference<css::xml::xpath::XXPathAPI> BackendDb::getXPathAPI()
+{
+ if (!m_xpathApi.is())
+ {
+ m_xpathApi = Reference< css::xml::xpath::XXPathAPI >(
+ m_xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.xpath.XPathAPI"),
+ m_xContext), css::uno::UNO_QUERY);
+
+ if (!m_xpathApi.is())
+ throw css::uno::RuntimeException(
+ OUSTR(" Could not create service com.sun.star.xml.xpath.XPathAPI"), 0);
+
+ m_xpathApi->registerNS(
+ getNSPrefix(), getDbNSName());
+ }
+
+ return m_xpathApi;
+}
+
+void BackendDb::removeElement(::rtl::OUString const & sXPathExpression)
+{
+ try
+ {
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ //find the extension element that is to be removed
+ const Reference<css::xml::dom::XNode> aNode =
+ xpathApi->selectSingleNode(root, sXPathExpression);
+
+ if (aNode.is())
+ {
+ root->removeChild(aNode);
+ save();
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ //There must not be any other entry with the same url
+ const Reference<css::xml::dom::XNode> nextNode =
+ xpathApi->selectSingleNode(root, sXPathExpression);
+ OSL_ASSERT(! nextNode.is());
+#endif
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+void BackendDb::removeEntry(::rtl::OUString const & url)
+{
+ const OUString sKeyElement = getKeyElementName();
+ const OUString sPrefix = getNSPrefix();
+ ::rtl::OUStringBuffer sExpression(500);
+ sExpression.append(sPrefix);
+ sExpression.appendAscii(":");
+ sExpression.append(sKeyElement);
+ sExpression.append(OUSTR("[@url = \""));
+ sExpression.append(url);
+ sExpression.appendAscii("\"]");
+
+ removeElement(sExpression.makeStringAndClear());
+}
+
+Reference<css::xml::dom::XNode> BackendDb::getKeyElement(
+ ::rtl::OUString const & url)
+{
+ try
+ {
+ const OUString sPrefix = getNSPrefix();
+ const OUString sKeyElement = getKeyElementName();
+ ::rtl::OUStringBuffer sExpression(500);
+ sExpression.append(sPrefix);
+ sExpression.appendAscii(":");
+ sExpression.append(sKeyElement);
+ sExpression.append(OUSTR("[@url = \""));
+ sExpression.append(url);
+ sExpression.appendAscii("\"]");
+
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ return xpathApi->selectSingleNode(root, sExpression.makeStringAndClear());
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read key element in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+//Only writes the data if there is at least one entry
+void BackendDb::writeVectorOfPair(
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > const & vecPairs,
+ OUString const & sVectorTagName,
+ OUString const & sPairTagName,
+ OUString const & sFirstTagName,
+ OUString const & sSecondTagName,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent)
+{
+ try{
+ if (vecPairs.size() == 0)
+ return;
+ const OUString sNameSpace = getDbNSName();
+ OSL_ASSERT(sNameSpace.getLength());
+ const OUString sPrefix(getNSPrefix() + OUSTR(":"));
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ const Reference<css::xml::dom::XElement> vectorNode(
+ doc->createElementNS(sNameSpace, sPrefix + sVectorTagName));
+
+ xParent->appendChild(
+ Reference<css::xml::dom::XNode>(
+ vectorNode, css::uno::UNO_QUERY_THROW));
+ typedef ::std::vector< ::std::pair< OUString, OUString > >::const_iterator CIT;
+ for (CIT i = vecPairs.begin(); i != vecPairs.end(); i++)
+ {
+ const Reference<css::xml::dom::XElement> pairNode(
+ doc->createElementNS(sNameSpace, sPrefix + sPairTagName));
+
+ vectorNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ pairNode, css::uno::UNO_QUERY_THROW));
+
+ const Reference<css::xml::dom::XElement> firstNode(
+ doc->createElementNS(sNameSpace, sPrefix + sFirstTagName));
+
+ pairNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ firstNode, css::uno::UNO_QUERY_THROW));
+
+ const Reference<css::xml::dom::XText> firstTextNode(
+ doc->createTextNode( i->first));
+
+ firstNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ firstTextNode, css::uno::UNO_QUERY_THROW));
+
+ const Reference<css::xml::dom::XElement> secondNode(
+ doc->createElementNS(sNameSpace, sPrefix + sSecondTagName));
+
+ pairNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ secondNode, css::uno::UNO_QUERY_THROW));
+
+ const Reference<css::xml::dom::XText> secondTextNode(
+ doc->createTextNode( i->second));
+
+ secondNode->appendChild(
+ Reference<css::xml::dom::XNode>(
+ secondTextNode, css::uno::UNO_QUERY_THROW));
+ }
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::vector< ::std::pair< OUString, OUString > >
+BackendDb::readVectorOfPair(
+ Reference<css::xml::dom::XNode> const & parent,
+ OUString const & sListTagName,
+ OUString const & sPairTagName,
+ OUString const & sFirstTagName,
+ OUString const & sSecondTagName)
+{
+ try
+ {
+ OSL_ASSERT(parent.is());
+ const OUString sPrefix(getNSPrefix() + OUSTR(":"));
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sExprPairs(
+ sPrefix + sListTagName + OUSTR("/") + sPrefix + sPairTagName);
+ const Reference<css::xml::dom::XNodeList> listPairs =
+ xpathApi->selectNodeList(parent, sExprPairs);
+
+ ::std::vector< ::std::pair< OUString, OUString > > retVector;
+ sal_Int32 length = listPairs->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ const Reference<css::xml::dom::XNode> aPair = listPairs->item(i);
+ const OUString sExprFirst(sPrefix + sFirstTagName + OUSTR("/text()"));
+ const Reference<css::xml::dom::XNode> first =
+ xpathApi->selectSingleNode(aPair, sExprFirst);
+
+ const OUString sExprSecond(sPrefix + sSecondTagName + OUSTR("/text()"));
+ const Reference<css::xml::dom::XNode> second =
+ xpathApi->selectSingleNode(aPair, sExprSecond);
+ OSL_ASSERT(first.is() && second.is());
+
+ retVector.push_back(::std::make_pair(
+ first->getNodeValue(), second->getNodeValue()));
+ }
+ return retVector;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+//Only writes the data if there is at least one entry
+void BackendDb::writeSimpleList(
+ ::std::list< ::rtl::OUString> const & list,
+ OUString const & sListTagName,
+ OUString const & sMemberTagName,
+ Reference<css::xml::dom::XNode> const & xParent)
+{
+ try
+ {
+ if (list.size() == 0)
+ return;
+ const OUString sNameSpace = getDbNSName();
+ const OUString sPrefix(getNSPrefix() + OUSTR(":"));
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+
+ const Reference<css::xml::dom::XElement> listNode(
+ doc->createElementNS(sNameSpace, sPrefix + sListTagName));
+
+ xParent->appendChild(
+ Reference<css::xml::dom::XNode>(
+ listNode, css::uno::UNO_QUERY_THROW));
+
+ typedef ::std::list<OUString>::const_iterator ITC_ITEMS;
+ for (ITC_ITEMS i = list.begin(); i != list.end(); i++)
+ {
+ const Reference<css::xml::dom::XNode> memberNode(
+ doc->createElementNS(sNameSpace, sPrefix + sMemberTagName), css::uno::UNO_QUERY_THROW);
+
+ listNode->appendChild(memberNode);
+
+ const Reference<css::xml::dom::XNode> textNode(
+ doc->createTextNode( *i), css::uno::UNO_QUERY_THROW);
+
+ memberNode->appendChild(textNode);
+ }
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+//Writes only the element if is has a value.
+//The prefix is automatically added to the element name
+void BackendDb::writeSimpleElement(
+ OUString const & sElementName, OUString const & value,
+ Reference<css::xml::dom::XNode> const & xParent)
+{
+ try
+ {
+ if (value.getLength() == 0)
+ return;
+ const OUString sPrefix = getNSPrefix();
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const OUString sNameSpace = getDbNSName();
+ const Reference<css::xml::dom::XNode> dataNode(
+ doc->createElementNS(sNameSpace, sPrefix + OUSTR(":") + sElementName),
+ UNO_QUERY_THROW);
+ xParent->appendChild(dataNode);
+
+ const Reference<css::xml::dom::XNode> dataValue(
+ doc->createTextNode(value), UNO_QUERY_THROW);
+ dataNode->appendChild(dataValue);
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry(writeSimpleElement) in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+
+}
+
+/** The key elements have an url attribute and are always children of the root
+ element.
+*/
+Reference<css::xml::dom::XNode> BackendDb::writeKeyElement(
+ ::rtl::OUString const & url)
+{
+ try
+ {
+ const OUString sNameSpace = getDbNSName();
+ const OUString sPrefix = getNSPrefix();
+ const OUString sElementName = getKeyElementName();
+ const Reference<css::xml::dom::XDocument> doc = getDocument();
+ const Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ //Check if there are an entry with the same url. This can be the case if the
+ //the status of an XPackage is ambiguous. In this case a call to activateExtension
+ //(dp_extensionmanager.cxx), will register the package again. See also
+ //Package::processPackage_impl in dp_backend.cxx.
+ //A package can become
+ //invalid after its successful registration, for example if a second extension with
+ //the same service is installed.
+ const OUString sExpression(
+ sPrefix + OUSTR(":") + sElementName + OUSTR("[@url = \"") + url + OUSTR("\"]"));
+ const Reference<css::xml::dom::XNode> existingNode =
+ getXPathAPI()->selectSingleNode(root, sExpression);
+ if (existingNode.is())
+ {
+ OSL_ASSERT(0);
+ //replace the existing entry.
+ removeEntry(url);
+ }
+
+ const Reference<css::xml::dom::XElement> keyElement(
+ doc->createElementNS(sNameSpace, sPrefix + OUSTR(":") + sElementName));
+
+ keyElement->setAttribute(OUSTR("url"), url);
+
+ const Reference<css::xml::dom::XNode> keyNode(
+ keyElement, UNO_QUERY_THROW);
+ root->appendChild(keyNode);
+ return keyNode;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write key element in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+OUString BackendDb::readSimpleElement(
+ OUString const & sElementName, Reference<css::xml::dom::XNode> const & xParent)
+{
+ try
+ {
+ const OUString sPrefix = getNSPrefix();
+ const OUString sExpr(sPrefix + OUSTR(":") + sElementName + OUSTR("/text()"));
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const Reference<css::xml::dom::XNode> val =
+ xpathApi->selectSingleNode(xParent, sExpr);
+ if (val.is())
+ return val->getNodeValue();
+ return OUString();
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data (readSimpleElement) in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+::std::list< OUString> BackendDb::readList(
+ Reference<css::xml::dom::XNode> const & parent,
+ OUString const & sListTagName,
+ OUString const & sMemberTagName)
+{
+ try
+ {
+ OSL_ASSERT(parent.is());
+ const OUString sPrefix(getNSPrefix() + OUSTR(":"));
+ const Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sExprList(
+ sPrefix + sListTagName + OUSTR("/") + sPrefix + sMemberTagName + OUSTR("/text()"));
+ const Reference<css::xml::dom::XNodeList> list =
+ xpathApi->selectNodeList(parent, sExprList);
+
+ ::std::list<OUString > retList;
+ sal_Int32 length = list->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ const Reference<css::xml::dom::XNode> member = list->item(i);
+ retList.push_back(member->getNodeValue());
+ }
+ return retList;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::list<OUString> BackendDb::getOneChildFromAllEntries(
+ OUString const & name)
+{
+ try
+ {
+ ::std::list<OUString> listRet;
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sPrefix = getNSPrefix();
+ const OUString sKeyElement = getKeyElementName();
+ ::rtl::OUStringBuffer buf(512);
+ buf.append(sPrefix);
+ buf.appendAscii(":");
+ buf.append(sKeyElement);
+ buf.appendAscii("/");
+ buf.append(sPrefix);
+ buf.appendAscii(":");
+ buf.append(name);
+ buf.append(OUSTR("/text()"));
+
+ Reference<css::xml::dom::XNodeList> nodes =
+ xpathApi->selectNodeList(root, buf.makeStringAndClear());
+ if (nodes.is())
+ {
+ sal_Int32 length = nodes->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ listRet.push_back(nodes->item(i)->getNodeValue());
+ }
+ return listRet;
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+
+//================================================================================
+RegisteredDb::RegisteredDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+void RegisteredDb::addEntry(::rtl::OUString const & url)
+{
+ try{
+
+ const OUString sNameSpace = getDbNSName();
+ const OUString sPrefix = getNSPrefix();
+ const OUString sEntry = getKeyElementName();
+
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+#if OSL_DEBUG_LEVEL > 0
+ //There must not be yet an entry with the same url
+ OUString sExpression(
+ sPrefix + OUSTR(":") + sEntry + OUSTR("[@url = \"") + url + OUSTR("\"]"));
+ Reference<css::xml::dom::XNode> _extensionNode =
+ getXPathAPI()->selectSingleNode(root, sExpression);
+ OSL_ASSERT(! _extensionNode.is());
+#endif
+ Reference<css::xml::dom::XElement> helpElement(
+ doc->createElementNS(sNameSpace, sPrefix + OUSTR(":") + sEntry));
+
+ helpElement->setAttribute(OUSTR("url"), url);
+
+ Reference<css::xml::dom::XNode> helpNode(
+ helpElement, UNO_QUERY_THROW);
+ root->appendChild(helpNode);
+
+ save();
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+bool RegisteredDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ const OUString sPrefix = getNSPrefix();
+ const OUString sEntry = getKeyElementName();
+ const OUString sExpression(
+ sPrefix + OUSTR(":") + sEntry + OUSTR("[@url = \"") + url + OUSTR("\"]"));
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ //find the extension element that is to be removed
+ Reference<css::xml::dom::XNode> aNode =
+ xpathApi->selectSingleNode(root, sExpression);
+ if (!aNode.is())
+ {
+ return false;
+ }
+ return true;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/dp_registry.cxx b/desktop/source/deployment/registry/dp_registry.cxx
new file mode 100644
index 000000000000..c5e440a2a825
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_registry.cxx
@@ -0,0 +1,555 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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, sal_Bool bRemoved,
+ OUString const & identifier, 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() );
+ //The package backend shall also be called to determine the mediatype
+ //(XPackageRegistry.bindPackage) when the URL points to a directory.
+ const bool bExtension = mediaType.equals(OUSTR("application/vnd.sun.star.package-bundle"));
+ if (fileFilter.getLength() == 0 ||
+ fileFilter.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*.*") ) ||
+ fileFilter.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*") ) ||
+ bExtension)
+ {
+ 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 back-end.
+ // Always register as last, because we want to add extensions also as folders
+ // and as a default we accept every folder, which was not recognized by the other
+ // backends.
+ Reference<deployment::XPackageRegistry> extensionBackend =
+ ::dp_registry::backend::bundle::create(
+ that, context, cachePath, readOnly, xComponentContext);
+ that->insertBackend(extensionBackend);
+
+ Reference<lang::XServiceInfo> xServiceInfo(
+ extensionBackend, UNO_QUERY_THROW );
+
+ OSL_ASSERT(xServiceInfo.is());
+ OUString registryCachePath(
+ makeURL( cachePath,
+ ::rtl::Uri::encode(
+ xServiceInfo->getImplementationName(),
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) ) );
+ create_folder( 0, registryCachePath, Reference<XCommandEnvironment>());
+
+
+#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_, sal_Bool bRemoved,
+ OUString const & identifier, 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 */ )
+ && !ucbContent.isFolder())
+ {
+ 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, bRemoved,
+ identifier, 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, bRemoved,
+ identifier, 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..68a52621741f
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_registry.src
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..968ee7297b0f
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/dp_executable.cxx
@@ -0,0 +1,331 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "dp_misc.h"
+#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 "svl/inettype.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "dp_executablebackenddb.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace dp_misc;
+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,
+ bool startup,
+ ::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,
+ bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier)
+ {}
+ };
+ 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, sal_Bool bRemoved,
+ OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void addDataToDb(OUString const & url);
+ bool isRegisteredInDb(OUString const & url);
+ void deleteDataFromDb(OUString const & url);
+
+ Reference<deployment::XPackageTypeInfo> m_xExecutableTypeInfo;
+ std::auto_ptr<ExecutableBackendDb> m_backendDb;
+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 ) )
+{
+ if (!transientMode())
+ {
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ExecutableBackendDb(getComponentContext(), dbFile));
+ }
+}
+
+void BackendImpl::addDataToDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url);
+}
+
+bool BackendImpl::isRegisteredInDb(OUString const & url)
+{
+ bool ret = false;
+ if (m_backendDb.get())
+ ret = m_backendDb->getEntry(url);
+ return ret;
+}
+
+void BackendImpl::deleteDataFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+// 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, sal_Bool bRemoved,
+ OUString const & identifier, 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"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ 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, bRemoved,
+ identifier);
+ }
+ }
+ }
+ 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 & )
+{
+ bool registered = getMyBackend()->isRegisteredInDb(getURL());
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ sal_True /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ registered, sal_False /* IsAmbiguous */ ) );
+}
+
+void BackendImpl::ExecutablePackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool /*startup*/,
+ ::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 if (!getMyBackend()->m_context.equals(OUSTR("bundled")))
+ //Bundled extension are required to be in the properly
+ //installed. That is an executable must have the right flags
+ OSL_ASSERT(0);
+
+ //This won't have affect on Windows
+ osl::File::setAttributes(
+ dp_misc::expandUnoRcUrl(m_url), attributes);
+ }
+ getMyBackend()->addDataToDb(getURL());
+ }
+ else
+ {
+ getMyBackend()->deleteDataFromDb(getURL());
+ }
+}
+
+//We currently cannot check if this XPackage represents a content of a particular extension
+//But we can check if we are within $UNO_USER_PACKAGES_CACHE etc.
+//Done for security reasons. For example an extension manifest could contain a path to
+//an executable outside the extension.
+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 if (getMyBackend()->m_context.equals(OUSTR("bundled")))
+ sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$BUNDLED_EXTENSIONS"));
+ 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/dp_executablebackenddb.cxx b/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx
new file mode 100644
index 000000000000..976a6281a2bd
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/dp_executablebackenddb.cxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * 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 "rtl/string.h"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "dp_misc.h"
+#include "dp_executablebackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/executable-registry/2010"
+#define NS_PREFIX "exe"
+#define ROOT_ELEMENT_NAME "executable-backend-db"
+#define ENTRY_NAME "executable"
+
+namespace dp_registry {
+namespace backend {
+namespace executable {
+
+ExecutableBackendDb::ExecutableBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):RegisteredDb(xContext, url)
+{
+
+}
+
+OUString ExecutableBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ExecutableBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ExecutableBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ExecutableBackendDb::getKeyElementName()
+{
+ return OUSTR(ENTRY_NAME);
+}
+
+
+} // namespace executable
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx b/desktop/source/deployment/registry/executable/dp_executablebackenddb.hxx
new file mode 100644
index 000000000000..4f17eeda24a6
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/dp_executablebackenddb.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_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_EXECUTABLEBACKENDDB_HXX
+#define INCLUDED_DP_EXECUTABLEBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace executable {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ The format looks like this:
+
+<?xml version="1.0"?>
+ */
+class ExecutableBackendDb: public dp_registry::backend::RegisteredDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+
+ virtual ::rtl::OUString getNSPrefix();
+
+ virtual ::rtl::OUString getRootElementName();
+
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+
+ ExecutableBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+};
+
+
+
+}
+}
+}
+#endif
+
diff --git a/desktop/source/deployment/registry/executable/makefile.mk b/desktop/source/deployment/registry/executable/makefile.mk
new file mode 100644
index 000000000000..81b2baa44e5d
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/makefile.mk
@@ -0,0 +1,44 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_executable
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_executable.obj \
+ $(SLO)$/dp_executablebackenddb.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..bc17a1f7163d
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.cxx
@@ -0,0 +1,598 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "dp_help.hrc"
+#include "dp_backend.h"
+#include "dp_helpbackenddb.hxx"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "osl/file.hxx"
+#include "rtl/bootstrap.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svl/inettype.hxx"
+#include "unotools/pathoptions.hxx"
+
+#include <l10ntools/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>
+#include "boost/optional.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;
+
+// HelpBackendDb::Data m_dbData;
+
+ // 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,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier);
+
+ //XPackage
+ virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getRegistrationDataURL()
+ throw (deployment::ExtensionRemovedException, css::uno::RuntimeException);
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void implProcessHelp( Reference< deployment::XPackage > xPackage, bool doRegisterPackage,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv);
+ void implCollectXhpFiles( const rtl::OUString& aDir,
+ std::vector< rtl::OUString >& o_rXhpFileVector );
+
+ void addDataToDb(OUString const & url, HelpBackendDb::Data const & data);
+ ::boost::optional<HelpBackendDb::Data> readDataFromDb(OUString const & url);
+ void deleteDataFromDb(OUString const & url);
+
+ Reference< ucb::XSimpleFileAccess > getFileAccess( void );
+ Reference< ucb::XSimpleFileAccess > m_xSFA;
+
+ const Reference<deployment::XPackageTypeInfo> m_xHelpTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+ std::auto_ptr<HelpBackendDb> m_backendDb;
+
+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;
+ if (!transientMode())
+ {
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new HelpBackendDb(getComponentContext(), dbFile));
+
+ //clean up data folders which are no longer used.
+ //This must not be done in the same process where the help files
+ //are still registers. Only after revoking and restarting OOo the folders
+ //can be removed. This works now, because the extension manager is a singleton
+ //and the backends are only create once per process.
+ ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
+ deleteUnusedFolders(OUString(), folders);
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ sal_Bool bRemoved, OUString const & identifier,
+ 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"))
+ {
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>();
+ }
+
+ if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.help"))
+ {
+ return new PackageImpl(
+ this, url, name, m_xHelpTypeInfo, bRemoved,
+ identifier);
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType_,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, HelpBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+::boost::optional<HelpBackendDb::Data> BackendImpl::readDataFromDb(
+ OUString const & url)
+{
+ ::boost::optional<HelpBackendDb::Data> data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+void BackendImpl::deleteDataFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+//##############################################################################
+BackendImpl::PackageImpl::PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name, xPackageType, bRemoved,
+ identifier)
+{
+// if (bRemoved)
+// {
+// ::boost::optional<HelpBackendDb::Data> opt =
+// getMyBackend()->readDataFromDb(url);
+// if (opt)
+// m_dbData = *opt;
+// }
+}
+
+// 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();
+
+ bool bReg = false;
+ if (that->readDataFromDb(getURL()))
+ bReg = true;
+
+ return beans::Optional< beans::Ambiguous<sal_Bool> >( true, beans::Ambiguous<sal_Bool>( bReg, false ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool /* startup */,
+ ::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, xCmdEnv);
+}
+
+beans::Optional< OUString > BackendImpl::PackageImpl::getRegistrationDataURL()
+ throw (deployment::ExtensionRemovedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ ::boost::optional<HelpBackendDb::Data> data =
+ getMyBackend()->readDataFromDb(getURL());
+
+ if (data)
+ return beans::Optional<OUString>(true, data->dataUrl);
+
+ return beans::Optional<OUString>(true, OUString());
+}
+
+
+//##############################################################################
+
+static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) );
+static rtl::OUString aHelpStr( rtl::OUString::createFromAscii( "help" ) );
+
+
+void BackendImpl::implProcessHelp
+( Reference< deployment::XPackage > xPackage, bool doRegisterPackage,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ OSL_ASSERT(xPackage.is());
+ if (doRegisterPackage)
+ {
+ HelpBackendDb::Data data;
+ const OUString sHelpFolder = createFolder(OUString(), xCmdEnv);
+ data.dataUrl = sHelpFolder;
+
+ Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess();
+ rtl::OUString aHelpURL = xPackage->getURL();
+ rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl( 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;
+
+ // calculate jar file URL
+ sal_Int32 indexStartSegment = aLangURL.lastIndexOf('/');
+ // for example "/en"
+ OUString langFolderURLSegment(
+ aLangURL.copy(
+ indexStartSegment + 1, aLangURL.getLength() - indexStartSegment - 1));
+
+ //create the folder in the "temporary folder"
+ ::ucbhelper::Content langFolderContent;
+ const OUString langFolderDest = makeURL(sHelpFolder, langFolderURLSegment);
+ const OUString langFolderDestExpanded = ::dp_misc::expandUnoRcUrl(langFolderDest);
+ ::dp_misc::create_folder(
+ &langFolderContent,
+ langFolderDest, xCmdEnv);
+
+ rtl::OUString aJarFile(
+ makeURL(sHelpFolder, langFolderURLSegment + aSlash + aHelpStr +
+ OUSTR(".jar")));
+ aJarFile = ::dp_misc::expandUnoRcUrl(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;
+ }
+
+ rtl::OUString aOfficeHelpPath( SvtPathOptions().GetHelpPath() );
+ rtl::OUString aOfficeHelpPathFileURL;
+ ::osl::File::getFileURLFromSystemPath( aOfficeHelpPath, aOfficeHelpPathFileURL );
+
+ HelpProcessingErrorInfo aErrorInfo;
+ bool bSuccess = compileExtensionHelp(
+ aOfficeHelpPathFileURL, aHelpStr, aLangURL,
+ nXhpFileCount, pXhpFiles,
+ langFolderDestExpanded, 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(
+ langFolderDestExpanded, 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 ) ) );
+ }
+ }
+ }
+
+ //Writing the data entry replaces writing the flag file. If we got to this
+ //point the registration was successful.
+ addDataToDb(xPackage->getURL(), data);
+ }
+ else
+ {
+ deleteDataFromDb(xPackage->getURL());
+ }
+}
+
+
+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..c1e10547ccdd
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..6b6a3f9a6508
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.src
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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/dp_helpbackenddb.cxx b/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx
new file mode 100644
index 000000000000..3bf67e0c050b
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_helpbackenddb.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * 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 "rtl/string.h"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+
+#include "dp_helpbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/help-registry/2010"
+#define NS_PREFIX "help"
+#define ROOT_ELEMENT_NAME "help-backend-db"
+#define KEY_ELEMENT_NAME "help"
+
+namespace dp_registry {
+namespace backend {
+namespace help {
+
+HelpBackendDb::HelpBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+OUString HelpBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString HelpBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString HelpBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString HelpBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+
+void HelpBackendDb::addEntry(::rtl::OUString const & url, Data const & data)
+{
+ try{
+ Reference<css::xml::dom::XNode> helpNode
+ = writeKeyElement(url);
+
+ writeSimpleElement(OUSTR("data-url"), data.dataUrl, helpNode);
+ save();
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in help backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+::boost::optional<HelpBackendDb::Data>
+HelpBackendDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ HelpBackendDb::Data retData;
+ Reference<css::xml::dom::XNode> aNode = getKeyElement(url);
+ if (aNode.is())
+ {
+ retData.dataUrl = readSimpleElement(OUSTR("data-url"), aNode);
+ }
+ else
+ {
+ return ::boost::optional<Data>();
+ }
+ return ::boost::optional<Data>(retData);
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in help backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+::std::list<OUString> HelpBackendDb::getAllDataUrls()
+{
+ try
+ {
+ ::std::list<OUString> listRet;
+ Reference<css::xml::dom::XDocument> doc = getDocument();
+ Reference<css::xml::dom::XNode> root = doc->getFirstChild();
+
+ Reference<css::xml::xpath::XXPathAPI> xpathApi = getXPathAPI();
+ const OUString sPrefix = getNSPrefix();
+ OUString sExpression(
+ sPrefix + OUSTR(":help/") + sPrefix + OUSTR(":data-url/text()"));
+ Reference<css::xml::dom::XNodeList> nodes =
+ xpathApi->selectNodeList(root, sExpression);
+ if (nodes.is())
+ {
+ sal_Int32 length = nodes->getLength();
+ for (sal_Int32 i = 0; i < length; i++)
+ listRet.push_back(nodes->item(i)->getNodeValue());
+ }
+ return listRet;
+ }
+ catch (css::deployment::DeploymentException& )
+ {
+ throw;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in help backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+
+} // namespace help
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx b/desktop/source/deployment/registry/help/dp_helpbackenddb.hxx
new file mode 100644
index 000000000000..edf7dfdfc284
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_helpbackenddb.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_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_HELPBACKENDDB_HXX
+#define INCLUDED_DP_HELPBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include <list>
+#include "boost/optional.hpp"
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace help {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ */
+class HelpBackendDb: public dp_registry::backend::BackendDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+
+ virtual ::rtl::OUString getNSPrefix();
+
+ virtual ::rtl::OUString getRootElementName();
+
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+ struct Data
+ {
+ /* the URL to the folder containing the compiled help files, etc.
+ */
+ ::rtl::OUString dataUrl;
+
+ };
+
+public:
+
+ HelpBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+ void addEntry(::rtl::OUString const & url, Data const & data);
+
+ ::boost::optional<Data> getEntry(::rtl::OUString const & url);
+ ::std::list< ::rtl::OUString> getAllDataUrls();
+
+};
+
+
+
+}
+}
+}
+#endif
+
diff --git a/desktop/source/deployment/registry/help/makefile.mk b/desktop/source/deployment/registry/help/makefile.mk
new file mode 100644
index 000000000000..d4934f71a46f
--- /dev/null
+++ b/desktop/source/deployment/registry/help/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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 \
+ $(SLO)$/dp_helpbackenddb.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..3d3bf7cf912c
--- /dev/null
+++ b/desktop/source/deployment/registry/inc/dp_backend.h
@@ -0,0 +1,379 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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 "com/sun/star/deployment/InvalidRemovedParameterException.hpp"
+#include <memory>
+#include <hash_map>
+#include <list>
+#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
+{
+ PackageRegistryBackend * getMyBackend() const;
+ void processPackage_impl(
+ bool registerPackage,
+ bool startup,
+ 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;
+ const bool m_bRemoved;
+ //Only set if m_bRemoved = true;
+ const ::rtl::OUString m_identifier;
+
+ 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,
+ bool startup,
+ ::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,
+ bool bRemoved,
+ ::rtl::OUString const & identifier);
+
+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::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getShortDescription()
+ throw (css::deployment::ExtensionRemovedException,
+ 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_Int32 SAL_CALL checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >& xAbortChannel,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ sal_Bool noLicenseChecking)
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ 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::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL registerPackage(
+ sal_Bool startup,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ 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::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getURL()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDisplayName()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDescription()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getUpdateInformationURLs()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual css::beans::StringPair SAL_CALL getPublisherInfo()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual css::uno::Reference< css::graphic::XGraphic > SAL_CALL
+ getIcon( sal_Bool bHighContrast )
+ throw (css::deployment::ExtensionRemovedException,
+ 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::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException, css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getRepositoryName()
+ throw (css::uno::RuntimeException);
+ virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getRegistrationDataURL()
+ throw (css::deployment::ExtensionRemovedException,
+ css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isRemoved()
+ throw (css::uno::RuntimeException);
+
+};
+
+typedef ::cppu::WeakComponentImplHelper2<
+ css::lang::XEventListener,
+ css::deployment::XPackageRegistry > t_BackendBase;
+
+//==============================================================================
+class PackageRegistryBackend
+ : protected ::dp_misc::MutexHolder, public t_BackendBase
+{
+ //The map held originally WeakReferences. The map entries are removed in the disposing
+ //function, which is called when the XPackages are destructed or they are
+ //explicitely disposed. The latter happens, for example, when a extension is
+ //removed (see dp_manager.cxx). However, because of how the help systems work, now
+ // XPackageManager::getDeployedPackages is called often. This results in a lot
+ //of bindPackage calls which are costly. Therefore we keep hard references in
+ //the map now.
+ typedef ::std::hash_map<
+ ::rtl::OUString, css::uno::Reference<css::deployment::XPackage>,
+ ::rtl::OUStringHash > t_string2ref;
+ t_string2ref m_bound;
+
+protected:
+ ::rtl::OUString m_cachePath;
+ 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_BUNDLED, CONTEXT_TMP,
+ 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,
+ sal_Bool bRemoved, ::rtl::OUString const & identifier,
+ 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 );
+
+ /* creates a folder with a unique name.
+ If url is empty then it is created in the the backend folder, otherwise
+ at a location relative to that folder specified by url.
+ */
+ ::rtl::OUString createFolder(
+ ::rtl::OUString const & relUrl,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv);
+ /* deletes folders and files.
+
+ All folder all files which end with ".tmp" or ".tmp_" and which are
+ not used are deleted.
+ */
+ void deleteUnusedFolders(
+ ::rtl::OUString const & relUrl,
+ ::std::list< ::rtl::OUString> const & usedFolders);
+ /* deletes one folder with a "temporary" name and the corresponding
+ tmp file, which was used to derive the folder name.
+ */
+ static void deleteTempFolder(
+ ::rtl::OUString const & folderUrl);
+
+
+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; }
+
+ inline ::rtl::OUString getContext() const {return m_context; }
+
+ // 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,
+ sal_Bool bRemoved, ::rtl::OUString const & identifier,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::deployment::InvalidRemovedParameterException,
+ css::ucb::CommandFailedException,
+ css::lang::IllegalArgumentException, css::uno::RuntimeException);
+};
+
+}
+}
+
+#endif
+
diff --git a/desktop/source/deployment/registry/inc/dp_backenddb.hxx b/desktop/source/deployment/registry/inc/dp_backenddb.hxx
new file mode 100644
index 000000000000..a0e477979f8c
--- /dev/null
+++ b/desktop/source/deployment/registry/inc/dp_backenddb.hxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_BACKENDDB_HXX
+#define INCLUDED_DP_BACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include <list>
+#include <vector>
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace xml { namespace dom {
+ class XDocument;
+ class XNode;
+ }}
+ namespace xml { namespace xpath {
+ class XXPathAPI;
+ }}
+}}}
+
+namespace dp_registry {
+namespace backend {
+
+class BackendDb
+{
+private:
+
+ css::uno::Reference<css::xml::dom::XDocument> m_doc;
+ css::uno::Reference<css::xml::xpath::XXPathAPI> m_xpathApi;
+
+ BackendDb(BackendDb const &);
+ BackendDb & operator = (BackendDb const &);
+
+protected:
+ const css::uno::Reference<css::uno::XComponentContext> m_xContext;
+ ::rtl::OUString m_urlDb;
+
+protected:
+
+ /* caller must make sure that only one thread accesses the function
+ */
+ css::uno::Reference<css::xml::dom::XDocument> getDocument();
+
+ /* the namespace prefix is "reg" (without quotes)
+ */
+ css::uno::Reference<css::xml::xpath::XXPathAPI> getXPathAPI();
+ void save();
+ void removeElement(::rtl::OUString const & sXPathExpression);
+
+ css::uno::Reference<css::xml::dom::XNode> getKeyElement(
+ ::rtl::OUString const & url);
+
+ void writeSimpleList(
+ ::std::list< ::rtl::OUString> const & list,
+ ::rtl::OUString const & sListTagName,
+ ::rtl::OUString const & sMemberTagName,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent);
+
+ void writeVectorOfPair(
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > const & vecPairs,
+ ::rtl::OUString const & sVectorTagName,
+ ::rtl::OUString const & sPairTagName,
+ ::rtl::OUString const & sFirstTagName,
+ ::rtl::OUString const & sSecondTagName,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent);
+
+ void writeSimpleElement(
+ ::rtl::OUString const & sElementName, ::rtl::OUString const & value,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent);
+
+ css::uno::Reference<css::xml::dom::XNode> writeKeyElement(
+ ::rtl::OUString const & url);
+
+ ::rtl::OUString readSimpleElement(
+ ::rtl::OUString const & sElementName,
+ css::uno::Reference<css::xml::dom::XNode> const & xParent);
+
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > >
+ readVectorOfPair(
+ css::uno::Reference<css::xml::dom::XNode> const & parent,
+ ::rtl::OUString const & sListTagName,
+ ::rtl::OUString const & sPairTagName,
+ ::rtl::OUString const & sFirstTagName,
+ ::rtl::OUString const & sSecondTagName);
+
+ ::std::list< ::rtl::OUString> readList(
+ css::uno::Reference<css::xml::dom::XNode> const & parent,
+ ::rtl::OUString const & sListTagName,
+ ::rtl::OUString const & sMemberTagName);
+
+ /* returns the values of one particulary child element of all key elements.
+ */
+ ::std::list< ::rtl::OUString> getOneChildFromAllEntries(
+ ::rtl::OUString const & sElementName);
+
+
+ /* returns the namespace which is to be written as xmlns attribute
+ into the root element.
+ */
+ virtual ::rtl::OUString getDbNSName()=0;
+ /* return the namespace prefix which is to be registered with the XPath API.
+
+ The prefix can then be used in XPath expressions.
+ */
+ virtual ::rtl::OUString getNSPrefix()=0;
+ /* returns the name of the root element without any namespace prefix.
+ */
+ virtual ::rtl::OUString getRootElementName()=0;
+ /* returns the name of xml element for each entry
+ */
+ virtual ::rtl::OUString getKeyElementName()=0;
+
+
+
+public:
+ BackendDb(css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+ virtual ~BackendDb() {};
+
+ void removeEntry(::rtl::OUString const & url);
+};
+
+class RegisteredDb: public BackendDb
+{
+
+public:
+ RegisteredDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+ virtual ~RegisteredDb() {};
+
+
+ virtual void addEntry(::rtl::OUString const & url);
+ virtual bool getEntry(::rtl::OUString const & url);
+
+};
+
+
+}
+}
+#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..4a3b1d0b1a4a
--- /dev/null
+++ b/desktop/source/deployment/registry/inc/dp_registry.hrc
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..e45cec272ca7
--- /dev/null
+++ b/desktop/source/deployment/registry/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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 \
+ $(SLO)$/dp_backenddb.obj
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/package/dp_extbackenddb.cxx b/desktop/source/deployment/registry/package/dp_extbackenddb.cxx
new file mode 100644
index 000000000000..2e92a907f8fb
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_extbackenddb.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "rtl/string.h"
+#include "rtl/bootstrap.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+
+#include "dp_extbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/extension-registry/2010"
+#define NS_PREFIX "ext"
+#define ROOT_ELEMENT_NAME "extension-backend-db"
+#define KEY_ELEMENT_NAME "extension"
+
+namespace dp_registry {
+namespace backend {
+namespace bundle {
+
+ExtensionBackendDb::ExtensionBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):BackendDb(xContext, url)
+{
+
+}
+
+OUString ExtensionBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ExtensionBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ExtensionBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ExtensionBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+void ExtensionBackendDb::addEntry(::rtl::OUString const & url, Data const & data)
+{
+ try{
+ Reference<css::xml::dom::XNode> extensionNodeNode = writeKeyElement(url);
+ writeVectorOfPair(
+ data.items,
+ OUSTR("extension-items"),
+ OUSTR("item"),
+ OUSTR("url"),
+ OUSTR("media-type"),
+ extensionNodeNode);
+ save();
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to write data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+ExtensionBackendDb::Data ExtensionBackendDb::getEntry(::rtl::OUString const & url)
+{
+ try
+ {
+ ExtensionBackendDb::Data retData;
+ Reference<css::xml::dom::XNode> aNode = getKeyElement(url);
+
+ if (aNode.is())
+ {
+ retData.items =
+ readVectorOfPair(
+ aNode,
+ OUSTR("extension-items"),
+ OUSTR("item"),
+ OUSTR("url"),
+ OUSTR("media-type"));
+ }
+ return retData;
+ }
+ catch(css::uno::Exception &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Extension Manager: failed to read data entry in backend db: ") +
+ m_urlDb, 0, exc);
+ }
+}
+
+} // namespace bundle
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/package/dp_extbackenddb.hxx b/desktop/source/deployment/registry/package/dp_extbackenddb.hxx
new file mode 100644
index 000000000000..d09fd0891a32
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_extbackenddb.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_EXTBACKENDDB_HXX
+#define INCLUDED_DP_EXTBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "rtl/string.hxx"
+#include <vector>
+#include "dp_backenddb.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace xml { namespace dom {
+ class XDocument;
+ class XNode;
+ }}
+ namespace xml { namespace xpath {
+ class XXPathAPI;
+ }}
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace bundle {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ */
+class ExtensionBackendDb: public dp_registry::backend::BackendDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+ virtual ::rtl::OUString getNSPrefix();
+ virtual ::rtl::OUString getRootElementName();
+ virtual ::rtl::OUString getKeyElementName();
+
+public:
+ struct Data
+ {
+ /* every element consists of a pair of the url to the item (jar,rdb, etc)
+ and the media type
+ */
+ ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString> > items;
+ typedef ::std::vector<
+ ::std::pair< ::rtl::OUString, ::rtl::OUString> >::const_iterator ITC_ITEMS;
+
+ };
+
+public:
+
+ ExtensionBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+
+ void addEntry(::rtl::OUString const & url, Data const & data);
+
+ Data getEntry(::rtl::OUString const & url);
+
+};
+
+
+
+}
+}
+}
+#endif
+
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..2ad6478b665c
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.cxx
@@ -0,0 +1,1655 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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_descriptioninfoset.hxx"
+#include "dp_identifier.hxx"
+#include "rtl/uri.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "ucbhelper/content.hxx"
+#include "svl/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/PlatformException.hpp"
+#include "com/sun/star/deployment/Prerequisites.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 "boost/optional.hpp"
+#include <vector>
+#include <stdio.h>
+
+#include "dp_extbackenddb.hxx"
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace css = ::com::sun::star;
+
+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;
+
+ ExtensionBackendDb::Data m_dbData;
+
+ Reference<deployment::XPackage> bindBundleItem(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, //that is, useing data base information
+ OUString const & identifier,
+ Reference<ucb::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<ucb::XCommandEnvironment> const & xCmdEnv );
+ void scanLegacyBundle(
+ t_packagevec & bundle,
+ OUString const & url,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv,
+ bool skip_registration = false );
+ ::std::vector<Reference<deployment::XPackage> > getPackagesFromDb(
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv);
+ bool checkPlatform(
+ Reference<ucb::XCommandEnvironment > const & environment);
+
+ bool checkDependencies(
+ Reference<ucb::XCommandEnvironment > const &
+ environment,
+ DescriptionInfoset const & description);
+ // throws css::uno::RuntimeException,
+ // css::deployment::DeploymentException
+
+ ::sal_Bool checkLicense(
+ Reference< ucb::XCommandEnvironment > const & xCmdEnv,
+ DescriptionInfoset const & description, bool bNoLicenseChecking)
+ throw (deployment::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ RuntimeException);
+ // @throws DeploymentException
+ OUString getTextFromURL(
+ const Reference< 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<ucb::XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::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,
+ bool bRemoved,
+ OUString const & identifier);
+
+ // XPackage
+ virtual sal_Bool SAL_CALL isBundle() throw (RuntimeException);
+
+ virtual Sequence< Reference<deployment::XPackage> > SAL_CALL getBundle(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException);
+ virtual OUString SAL_CALL getDescription()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual void SAL_CALL exportTo(
+ OUString const & destFolderURL, OUString const & newTitle,
+ sal_Int32 nameClashAction,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::ExtensionRemovedException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ RuntimeException);
+
+ virtual ::sal_Int32 SAL_CALL checkPrerequisites(
+ const Reference< task::XAbortChannel >& xAbortChannel,
+ const Reference< ucb::XCommandEnvironment >& xCmdEnv,
+ ::sal_Bool noLicenseChecking)
+ throw (deployment::ExtensionRemovedException,
+ deployment::DeploymentException,
+ ucb::CommandFailedException,
+ ucb::CommandAbortedException,
+ RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL checkDependencies(
+ const Reference< ucb::XCommandEnvironment >& xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::ExtensionRemovedException,
+ ucb::CommandFailedException,
+ RuntimeException);
+
+ virtual beans::Optional<OUString> SAL_CALL getIdentifier()
+ throw (RuntimeException);
+
+ virtual OUString SAL_CALL getVersion()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual Sequence<OUString> SAL_CALL getUpdateInformationURLs()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual beans::StringPair SAL_CALL getPublisherInfo()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual OUString SAL_CALL getDisplayName()
+ throw (deployment::ExtensionRemovedException, RuntimeException);
+
+ virtual Reference< graphic::XGraphic > SAL_CALL
+ getIcon( ::sal_Bool bHighContrast )
+ throw (deployment::ExtensionRemovedException,
+ 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;
+
+ std::auto_ptr<ExtensionBackendDb> m_backendDb;
+
+ void addDataToDb(OUString const & url, ExtensionBackendDb::Data const & data);
+ ExtensionBackendDb::Data readDataFromDb(OUString const & url);
+ void deleteDataFromDb(OUString const & url);
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<ucb::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;
+
+ if (!transientMode())
+ {
+ OUString dbFile = makeURL(getCachePath(), getImplementationName());
+ dbFile = makeURL(dbFile, OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ExtensionBackendDb(getComponentContext(), dbFile));
+ }
+}
+
+//______________________________________________________________________________
+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_,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ))
+ {
+ if (ucbContent.isFolder())
+ {
+ //Every .oxt, uno.pkg file must contain a META-INF folder
+ ::ucbhelper::Content metaInfContent;
+ if (create_ucb_content(
+ &metaInfContent, makeURL( url, OUSTR("META-INF") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ mediaType = OUSTR("application/vnd.sun.star.package-bundle");
+ }
+ //No support of legacy bundles, because every folder could be one.
+ }
+ else
+ {
+ 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"))
+ {
+
+ //In case a XPackage is created for a removed extension, we cannot
+ //obtain the name
+ OUString name;
+ if (!bRemoved)
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ name = ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>();
+ }
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.package-bundle")) {
+ return new PackageImpl(
+ this, url, name, m_xBundleTypeInfo, false, bRemoved,
+ identifier);
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.legacy-package-bundle")) {
+ return new PackageImpl(
+ this, url, name, m_xLegacyBundleTypeInfo, true, bRemoved,
+ identifier);
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+void BackendImpl::addDataToDb(
+ OUString const & url, ExtensionBackendDb::Data const & data)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url, data);
+}
+
+ExtensionBackendDb::Data BackendImpl::readDataFromDb(
+ OUString const & url)
+{
+ ExtensionBackendDb::Data data;
+ if (m_backendDb.get())
+ data = m_backendDb->getEntry(url);
+ return data;
+}
+
+void BackendImpl::deleteDataFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+
+//##############################################################################
+
+BackendImpl::PackageImpl::PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url,
+ OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool legacyBundle, bool bRemoved, OUString const & identifier)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType, bRemoved, identifier),
+ m_url_expanded( expandUnoRcUrl( url ) ),
+ m_legacyBundle( legacyBundle ),
+ m_pBundle( 0 )
+{
+ if (bRemoved)
+ m_dbData = getMyBackend()->readDataFromDb(url);
+}
+
+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<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ //In case the object was created for a removed extension (m_bRemoved = true)
+ //but the extension is not registered, then bundle will be empty. Then
+ //the return value will be Optional<...>.IsPresent= false. Althoug this is
+ //not true, this does not matter. Then registerPackage or revokePackage
+ //would never be called for the items. But since the extension is removed
+ //and not registered anyway, this does not matter.
+ 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 ];
+ Reference<task::XAbortChannel> xSubAbortChannel(
+ xPackage->createAbortChannel() );
+ AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ xPackage->isRegistered( xSubAbortChannel, xCmdEnv ) );
+
+ //present = true if at least one bundle item has this value.
+ //reg = true if all bundle items have an option value (option.IsPresent == 1)
+ //and all have value of true (option.Value.Value == true)
+ //If not, then the bundle has the status of not registered and ambiguous.
+ if (option.IsPresent)
+ {
+ beans::Ambiguous<sal_Bool> const & status = option.Value;
+ if (present)
+ {
+ //we never come here in the first iteration
+ if (reg != (status.Value != sal_False)) {
+
+ ambig = true;
+ reg = false;
+ break;
+ }
+ }
+ else
+ {
+ //we always come here in the first iteration
+ 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()
+{
+ return dp_misc::getDescriptionInfoset(m_url_expanded);
+}
+
+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,
+ DescriptionInfoset const & description)
+{
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+ unsatisfied(dp_misc::Dependencies::check(description));
+
+ 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,
+ DescriptionInfoset const & info, bool alreadyInstalled)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ try
+ {
+ ::boost::optional<SimpleLicenseAttributes> simplLicAttr
+ = info.getSimpleLicenseAttributes();
+ if (! simplLicAttr)
+ return true;
+ OUString sLic = info.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 = m_url_expanded + OUSTR("/") + sLic;
+ OUString sLicense = getTextFromURL(xCmdEnv, sHref);
+ ////determine who has to agree to the license
+ //check correct value for attribute
+ if ( ! (simplLicAttr->acceptBy.equals(OUSTR("user")) || simplLicAttr->acceptBy.equals(OUSTR("admin"))))
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not obtain attribute simple-lincense@accept-by or it has no valid value"), 0, Any());
+
+
+ //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
+ // alreadyInstalled | bSuppressOnUpdate | show license
+ //----------------------------------------
+ // 0 | 0 | 1
+ // 0 | 1 | 1
+ // 1 | 0 | 1
+ // 1 | 1 | 0
+
+ if ( !(alreadyInstalled && simplLicAttr->suppressOnUpdate))
+ {
+ css::deployment::LicenseException licExc(
+ OUString(), 0, getDisplayName(), sLicense,
+ simplLicAttr->acceptBy);
+ 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_Int32 BackendImpl::PackageImpl::checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >&,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ sal_Bool alreadyInstalled)
+ throw (css::deployment::DeploymentException,
+ css::deployment::ExtensionRemovedException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ DescriptionInfoset info = getDescriptionInfoset();
+ if (!info.hasDescription())
+ return 0;
+
+ //always return LICENSE as long as the user did not accept the license
+ //so that XExtensonManager::checkPrerequisitesAndEnable will again
+ //check the license
+ if (!checkPlatform(xCmdEnv))
+ return deployment::Prerequisites::PLATFORM |
+ deployment::Prerequisites::LICENSE;
+ else if(!checkDependencies(xCmdEnv, info))
+ return deployment::Prerequisites::DEPENDENCIES |
+ deployment::Prerequisites::LICENSE;
+ else if(!checkLicense(xCmdEnv, info, alreadyInstalled))
+ return deployment::Prerequisites::LICENSE;
+ else
+ return 0;
+}
+
+::sal_Bool BackendImpl::PackageImpl::checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv )
+ throw (deployment::DeploymentException,
+ deployment::ExtensionRemovedException,
+ ucb::CommandFailedException,
+ RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ DescriptionInfoset info = getDescriptionInfoset();
+ if (!info.hasDescription())
+ return sal_True;
+
+ return checkDependencies(xCmdEnv, info);
+}
+
+beans::Optional<OUString> BackendImpl::PackageImpl::getIdentifier()
+ throw (RuntimeException)
+{
+ OUString identifier;
+ if (m_bRemoved)
+ identifier = m_identifier;
+ else
+ identifier = dp_misc::generateIdentifier(
+ getDescriptionInfoset().getIdentifier(), m_name);
+
+ return beans::Optional<OUString>(
+ true, identifier);
+}
+
+OUString BackendImpl::PackageImpl::getVersion()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return getDescriptionInfoset().getVersion();
+}
+
+Sequence<OUString> BackendImpl::PackageImpl::getUpdateInformationURLs()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ return getDescriptionInfoset().getUpdateInformationUrls();
+}
+
+beans::StringPair BackendImpl::PackageImpl::getPublisherInfo()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+ ::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 (deployment::ExtensionRemovedException, RuntimeException )
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ 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,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ const Sequence< Reference<deployment::XPackage> > bundle(
+ getBundle( abortChannel.get(), xCmdEnv ) );
+
+ if (doRegisterPackage)
+ {
+ ExtensionBackendDb::Data data;
+ 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( startup, xSubAbortChannel, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (ucb::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 (ucb::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 ucb::CommandFailedException(
+ dpExc.Message, dpExc.Context, dpExc.Cause );
+ }
+ else {
+ // rethrow CommandFailedException
+ ::cppu::throwException(exc);
+ }
+ }
+ data.items.push_back(
+ ::std::make_pair(xPackage->getURL(),
+ xPackage->getPackageType()->getMediaType()));
+ }
+ getMyBackend()->addDataToDb(getURL(), data);
+ }
+ 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 (ucb::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
+ }
+ }
+ getMyBackend()->deleteDataFromDb(getURL());
+ }
+}
+
+//______________________________________________________________________________
+OUString BackendImpl::PackageImpl::getDescription()
+ throw (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ 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<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (ucb::CommandFailedException,
+ deployment::ExtensionRemovedException,
+ ucb::CommandAbortedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ ::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 == ucb::NameClash::ASK)
+ {
+ if (create_ucb_content(
+ 0, destURL, xCmdEnv, false /* no throw */ )) {
+ bool replace = false, abort = false;
+ if (! interactContinuation(
+ Any( ucb::NameClashResolveRequest(
+ OUSTR("file already exists: ") + title,
+ static_cast<OWeakObject *>(this),
+ task::InteractionClassification_QUERY,
+ destFolderURL, title, OUString() ) ),
+ ucb::XInteractionReplaceExistingData::static_type(), xCmdEnv,
+ &replace, &abort ) || !replace) {
+ return;
+ }
+ }
+ }
+ else if (nameClashAction != ucb::NameClash::OVERWRITE) {
+ throw ucb::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<ucb::XContentAccess>(
+ xResultSet, UNO_QUERY_THROW )->queryContent(), xCmdEnv );
+ if (! destFolderContent.transferContent(
+ subContent, ::ucbhelper::InsertOperation_COPY,
+ OUString(), ucb::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(), ucb::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 (ucb::UnsupportedCommandException &) {
+ }
+}
+
+//______________________________________________________________________________
+sal_Bool BackendImpl::PackageImpl::isBundle() throw (RuntimeException)
+{
+ return true;
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> > BackendImpl::PackageImpl::getBundle(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ ucb::CommandFailedException, ucb::CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ Sequence< Reference<deployment::XPackage> > * pBundle = m_pBundle;
+ if (pBundle == 0)
+ {
+ t_packagevec bundle;
+ if (m_bRemoved)
+ {
+ bundle = getPackagesFromDb(xCmdEnv);
+ }
+ else
+ {
+ 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, false, OUString(),
+ 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 (ucb::CommandFailedException &) {
+ throw;
+ }
+ catch (ucb::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,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<ucb::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, bRemoved, identifier, xCmdEnv ) );
+ OSL_ASSERT( xPackage.is() );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (ucb::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<ucb::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, false, OUString(), 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<ucb::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 */, false, OUString(),
+ 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 (deployment::ExtensionRemovedException, RuntimeException)
+{
+ if (m_bRemoved)
+ throw deployment::ExtensionRemovedException();
+
+ OUString sName = getDescriptionInfoset().getLocalizedDisplayName();
+ if (sName.getLength() == 0)
+ return m_displayName;
+ else
+ return sName;
+}
+
+::std::vector<Reference<deployment::XPackage> >
+BackendImpl::PackageImpl::getPackagesFromDb(
+ Reference<ucb::XCommandEnvironment> const & xCmdEnv)
+{
+ ::std::vector<Reference<deployment::XPackage> > retVector;
+
+ typedef ::std::vector< ::std::pair<OUString, OUString> >::const_iterator ITC;
+ for (ITC i = m_dbData.items.begin(); i != m_dbData.items.end(); i++)
+ {
+ Reference<deployment::XPackage> xExtension =
+ bindBundleItem(i->first, i->second, true, m_identifier, xCmdEnv);
+ OSL_ASSERT(xExtension.is());
+ retVector.push_back(xExtension);
+ }
+
+ return retVector;
+}
+
+} // 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..3a840b64f0b6
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.hrc
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..57307040bba4
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.src
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..203ce176d289
--- /dev/null
+++ b/desktop/source/deployment/registry/package/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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_extbackenddb.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..be6170cdf5d8
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_lib_container.cxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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..3e7cbf54cbae
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_lib_container.h
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..edeae256cbaf
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.cxx
@@ -0,0 +1,499 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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 "svl/inettype.hxx"
+#include "com/sun/star/util/XUpdatable.hpp"
+#include "com/sun/star/script/XLibraryContainer3.hpp"
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/util/XMacroExpander.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <memory>
+#include "dp_scriptbackenddb.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 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,
+ bool startup,
+ ::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,
+ bool bRemoved, OUString const & identifier);
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void addDataToDb(OUString const & url);
+ void deleteDataFromDb(OUString const & url);
+ bool isRegisteredInDb(OUString const & url);
+
+
+
+// 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;
+ std::auto_ptr<ScriptBackendDb> m_backendDb;
+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, bool bRemoved,
+ OUString const & identifier)
+ : Package( myBackend.get(), url,
+ OUString(), OUString(), // will be late-initialized
+ scriptURL.getLength() > 0 ? myBackend->m_xBasicLibTypeInfo
+ : myBackend->m_xDialogLibTypeInfo, bRemoved, identifier),
+ 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() );
+
+ if (!transientMode())
+ {
+ OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
+ m_backendDb.reset(
+ new ScriptBackendDb(getComponentContext(), dbFile));
+ }
+
+}
+void BackendImpl::addDataToDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->addEntry(url);
+}
+
+bool BackendImpl::isRegisteredInDb(OUString const & url)
+{
+ bool registered = false;
+ if (m_backendDb.get())
+ registered = m_backendDb->getEntry(url);
+ return registered;
+}
+
+void BackendImpl::deleteDataFromDb(OUString const & url)
+{
+ if (m_backendDb.get())
+ m_backendDb->removeEntry(url);
+}
+
+// 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_,
+ sal_Bool bRemoved, OUString const & identifier,
+ 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"))
+ {
+ OUString dialogURL( makeURL( url, OUSTR("dialog.xlb") ) );
+ if (! create_ucb_content(
+ 0, dialogURL, xCmdEnv, false /* no throw */ )) {
+ dialogURL = OUString();
+ }
+
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.basic-library"))
+ {
+ OUString scriptURL( makeURL( url, OUSTR("script.xlb")));
+ if (! create_ucb_content(
+ 0, scriptURL, xCmdEnv, false /* no throw */ )) {
+ scriptURL = OUString();
+ }
+
+ return new PackageImpl(
+ this, url, xCmdEnv, scriptURL,
+ dialogURL, bRemoved, identifier);
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.dialog-library")) {
+ return new PackageImpl(
+ this, url, xCmdEnv,
+ OUString() /* no script lib */,
+ dialogURL,
+ bRemoved, identifier);
+ }
+ }
+ }
+ 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 & xCmdEnv )
+{
+ (void)xCmdEnv;
+
+ BackendImpl * that = getMyBackend();
+ Reference< deployment::XPackage > xThisPackage( this );
+
+ bool registered = that->isRegisteredInDb(getURL());
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>( registered, false /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ (void)xCmdEnv;
+
+ BackendImpl * that = getMyBackend();
+
+ Reference< deployment::XPackage > xThisPackage( this );
+ Reference<XComponentContext> const & xComponentContext = that->getComponentContext();
+
+ bool bScript = (m_scriptURL.getLength() > 0);
+ Reference<css::script::XLibraryContainer3> xScriptLibs;
+
+ bool bDialog = (m_dialogURL.getLength() > 0);
+ Reference<css::script::XLibraryContainer3> 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 );
+ }
+ }
+ bool bRegistered = getMyBackend()->isRegisteredInDb(getURL());
+ if( !doRegisterPackage )
+ {
+ //We cannot just call removeLibrary(name) because this could remove a
+ //script which was added by an extension in a different repository. For
+ //example, extension foo is contained in the bundled repository and then
+ //the user adds it it to the user repository. The extension manager will
+ //then register the new script and revoke the script from the bundled
+ //extension. removeLibrary(name) would now remove the script from the
+ //user repository. That is, the script of the newly added user extension does
+ //not work anymore. Therefore we must check if the currently active
+ //script comes in fact from the currently processed extension.
+
+ if (bRegistered)
+ {
+ //we also prevent and live deployment at startup
+ if (!isRemoved() && !startup)
+ {
+ if (bScript && xScriptLibs.is() && xScriptLibs->hasByName(m_name))
+ {
+ const OUString sScriptUrl = xScriptLibs->getOriginalLibraryLinkURL(m_name);
+ if (sScriptUrl.equals(m_scriptURL))
+ xScriptLibs->removeLibrary(m_name);
+ }
+
+ if (bDialog && xDialogLibs.is() && xDialogLibs->hasByName(m_dialogName))
+ {
+ const OUString sDialogUrl = xDialogLibs->getOriginalLibraryLinkURL(m_dialogName);
+ if (sDialogUrl.equals(m_dialogURL))
+ xDialogLibs->removeLibrary(m_dialogName);
+ }
+ }
+ getMyBackend()->deleteDataFromDb(getURL());
+ return;
+ }
+ }
+ if (bRegistered)
+ return; // Already registered
+
+ // Update LibraryContainer
+ bool bScriptSuccess = false;
+ const bool bReadOnly = false;
+
+ bool bDialogSuccess = false;
+ if (!startup)
+ {
+ //If there is a bundled extension, and the user installes the same extension
+ //then the script from the bundled extension must be removed. If this does not work
+ //then live deployment does not work for scripts.
+ if (bScript && xScriptLibs.is())
+ {
+ bool bCanAdd = true;
+ if (xScriptLibs->hasByName(m_name))
+ {
+ const OUString sOriginalUrl = xScriptLibs->getOriginalLibraryLinkURL(m_name);
+ //We assume here that library names in extensions are unique, which may not be the case
+ //ToDo: If the script exist in another extension, then both extensions must have the
+ //same id
+ if (sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE"))
+ || sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE"))
+ || sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$BUNDLED_EXTENSIONS")))
+ {
+ xScriptLibs->removeLibrary(m_name);
+ bCanAdd = true;
+ }
+ else
+ {
+ bCanAdd = false;
+ }
+ }
+
+ if (bCanAdd)
+ {
+ xScriptLibs->createLibraryLink( m_name, m_scriptURL, bReadOnly );
+ bScriptSuccess = xScriptLibs->hasByName( m_name );
+ }
+ }
+
+
+ if (bDialog && xDialogLibs.is())
+ {
+ bool bCanAdd = true;
+ if (xDialogLibs->hasByName(m_dialogName))
+ {
+ const OUString sOriginalUrl = xDialogLibs->getOriginalLibraryLinkURL(m_dialogName);
+ //We assume here that library names in extensions are unique, which may not be the case
+ //ToDo: If the script exist in another extension, then both extensions must have the
+ //same id
+ if (sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE"))
+ || sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE"))
+ || sOriginalUrl.match(OUSTR("vnd.sun.star.expand:$BUNDLED_EXTENSIONS")))
+ {
+ xDialogLibs->removeLibrary(m_dialogName);
+ bCanAdd = true;
+ }
+ else
+ {
+ bCanAdd = false;
+ }
+ }
+
+ if (bCanAdd)
+ {
+ xDialogLibs->createLibraryLink( m_dialogName, m_dialogURL, bReadOnly );
+ bDialogSuccess = xDialogLibs->hasByName(m_dialogName);
+ }
+ }
+ }
+ bool bSuccess = bScript || bDialog; // Something must have happened
+ if( bRunning && !startup)
+ if( (bScript && !bScriptSuccess) || (bDialog && !bDialogSuccess) )
+ bSuccess = false;
+
+ if (bSuccess)
+ getMyBackend()->addDataToDb(getURL());
+}
+
+} // 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..8ddfa6f51ffc
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..117f4eac945a
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.src
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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/dp_scriptbackenddb.cxx b/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx
new file mode 100644
index 000000000000..ce0d3029084d
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_scriptbackenddb.cxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * 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 "rtl/string.h"
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XDocument.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "dp_misc.h"
+#include "dp_scriptbackenddb.hxx"
+
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+#define EXTENSION_REG_NS "http://openoffice.org/extensionmanager/script-registry/2010"
+#define NS_PREFIX "script"
+#define ROOT_ELEMENT_NAME "script-backend-db"
+#define KEY_ELEMENT_NAME "script"
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+
+ScriptBackendDb::ScriptBackendDb(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::OUString const & url):RegisteredDb(xContext, url)
+{
+
+}
+
+OUString ScriptBackendDb::getDbNSName()
+{
+ return OUSTR(EXTENSION_REG_NS);
+}
+
+OUString ScriptBackendDb::getNSPrefix()
+{
+ return OUSTR(NS_PREFIX);
+}
+
+OUString ScriptBackendDb::getRootElementName()
+{
+ return OUSTR(ROOT_ELEMENT_NAME);
+}
+
+OUString ScriptBackendDb::getKeyElementName()
+{
+ return OUSTR(KEY_ELEMENT_NAME);
+}
+
+
+
+} // namespace executable
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx b/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx
new file mode 100644
index 000000000000..9d227f8b64b8
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_scriptbackenddb.hxx
@@ -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_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_SCRIPTBACKENDDB_HXX
+#define INCLUDED_DP_SCRIPTBACKENDDB_HXX
+
+#include "rtl/ustring.hxx"
+#include "dp_backenddb.hxx"
+#include "boost/optional.hpp"
+namespace css = ::com::sun::star;
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+
+/* The XML file stores the extensions which are currently registered.
+ They will be removed when they are revoked.
+ */
+class ScriptBackendDb: public dp_registry::backend::RegisteredDb
+{
+protected:
+ virtual ::rtl::OUString getDbNSName();
+
+ virtual ::rtl::OUString getNSPrefix();
+
+ virtual ::rtl::OUString getRootElementName();
+
+ virtual ::rtl::OUString getKeyElementName();
+
+
+public:
+
+ ScriptBackendDb( css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & url);
+};
+
+
+
+}
+}
+}
+#endif
+
diff --git a/desktop/source/deployment/registry/script/makefile.mk b/desktop/source/deployment/registry/script/makefile.mk
new file mode 100644
index 000000000000..708def358021
--- /dev/null
+++ b/desktop/source/deployment/registry/script/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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 \
+ $(SLO)$/dp_scriptbackenddb.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..bf35aa2f50a5
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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..a23e9f865894
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <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..8a4ee1b45fbc
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx
@@ -0,0 +1,408 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "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 "svl/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,
+ bool startup,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ PackageImpl(
+ ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url, OUString const & libType, bool bRemoved,
+ OUString const & identifier);
+ // XPackage
+ virtual OUString SAL_CALL getDescription() throw (RuntimeException);
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ sal_Bool bRemoved, OUString const & identifier,
+ 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, bool bRemoved,
+ OUString const & identifier)
+ : Package( myBackend.get(), url, OUString(), OUString(),
+ myBackend->m_xTypeInfo, bRemoved, identifier),
+ 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_, sal_Bool bRemoved,
+ OUString const & identifier, 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, bRemoved, identifier);
+ }
+ }
+ }
+ 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 if ( that->m_eContext == CONTEXT_BUNDLED )
+ {
+ aContext <<= OUSTR("bundled");
+ }
+ 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,
+ bool /* startup */,
+ ::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..0eb619e839e3
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.hrc
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..c8d37ce067ac
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.src
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_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..a052296d5c21
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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..82b41766b253
--- /dev/null
+++ b/desktop/source/deployment/target.pmk
@@ -0,0 +1,36 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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 "$(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..06b39cd2d04e
--- /dev/null
+++ b/desktop/source/deployment/unopkg/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+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..dc204e265ec6
--- /dev/null
+++ b/desktop/source/deployment/unopkg/unopkg.src
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "deployment.hrc"
+
+
+String RID_STR_UNOPKG_ACCEPT_LIC_1
+{
+ Text [ en-US ] = "Extension Software License Agreement of $NAME:";
+};
+
+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: ";
+};
+
diff --git a/desktop/source/inc/exithelper.hxx b/desktop/source/inc/exithelper.hxx
new file mode 100644
index 000000000000..e2604ce49b68
--- /dev/null
+++ b/desktop/source/inc/exithelper.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_EXITHELPER_HXX_
+#define _DESKTOP_EXITHELPER_HXX_
+
+namespace desktop
+{
+
+//=============================================================================
+/** @short provide helper functions to handle a abnormal exit
+ and contain a list of all "well known" exit codes.
+ */
+class ExitHelper
+{
+ //-------------------------------------------------------------------------
+ // const
+ public:
+
+ //---------------------------------------------------------------------
+ /** @short list of all well known exit codes.
+
+ @descr Its not allowed to use exit codes hard coded
+ inside office. All places must use these list to
+ be synchron.
+ */
+ enum EExitCodes
+ {
+ /// e.g. used to force showing of the command line help
+ E_NO_ERROR = 0,
+ /// pipe was detected - second office must terminate itself
+ E_SECOND_OFFICE = 1,
+ /// an uno exception was catched during startup
+ E_FATAL_ERROR = 333, // Only the low 8 bits are significant 333 % 256 = 77
+ /// user force automatic restart after crash
+ E_CRASH_WITH_RESTART = 79,
+ /// the office restarts itself
+ E_NORMAL_RESTART = 81
+ };
+};
+
+} // namespace desktop
+
+#endif // #ifndef _DESKTOP_EXITHELPER_HXX_
diff --git a/desktop/source/inc/helpid.hrc b/desktop/source/inc/helpid.hrc
new file mode 100644
index 000000000000..2619c4398881
--- /dev/null
+++ b/desktop/source/inc/helpid.hrc
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_DESKTOP_HELPID_HRC
+#define INCLUDED_DESKTOP_HELPID_HRC
+
+#include "svl/solar.hrc"
+
+#define HID_GLOBAL_FALLBACK 0xFFFFFFFF
+
+#define HID_PACKAGE_MANAGER (HID_DESKTOP_START + 0)
+#define HID_PACKAGE_MANAGER_TREELISTBOX (HID_DESKTOP_START + 1)
+#define HID_PACKAGE_MANAGER_PROGRESS (HID_DESKTOP_START + 2)
+#define HID_PACKAGE_MANAGER_PROGRESS_CANCEL (HID_DESKTOP_START + 3)
+#define HID_PACKAGE_MANAGER_MENU_ITEM (HID_DESKTOP_START + 4)
+
+#define HID_FIRSTSTART_DIALOG (HID_DESKTOP_START + 5)
+#define HID_FIRSTSTART_WELCOME (HID_DESKTOP_START + 6)
+#define HID_FIRSTSTART_LICENSE (HID_DESKTOP_START + 7)
+#define HID_FIRSTSTART_MIGRATION (HID_DESKTOP_START + 8)
+#define HID_FIRSTSTART_REGISTRATION (HID_DESKTOP_START + 9)
+#define HID_FIRSTSTART_USER (HID_DESKTOP_START + 10)
+#define HID_FIRSTSTART_PREV (HID_DESKTOP_START + 11)
+#define HID_FIRSTSTART_NEXT (HID_DESKTOP_START + 12)
+#define HID_FIRSTSTART_CANCEL (HID_DESKTOP_START + 13)
+#define HID_FIRSTSTART_FINISH (HID_DESKTOP_START + 14)
+#define UID_FIRSTSTART_HELP (HID_DESKTOP_START + 15)
+#define UID_BTN_LICENSE_ACCEPT (HID_DESKTOP_START + 16)
+#define HID_FIRSTSTART_UPDATE_CHECK (HID_DESKTOP_START + 17)
+#define HID_DEPLOYMENT_GUI_UPDATE (HID_DESKTOP_START + 18)
+#define HID_DEPLOYMENT_GUI_UPDATEINSTALL (HID_DESKTOP_START + 19)
+#define HID_DEPLOYMENT_GUI_UPDATE_PUBLISHER (HID_DESKTOP_START + 20)
+#define HID_DEPLOYMENT_GUI_UPDATE_RELEASENOTES (HID_DESKTOP_START + 21)
+#define HID_DEPLOYMENT_GUI_UPDATE_AVAILABLE_UPDATES (HID_DESKTOP_START + 22)
+
+#define HID_EXTENSION_MANAGER_LISTBOX (HID_DESKTOP_START + 23)
+#define HID_EXTENSION_MANAGER_LISTBOX_OPTIONS (HID_DESKTOP_START + 24)
+#define HID_EXTENSION_MANAGER_LISTBOX_ENABLE (HID_DESKTOP_START + 25)
+#define HID_EXTENSION_MANAGER_LISTBOX_DISABLE (HID_DESKTOP_START + 26)
+#define HID_EXTENSION_MANAGER_LISTBOX_REMOVE (HID_DESKTOP_START + 27)
+
+#define HID_EXTENSION_DEPENDENCIES (HID_DESKTOP_START + 28)
+
+#define HID_PACKAGE_MANAGER_UPD_REQ (HID_DESKTOP_START + 29)
+
+#define ACT_DESKTOP_HID_END HID_PACKAGE_MANAGER_UPD_REQ
+
+// check bounds:
+#if ACT_DESKTOP_HID_END > HID_DESKTOP_END
+#error Resource overflow in #line, #file
+#endif
+
+#endif
+
diff --git a/desktop/source/migration/cfgfilter.cxx b/desktop/source/migration/cfgfilter.cxx
new file mode 100644
index 000000000000..e4589e1a10e1
--- /dev/null
+++ b/desktop/source/migration/cfgfilter.cxx
@@ -0,0 +1,333 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "cfgfilter.hxx"
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <unotools/textsearch.hxx>
+
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::configuration::backend;
+
+namespace desktop {
+
+CConfigFilter::CConfigFilter(const strings_v* include, const strings_v* exclude)
+ : m_pvInclude(include)
+ , m_pvExclude(exclude)
+{
+}
+
+void SAL_CALL CConfigFilter::initialize(const Sequence< Any >& seqArgs)
+ throw (Exception)
+{
+ NamedValue nv;
+ for (sal_Int32 i=0; i < seqArgs.getLength(); i++)
+ {
+ if (seqArgs[i] >>= nv)
+ {
+ if (nv.Name.equalsAscii("Source"))
+ nv.Value >>= m_xSourceLayer;
+ if (nv.Name.equalsAscii("ComponentName"))
+ nv.Value >>= m_aCurrentComponent;
+ }
+ }
+ if (m_aCurrentComponent.getLength() == 0)
+ m_aCurrentComponent = OUString::createFromAscii("unknown.component");
+
+ if (!m_xSourceLayer.is()) {
+ throw Exception();
+ }
+
+}
+
+
+void CConfigFilter::pushElement(rtl::OUString aName, sal_Bool bUse)
+{
+ OUString aPath;
+ if (!m_elementStack.empty()) {
+ aPath = m_elementStack.top().path; // or use base path
+ aPath += OUString::createFromAscii("/");
+ }
+ aPath += aName;
+
+ // create element
+ element elem;
+ elem.name = aName;
+ elem.path = aPath;
+ elem.use = bUse;
+ m_elementStack.push(elem);
+}
+
+sal_Bool CConfigFilter::checkCurrentElement()
+{
+ return m_elementStack.top().use;
+}
+
+sal_Bool CConfigFilter::checkElement(rtl::OUString aName)
+{
+
+ sal_Bool bResult = sal_False;
+
+ // get full pathname for element
+ OUString aFullPath;
+ if (!m_elementStack.empty())
+ aFullPath = m_elementStack.top().path + OUString::createFromAscii("/");
+
+ aFullPath += aName;
+
+ // check whether any include patterns patch this path
+ for (strings_v::const_iterator i_in = m_pvInclude->begin();
+ i_in != m_pvInclude->end(); i_in++)
+ {
+ // pattern is beginning of path
+ // or path is a begiing for pattern
+ if (i_in->match(aFullPath.copy(0, i_in->getLength()>aFullPath.getLength()
+ ? aFullPath.getLength() : i_in->getLength()), 0))
+ {
+ bResult = sal_True;
+ break; // one match is enough
+ }
+ }
+ // if match is found, check for exclusion
+ if (bResult)
+ {
+ for (strings_v::const_iterator i_ex = m_pvExclude->begin();
+ i_ex != m_pvExclude->end(); i_ex++)
+ {
+ if (aFullPath.match(*i_ex, 0)) // pattern is beginning of path
+ {
+ bResult = sal_False;
+ break; // one is enough...
+ }
+ }
+ }
+ return bResult;
+}
+
+void CConfigFilter::popElement()
+{
+ m_elementStack.pop();
+}
+
+
+void SAL_CALL CConfigFilter::readData(
+ const Reference< configuration::backend::XLayerHandler >& layerHandler)
+ throw (
+ com::sun::star::lang::NullPointerException, lang::WrappedTargetException,
+ com::sun::star::configuration::backend::MalformedDataException)
+{
+ // when readData is called, the submitted handler will be stored
+ // in m_xLayerHandler. we will then submit ourself as a handler to
+ // the SourceLayer in m_xSourceLayer.
+ // when the source calls our handler functions we will use the patterns that
+ // where given in the ctor to decide whther they should be relaied to the caller
+
+ if (m_xSourceLayer.is() && layerHandler.is())
+ {
+ m_xLayerHandler = layerHandler;
+ m_xSourceLayer->readData(Reference<XLayerHandler>(static_cast< XLayerHandler* >(this)));
+ } else
+ {
+ throw NullPointerException();
+ }
+}
+
+// XLayerHandler
+void SAL_CALL CConfigFilter::startLayer()
+ throw(::com::sun::star::lang::WrappedTargetException)
+{
+ m_xLayerHandler->startLayer();
+}
+
+void SAL_CALL CConfigFilter::endLayer()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ m_xLayerHandler->endLayer();
+}
+
+void SAL_CALL CConfigFilter::overrideNode(
+ const OUString& aName,
+ sal_Int16 aAttributes,
+ sal_Bool bClear)
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkElement(aName))
+ {
+ m_xLayerHandler->overrideNode(aName, aAttributes, bClear);
+ pushElement(aName);
+ }
+ else
+ pushElement(aName, sal_False);
+}
+
+void SAL_CALL CConfigFilter::addOrReplaceNode(
+ const OUString& aName,
+ sal_Int16 aAttributes)
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkElement(aName))
+ {
+ m_xLayerHandler->addOrReplaceNode(aName, aAttributes);
+ pushElement(aName);
+ }
+ else
+ pushElement(aName, sal_False);
+}
+
+void SAL_CALL CConfigFilter::addOrReplaceNodeFromTemplate(
+ const OUString& aName,
+ const com::sun::star::configuration::backend::TemplateIdentifier& aTemplate,
+ sal_Int16 aAttributes )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkElement(aName))
+ {
+ m_xLayerHandler->addOrReplaceNodeFromTemplate(aName, aTemplate, aAttributes);
+ pushElement(aName);
+ }
+ else
+ pushElement(aName, sal_False);
+}
+
+void SAL_CALL CConfigFilter::endNode()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkCurrentElement())
+ {
+ m_xLayerHandler->endNode();
+ }
+ popElement();
+}
+
+void SAL_CALL CConfigFilter::dropNode(
+ const OUString& aName )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ // does not get pushed
+ if (checkElement(aName))
+ {
+ m_xLayerHandler->dropNode(aName);
+ }
+}
+
+void SAL_CALL CConfigFilter::overrideProperty(
+ const OUString& aName,
+ sal_Int16 aAttributes,
+ const Type& aType,
+ sal_Bool bClear )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkElement(aName)){
+ m_xLayerHandler->overrideProperty(aName, aAttributes, aType, bClear);
+ pushElement(aName);
+ }
+ else
+ pushElement(aName, sal_False);
+}
+
+void SAL_CALL CConfigFilter::setPropertyValue(
+ const Any& aValue )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkCurrentElement())
+ m_xLayerHandler->setPropertyValue(aValue);
+}
+
+void SAL_CALL CConfigFilter::setPropertyValueForLocale(
+ const Any& aValue,
+ const OUString& aLocale )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkCurrentElement())
+ m_xLayerHandler->setPropertyValueForLocale(aValue, aLocale);
+}
+
+void SAL_CALL CConfigFilter::endProperty()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkCurrentElement())
+ {
+ m_xLayerHandler->endProperty();
+ }
+ popElement();
+
+}
+
+void SAL_CALL CConfigFilter::addProperty(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const Type& aType )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ if (checkElement(aName))
+ m_xLayerHandler->addProperty(aName, aAttributes, aType);
+}
+
+void SAL_CALL CConfigFilter::addPropertyWithValue(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const Any& aValue )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException )
+{
+ // add property with value doesn't push the property
+ if (checkElement(aName))
+ m_xLayerHandler->addPropertyWithValue(aName, aAttributes, aValue);
+
+}
+
+} // namespace desktop
diff --git a/desktop/source/migration/cfgfilter.hxx b/desktop/source/migration/cfgfilter.hxx
new file mode 100644
index 000000000000..605788a12e1b
--- /dev/null
+++ b/desktop/source/migration/cfgfilter.hxx
@@ -0,0 +1,173 @@
+#ifndef _DESKTOP_CFGFILTER_HXX_
+#define _DESKTOP_CFGFILTER_HXX_
+
+#include <stack>
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Type.hxx>
+
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+#include <com/sun/star/configuration/backend/TemplateIdentifier.hpp>
+
+
+#include "migration_impl.hxx"
+
+#define NS_CSS com::sun::star
+#define NS_UNO com::sun::star::uno
+
+
+namespace desktop {
+
+struct element
+{
+ rtl::OUString name;
+ rtl::OUString path;
+ sal_Bool use;
+
+};
+
+typedef std::stack< element > element_stack;
+
+// XInitialization:
+// -> Source : XLayer
+// XLayer
+// XLayerHandler
+class CConfigFilter : public cppu::WeakImplHelper3<
+ NS_CSS::configuration::backend::XLayer,
+ NS_CSS::configuration::backend::XLayerHandler,
+ NS_CSS::lang::XInitialization>
+{
+
+private:
+ NS_UNO::Reference< NS_CSS::configuration::backend::XLayerHandler > m_xLayerHandler;
+ NS_UNO::Reference< NS_CSS::configuration::backend::XLayer > m_xSourceLayer;
+
+ rtl::OUString m_aCurrentComponent;
+
+ const strings_v *m_pvInclude;
+ const strings_v *m_pvExclude;
+
+ element_stack m_elementStack;
+
+ void pushElement(rtl::OUString aName, sal_Bool bUse = sal_True);
+ void popElement();
+ sal_Bool checkElement(rtl::OUString aName);
+ sal_Bool checkCurrentElement();
+
+public:
+ CConfigFilter(const strings_v* include, const strings_v* exclude);
+
+ // XInitialization
+ virtual void SAL_CALL initialize(const NS_UNO::Sequence< NS_UNO::Any >& seqArgs)
+ throw (NS_UNO::Exception);
+
+ // XLayer
+ virtual void SAL_CALL readData(
+ const NS_UNO::Reference< NS_CSS::configuration::backend::XLayerHandler >& layerHandler)
+ throw (NS_CSS::lang::NullPointerException, NS_CSS::lang::WrappedTargetException,
+ NS_CSS::configuration::backend::MalformedDataException);
+
+ // XLayerHandler
+ virtual void SAL_CALL startLayer()
+ throw(::com::sun::star::lang::WrappedTargetException);
+
+ virtual void SAL_CALL endLayer()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL overrideNode(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ sal_Bool bClear)
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addOrReplaceNode(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes)
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addOrReplaceNodeFromTemplate(
+ const rtl::OUString& aName,
+ const NS_CSS::configuration::backend::TemplateIdentifier& aTemplate,
+ sal_Int16 aAttributes )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL endNode()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL dropNode(
+ const rtl::OUString& aName )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL overrideProperty(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const NS_UNO::Type& aType,
+ sal_Bool bClear )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL setPropertyValue(
+ const NS_UNO::Any& aValue )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL setPropertyValueForLocale(
+ const NS_UNO::Any& aValue,
+ const rtl::OUString& aLocale )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL endProperty()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addProperty(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const NS_UNO::Type& aType )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addPropertyWithValue(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const NS_UNO::Any& aValue )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+};
+
+} // namespace desktop
+#undef NS_CSS
+#undef NS_UNO
+
+#endif
+
+
diff --git a/desktop/source/migration/makefile.mk b/desktop/source/migration/makefile.mk
new file mode 100644
index 000000000000..bc0cd9a62b10
--- /dev/null
+++ b/desktop/source/migration/makefile.mk
@@ -0,0 +1,59 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=mig
+AUTOSEG=true
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+RSCEXTINC=..$/app
+
+# hacky - is no define
+CDEFS+=-I..$/app
+
+SLOFILES = \
+ $(SLO)$/migration.obj \
+ $(SLO)$/wizard.obj \
+ $(SLO)$/pages.obj \
+ $(SLO)$/cfgfilter.obj
+
+SRS1NAME= wizard
+SRC1FILES= wizard.src
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/migration/migration.cxx b/desktop/source/migration/migration.cxx
new file mode 100755
index 000000000000..314537836921
--- /dev/null
+++ b/desktop/source/migration/migration.cxx
@@ -0,0 +1,1365 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <map>
+#include <new>
+#include <set>
+
+#include "migration.hxx"
+#include "migration_impl.hxx"
+#include "cfgfilter.hxx"
+
+#include <unotools/textsearch.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <unotools/bootstrap.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/uri.hxx>
+#include <tools/config.hxx>
+#include <i18npool/lang.h>
+#include <tools/urlobj.hxx>
+#include <osl/file.hxx>
+#include <osl/mutex.hxx>
+#include <ucbhelper/content.hxx>
+#include <osl/security.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <com/sun/star/configuration/Update.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/XStringSubstitution.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/ui/XUIConfiguration.hpp>
+#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+
+using namespace rtl;
+using namespace osl;
+using namespace std;
+using namespace com::sun::star::task;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::container;
+using com::sun::star::uno::Exception;
+using namespace com::sun::star;
+
+namespace desktop {
+
+static const ::rtl::OUString ITEM_DESCRIPTOR_COMMANDURL = ::rtl::OUString::createFromAscii("CommandURL");
+static const ::rtl::OUString ITEM_DESCRIPTOR_CONTAINER = ::rtl::OUString::createFromAscii("ItemDescriptorContainer");
+static const ::rtl::OUString ITEM_DESCRIPTOR_LABEL = ::rtl::OUString::createFromAscii("Label");
+
+static const ::rtl::OUString MENU_SEPERATOR = ::rtl::OUString::createFromAscii(" | ");
+static const ::rtl::OUString MENU_SUBMENU = ::rtl::OUString::createFromAscii("...");
+
+::rtl::OUString retrieveLabelFromCommand(const ::rtl::OUString& sCommand, const ::rtl::OUString& sModuleIdentifier)
+{
+ ::rtl::OUString sLabel;
+
+ uno::Reference< container::XNameAccess > xUICommands;
+ uno::Reference< container::XNameAccess > xNameAccess( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.frame.UICommandDescription") ), uno::UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ uno::Any a = xNameAccess->getByName( sModuleIdentifier );
+ a >>= xUICommands;
+ }
+ if (xUICommands.is())
+ {
+ if ( sCommand.getLength() > 0 )
+ {
+ rtl::OUString aStr;
+ ::uno::Sequence< beans::PropertyValue > aPropSeq;
+ try
+ {
+ uno::Any a( xUICommands->getByName( sCommand ));
+ if ( a >>= aPropSeq )
+ {
+ for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
+ {
+ if ( aPropSeq[i].Name.equalsAscii( "Label" ))
+ {
+ aPropSeq[i].Value >>= aStr;
+ break;
+ }
+ }
+ }
+
+ sLabel = aStr;
+ }
+
+ catch(container::NoSuchElementException&)
+ {
+ sLabel = sCommand;
+ sal_Int32 nIndex = sLabel.indexOf(':');
+ if (nIndex>=0 && nIndex <= sLabel.getLength()-1)
+ sLabel = sLabel.copy(nIndex+1);
+ }
+
+ }
+ }
+
+ return sLabel;
+}
+
+::rtl::OUString stripHotKey( const ::rtl::OUString& str )
+{
+ sal_Int32 index = str.indexOf( '~' );
+ if ( index == -1 )
+ {
+ return str;
+ }
+ else
+ {
+ return str.replaceAt( index, 1, ::rtl::OUString() );
+ }
+}
+
+::rtl::OUString mapModuleShortNameToIdentifier(const ::rtl::OUString& sShortName)
+{
+ ::rtl::OUString sIdentifier;
+
+ if (sShortName.equals(::rtl::OUString::createFromAscii("StartModule")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.frame.StartModule");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("swriter")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("scalc")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("sdraw")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("simpress")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("smath")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("schart")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.chart2.ChartDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("BasicIDE")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.script.BasicIDE");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("dbapp")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.sdb.OfficeDatabaseDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("sglobal")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("sweb")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("swxform")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.xforms.XMLFormDocument");
+
+ else if (sShortName.equals(::rtl::OUString::createFromAscii("sbibliography")))
+ sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.frame.Bibliography");
+
+ return sIdentifier;
+}
+
+static MigrationImpl *pImpl = 0;
+static Mutex aMutex;
+static MigrationImpl *getImpl()
+{
+ MutexGuard aGuard(aMutex);
+ if (pImpl == 0)
+ pImpl = new MigrationImpl(comphelper::getProcessServiceFactory());
+ return pImpl;
+}
+
+static void releaseImpl()
+{
+ MutexGuard aGuard(aMutex);
+ if (pImpl != 0)
+ {
+ delete pImpl;
+ pImpl = 0;
+ }
+}
+
+// static main entry point for the migration process
+void Migration::doMigration()
+{
+ sal_Bool bResult = sal_False;
+ try {
+ bResult = getImpl()->doMigration();
+ } catch (Exception& e)
+ {
+ OString aMsg("doMigration() exception: ");
+ aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ }
+ OSL_ENSURE(bResult, "Migration has not been successfull");
+ // shut down migration framework
+ releaseImpl();
+}
+
+void Migration::cancelMigration()
+{
+ releaseImpl();
+}
+
+sal_Bool Migration::checkMigration()
+{
+ return getImpl()->checkMigration();
+}
+
+OUString Migration::getOldVersionName()
+{
+ return getImpl()->getOldVersionName();
+}
+
+OUString MigrationImpl::getOldVersionName()
+{
+ return m_aInfo.productname;
+}
+
+sal_Bool MigrationImpl::checkMigration()
+{
+ if (m_aInfo.userdata.getLength() > 0 && ! checkMigrationCompleted())
+ return sal_True;
+ else
+ return sal_False;
+}
+
+MigrationImpl::MigrationImpl(const uno::Reference< XMultiServiceFactory >& xFactory)
+ : m_vrVersions(new strings_v)
+ , m_xFactory(xFactory)
+{
+ readAvailableMigrations(m_vMigrationsAvailable);
+ sal_Int32 nIndex = findPreferedMigrationProcess(m_vMigrationsAvailable);
+ if ( nIndex >= 0 )
+ m_vrMigrations = readMigrationSteps(m_vMigrationsAvailable[nIndex].name);
+}
+
+MigrationImpl::~MigrationImpl()
+{
+
+}
+
+sal_Bool MigrationImpl::doMigration()
+{
+ // compile file list for migration
+ m_vrFileList = compileFileList();
+
+ sal_Bool result = sal_False;
+ try
+ {
+ NewVersionUIInfo aNewVersionUIInfo;
+ ::std::vector< MigrationModuleInfo > vModulesInfo = dectectUIChangesForAllModules();
+ aNewVersionUIInfo.init(vModulesInfo);
+
+ copyFiles();
+
+ const ::rtl::OUString sMenubarResourceURL = ::rtl::OUString::createFromAscii("private:resource/menubar/menubar");
+ const ::rtl::OUString sToolbarResourcePre = ::rtl::OUString::createFromAscii("private:resource/toolbar/");
+ for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i)
+ {
+ ::rtl::OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName);
+ if (sModuleIdentifier.getLength()==0)
+ continue;
+
+ uno::Sequence< uno::Any > lArgs(2);
+ ::rtl::OUString aOldCfgDataPath = m_aInfo.userdata + ::rtl::OUString::createFromAscii("/user/config/soffice.cfg/modules/");
+ lArgs[0] <<= aOldCfgDataPath + vModulesInfo[i].sModuleShortName;
+ lArgs[1] <<= embed::ElementModes::READ;
+
+ uno::Reference< lang::XSingleServiceFactory > xStorageFactory(m_xFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.embed.FileSystemStorageFactory")), uno::UNO_QUERY);
+ uno::Reference< embed::XStorage > xModules;
+
+ xModules = uno::Reference< embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
+ uno::Reference< ui::XUIConfigurationManager > xOldCfgManager( m_xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.ui.UIConfigurationManager")), uno::UNO_QUERY );
+ uno::Reference< ui::XUIConfigurationStorage > xOldCfgStorage( xOldCfgManager, uno::UNO_QUERY );
+ uno::Reference< ui::XUIConfigurationPersistence > xOldCfgPersistence( xOldCfgManager, uno::UNO_QUERY );
+
+ if ( xOldCfgStorage.is() && xOldCfgPersistence.is() && xModules.is() )
+ {
+ xOldCfgStorage->setStorage( xModules );
+ xOldCfgPersistence->reload();
+ }
+
+ uno::Reference< ui::XUIConfigurationManager > xCfgManager = aNewVersionUIInfo.getConfigManager(vModulesInfo[i].sModuleShortName);
+
+ if (vModulesInfo[i].bHasMenubar)
+ {
+ uno::Reference< container::XIndexContainer > xOldVersionMenuSettings = uno::Reference< container::XIndexContainer >(xOldCfgManager->getSettings(sMenubarResourceURL, sal_True), uno::UNO_QUERY);
+ uno::Reference< container::XIndexContainer > xNewVersionMenuSettings = aNewVersionUIInfo.getNewMenubarSettings(vModulesInfo[i].sModuleShortName);
+ ::rtl::OUString sParent;
+ compareOldAndNewConfig(sParent, xOldVersionMenuSettings, xNewVersionMenuSettings, sMenubarResourceURL);
+ mergeOldToNewVersion(xCfgManager, xNewVersionMenuSettings, sModuleIdentifier, sMenubarResourceURL);
+ }
+
+ sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size();
+ if (nToolbars >0)
+ {
+ for (sal_Int32 j=0; j<nToolbars; ++j)
+ {
+ ::rtl::OUString sToolbarName = vModulesInfo[i].m_vToolbars[j];
+ ::rtl::OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
+
+ uno::Reference< container::XIndexContainer > xOldVersionToolbarSettings = uno::Reference< container::XIndexContainer >(xOldCfgManager->getSettings(sToolbarResourceURL, sal_True), uno::UNO_QUERY);
+ uno::Reference< container::XIndexContainer > xNewVersionToolbarSettings = aNewVersionUIInfo.getNewToolbarSettings(vModulesInfo[i].sModuleShortName, sToolbarName);
+ ::rtl::OUString sParent;
+ compareOldAndNewConfig(sParent, xOldVersionToolbarSettings, xNewVersionToolbarSettings, sToolbarResourceURL);
+ mergeOldToNewVersion(xCfgManager, xNewVersionToolbarSettings, sModuleIdentifier, sToolbarResourceURL);
+ }
+ }
+
+ m_aOldVersionItemsHashMap.clear();
+ m_aNewVersionItemsHashMap.clear();
+ }
+
+ // execute the migration items from Setup.xcu
+ copyConfig();
+
+ // execute custom migration services from Setup.xcu
+ // and refresh the cache
+ runServices();
+ refresh();
+
+ result = sal_True;
+ } catch (...)
+ {
+ OString aMsg("An unexpected exception was thrown during migration");
+ aMsg += "\nOldVersion: " + OUStringToOString(m_aInfo.productname, RTL_TEXTENCODING_ASCII_US);
+ aMsg += "\nDataPath : " + OUStringToOString(m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ }
+
+ // prevent running the migration multiple times
+ setMigrationCompleted();
+ return result;
+}
+
+void MigrationImpl::refresh()
+{
+ uno::Reference< XRefreshable > xRefresh(m_xFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY);
+ if (xRefresh.is())
+ xRefresh->refresh();
+ else
+ OSL_ENSURE(sal_False, "could not get XRefresh interface from default config provider. No refresh done.");
+
+}
+
+void MigrationImpl::setMigrationCompleted()
+{
+ try {
+ uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW);
+ aPropertySet->setPropertyValue(OUString::createFromAscii("MigrationCompleted"), uno::makeAny(sal_True));
+ uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
+ } catch (...) {
+ // fail silently
+ }
+}
+
+sal_Bool MigrationImpl::checkMigrationCompleted()
+{
+ sal_Bool bMigrationCompleted = sal_False;
+ try {
+ uno::Reference< XPropertySet > aPropertySet(
+ getConfigAccess("org.openoffice.Setup/Office"), uno::UNO_QUERY_THROW);
+ aPropertySet->getPropertyValue(
+ OUString::createFromAscii("MigrationCompleted")) >>= bMigrationCompleted;
+ } catch (Exception&) {
+ // just return false...
+ }
+ return bMigrationCompleted;
+}
+
+static void insertSorted(migrations_available& rAvailableMigrations, supported_migration& aSupportedMigration)
+{
+ bool bInserted( false );
+ migrations_available::iterator pIter = rAvailableMigrations.begin();
+ while ( !bInserted && pIter != rAvailableMigrations.end())
+ {
+ if ( pIter->nPriority < aSupportedMigration.nPriority )
+ {
+ rAvailableMigrations.insert(pIter, aSupportedMigration );
+ bInserted = true;
+ break; // i111193: insert invalidates iterator!
+ }
+ ++pIter;
+ }
+ if ( !bInserted )
+ rAvailableMigrations.push_back( aSupportedMigration );
+}
+
+bool MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigrations)
+{
+ // get supported version names
+ uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW);
+ uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames();
+
+ const OUString aVersionIdentifiers( RTL_CONSTASCII_USTRINGPARAM( "VersionIdentifiers" ));
+ const OUString aPriorityIdentifier( RTL_CONSTASCII_USTRINGPARAM( "Priority" ));
+
+ for (sal_Int32 i=0; i<seqSupportedVersions.getLength(); i++)
+ {
+ sal_Int32 nPriority( 0 );
+ uno::Sequence< OUString > seqVersions;
+ uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(seqSupportedVersions[i]), uno::UNO_QUERY_THROW );
+ xMigrationData->getByName( aVersionIdentifiers ) >>= seqVersions;
+ xMigrationData->getByName( aPriorityIdentifier ) >>= nPriority;
+
+ supported_migration aSupportedMigration;
+ aSupportedMigration.name = seqSupportedVersions[i];
+ aSupportedMigration.nPriority = nPriority;
+ for (sal_Int32 j=0; j<seqVersions.getLength(); j++)
+ aSupportedMigration.supported_versions.push_back(seqVersions[j].trim());
+ insertSorted( rAvailableMigrations, aSupportedMigration );
+ }
+
+ return true;
+}
+
+migrations_vr MigrationImpl::readMigrationSteps(const ::rtl::OUString& rMigrationName)
+{
+ // get migration access
+ uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW);
+ uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(rMigrationName), uno::UNO_QUERY_THROW );
+
+ // get migration description from from org.openoffice.Setup/Migration
+ // and build vector of migration steps
+ OUString aMigrationSteps( RTL_CONSTASCII_USTRINGPARAM( "MigrationSteps" ));
+ uno::Reference< XNameAccess > theNameAccess(xMigrationData->getByName(aMigrationSteps), uno::UNO_QUERY_THROW);
+ uno::Sequence< OUString > seqMigrations = theNameAccess->getElementNames();
+ uno::Reference< XNameAccess > tmpAccess;
+ uno::Reference< XNameAccess > tmpAccess2;
+ uno::Sequence< OUString > tmpSeq;
+ migrations_vr vrMigrations(new migrations_v);
+ for (sal_Int32 i = 0; i < seqMigrations.getLength(); i++)
+ {
+ // get current migration step
+ theNameAccess->getByName(seqMigrations[i]) >>= tmpAccess;
+ // tmpStepPtr = new migration_step();
+ migration_step tmpStep;
+ tmpStep.name = seqMigrations[i];
+
+ // read included files from current step description
+ ::rtl::OUString aSeqEntry;
+ if (tmpAccess->getByName(OUString::createFromAscii("IncludedFiles")) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ {
+ aSeqEntry = tmpSeq[j];
+ tmpStep.includeFiles.push_back(aSeqEntry);
+ }
+ }
+
+ // exluded files...
+ if (tmpAccess->getByName(OUString::createFromAscii("ExcludedFiles")) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ tmpStep.excludeFiles.push_back(tmpSeq[j]);
+ }
+
+ // included nodes...
+ if (tmpAccess->getByName(OUString::createFromAscii("IncludedNodes")) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ tmpStep.includeConfig.push_back(tmpSeq[j]);
+ }
+
+ // excluded nodes...
+ if (tmpAccess->getByName(OUString::createFromAscii("ExcludedNodes")) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ tmpStep.excludeConfig.push_back(tmpSeq[j]);
+ }
+
+ // included extensions...
+ if (tmpAccess->getByName(OUString::createFromAscii("IncludedExtensions")) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ tmpStep.includeExtensions.push_back(tmpSeq[j]);
+ }
+
+ // excluded extensions...
+ if (tmpAccess->getByName(OUString::createFromAscii("ExcludedExtensions")) >>= tmpSeq)
+ {
+ for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
+ {
+ aSeqEntry = tmpSeq[j];
+ tmpStep.excludeExtensions.push_back(aSeqEntry);
+ }
+ }
+
+ // generic service
+ tmpAccess->getByName(OUString::createFromAscii("MigrationService")) >>= tmpStep.service;
+
+ vrMigrations->push_back(tmpStep);
+ }
+ return vrMigrations;
+}
+
+static FileBase::RC _checkAndCreateDirectory(INetURLObject& dirURL)
+{
+ FileBase::RC result = Directory::create(dirURL.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ if (result == FileBase::E_NOENT)
+ {
+ INetURLObject baseURL(dirURL);
+ baseURL.removeSegment();
+ _checkAndCreateDirectory(baseURL);
+ return Directory::create(dirURL.GetMainURL(INetURLObject::DECODE_TO_IURI));
+ } else
+ return result;
+}
+
+install_info MigrationImpl::findInstallation(const strings_v& rVersions)
+{
+ rtl::OUString aProductName;
+ uno::Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
+ aRet >>= aProductName;
+ aProductName = aProductName.toAsciiLowerCase();
+
+ install_info aInfo;
+ strings_v::const_iterator i_ver = rVersions.begin();
+ uno::Reference < util::XStringSubstitution > xSubst( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.PathSubstitution")), uno::UNO_QUERY );
+ while (i_ver != rVersions.end())
+ {
+ ::rtl::OUString aVersion, aProfileName;
+ sal_Int32 nSeparatorIndex = (*i_ver).indexOf('=');
+ if ( nSeparatorIndex != -1 )
+ {
+ aVersion = (*i_ver).copy( 0, nSeparatorIndex );
+ aProfileName = (*i_ver).copy( nSeparatorIndex+1 );
+ }
+
+ if ( aVersion.getLength() && aProfileName.getLength() &&
+ ( !aInfo.userdata.getLength() || !aProfileName.toAsciiLowerCase().compareTo( aProductName, aProductName.getLength() ) )
+ )
+ {
+ ::rtl::OUString aUserInst;
+ osl::Security().getConfigDir( aUserInst );
+ if ( aUserInst.getLength() && aUserInst[ aUserInst.getLength()-1 ] != '/' )
+ aUserInst += ::rtl::OUString::createFromAscii("/");
+#if defined UNX && ! defined MACOSX
+ // tribute to whoever had the "great" idea to use different names on Windows and Unix
+ aUserInst += ::rtl::OUString::createFromAscii(".");
+#endif
+ aUserInst += aProfileName;
+ try
+ {
+ INetURLObject aObj(aUserInst);
+ ::ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment > () );
+ aCnt.isDocument();
+ aInfo.userdata = aObj.GetMainURL( INetURLObject::NO_DECODE );
+ aInfo.productname = aVersion;
+ }
+ catch( uno::Exception& ){}
+ }
+ ++i_ver;
+ }
+
+ return aInfo;
+}
+
+sal_Int32 MigrationImpl::findPreferedMigrationProcess(const migrations_available& rAvailableMigrations)
+{
+ sal_Int32 nIndex( -1 );
+ sal_Int32 i( 0 );
+
+ migrations_available::const_iterator rIter = rAvailableMigrations.begin();
+ while ( rIter != rAvailableMigrations.end() )
+ {
+ install_info aInstallInfo = findInstallation(rIter->supported_versions);
+ if (aInstallInfo.productname.getLength() > 0 )
+ {
+ m_aInfo = aInstallInfo;
+ nIndex = i;
+ break;
+ }
+ ++i;
+ ++rIter;
+ }
+
+ return nIndex;
+}
+
+strings_vr MigrationImpl::applyPatterns(const strings_v& vSet, const strings_v& vPatterns) const
+{
+ using namespace utl;
+ strings_vr vrResult(new strings_v);
+ strings_v::const_iterator i_set;
+ strings_v::const_iterator i_pat = vPatterns.begin();
+ while (i_pat != vPatterns.end())
+ {
+ // find matches for this pattern in input set
+ // and copy them to the result
+ SearchParam param(*i_pat, SearchParam::SRCH_REGEXP);
+ TextSearch ts(param, LANGUAGE_DONTKNOW);
+ i_set = vSet.begin();
+ xub_StrLen start = 0;
+ xub_StrLen end = 0;
+ while (i_set != vSet.end())
+ {
+ end = (xub_StrLen)(i_set->getLength());
+ if (ts.SearchFrwrd(*i_set, &start, &end))
+ vrResult->push_back(*i_set);
+ i_set++;
+ }
+ i_pat++;
+ }
+ return vrResult;
+}
+
+strings_vr MigrationImpl::getAllFiles(const OUString& baseURL) const
+{
+ using namespace osl;
+ strings_vr vrResult(new strings_v);
+
+ // get sub dirs
+ Directory dir(baseURL);
+ if (dir.open() == FileBase::E_None)
+ {
+ strings_v vSubDirs;
+ strings_vr vrSubResult;
+
+ // work through directory contents...
+ DirectoryItem item;
+ FileStatus fs(FileStatusMask_Type | FileStatusMask_FileURL);
+ while (dir.getNextItem(item) == FileBase::E_None)
+ {
+ if (item.getFileStatus(fs) == FileBase::E_None)
+ {
+ if (fs.getFileType() == FileStatus::Directory)
+ vSubDirs.push_back(fs.getFileURL());
+ else
+ vrResult->push_back(fs.getFileURL());
+ }
+ }
+
+ // recurse subfolders
+ strings_v::const_iterator i = vSubDirs.begin();
+ while (i != vSubDirs.end())
+ {
+ vrSubResult = getAllFiles(*i);
+ vrResult->insert(vrResult->end(), vrSubResult->begin(), vrSubResult->end());
+ i++;
+ }
+ }
+ return vrResult;
+}
+
+strings_vr MigrationImpl::compileFileList()
+{
+
+ strings_vr vrResult(new strings_v);
+ strings_vr vrInclude;
+ strings_vr vrExclude;
+ strings_vr vrTemp;
+
+#ifdef SAL_OS2
+ if (m_aInfo.userdata.getLength() == 0)
+ return vrResult;
+#endif
+
+ // get a list of all files:
+ strings_vr vrFiles = getAllFiles(m_aInfo.userdata);
+
+ // get a file list result for each migration step
+ migrations_v::const_iterator i_migr = m_vrMigrations->begin();
+ while (i_migr != m_vrMigrations->end())
+ {
+ vrInclude = applyPatterns(*vrFiles, i_migr->includeFiles);
+ vrExclude = applyPatterns(*vrFiles, i_migr->excludeFiles);
+ substract(*vrInclude, *vrExclude);
+ vrResult->insert(vrResult->end(), vrInclude->begin(), vrInclude->end());
+ i_migr++;
+ }
+ return vrResult;
+}
+
+namespace {
+
+struct componentParts {
+ std::set< rtl::OUString > includedPaths;
+ std::set< rtl::OUString > excludedPaths;
+};
+
+typedef std::map< rtl::OUString, componentParts > Components;
+
+bool getComponent(rtl::OUString const & path, rtl::OUString * component) {
+ OSL_ASSERT(component != 0);
+ if (path.getLength() == 0 || path[0] != '/') {
+ OSL_TRACE(
+ ("configuration migration in/exclude path %s ignored (does not"
+ " start with slash)"),
+ rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr());
+ return false;
+ }
+ sal_Int32 i = path.indexOf('/', 1);
+ *component = i < 0 ? path.copy(1) : path.copy(1, i - 1);
+ return true;
+}
+
+uno::Sequence< rtl::OUString > setToSeq(std::set< rtl::OUString > const & set) {
+ std::set< rtl::OUString >::size_type n = set.size();
+ if (n > SAL_MAX_INT32) {
+ throw std::bad_alloc();
+ }
+ uno::Sequence< rtl::OUString > seq(static_cast< sal_Int32 >(n));
+ sal_Int32 i = 0;
+ for (std::set< rtl::OUString >::const_iterator j(set.begin());
+ j != set.end(); ++j)
+ {
+ seq[i++] = *j;
+ }
+ return seq;
+}
+
+}
+
+void MigrationImpl::copyConfig() {
+ Components comps;
+ for (migrations_v::const_iterator i(m_vrMigrations->begin());
+ i != m_vrMigrations->end(); ++i)
+ {
+ for (strings_v::const_iterator j(i->includeConfig.begin());
+ j != i->includeConfig.end(); ++j)
+ {
+ rtl::OUString comp;
+ if (getComponent(*j, &comp)) {
+ comps[comp].includedPaths.insert(*j);
+ }
+ }
+ for (strings_v::const_iterator j(i->excludeConfig.begin());
+ j != i->excludeConfig.end(); ++j)
+ {
+ rtl::OUString comp;
+ if (getComponent(*j, &comp)) {
+ comps[comp].excludedPaths.insert(*j);
+ }
+ }
+ }
+ for (Components::const_iterator i(comps.begin()); i != comps.end(); ++i) {
+ if (!i->second.includedPaths.empty()) {
+ rtl::OUStringBuffer buf(m_aInfo.userdata);
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/user/registry/data"));
+ sal_Int32 n = 0;
+ do {
+ rtl::OUString seg(i->first.getToken(0, '.', n));
+ rtl::OUString enc(
+ rtl::Uri::encode(
+ seg, rtl_UriCharClassPchar, rtl_UriEncodeStrict,
+ RTL_TEXTENCODING_UTF8));
+ if (enc.getLength() == 0 && seg.getLength() != 0) {
+ OSL_TRACE(
+ ("configuration migration component %s ignored (cannot"
+ " be encoded as file path)"),
+ rtl::OUStringToOString(
+ i->first, RTL_TEXTENCODING_UTF8).getStr());
+ goto next;
+ }
+ buf.append(sal_Unicode('/'));
+ buf.append(enc);
+ } while (n >= 0);
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(".xcu"));
+ configuration::Update::get(
+ comphelper::getProcessComponentContext())->
+ insertModificationXcuFile(
+ buf.makeStringAndClear(), setToSeq(i->second.includedPaths),
+ setToSeq(i->second.excludedPaths));
+ } else {
+ OSL_TRACE(
+ ("configuration migration component %s ignored (only excludes,"
+ " no includes)"),
+ rtl::OUStringToOString(
+ i->first, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ next:;
+ }
+}
+
+// removes elements of vector 2 in vector 1
+void MigrationImpl::substract(strings_v& va, const strings_v& vb_c) const
+{
+ strings_v vb(vb_c);
+ // ensure uniqueness of entries
+ sort(va.begin(), va.end());
+ sort(vb.begin(), vb.end());
+ unique(va.begin(), va.end());
+ unique(vb.begin(), vb.end());
+
+ strings_v::const_iterator i_ex = vb.begin();
+ strings_v::iterator i_in;
+ strings_v::iterator i_next;
+ while (i_ex != vb.end())
+ {
+ i_in = va.begin();
+ while (i_in != va.end())
+ {
+ if ( *i_in == *i_ex)
+ {
+ i_next = i_in+1;
+ va.erase(i_in);
+ i_in = i_next;
+ // we can only find one match since we
+ // ensured uniquness of the entries. ergo:
+ break;
+ }
+ else
+ i_in++;
+ }
+ i_ex++;
+ }
+}
+
+uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
+{
+ uno::Reference< XNameAccess > xNameAccess;
+ try{
+ OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
+ OUString sAccessSrvc;
+ if (bUpdate)
+ sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
+ else
+ sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
+
+ OUString sConfigURL = OUString::createFromAscii(pPath);
+
+ // get configuration provider
+ uno::Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ uno::Reference< XMultiServiceFactory > theConfigProvider = uno::Reference< XMultiServiceFactory > (
+ theMSF->createInstance( sConfigSrvc ),uno::UNO_QUERY_THROW );
+
+ // access the provider
+ uno::Sequence< uno::Any > theArgs(1);
+ theArgs[ 0 ] <<= sConfigURL;
+ xNameAccess = uno::Reference< XNameAccess > (
+ theConfigProvider->createInstanceWithArguments(
+ sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW );
+ } catch (com::sun::star::uno::Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ }
+ return xNameAccess;
+}
+
+void MigrationImpl::copyFiles()
+{
+ strings_v::const_iterator i_file = m_vrFileList->begin();
+ OUString localName;
+ OUString destName;
+ OUString userInstall;
+ utl::Bootstrap::PathStatus aStatus;
+ aStatus = utl::Bootstrap::locateUserInstallation(userInstall);
+ if (aStatus == utl::Bootstrap::PATH_EXISTS)
+ {
+ while (i_file != m_vrFileList->end())
+ {
+
+ // remove installation prefix from file
+ localName = i_file->copy(m_aInfo.userdata.getLength());
+ destName = userInstall + localName;
+ INetURLObject aURL(destName);
+ // check whether destination directory exists
+ aURL.removeSegment();
+ _checkAndCreateDirectory(aURL);
+ FileBase::RC copyResult = File::copy(*i_file, destName);
+ if (copyResult != FileBase::E_None)
+ {
+ OString msg("Cannot copy ");
+ msg += OUStringToOString(*i_file, RTL_TEXTENCODING_UTF8) + " to "
+ + OUStringToOString(destName, RTL_TEXTENCODING_UTF8);
+ OSL_ENSURE(sal_False, msg.getStr());
+ }
+ i_file++;
+ }
+ }
+ else
+ {
+ OSL_ENSURE(sal_False, "copyFiles: UserInstall does not exist");
+ }
+}
+
+void MigrationImpl::runServices()
+{
+ // Build argument array
+ uno::Sequence< uno::Any > seqArguments(3);
+ seqArguments[0] = uno::makeAny(NamedValue(
+ OUString::createFromAscii("Productname"),
+ uno::makeAny(m_aInfo.productname)));
+ seqArguments[1] = uno::makeAny(NamedValue(
+ OUString::createFromAscii("UserData"),
+ uno::makeAny(m_aInfo.userdata)));
+
+
+ // create an instance of every migration service
+ // and execute the migration job
+ uno::Reference< XJob > xMigrationJob;
+
+ migrations_v::const_iterator i_mig = m_vrMigrations->begin();
+ while (i_mig != m_vrMigrations->end())
+ {
+ if( i_mig->service.getLength() > 0)
+ {
+
+ try
+ {
+ // set black list for extension migration
+ uno::Sequence< rtl::OUString > seqExtBlackList;
+ sal_uInt32 nSize = i_mig->excludeExtensions.size();
+ if ( nSize > 0 )
+ seqExtBlackList = comphelper::arrayToSequence< ::rtl::OUString >(
+ &i_mig->excludeExtensions[0], nSize );
+ seqArguments[2] = uno::makeAny(NamedValue(
+ OUString::createFromAscii("ExtensionBlackList"),
+ uno::makeAny( seqExtBlackList )));
+
+ xMigrationJob = uno::Reference< XJob >(m_xFactory->createInstanceWithArguments(
+ i_mig->service, seqArguments), uno::UNO_QUERY_THROW);
+
+ xMigrationJob->execute(uno::Sequence< NamedValue >());
+
+
+ } catch (Exception& e)
+ {
+ OString aMsg("Execution of migration service failed (Exception caught).\nService: ");
+ aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) + "\nMessage: ";
+ aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ } catch (...)
+ {
+ OString aMsg("Execution of migration service failed (Exception caught).\nService: ");
+ aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) +
+ "\nNo message available";
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ }
+
+ }
+ i_mig++;
+ }
+}
+
+::std::vector< MigrationModuleInfo > MigrationImpl::dectectUIChangesForAllModules() const
+{
+ ::std::vector< MigrationModuleInfo > vModulesInfo;
+ const ::rtl::OUString MENUBAR = ::rtl::OUString::createFromAscii("menubar");
+ const ::rtl::OUString TOOLBAR = ::rtl::OUString::createFromAscii("toolbar");
+
+ uno::Sequence< uno::Any > lArgs(2);
+ lArgs[0] <<= m_aInfo.userdata + ::rtl::OUString::createFromAscii("/user/config/soffice.cfg/modules");
+ lArgs[1] <<= embed::ElementModes::READ;
+
+ uno::Reference< lang::XSingleServiceFactory > xStorageFactory(m_xFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.embed.FileSystemStorageFactory")), uno::UNO_QUERY);
+ uno::Reference< embed::XStorage > xModules;
+
+ xModules = uno::Reference< embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
+ if (!xModules.is())
+ return vModulesInfo;
+
+ uno::Reference< container::XNameAccess > xAccess = uno::Reference< container::XNameAccess >(xModules, uno::UNO_QUERY);
+ uno::Sequence< ::rtl::OUString > lNames = xAccess->getElementNames();
+ sal_Int32 nLength = lNames.getLength();
+ for (sal_Int32 i=0; i<nLength; ++i)
+ {
+ ::rtl::OUString sModuleShortName = lNames[i];
+ uno::Reference< embed::XStorage > xModule = xModules->openStorageElement(sModuleShortName, embed::ElementModes::READ);
+ if (xModule.is())
+ {
+ MigrationModuleInfo aModuleInfo;
+
+ uno::Reference< embed::XStorage > xMenubar = xModule->openStorageElement(MENUBAR, embed::ElementModes::READ);
+ if (xMenubar.is())
+ {
+ uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xMenubar, uno::UNO_QUERY);
+ if (xNameAccess->getElementNames().getLength() > 0)
+ {
+ aModuleInfo.sModuleShortName = sModuleShortName;
+ aModuleInfo.bHasMenubar = sal_True;
+ }
+ }
+
+ uno::Reference< embed::XStorage > xToolbar = xModule->openStorageElement(TOOLBAR, embed::ElementModes::READ);
+ if (xToolbar.is())
+ {
+ const ::rtl::OUString RESOURCEURL_CUSTOM_ELEMENT = ::rtl::OUString::createFromAscii("custom_");
+ sal_Int32 nCustomLen = 7;
+
+ uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xToolbar, uno::UNO_QUERY);
+ ::uno::Sequence< ::rtl::OUString > lToolbars = xNameAccess->getElementNames();
+ for (sal_Int32 j=0; j<lToolbars.getLength(); ++j)
+ {
+ ::rtl::OUString sToolbarName = lToolbars[j];
+ if (sToolbarName.getLength()>=nCustomLen &&
+ sToolbarName.copy(0, nCustomLen).equals(RESOURCEURL_CUSTOM_ELEMENT))
+ continue;
+
+ aModuleInfo.sModuleShortName = sModuleShortName;
+ sal_Int32 nIndex = sToolbarName.lastIndexOf('.');
+ if (nIndex > 0)
+ {
+ ::rtl::OUString sExtension(sToolbarName.copy(nIndex));
+ ::rtl::OUString sToolbarResourceName(sToolbarName.copy(0, nIndex));
+ if (sToolbarResourceName.getLength()>0 && sExtension.equalsAsciiL(".xml", 4))
+ aModuleInfo.m_vToolbars.push_back(sToolbarResourceName);
+ }
+ }
+ }
+
+ if (aModuleInfo.sModuleShortName.getLength()>0)
+ vModulesInfo.push_back(aModuleInfo);
+ }
+ }
+
+ return vModulesInfo;
+}
+
+void MigrationImpl::compareOldAndNewConfig(const ::rtl::OUString& sParent,
+ const uno::Reference< container::XIndexContainer >& xIndexOld,
+ const uno::Reference< container::XIndexContainer >& xIndexNew,
+ const ::rtl::OUString& sResourceURL)
+{
+ ::std::vector< MigrationItem > vOldItems;
+ ::std::vector< MigrationItem > vNewItems;
+ uno::Sequence< beans::PropertyValue > aProp;
+ sal_Int32 nOldCount = xIndexOld->getCount();
+ sal_Int32 nNewCount = xIndexNew->getCount();
+
+ for (int n=0; n<nOldCount; ++n)
+ {
+ MigrationItem aMigrationItem;
+ if (xIndexOld->getByIndex(n) >>= aProp)
+ {
+ for(int i=0; i<aProp.getLength(); ++i)
+ {
+ if (aProp[i].Name.equals(ITEM_DESCRIPTOR_COMMANDURL))
+ aProp[i].Value >>= aMigrationItem.m_sCommandURL;
+ else if (aProp[i].Name.equals(ITEM_DESCRIPTOR_CONTAINER))
+ aProp[i].Value >>= aMigrationItem.m_xPopupMenu;
+ }
+
+ if (aMigrationItem.m_sCommandURL.getLength())
+ vOldItems.push_back(aMigrationItem);
+ }
+ }
+
+ for (int n=0; n<nNewCount; ++n)
+ {
+ MigrationItem aMigrationItem;
+ if (xIndexNew->getByIndex(n) >>= aProp)
+ {
+ for(int i=0; i<aProp.getLength(); ++i)
+ {
+ if (aProp[i].Name.equals(ITEM_DESCRIPTOR_COMMANDURL))
+ aProp[i].Value >>= aMigrationItem.m_sCommandURL;
+ else if (aProp[i].Name.equals(ITEM_DESCRIPTOR_CONTAINER))
+ aProp[i].Value >>= aMigrationItem.m_xPopupMenu;
+ }
+
+ if (aMigrationItem.m_sCommandURL.getLength())
+ vNewItems.push_back(aMigrationItem);
+ }
+ }
+
+ ::std::vector< MigrationItem >::iterator it;
+
+ ::rtl::OUString sSibling;
+ for (it = vOldItems.begin(); it!=vOldItems.end(); ++it)
+ {
+ ::std::vector< MigrationItem >::iterator pFound = ::std::find(vNewItems.begin(), vNewItems.end(), *it);
+ if (pFound != vNewItems.end() && it->m_xPopupMenu.is())
+ {
+ ::rtl::OUString sName;
+ if (sParent.getLength()>0)
+ sName = sParent + MENU_SEPERATOR + it->m_sCommandURL;
+ else
+ sName = it->m_sCommandURL;
+ compareOldAndNewConfig(sName, it->m_xPopupMenu, pFound->m_xPopupMenu, sResourceURL);
+ }
+ else if (pFound == vNewItems.end())
+ {
+ MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu);
+ if (m_aOldVersionItemsHashMap.find(sResourceURL)==m_aOldVersionItemsHashMap.end())
+ {
+ ::std::vector< MigrationItem > vMigrationItems;
+ m_aOldVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems));
+ m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
+ }
+ else
+ {
+ if (::std::find(m_aOldVersionItemsHashMap[sResourceURL].begin(), m_aOldVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aOldVersionItemsHashMap[sResourceURL].end())
+ m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
+ }
+ }
+
+ sSibling = it->m_sCommandURL;
+ }
+
+ ::rtl::OUString sNewSibling;
+ uno::Reference< container::XIndexContainer > xPopup;
+ for (it = vNewItems.begin(); it!=vNewItems.end(); ++it)
+ {
+ ::std::vector< MigrationItem >::iterator pFound = ::std::find(vOldItems.begin(), vOldItems.end(), *it);
+ if (pFound != vOldItems.end() && it->m_xPopupMenu.is())
+ {
+ ::rtl::OUString sName;
+ if (sParent.getLength()>0)
+ sName = sParent + MENU_SEPERATOR + it->m_sCommandURL;
+ else
+ sName = it->m_sCommandURL;
+ compareOldAndNewConfig(sName, pFound->m_xPopupMenu, it->m_xPopupMenu, sResourceURL);
+ }
+ else if (::std::find(vOldItems.begin(), vOldItems.end(), *it) == vOldItems.end())
+ {
+ MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu);
+ if (m_aNewVersionItemsHashMap.find(sResourceURL)==m_aNewVersionItemsHashMap.end())
+ {
+ ::std::vector< MigrationItem > vMigrationItems;
+ m_aNewVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems));
+ m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
+ }
+ else
+ {
+ if (::std::find(m_aNewVersionItemsHashMap[sResourceURL].begin(), m_aNewVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aNewVersionItemsHashMap[sResourceURL].end())
+ m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
+ }
+ }
+ }
+}
+
+void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurationManager >& xCfgManager,
+ const uno::Reference< container::XIndexContainer>& xIndexContainer,
+ const ::rtl::OUString& sModuleIdentifier,
+ const ::rtl::OUString& sResourceURL)
+{
+ MigrationHashMap::iterator pFound = m_aOldVersionItemsHashMap.find(sResourceURL);
+ if (pFound==m_aOldVersionItemsHashMap.end())
+ return;
+
+ ::std::vector< MigrationItem >::iterator it;
+ for (it=pFound->second.begin(); it!=pFound->second.end(); ++it)
+ {
+ uno::Reference< container::XIndexContainer > xTemp = xIndexContainer;
+
+ ::rtl::OUString sParentNodeName = it->m_sParentNodeName;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString sToken = sParentNodeName.getToken(0, '|', nIndex).trim();
+ if (sToken.getLength()<=0)
+ break;
+
+ sal_Int32 nCount = xTemp->getCount();
+ for (sal_Int32 i=0; i<nCount; ++i)
+ {
+ ::rtl::OUString sCommandURL;
+ ::rtl::OUString sLabel;
+ uno::Reference< container::XIndexContainer > xChild;
+
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ xTemp->getByIndex(i) >>= aPropSeq;
+ for (sal_Int32 j=0; j<aPropSeq.getLength(); ++j)
+ {
+ ::rtl::OUString sPropName = aPropSeq[j].Name;
+ if (sPropName.equals(ITEM_DESCRIPTOR_COMMANDURL))
+ aPropSeq[j].Value >>= sCommandURL;
+ else if (sPropName.equals(ITEM_DESCRIPTOR_LABEL))
+ aPropSeq[j].Value >>= sLabel;
+ else if (sPropName.equals(ITEM_DESCRIPTOR_CONTAINER))
+ aPropSeq[j].Value >>= xChild;
+ }
+
+ if (sCommandURL == sToken)
+ {
+ xTemp = xChild;
+ break;
+ }
+ }
+
+ } while (nIndex>=0);
+
+ if (nIndex == -1)
+ {
+ uno::Sequence< beans::PropertyValue > aPropSeq(3);
+
+ aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL;
+ aPropSeq[0].Value <<= it->m_sCommandURL;
+ aPropSeq[1].Name = ITEM_DESCRIPTOR_LABEL;
+ aPropSeq[1].Value <<= retrieveLabelFromCommand(it->m_sCommandURL, sModuleIdentifier);
+ aPropSeq[2].Name = ITEM_DESCRIPTOR_CONTAINER;
+ aPropSeq[2].Value <<= it->m_xPopupMenu;
+
+ if (it->m_sPrevSibling.getLength() == 0)
+ xTemp->insertByIndex(0, uno::makeAny(aPropSeq));
+ else if (it->m_sPrevSibling.getLength() > 0)
+ {
+ sal_Int32 nCount = xTemp->getCount();
+ sal_Int32 i = 0;
+ for (; i<nCount; ++i)
+ {
+ ::rtl::OUString sCmd;
+ uno::Sequence< beans::PropertyValue > aTempPropSeq;
+ xTemp->getByIndex(i) >>= aTempPropSeq;
+ for (sal_Int32 j=0; j<aTempPropSeq.getLength(); ++j)
+ {
+ if (aTempPropSeq[j].Name.equals(ITEM_DESCRIPTOR_COMMANDURL))
+ {
+ aTempPropSeq[j].Value >>= sCmd;
+ break;
+ }
+ }
+
+ if (sCmd.equals(it->m_sPrevSibling))
+ break;
+ }
+
+ xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq));
+ }
+ }
+ }
+
+ uno::Reference< container::XIndexAccess > xIndexAccess(xIndexContainer, uno::UNO_QUERY);
+ if (xIndexAccess.is())
+ xCfgManager->replaceSettings(sResourceURL, xIndexAccess);
+
+ uno::Reference< ui::XUIConfigurationPersistence > xUIConfigurationPersistence(xCfgManager, uno::UNO_QUERY);
+ if (xUIConfigurationPersistence.is())
+ xUIConfigurationPersistence->store();
+}
+
+uno::Reference< ui::XUIConfigurationManager > NewVersionUIInfo::getConfigManager(const ::rtl::OUString& sModuleShortName) const
+{
+ uno::Reference< ui::XUIConfigurationManager > xCfgManager;
+
+ for (sal_Int32 i=0; i<m_lCfgManagerSeq.getLength(); ++i)
+ {
+ if (m_lCfgManagerSeq[i].Name.equals(sModuleShortName))
+ {
+ m_lCfgManagerSeq[i].Value >>= xCfgManager;
+ break;
+ }
+ }
+
+ return xCfgManager;
+}
+
+uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewMenubarSettings(const ::rtl::OUString& sModuleShortName) const
+{
+ uno::Reference< container::XIndexContainer > xNewMenuSettings;
+
+ for (sal_Int32 i=0; i<m_lNewVersionMenubarSettingsSeq.getLength(); ++i)
+ {
+ if (m_lNewVersionMenubarSettingsSeq[i].Name.equals(sModuleShortName))
+ {
+ m_lNewVersionMenubarSettingsSeq[i].Value >>= xNewMenuSettings;
+ break;
+ }
+ }
+
+ return xNewMenuSettings;
+}
+
+uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSettings(const ::rtl::OUString& sModuleShortName, const ::rtl::OUString& sToolbarName) const
+{
+ uno::Reference< container::XIndexContainer > xNewToolbarSettings;
+
+ for (sal_Int32 i=0; i<m_lNewVersionToolbarSettingsSeq.getLength(); ++i)
+ {
+ if (m_lNewVersionToolbarSettingsSeq[i].Name.equals(sModuleShortName))
+ {
+ uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq;
+ m_lNewVersionToolbarSettingsSeq[i].Value >>= lToolbarSettingsSeq;
+ for (sal_Int32 j=0; j<lToolbarSettingsSeq.getLength(); ++j)
+ {
+ if (lToolbarSettingsSeq[j].Name.equals(sToolbarName))
+ {
+ lToolbarSettingsSeq[j].Value >>= xNewToolbarSettings;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return xNewToolbarSettings;
+}
+
+void NewVersionUIInfo::init(const ::std::vector< MigrationModuleInfo >& vModulesInfo)
+{
+ m_lCfgManagerSeq.realloc(vModulesInfo.size());
+ m_lNewVersionMenubarSettingsSeq.realloc(vModulesInfo.size());
+ m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size());
+
+ const ::rtl::OUString sModuleCfgSupplier = ::rtl::OUString::createFromAscii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier");
+ const ::rtl::OUString sMenubarResourceURL = ::rtl::OUString::createFromAscii("private:resource/menubar/menubar");
+ const ::rtl::OUString sToolbarResourcePre = ::rtl::OUString::createFromAscii("private:resource/toolbar/");
+
+ uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier = uno::Reference< ui::XModuleUIConfigurationManagerSupplier >(::comphelper::getProcessServiceFactory()->createInstance(sModuleCfgSupplier), uno::UNO_QUERY);
+
+ for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i)
+ {
+ ::rtl::OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName);
+ if (sModuleIdentifier.getLength() > 0)
+ {
+ uno::Reference< ui::XUIConfigurationManager > xCfgManager = xModuleCfgSupplier->getUIConfigurationManager(sModuleIdentifier);
+ m_lCfgManagerSeq[i].Name = vModulesInfo[i].sModuleShortName;
+ m_lCfgManagerSeq[i].Value <<= xCfgManager;
+
+ if (vModulesInfo[i].bHasMenubar)
+ {
+ m_lNewVersionMenubarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
+ m_lNewVersionMenubarSettingsSeq[i].Value <<= xCfgManager->getSettings(sMenubarResourceURL, sal_True);
+ }
+
+ sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size();
+ if (nToolbars > 0)
+ {
+ uno::Sequence< beans::PropertyValue > lPropSeq(nToolbars);
+ for (sal_Int32 j=0; j<nToolbars; ++j)
+ {
+ ::rtl::OUString sToolbarName = vModulesInfo[i].m_vToolbars[j];
+ ::rtl::OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
+
+ lPropSeq[j].Name = sToolbarName;
+ lPropSeq[j].Value <<= xCfgManager->getSettings(sToolbarResourceURL, sal_True);
+ }
+
+ m_lNewVersionToolbarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
+ m_lNewVersionToolbarSettingsSeq[i].Value <<= lPropSeq;
+ }
+ }
+ }
+}
+
+} // namespace desktop
diff --git a/desktop/source/migration/migration.hxx b/desktop/source/migration/migration.hxx
new file mode 100644
index 000000000000..5ac8c5f5702c
--- /dev/null
+++ b/desktop/source/migration/migration.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_MIGRATION_HXX_
+#define _DESKTOP_MIGRATION_HXX_
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+namespace desktop {
+
+class Migration
+{
+public:
+ // starts the migration process
+ static void doMigration();
+ static void cancelMigration();
+ static sal_Bool checkMigration();
+ static rtl::OUString getOldVersionName();
+};
+}
+#endif
diff --git a/desktop/source/migration/migration_impl.hxx b/desktop/source/migration/migration_impl.hxx
new file mode 100644
index 000000000000..f73e44fea523
--- /dev/null
+++ b/desktop/source/migration/migration_impl.hxx
@@ -0,0 +1,252 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_MIGRATION_IMPL_HXX_
+#define _DESKTOP_MIGRATION_IMPL_HXX_
+
+#include <vector>
+#include <algorithm>
+#include <memory>
+#include <hash_map>
+
+#include "migration.hxx"
+
+#include <sal/types.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+
+#define NS_CSS com::sun::star
+#define NS_UNO com::sun::star::uno
+
+namespace desktop
+{
+
+struct install_info
+{
+ rtl::OUString productname; // human readeable product name
+ rtl::OUString userdata; // file: url for user installation
+};
+
+typedef std::vector< rtl::OUString > strings_v;
+typedef std::auto_ptr< strings_v > strings_vr;
+
+struct migration_step
+{
+ rtl::OUString name;
+ strings_v includeFiles;
+ strings_v excludeFiles;
+ strings_v includeConfig;
+ strings_v excludeConfig;
+ strings_v includeExtensions;
+ strings_v excludeExtensions;
+ rtl::OUString service;
+};
+
+struct supported_migration
+{
+ rtl::OUString name;
+ sal_Int32 nPriority;
+ strings_v supported_versions;
+};
+
+typedef std::vector< migration_step > migrations_v;
+typedef std::auto_ptr< migrations_v > migrations_vr;
+typedef std::vector< supported_migration > migrations_available;
+
+//__________________________________________
+/**
+ define the item, e.g.:menuitem, toolbaritem, to be migrated. we keep the information
+ of the command URL, the previous sibling node and the parent node of a item
+*/
+struct MigrationItem
+{
+ ::rtl::OUString m_sParentNodeName;
+ ::rtl::OUString m_sPrevSibling;
+ ::rtl::OUString m_sCommandURL;
+ NS_UNO::Reference< NS_CSS::container::XIndexContainer > m_xPopupMenu;
+
+ MigrationItem()
+ :m_xPopupMenu(0)
+ {
+ }
+
+ MigrationItem(const ::rtl::OUString& sParentNodeName,
+ const ::rtl::OUString& sPrevSibling,
+ const ::rtl::OUString& sCommandURL,
+ const NS_UNO::Reference< NS_CSS::container::XIndexContainer > xPopupMenu)
+ {
+ m_sParentNodeName = sParentNodeName;
+ m_sPrevSibling = sPrevSibling;
+ m_sCommandURL = sCommandURL;
+ m_xPopupMenu = xPopupMenu;
+ }
+
+ MigrationItem& operator=(const MigrationItem& aMigrationItem)
+ {
+ m_sParentNodeName = aMigrationItem.m_sParentNodeName;
+ m_sPrevSibling = aMigrationItem.m_sPrevSibling;
+ m_sCommandURL = aMigrationItem.m_sCommandURL;
+ m_xPopupMenu = aMigrationItem.m_xPopupMenu;
+
+ return *this;
+ }
+
+ sal_Bool operator==(const MigrationItem& aMigrationItem)
+ {
+ return ( aMigrationItem.m_sParentNodeName == m_sParentNodeName &&
+ aMigrationItem.m_sPrevSibling == m_sPrevSibling &&
+ aMigrationItem.m_sCommandURL == m_sCommandURL &&
+ aMigrationItem.m_xPopupMenu.is() == m_xPopupMenu.is() );
+ }
+
+ ::rtl::OUString GetPrevSibling() const { return m_sPrevSibling; }
+};
+
+typedef ::std::hash_map< ::rtl::OUString,
+ ::std::vector< MigrationItem >,
+ ::rtl::OUStringHash,
+ ::std::equal_to< ::rtl::OUString > > MigrationHashMap;
+
+struct MigrationItemInfo
+{
+ ::rtl::OUString m_sResourceURL;
+ MigrationItem m_aMigrationItem;
+
+ MigrationItemInfo(){}
+
+ MigrationItemInfo(const ::rtl::OUString& sResourceURL, const MigrationItem& aMigratiionItem)
+ {
+ m_sResourceURL = sResourceURL;
+ m_aMigrationItem = aMigratiionItem;
+ }
+};
+
+//__________________________________________
+/**
+ information for the UI elements to be migrated for one module
+*/
+struct MigrationModuleInfo
+{
+ ::rtl::OUString sModuleShortName;
+ sal_Bool bHasMenubar;
+ ::std::vector< ::rtl::OUString > m_vToolbars;
+
+ MigrationModuleInfo():bHasMenubar(sal_False){};
+};
+
+//__________________________________________
+/**
+ get the information before copying the ui configuration files of old version to new version
+*/
+class NewVersionUIInfo
+{
+public:
+
+ NS_UNO::Reference< NS_CSS::ui::XUIConfigurationManager > getConfigManager(const ::rtl::OUString& sModuleShortName) const;
+ NS_UNO::Reference< NS_CSS::container::XIndexContainer > getNewMenubarSettings(const ::rtl::OUString& sModuleShortName) const;
+ NS_UNO::Reference< NS_CSS::container::XIndexContainer > getNewToolbarSettings(const ::rtl::OUString& sModuleShortName, const ::rtl::OUString& sToolbarName) const;
+ void init(const ::std::vector< MigrationModuleInfo >& vModulesInfo);
+
+private:
+
+ NS_UNO::Sequence< NS_CSS::beans::PropertyValue > m_lCfgManagerSeq;
+ NS_UNO::Sequence< NS_CSS::beans::PropertyValue > m_lNewVersionMenubarSettingsSeq;
+ NS_UNO::Sequence< NS_CSS::beans::PropertyValue > m_lNewVersionToolbarSettingsSeq;
+};
+
+class MigrationImpl
+{
+
+private:
+ strings_vr m_vrVersions;
+ NS_UNO::Reference< NS_CSS::lang::XMultiServiceFactory > m_xFactory;
+
+ migrations_available m_vMigrationsAvailable; // list of all available migrations
+ migrations_vr m_vrMigrations; // list of all migration specs from config
+ install_info m_aInfo; // info about the version being migrated
+ strings_vr m_vrFileList; // final list of files to be copied
+ MigrationHashMap m_aOldVersionItemsHashMap;
+ MigrationHashMap m_aNewVersionItemsHashMap;
+ ::rtl::OUString m_sModuleIdentifier;
+
+ // functions to control the migration process
+ bool readAvailableMigrations(migrations_available&);
+ migrations_vr readMigrationSteps(const ::rtl::OUString& rMigrationName);
+ sal_Int32 findPreferedMigrationProcess(const migrations_available&);
+ install_info findInstallation(const strings_v& rVersions);
+ strings_vr compileFileList();
+
+ // helpers
+ void substract(strings_v& va, const strings_v& vb_c) const;
+ strings_vr getAllFiles(const rtl::OUString& baseURL) const;
+ strings_vr applyPatterns(const strings_v& vSet, const strings_v& vPatterns) const;
+ NS_UNO::Reference< NS_CSS::container::XNameAccess > getConfigAccess(const sal_Char* path, sal_Bool rw=sal_False);
+
+ ::std::vector< MigrationModuleInfo > dectectUIChangesForAllModules() const;
+ void compareOldAndNewConfig(const ::rtl::OUString& sParentNodeName,
+ const NS_UNO::Reference< NS_CSS::container::XIndexContainer >& xOldIndexContainer,
+ const NS_UNO::Reference< NS_CSS::container::XIndexContainer >& xNewIndexContainer,
+ const ::rtl::OUString& sToolbarName);
+ void mergeOldToNewVersion(const NS_UNO::Reference< NS_CSS::ui::XUIConfigurationManager >& xCfgManager,
+ const NS_UNO::Reference< NS_CSS::container::XIndexContainer>& xIndexContainer,
+ const ::rtl::OUString& sModuleIdentifier,
+ const ::rtl::OUString& sResourceURL);
+
+ // actual processing function that perform the migration steps
+ void copyFiles();
+ void copyConfig();
+ void runServices();
+ void refresh();
+
+ void setMigrationCompleted();
+ sal_Bool checkMigrationCompleted();
+
+public:
+ MigrationImpl(const NS_UNO::Reference< NS_CSS::lang::XMultiServiceFactory >&);
+ ~MigrationImpl();
+ sal_Bool doMigration();
+ sal_Bool checkMigration();
+ rtl::OUString getOldVersionName();
+
+
+};
+}
+#undef NS_CSS
+#undef NS_UNO
+
+#endif
diff --git a/desktop/source/migration/pages.cxx b/desktop/source/migration/pages.cxx
new file mode 100644
index 000000000000..53ec488c2082
--- /dev/null
+++ b/desktop/source/migration/pages.cxx
@@ -0,0 +1,673 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "pages.hxx"
+#include "wizard.hrc"
+#include "wizard.hxx"
+#include "migration.hxx"
+#include <vcl/msgbox.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vos/security.hxx>
+#include <app.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <unotools/bootstrap.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/regoptions.hxx>
+#include <unotools/useroptions.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <comphelper/configurationhelper.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.hxx>
+#include <unotools/bootstrap.hxx>
+#include <tools/config.hxx>
+
+using namespace rtl;
+using namespace osl;
+using namespace utl;
+using namespace svt;
+using namespace com::sun::star;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::util;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::container;
+
+#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace desktop {
+
+static void _setBold(FixedText& ft)
+{
+ Font f = ft.GetControlFont();
+ f.SetWeight(WEIGHT_BOLD);
+ ft.SetControlFont(f);
+}
+
+WelcomePage::WelcomePage( svt::OWizardMachine* parent, const ResId& resid, sal_Bool bLicenseNeedsAcceptance )
+ : OWizardPage(parent, resid)
+ , m_ftHead(this, WizardResId(FT_WELCOME_HEADER))
+ , m_ftBody(this, WizardResId(FT_WELCOME_BODY))
+ , m_pParent(parent)
+ , m_bLicenseNeedsAcceptance( bLicenseNeedsAcceptance )
+ , bIsEvalVersion(false)
+ , bNoEvalText(false)
+{
+ FreeResource();
+
+ _setBold(m_ftHead);
+
+ checkEval();
+
+ // check for migration
+ if (Migration::checkMigration())
+ {
+ String aText(WizardResId(STR_WELCOME_MIGRATION));
+ // replace %OLDPRODUCT with found version name
+ aText.SearchAndReplaceAll( UniString::CreateFromAscii("%OLD_VERSION"), Migration::getOldVersionName());
+ m_ftBody.SetText( aText );
+ }
+ else if ( ! m_bLicenseNeedsAcceptance )
+ {
+ String aText(WizardResId(STR_WELCOME_WITHOUT_LICENSE));
+ m_ftBody.SetText( aText );
+ }
+}
+
+
+void WelcomePage::checkEval()
+{
+ Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XMaterialHolder > xHolder(xFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.tab.tabreg")), UNO_QUERY);
+ if (xHolder.is()) {
+ Any aData = xHolder->getMaterial();
+ Sequence < NamedValue > aSeq;
+ if (aData >>= aSeq) {
+ bIsEvalVersion = true;
+ for (int i=0; i< aSeq.getLength(); i++) {
+ if (aSeq[i].Name.equalsAscii("NoEvalText")) {
+ aSeq[i].Value >>= bNoEvalText;
+ }
+ }
+ }
+ }
+}
+
+
+void WelcomePage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ // this page has no controls, so forwarding to default
+ // button (next) won't work if we grap focus
+ // GrabFocus();
+}
+
+LicensePage::LicensePage( svt::OWizardMachine* parent, const ResId& resid, const rtl::OUString &rLicensePath )
+ : OWizardPage(parent, resid)
+ , m_pParent(parent)
+ , m_ftHead(this, WizardResId(FT_LICENSE_HEADER))
+ , m_ftBody1(this, WizardResId(FT_LICENSE_BODY_1))
+ , m_ftBody1Txt(this, WizardResId(FT_LICENSE_BODY_1_TXT))
+ , m_ftBody2(this, WizardResId(FT_LICENSE_BODY_2))
+ , m_ftBody2Txt(this, WizardResId(FT_LICENSE_BODY_2_TXT))
+ , m_mlLicense(this, WizardResId(ML_LICENSE))
+ , m_pbDown(this, WizardResId(PB_LICENSE_DOWN))
+ , m_bLicenseRead(sal_False)
+{
+ FreeResource();
+
+ _setBold(m_ftHead);
+
+ m_mlLicense.SetEndReachedHdl( LINK(this, LicensePage, EndReachedHdl) );
+ m_mlLicense.SetScrolledHdl( LINK(this, LicensePage, ScrolledHdl) );
+ m_pbDown.SetClickHdl( LINK(this, LicensePage, PageDownHdl) );
+
+ // We want a automatic repeating page down button
+ WinBits aStyle = m_pbDown.GetStyle();
+ aStyle |= WB_REPEAT;
+ m_pbDown.SetStyle( aStyle );
+
+ // replace %PAGEDOWN in text2 with button text
+ String aText = m_ftBody1Txt.GetText();
+ aText.SearchAndReplaceAll( UniString::CreateFromAscii("%PAGEDOWN"),
+ MnemonicGenerator::EraseAllMnemonicChars(m_pbDown.GetText()));
+
+ m_ftBody1Txt.SetText( aText );
+
+ // load license text
+ File aLicenseFile(rLicensePath);
+ if ( aLicenseFile.open(OpenFlag_Read) == FileBase::E_None)
+ {
+ DirectoryItem d;
+ DirectoryItem::get(rLicensePath, d);
+ FileStatus fs(FileStatusMask_FileSize);
+ d.getFileStatus(fs);
+ sal_uInt64 nBytesRead = 0;
+ sal_uInt64 nPosition = 0;
+ sal_uInt32 nBytes = (sal_uInt32)fs.getFileSize();
+ sal_Char *pBuffer = new sal_Char[nBytes];
+ // FileBase RC r = FileBase::E_None;
+ while (aLicenseFile.read(pBuffer+nPosition, nBytes-nPosition, nBytesRead) == FileBase::E_None
+ && nPosition + nBytesRead < nBytes)
+ {
+ nPosition += nBytesRead;
+ }
+ OUString aLicenseString(pBuffer, nBytes, RTL_TEXTENCODING_UTF8,
+ OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE);
+ delete[] pBuffer;
+ m_mlLicense.SetText(aLicenseString);
+
+ }
+}
+
+void LicensePage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ m_bLicenseRead = m_mlLicense.IsEndReached();
+ m_pbDown.GrabFocus();
+ updateDialogTravelUI();
+}
+
+bool LicensePage::canAdvance() const
+{
+ if (m_mlLicense.IsEndReached())
+ const_cast< LicensePage* >( this )->m_pbDown.Disable();
+ else
+ const_cast< LicensePage* >( this )->m_pbDown.Enable();
+
+ return m_bLicenseRead;
+}
+
+IMPL_LINK( LicensePage, PageDownHdl, PushButton *, EMPTYARG )
+{
+ m_mlLicense.ScrollDown( SCROLL_PAGEDOWN );
+ return 0;
+}
+
+IMPL_LINK( LicensePage, EndReachedHdl, LicenseView *, EMPTYARG )
+{
+ m_bLicenseRead = TRUE;
+ updateDialogTravelUI();
+ return 0;
+}
+
+IMPL_LINK( LicensePage, ScrolledHdl, LicenseView *, EMPTYARG )
+{
+ updateDialogTravelUI();
+ return 0;
+}
+
+
+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 );
+ }
+ }
+}
+
+
+
+// -------------------------------------------------------------------
+
+class MigrationThread : public ::osl::Thread
+{
+ public:
+ MigrationThread();
+
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL onTerminated();
+};
+
+MigrationThread::MigrationThread()
+{
+}
+
+void MigrationThread::run()
+{
+ try
+ {
+ Migration::doMigration();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+}
+
+void MigrationThread::onTerminated()
+{
+}
+
+// -------------------------------------------------------------------
+
+MigrationPage::MigrationPage(
+ svt::OWizardMachine* parent,
+ const ResId& resid,
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XThrobber > xThrobber)
+ : OWizardPage(parent, resid)
+ , m_ftHead(this, WizardResId(FT_MIGRATION_HEADER))
+ , m_ftBody(this, WizardResId(FT_MIGRATION_BODY))
+ , m_cbMigration(this, WizardResId(CB_MIGRATION))
+ , m_bMigrationDone(sal_False)
+ , m_xThrobber(xThrobber)
+{
+ FreeResource();
+ _setBold(m_ftHead);
+
+ // replace %OLDPRODUCT with found version name
+ String aText = m_ftBody.GetText();
+ aText.SearchAndReplaceAll( UniString::CreateFromAscii("%OLDPRODUCT"), Migration::getOldVersionName());
+ m_ftBody.SetText( aText );
+}
+
+sal_Bool MigrationPage::commitPage( svt::WizardTypes::CommitPageReason _eReason )
+{
+ if (_eReason == svt::WizardTypes::eTravelForward && m_cbMigration.IsChecked() && !m_bMigrationDone)
+ {
+ GetParent()->EnterWait();
+ FirstStartWizard* pWizard = dynamic_cast< FirstStartWizard* >( GetParent() );
+ if ( pWizard )
+ pWizard->DisableButtonsWhileMigration();
+
+ uno::Reference< awt::XWindow > xWin( m_xThrobber, uno::UNO_QUERY );
+ xWin->setVisible( true );
+ m_xThrobber->start();
+ MigrationThread* pMigThread = new MigrationThread();
+ pMigThread->create();
+
+ while ( pMigThread->isRunning() )
+ {
+ Application::Reschedule();
+ }
+
+ m_xThrobber->stop();
+ GetParent()->LeaveWait();
+ // Next state will enable buttons - so no EnableButtons necessary!
+ xWin->setVisible( false );
+ pMigThread->join();
+ delete pMigThread;
+ m_bMigrationDone = sal_True;
+ }
+ else
+ Migration::cancelMigration();
+ return sal_True;
+}
+
+void MigrationPage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ GrabFocus();
+}
+
+UserPage::UserPage( svt::OWizardMachine* parent, const ResId& resid)
+ : OWizardPage(parent, resid)
+ , m_ftHead(this, WizardResId(FT_USER_HEADER))
+ , m_ftBody(this, WizardResId(FT_USER_BODY))
+ , m_ftFirst(this, WizardResId(FT_USER_FIRST))
+ , m_edFirst(this, WizardResId(ED_USER_FIRST))
+ , m_ftLast(this, WizardResId(FT_USER_LAST))
+ , m_edLast(this, WizardResId(ED_USER_LAST))
+ , m_ftInitials(this, WizardResId(FT_USER_INITIALS))
+ , m_edInitials(this, WizardResId(ED_USER_INITIALS))
+ , m_ftFather(this, WizardResId(FT_USER_FATHER))
+ , m_edFather(this, WizardResId(ED_USER_FATHER))
+ , m_lang(Application::GetSettings().GetUILanguage())
+{
+ FreeResource();
+ _setBold(m_ftHead);
+
+ // check whether this is a russian version. otherwise
+ // we'll hide the 'Fathers name' field
+ SvtUserOptions aUserOpt;
+ m_edFirst.SetText(aUserOpt.GetFirstName());
+ m_edLast.SetText(aUserOpt.GetLastName());
+#if 0
+ rtl::OUString aUserName;
+ vos::OSecurity().getUserName( aUserName );
+ aUserOpt.SetID( aUserName );
+#endif
+
+ m_edInitials.SetText(aUserOpt.GetID());
+ if (m_lang == LANGUAGE_RUSSIAN)
+ {
+ m_ftFather.Show();
+ m_edFather.Show();
+ m_edFather.SetText(aUserOpt.GetFathersName());
+ }
+}
+
+sal_Bool UserPage::commitPage( svt::WizardTypes::CommitPageReason )
+{
+ SvtUserOptions aUserOpt;
+ aUserOpt.SetFirstName(m_edFirst.GetText());
+ aUserOpt.SetLastName(m_edLast.GetText());
+ aUserOpt.SetID( m_edInitials.GetText());
+
+ if (m_lang == LANGUAGE_RUSSIAN)
+ aUserOpt.SetFathersName(m_edFather.GetText());
+
+ return sal_True;
+}
+
+void UserPage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ GrabFocus();
+}
+
+// -------------------------------------------------------------------
+UpdateCheckPage::UpdateCheckPage( svt::OWizardMachine* parent, const ResId& resid)
+ : OWizardPage(parent, resid)
+ , m_ftHead(this, WizardResId(FT_UPDATE_CHECK_HEADER))
+ , m_ftBody(this, WizardResId(FT_UPDATE_CHECK_BODY))
+ , m_cbUpdateCheck(this, WizardResId(CB_UPDATE_CHECK))
+{
+ FreeResource();
+ _setBold(m_ftHead);
+}
+
+sal_Bool UpdateCheckPage::commitPage( svt::WizardTypes::CommitPageReason _eReason )
+{
+ if ( _eReason == svt::WizardTypes::eTravelForward )
+ {
+ try {
+ Reference < XNameReplace > xUpdateAccess;
+ Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+
+ xUpdateAccess = Reference < XNameReplace >(
+ xFactory->createInstance( UNISTRING( "com.sun.star.setup.UpdateCheckConfig" ) ), UNO_QUERY_THROW );
+
+ if ( !xUpdateAccess.is() )
+ return sal_False;
+
+ sal_Bool bAutoUpdChk = m_cbUpdateCheck.IsChecked();
+ xUpdateAccess->replaceByName( UNISTRING("AutoCheckEnabled"), makeAny( bAutoUpdChk ) );
+
+ Reference< XChangesBatch > xChangesBatch( xUpdateAccess, UNO_QUERY);
+ if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
+ xChangesBatch->commitChanges();
+ } catch (RuntimeException)
+ {
+ }
+ }
+
+ return sal_True;
+}
+
+void UpdateCheckPage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ GrabFocus();
+}
+
+// -------------------------------------------------------------------
+RegistrationPage::RegistrationPage( Window* pParent, const ResId& rResid )
+ : OWizardPage( pParent, rResid )
+ , m_ftHeader(this, WizardResId(FT_REGISTRATION_HEADER))
+ , m_ftBody(this, WizardResId(FT_REGISTRATION_BODY))
+ , m_rbNow(this, WizardResId(RB_REGISTRATION_NOW))
+ , m_rbLater(this, WizardResId(RB_REGISTRATION_LATER))
+ , m_rbNever(this, WizardResId(RB_REGISTRATION_NEVER))
+ , m_flSeparator(this, WizardResId(FL_REGISTRATION))
+ , m_ftEnd(this, WizardResId(FT_REGISTRATION_END))
+ , m_bNeverVisible( sal_True )
+{
+ FreeResource();
+
+ // another text for OOo
+ sal_Int32 nOpenSourceContext = 0;
+ try
+ {
+ ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::OPENSOURCECONTEXT ) >>= nOpenSourceContext;
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "RegistrationPage::RegistrationPage(): error while getting open source context" );
+ }
+
+ if ( nOpenSourceContext > 0 )
+ {
+ String sBodyText( WizardResId( STR_REGISTRATION_OOO ) );
+ m_ftBody.SetText( sBodyText );
+ }
+
+ // calculate height of body text and rearrange the buttons
+ Size aSize = m_ftBody.GetSizePixel();
+ Size aMinSize = m_ftBody.CalcMinimumSize( aSize.Width() );
+ long nTxtH = aMinSize.Height();
+ long nCtrlH = aSize.Height();
+ long nDelta = ( nCtrlH - nTxtH );
+ aSize.Height() -= nDelta;
+ m_ftBody.SetSizePixel( aSize );
+ Window* pWins[] = { &m_rbNow, &m_rbLater, &m_rbNever };
+ Window** pCurrent = pWins;
+ for ( sal_uInt32 i = 0; i < sizeof( pWins ) / sizeof( pWins[ 0 ] ); ++i, ++pCurrent )
+ {
+ Point aNewPos = (*pCurrent)->GetPosPixel();
+ aNewPos.Y() -= nDelta;
+ (*pCurrent)->SetPosPixel( aNewPos );
+ }
+
+ _setBold(m_ftHeader);
+ impl_retrieveConfigurationData();
+ updateButtonStates();
+}
+
+bool RegistrationPage::canAdvance() const
+{
+ return false;
+}
+
+void RegistrationPage::ActivatePage()
+{
+ OWizardPage::ActivatePage();
+ GrabFocus();
+}
+
+void RegistrationPage::impl_retrieveConfigurationData()
+{
+ static ::rtl::OUString PACKAGE = ::rtl::OUString::createFromAscii("org.openoffice.FirstStartWizard");
+ static ::rtl::OUString PATH = ::rtl::OUString::createFromAscii("TabPages/Registration/RegistrationOptions/NeverButton");
+ static ::rtl::OUString KEY = ::rtl::OUString::createFromAscii("Visible");
+
+ ::com::sun::star::uno::Any aValue;
+ try
+ {
+ aValue = ::comphelper::ConfigurationHelper::readDirectKey(
+ ::comphelper::getProcessServiceFactory(),
+ PACKAGE,
+ PATH,
+ KEY,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ }
+ catch(const ::com::sun::star::uno::Exception&)
+ { aValue.clear(); }
+
+ aValue >>= m_bNeverVisible;
+}
+
+void RegistrationPage::updateButtonStates()
+{
+ m_rbNever.Show( m_bNeverVisible );
+}
+
+sal_Bool RegistrationPage::commitPage( svt::WizardTypes::CommitPageReason _eReason )
+{
+ if ( _eReason == svt::WizardTypes::eFinish )
+ {
+ ::utl::RegOptions aOptions;
+ rtl::OUString aEvent;
+
+ if ( m_rbNow.IsChecked())
+ {
+ aEvent = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RegistrationRequired" ) );
+ }
+ else if (m_rbLater.IsChecked())
+ {
+ aOptions.activateReminder(7);
+ // avtivate a reminder job...
+ }
+ // aOptions.markSessionDone();
+
+ try
+ {
+ // create the Desktop component which can load components
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ if( xFactory.is() )
+ {
+ Reference< com::sun::star::task::XJobExecutor > xProductRegistration(
+ xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.setup.ProductRegistration" ) ) ),
+ UNO_QUERY_THROW );
+
+ // tell it that the user wants to register
+ xProductRegistration->trigger( aEvent );
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+ }
+ return sal_True;
+}
+
+RegistrationPage::RegistrationMode RegistrationPage::getRegistrationMode() const
+{
+ RegistrationPage::RegistrationMode eMode = rmNow;
+ if ( m_rbLater.IsChecked() )
+ eMode = rmLater;
+ else if ( m_rbNever.IsChecked() )
+ eMode = rmNever;
+ return eMode;
+}
+
+void RegistrationPage::prepareSingleMode()
+{
+ // remove wizard text (hide and cut)
+ m_flSeparator.Hide();
+ m_ftEnd.Hide();
+ Size aNewSize = GetSizePixel();
+ aNewSize.Height() -= ( aNewSize.Height() - m_flSeparator.GetPosPixel().Y() );
+ SetSizePixel( aNewSize );
+}
+
+bool RegistrationPage::hasReminderDateCome()
+{
+ return ::utl::RegOptions().hasReminderDateCome();
+}
+
+void RegistrationPage::executeSingleMode()
+{
+ // opens the page in a single tabdialog
+ SfxSingleTabDialog aSingleDlg( NULL, TP_REGISTRATION );
+ RegistrationPage* pPage = new RegistrationPage( &aSingleDlg, WizardResId( TP_REGISTRATION ) );
+ pPage->prepareSingleMode();
+ aSingleDlg.SetPage( pPage );
+ aSingleDlg.SetText( pPage->getSingleModeTitle() );
+ aSingleDlg.Execute();
+ // the registration modes "Now" and "Later" are handled by the page
+ RegistrationPage::RegistrationMode eMode = pPage->getRegistrationMode();
+ if ( eMode == RegistrationPage::rmNow || eMode == RegistrationPage::rmLater )
+ pPage->commitPage( WizardTypes::eFinish );
+ if ( eMode != RegistrationPage::rmLater )
+ ::utl::RegOptions().removeReminder();
+}
+
+} // namespace desktop
diff --git a/desktop/source/migration/pages.hxx b/desktop/source/migration/pages.hxx
new file mode 100644
index 000000000000..776268eb475c
--- /dev/null
+++ b/desktop/source/migration/pages.hxx
@@ -0,0 +1,214 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _PAGES_HXX_
+#define _PAGES_HXX_
+
+#include <vcl/tabpage.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/button.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/scrbar.hxx>
+#include <svtools/wizardmachine.hxx>
+#include <svtools/svmedit.hxx>
+#include <svl/lstner.hxx>
+#include <svtools/xtextedt.hxx>
+
+#include <com/sun/star/awt/XThrobber.hpp>
+
+namespace desktop
+{
+class WelcomePage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHead;
+ FixedText m_ftBody;
+ svt::OWizardMachine *m_pParent;
+ sal_Bool m_bLicenseNeedsAcceptance;
+ enum OEMType
+ {
+ OEM_NONE, OEM_NORMAL, OEM_EXTENDED
+ };
+ bool bIsEvalVersion;
+ bool bNoEvalText;
+ void checkEval();
+
+
+public:
+ WelcomePage( svt::OWizardMachine* parent, const ResId& resid, sal_Bool bLicenseNeedsAcceptance );
+protected:
+ virtual void ActivatePage();
+};
+
+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;
+};
+
+class LicensePage : public svt::OWizardPage
+{
+private:
+ svt::OWizardMachine *m_pParent;
+ FixedText m_ftHead;
+ FixedText m_ftBody1;
+ FixedText m_ftBody1Txt;
+ FixedText m_ftBody2;
+ FixedText m_ftBody2Txt;
+ LicenseView m_mlLicense;
+ PushButton m_pbDown;
+ sal_Bool m_bLicenseRead;
+public:
+ LicensePage( svt::OWizardMachine* parent, const ResId& resid, const rtl::OUString &rLicensePath );
+private:
+ DECL_LINK(PageDownHdl, PushButton*);
+ DECL_LINK(EndReachedHdl, LicenseView*);
+ DECL_LINK(ScrolledHdl, LicenseView*);
+protected:
+ virtual bool canAdvance() const;
+ virtual void ActivatePage();
+};
+
+class MigrationPage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHead;
+ FixedText m_ftBody;
+ CheckBox m_cbMigration;
+ sal_Bool m_bMigrationDone;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XThrobber > m_xThrobber;
+public:
+ MigrationPage( svt::OWizardMachine* parent, const ResId& resid, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XThrobber > xThrobber );
+ virtual sal_Bool commitPage( svt::WizardTypes::CommitPageReason _eReason );
+
+protected:
+ virtual void ActivatePage();
+};
+
+class UserPage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHead;
+ FixedText m_ftBody;
+ FixedText m_ftFirst;
+ Edit m_edFirst;
+ FixedText m_ftLast;
+ Edit m_edLast;
+ FixedText m_ftInitials;
+ Edit m_edInitials;
+ FixedText m_ftFather;
+ Edit m_edFather;
+ LanguageType m_lang;
+
+public:
+ UserPage( svt::OWizardMachine* parent, const ResId& resid);
+ virtual sal_Bool commitPage( svt::WizardTypes::CommitPageReason _eReason );
+protected:
+ virtual void ActivatePage();
+};
+
+class UpdateCheckPage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHead;
+ FixedText m_ftBody;
+ CheckBox m_cbUpdateCheck;
+public:
+ UpdateCheckPage( svt::OWizardMachine* parent, const ResId& resid);
+ virtual sal_Bool commitPage( svt::WizardTypes::CommitPageReason _eReason );
+
+protected:
+ virtual void ActivatePage();
+};
+
+
+class RegistrationPage : public svt::OWizardPage
+{
+private:
+ FixedText m_ftHeader;
+ FixedText m_ftBody;
+ RadioButton m_rbNow;
+ RadioButton m_rbLater;
+ RadioButton m_rbNever;
+ FixedLine m_flSeparator;
+ FixedText m_ftEnd;
+
+ sal_Bool m_bNeverVisible;
+
+ void updateButtonStates();
+ void impl_retrieveConfigurationData();
+
+protected:
+ virtual bool canAdvance() const;
+ virtual void ActivatePage();
+
+ virtual sal_Bool commitPage( svt::WizardTypes::CommitPageReason _eReason );
+
+public:
+ RegistrationPage( Window* parent, const ResId& resid);
+
+ enum RegistrationMode
+ {
+ rmNow, // register now
+ rmLater, // register later
+ rmNever // register never
+ };
+
+ RegistrationMode getRegistrationMode() const;
+ void prepareSingleMode();
+ inline String getSingleModeTitle() const { return m_ftHeader.GetText(); }
+
+ static bool hasReminderDateCome();
+ static void executeSingleMode();
+};
+
+} // namespace desktop
+
+#endif // #ifndef _PAGES_HXX_
+
diff --git a/desktop/source/migration/services/autocorrmigration.cxx b/desktop/source/migration/services/autocorrmigration.cxx
new file mode 100644
index 000000000000..c416992da13c
--- /dev/null
+++ b/desktop/source/migration/services/autocorrmigration.cxx
@@ -0,0 +1,285 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "autocorrmigration.hxx"
+#include <i18npool/mslangid.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/bootstrap.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+
+ static ::rtl::OUString sSourceSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/autocorr" ) );
+ static ::rtl::OUString sTargetSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/autocorr" ) );
+ static ::rtl::OUString sBaseName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/acor" ) );
+ static ::rtl::OUString sSuffix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".dat" ) );
+
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ ::rtl::OUString AutocorrectionMigration_getImplementationName()
+ {
+ static ::rtl::OUString* pImplName = 0;
+ if ( !pImplName )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pImplName )
+ {
+ static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.Autocorrection" ) );
+ pImplName = &aImplName;
+ }
+ }
+ return *pImplName;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > AutocorrectionMigration_getSupportedServiceNames()
+ {
+ static Sequence< ::rtl::OUString >* pNames = 0;
+ if ( !pNames )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pNames )
+ {
+ static Sequence< ::rtl::OUString > aNames(1);
+ aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Autocorrection" ) );
+ pNames = &aNames;
+ }
+ }
+ return *pNames;
+ }
+
+ // =============================================================================
+ // AutocorrectionMigration
+ // =============================================================================
+
+ AutocorrectionMigration::AutocorrectionMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ AutocorrectionMigration::~AutocorrectionMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ TStringVectorPtr AutocorrectionMigration::getFiles( const ::rtl::OUString& rBaseURL ) const
+ {
+ TStringVectorPtr aResult( new TStringVector );
+ ::osl::Directory aDir( rBaseURL);
+
+ if ( aDir.open() == ::osl::FileBase::E_None )
+ {
+ // iterate over directory content
+ TStringVector aSubDirs;
+ ::osl::DirectoryItem aItem;
+ while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None )
+ {
+ ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
+ if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None )
+ {
+ if ( aFileStatus.getFileType() == ::osl::FileStatus::Directory )
+ aSubDirs.push_back( aFileStatus.getFileURL() );
+ else
+ aResult->push_back( aFileStatus.getFileURL() );
+ }
+ }
+
+ // iterate recursive over subfolders
+ TStringVector::const_iterator aI = aSubDirs.begin();
+ while ( aI != aSubDirs.end() )
+ {
+ TStringVectorPtr aSubResult = getFiles( *aI );
+ aResult->insert( aResult->end(), aSubResult->begin(), aSubResult->end() );
+ ++aI;
+ }
+ }
+
+ return aResult;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ ::osl::FileBase::RC AutocorrectionMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
+ {
+ ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ if ( aResult == ::osl::FileBase::E_NOENT )
+ {
+ INetURLObject aBaseURL( rDirURL );
+ aBaseURL.removeSegment();
+ checkAndCreateDirectory( aBaseURL );
+ return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+ else
+ {
+ return aResult;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+
+ void AutocorrectionMigration::copyFiles()
+ {
+ ::rtl::OUString sTargetDir;
+ ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( sTargetDir );
+ if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
+ {
+ sTargetDir += sTargetSubDir;
+ TStringVectorPtr aFileList = getFiles( m_sSourceDir );
+ TStringVector::const_iterator aI = aFileList->begin();
+ while ( aI != aFileList->end() )
+ {
+ ::rtl::OUString sSourceLocalName = aI->copy( m_sSourceDir.getLength() );
+ sal_Int32 nStart = sBaseName.getLength();
+ sal_Int32 nEnd = sSourceLocalName.lastIndexOf ( sSuffix );
+ ::rtl::OUString sLanguageType = sSourceLocalName.copy( nStart, nEnd - nStart );
+ ::rtl::OUString sIsoName = MsLangId::convertLanguageToIsoString( (LanguageType) sLanguageType.toInt32() );
+ ::rtl::OUString sTargetLocalName = sBaseName;
+ sTargetLocalName += ::rtl::OUString::createFromAscii( "_" );
+ sTargetLocalName += sIsoName;
+ sTargetLocalName += sSuffix;
+ ::rtl::OUString sTargetName = sTargetDir + sTargetLocalName;
+ INetURLObject aURL( sTargetName );
+ aURL.removeSegment();
+ checkAndCreateDirectory( aURL );
+ ::osl::FileBase::RC aResult = ::osl::File::copy( *aI, sTargetName );
+ if ( aResult != ::osl::FileBase::E_None )
+ {
+ ::rtl::OString aMsg( "AutocorrectionMigration::copyFiles: cannot copy " );
+ aMsg += ::rtl::OUStringToOString( *aI, RTL_TEXTENCODING_UTF8 ) + " to "
+ + ::rtl::OUStringToOString( sTargetName, RTL_TEXTENCODING_UTF8 );
+ OSL_ENSURE( sal_False, aMsg.getStr() );
+ }
+ ++aI;
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "AutocorrectionMigration::copyFiles: no user installation!" );
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XServiceInfo
+ // -----------------------------------------------------------------------------
+
+ ::rtl::OUString AutocorrectionMigration::getImplementationName() throw (RuntimeException)
+ {
+ return AutocorrectionMigration_getImplementationName();
+ }
+
+ // -----------------------------------------------------------------------------
+
+ sal_Bool AutocorrectionMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pNames + aNames.getLength();
+ for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
+ ;
+
+ return pNames != pEnd;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > AutocorrectionMigration::getSupportedServiceNames() throw (RuntimeException)
+ {
+ return AutocorrectionMigration_getSupportedServiceNames();
+ }
+
+ // -----------------------------------------------------------------------------
+ // XInitialization
+ // -----------------------------------------------------------------------------
+
+ void AutocorrectionMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const Any* pIter = aArguments.getConstArray();
+ const Any* pEnd = pIter + aArguments.getLength();
+ for ( ; pIter != pEnd ; ++pIter )
+ {
+ beans::NamedValue aValue;
+ *pIter >>= aValue;
+ if ( aValue.Name.equalsAscii( "UserData" ) )
+ {
+ if ( !(aValue.Value >>= m_sSourceDir) )
+ {
+ OSL_ENSURE( false, "AutocorrectionMigration::initialize: argument UserData has wrong type!" );
+ }
+ m_sSourceDir += sSourceSubDir;
+ break;
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XJob
+ // -----------------------------------------------------------------------------
+
+ Any AutocorrectionMigration::execute( const Sequence< beans::NamedValue >& )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ copyFiles();
+
+ return Any();
+ }
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ Reference< XInterface > SAL_CALL AutocorrectionMigration_create(
+ Reference< XComponentContext > const & )
+ SAL_THROW( () )
+ {
+ return static_cast< lang::XTypeProvider * >( new AutocorrectionMigration() );
+ }
+
+ // -----------------------------------------------------------------------------
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
diff --git a/desktop/source/migration/services/autocorrmigration.hxx b/desktop/source/migration/services/autocorrmigration.hxx
new file mode 100644
index 000000000000..715baa6bca12
--- /dev/null
+++ b/desktop/source/migration/services/autocorrmigration.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_AUTOCORRMIGRATION_HXX_
+#define _DESKTOP_AUTOCORRMIGRATION_HXX_
+
+#include "misc.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+
+
+class INetURLObject;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+ ::rtl::OUString SAL_CALL AutocorrectionMigration_getImplementationName();
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL AutocorrectionMigration_getSupportedServiceNames();
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL AutocorrectionMigration_create(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) );
+
+
+ // =============================================================================
+ // class AutocorrectionMigration
+ // =============================================================================
+
+ typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::task::XJob > AutocorrectionMigration_BASE;
+
+ class AutocorrectionMigration : public AutocorrectionMigration_BASE
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_sSourceDir;
+
+ TStringVectorPtr getFiles( const ::rtl::OUString& rBaseURL ) const;
+ ::osl::FileBase::RC checkAndCreateDirectory( INetURLObject& rDirURL );
+ void copyFiles();
+
+ public:
+ AutocorrectionMigration();
+ virtual ~AutocorrectionMigration();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_AUTOCORRMIGRATION_HXX_
diff --git a/desktop/source/migration/services/basicmigration.cxx b/desktop/source/migration/services/basicmigration.cxx
new file mode 100644
index 000000000000..3e7384f2262f
--- /dev/null
+++ b/desktop/source/migration/services/basicmigration.cxx
@@ -0,0 +1,274 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "basicmigration.hxx"
+#include <tools/urlobj.hxx>
+#include <unotools/bootstrap.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+
+ static ::rtl::OUString sSourceUserBasic = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/basic" ) );
+ static ::rtl::OUString sTargetUserBasic = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/__basic_80" ) );
+
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ ::rtl::OUString BasicMigration_getImplementationName()
+ {
+ static ::rtl::OUString* pImplName = 0;
+ if ( !pImplName )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pImplName )
+ {
+ static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.Basic" ) );
+ pImplName = &aImplName;
+ }
+ }
+ return *pImplName;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > BasicMigration_getSupportedServiceNames()
+ {
+ static Sequence< ::rtl::OUString >* pNames = 0;
+ if ( !pNames )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pNames )
+ {
+ static Sequence< ::rtl::OUString > aNames(1);
+ aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Basic" ) );
+ pNames = &aNames;
+ }
+ }
+ return *pNames;
+ }
+
+ // =============================================================================
+ // BasicMigration
+ // =============================================================================
+
+ BasicMigration::BasicMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ BasicMigration::~BasicMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ TStringVectorPtr BasicMigration::getFiles( const ::rtl::OUString& rBaseURL ) const
+ {
+ TStringVectorPtr aResult( new TStringVector );
+ ::osl::Directory aDir( rBaseURL);
+
+ if ( aDir.open() == ::osl::FileBase::E_None )
+ {
+ // iterate over directory content
+ TStringVector aSubDirs;
+ ::osl::DirectoryItem aItem;
+ while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None )
+ {
+ ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
+ if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None )
+ {
+ if ( aFileStatus.getFileType() == ::osl::FileStatus::Directory )
+ aSubDirs.push_back( aFileStatus.getFileURL() );
+ else
+ aResult->push_back( aFileStatus.getFileURL() );
+ }
+ }
+
+ // iterate recursive over subfolders
+ TStringVector::const_iterator aI = aSubDirs.begin();
+ while ( aI != aSubDirs.end() )
+ {
+ TStringVectorPtr aSubResult = getFiles( *aI );
+ aResult->insert( aResult->end(), aSubResult->begin(), aSubResult->end() );
+ ++aI;
+ }
+ }
+
+ return aResult;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ ::osl::FileBase::RC BasicMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
+ {
+ ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ if ( aResult == ::osl::FileBase::E_NOENT )
+ {
+ INetURLObject aBaseURL( rDirURL );
+ aBaseURL.removeSegment();
+ checkAndCreateDirectory( aBaseURL );
+ return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+ else
+ {
+ return aResult;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+
+ void BasicMigration::copyFiles()
+ {
+ ::rtl::OUString sTargetDir;
+ ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( sTargetDir );
+ if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
+ {
+ sTargetDir += sTargetUserBasic;
+ TStringVectorPtr aFileList = getFiles( m_sSourceDir );
+ TStringVector::const_iterator aI = aFileList->begin();
+ while ( aI != aFileList->end() )
+ {
+ ::rtl::OUString sLocalName = aI->copy( m_sSourceDir.getLength() );
+ ::rtl::OUString sTargetName = sTargetDir + sLocalName;
+ INetURLObject aURL( sTargetName );
+ aURL.removeSegment();
+ checkAndCreateDirectory( aURL );
+ ::osl::FileBase::RC aResult = ::osl::File::copy( *aI, sTargetName );
+ if ( aResult != ::osl::FileBase::E_None )
+ {
+ ::rtl::OString aMsg( "BasicMigration::copyFiles: cannot copy " );
+ aMsg += ::rtl::OUStringToOString( *aI, RTL_TEXTENCODING_UTF8 ) + " to "
+ + ::rtl::OUStringToOString( sTargetName, RTL_TEXTENCODING_UTF8 );
+ OSL_ENSURE( sal_False, aMsg.getStr() );
+ }
+ ++aI;
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "BasicMigration::copyFiles: no user installation!" );
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XServiceInfo
+ // -----------------------------------------------------------------------------
+
+ ::rtl::OUString BasicMigration::getImplementationName() throw (RuntimeException)
+ {
+ return BasicMigration_getImplementationName();
+ }
+
+ // -----------------------------------------------------------------------------
+
+ sal_Bool BasicMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pNames + aNames.getLength();
+ for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
+ ;
+
+ return pNames != pEnd;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > BasicMigration::getSupportedServiceNames() throw (RuntimeException)
+ {
+ return BasicMigration_getSupportedServiceNames();
+ }
+
+ // -----------------------------------------------------------------------------
+ // XInitialization
+ // -----------------------------------------------------------------------------
+
+ void BasicMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const Any* pIter = aArguments.getConstArray();
+ const Any* pEnd = pIter + aArguments.getLength();
+ for ( ; pIter != pEnd ; ++pIter )
+ {
+ beans::NamedValue aValue;
+ *pIter >>= aValue;
+ if ( aValue.Name.equalsAscii( "UserData" ) )
+ {
+ if ( !(aValue.Value >>= m_sSourceDir) )
+ {
+ OSL_ENSURE( false, "BasicMigration::initialize: argument UserData has wrong type!" );
+ }
+ m_sSourceDir += sSourceUserBasic;
+ break;
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XJob
+ // -----------------------------------------------------------------------------
+
+ Any BasicMigration::execute( const Sequence< beans::NamedValue >& )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ copyFiles();
+
+ return Any();
+ }
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ Reference< XInterface > SAL_CALL BasicMigration_create(
+ Reference< XComponentContext > const & )
+ SAL_THROW( () )
+ {
+ return static_cast< lang::XTypeProvider * >( new BasicMigration() );
+ }
+
+ // -----------------------------------------------------------------------------
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
diff --git a/desktop/source/migration/services/basicmigration.hxx b/desktop/source/migration/services/basicmigration.hxx
new file mode 100644
index 000000000000..9b6433ba88e8
--- /dev/null
+++ b/desktop/source/migration/services/basicmigration.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_BASICMIGRATION_HXX_
+#define _DESKTOP_BASICMIGRATION_HXX_
+
+#include "misc.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+
+
+class INetURLObject;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+ ::rtl::OUString SAL_CALL BasicMigration_getImplementationName();
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL BasicMigration_getSupportedServiceNames();
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL BasicMigration_create(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) );
+
+
+ // =============================================================================
+ // class BasicMigration
+ // =============================================================================
+
+ typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::task::XJob > BasicMigration_BASE;
+
+ class BasicMigration : public BasicMigration_BASE
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_sSourceDir;
+
+ TStringVectorPtr getFiles( const ::rtl::OUString& rBaseURL ) const;
+ ::osl::FileBase::RC checkAndCreateDirectory( INetURLObject& rDirURL );
+ void copyFiles();
+
+ public:
+ BasicMigration();
+ virtual ~BasicMigration();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_BASICMIGRATION_HXX_
diff --git a/desktop/source/migration/services/cexports.cxx b/desktop/source/migration/services/cexports.cxx
new file mode 100644
index 000000000000..cf9a9ab30b0c
--- /dev/null
+++ b/desktop/source/migration/services/cexports.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/implementationentry.hxx"
+#include "basicmigration.hxx"
+#include "wordbookmigration.hxx"
+//#include "extensionmigration.hxx"
+
+extern "C"
+{
+
+::cppu::ImplementationEntry entries [] =
+{
+ {
+ migration::BasicMigration_create, migration::BasicMigration_getImplementationName,
+ migration::BasicMigration_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ {
+ migration::WordbookMigration_create, migration::WordbookMigration_getImplementationName,
+ migration::WordbookMigration_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+// {
+// migration::ExtensionMigration_create, migration::ExtensionMigration_getImplementationName,
+// migration::ExtensionMigration_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+// 0, 0
+// },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_writeInfoHelper(
+ pServiceManager, pRegistryKey, entries );
+}
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, entries );
+}
+
+}
diff --git a/desktop/source/migration/services/cexportsoo3.cxx b/desktop/source/migration/services/cexportsoo3.cxx
new file mode 100755
index 000000000000..20b8232044e9
--- /dev/null
+++ b/desktop/source/migration/services/cexportsoo3.cxx
@@ -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: cexports.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/implementationentry.hxx"
+#include "oo3extensionmigration.hxx"
+
+extern "C"
+{
+
+::cppu::ImplementationEntry entries [] =
+{
+ {
+ migration::OO3ExtensionMigration_create, migration::OO3ExtensionMigration_getImplementationName,
+ migration::OO3ExtensionMigration_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_writeInfoHelper(
+ pServiceManager, pRegistryKey, entries );
+}
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, entries );
+}
+
+}
diff --git a/desktop/source/migration/services/cppumaker.mk b/desktop/source/migration/services/cppumaker.mk
new file mode 100644
index 000000000000..5ab16ed1e3fe
--- /dev/null
+++ b/desktop/source/migration/services/cppumaker.mk
@@ -0,0 +1,36 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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 "$(debug)" != ""
+
+# MSVC++: no inlining
+.IF "$(COM)" == "MSC"
+CFLAGS += -Ob0
+.ENDIF
+
+.ENDIF
+
diff --git a/desktop/source/migration/services/jvmfwk.cxx b/desktop/source/migration/services/jvmfwk.cxx
new file mode 100644
index 000000000000..381b6cb378c1
--- /dev/null
+++ b/desktop/source/migration/services/jvmfwk.cxx
@@ -0,0 +1,529 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/implbase4.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "rtl/bootstrap.hxx"
+#include "sal/types.h"
+#include "sal/config.h"
+#include "boost/scoped_array.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/task/XJob.hpp"
+#include "com/sun/star/configuration/backend/XLayer.hpp"
+#include "com/sun/star/configuration/backend/XLayerHandler.hpp"
+#include "com/sun/star/configuration/backend/MalformedDataException.hpp"
+#include "com/sun/star/configuration/backend/TemplateIdentifier.hpp"
+#include "jvmfwk/framework.h"
+#include "jvmfwk.hxx"
+#include <stack>
+#include <stdio.h>
+
+#include "osl/thread.hxx"
+#define OUSTR(x) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x ))
+
+#define SERVICE_NAME "com.sun.star.migration.Java"
+#define IMPL_NAME "com.sun.star.comp.desktop.migration.Java"
+
+#define ENABLE_JAVA 1
+#define USER_CLASS_PATH 2
+
+namespace css = com::sun::star;
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::configuration::backend;
+
+namespace migration
+{
+
+class CJavaInfo
+{
+ CJavaInfo(const CJavaInfo&);
+ CJavaInfo& operator = (const CJavaInfo&);
+public:
+ JavaInfo* pData;
+ CJavaInfo();
+ ~CJavaInfo();
+ operator JavaInfo* ();
+};
+
+CJavaInfo::CJavaInfo(): pData(NULL)
+{
+}
+
+CJavaInfo::~CJavaInfo()
+{
+ jfw_freeJavaInfo(pData);
+}
+
+CJavaInfo::operator JavaInfo*()
+{
+ return pData;
+}
+
+
+class JavaMigration : public ::cppu::WeakImplHelper4<
+ css::lang::XServiceInfo,
+ css::lang::XInitialization,
+ css::task::XJob,
+ css::configuration::backend::XLayerHandler>
+{
+public:
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw (css::uno::RuntimeException);
+
+ //XInitialization
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
+ throw(css::uno::Exception, css::uno::RuntimeException);
+
+ //XJob
+ virtual css::uno::Any SAL_CALL execute(
+ const css::uno::Sequence<css::beans::NamedValue >& Arguments )
+ throw (css::lang::IllegalArgumentException, css::uno::Exception,
+ css::uno::RuntimeException);
+
+ // XLayerHandler
+ virtual void SAL_CALL startLayer()
+ throw(::com::sun::star::lang::WrappedTargetException);
+
+ virtual void SAL_CALL endLayer()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL overrideNode(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ sal_Bool bClear)
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addOrReplaceNode(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes)
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addOrReplaceNodeFromTemplate(
+ const rtl::OUString& aName,
+ const ::com::sun::star::configuration::backend::TemplateIdentifier& aTemplate,
+ sal_Int16 aAttributes )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL endNode()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL dropNode(
+ const rtl::OUString& aName )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL overrideProperty(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const css::uno::Type& aType,
+ sal_Bool bClear )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL setPropertyValue(
+ const css::uno::Any& aValue )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL setPropertyValueForLocale(
+ const css::uno::Any& aValue,
+ const rtl::OUString& aLocale )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL endProperty()
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addProperty(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const css::uno::Type& aType )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+ virtual void SAL_CALL addPropertyWithValue(
+ const rtl::OUString& aName,
+ sal_Int16 aAttributes,
+ const css::uno::Any& aValue )
+ throw(
+ ::com::sun::star::configuration::backend::MalformedDataException,
+ ::com::sun::star::lang::WrappedTargetException );
+
+
+
+ //----------------
+ ~JavaMigration();
+
+private:
+ OUString m_sUserDir;
+ css::uno::Reference< ::css::configuration::backend::XLayer> m_xLayer;
+
+ void migrateJavarc();
+ typedef ::std::pair< ::rtl::OUString, sal_Int16> TElementType;
+ typedef ::std::stack< TElementType > TElementStack;
+ TElementStack m_aStack;
+
+};
+
+JavaMigration::~JavaMigration()
+{
+ OSL_ASSERT(m_aStack.empty());
+}
+
+OUString jvmfwk_getImplementationName()
+{
+ return OUSTR(IMPL_NAME);
+}
+
+css::uno::Sequence< OUString > jvmfwk_getSupportedServiceNames()
+{
+ OUString str_name = OUSTR(SERVICE_NAME);
+ return css::uno::Sequence< OUString >( &str_name, 1 );
+}
+
+// XServiceInfo
+OUString SAL_CALL JavaMigration::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return jvmfwk_getImplementationName();
+}
+
+sal_Bool SAL_CALL JavaMigration::supportsService( const OUString & rServiceName )
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< OUString > const & rSNL = getSupportedServiceNames();
+ OUString const * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (rServiceName.equals( pArray[ nPos ] ))
+ return true;
+ }
+ return false;
+
+}
+
+css::uno::Sequence< OUString > SAL_CALL JavaMigration::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return jvmfwk_getSupportedServiceNames();
+}
+
+//XInitialization ----------------------------------------------------------------------
+void SAL_CALL JavaMigration::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
+ throw(css::uno::Exception, css::uno::RuntimeException)
+{
+ const css::uno::Any* pIter = aArguments.getConstArray();
+ const css::uno::Any* pEnd = pIter + aArguments.getLength();
+ css::uno::Sequence<css::beans::NamedValue> aOldConfigValues;
+ css::beans::NamedValue aValue;
+ for(;pIter != pEnd;++pIter)
+ {
+ *pIter >>= aValue;
+ if (aValue.Name.equalsAscii("OldConfiguration"))
+ {
+ sal_Bool bSuccess = aValue.Value >>= aOldConfigValues;
+ OSL_ENSURE(bSuccess == sal_True, "[Service implementation " IMPL_NAME
+ "] XInitialization::initialize: Argument OldConfiguration has wrong type.");
+ if (bSuccess)
+ {
+ const css::beans::NamedValue* pIter2 = aOldConfigValues.getConstArray();
+ const css::beans::NamedValue* pEnd2 = pIter2 + aOldConfigValues.getLength();
+ for(;pIter2 != pEnd2;++pIter2)
+ {
+ if ( pIter2->Name.equalsAscii("org.openoffice.Office.Java") )
+ {
+ pIter2->Value >>= m_xLayer;
+ break;
+ }
+ }
+ }
+ }
+ else if (aValue.Name.equalsAscii("UserData"))
+ {
+ if ( !(aValue.Value >>= m_sUserDir) )
+ {
+ OSL_ENSURE(
+ false,
+ "[Service implementation " IMPL_NAME
+ "] XInitialization::initialize: Argument UserData has wrong type.");
+ }
+ }
+ }
+
+}
+
+//XJob
+css::uno::Any SAL_CALL JavaMigration::execute(
+ const css::uno::Sequence<css::beans::NamedValue >& )
+ throw (css::lang::IllegalArgumentException, css::uno::Exception,
+ css::uno::RuntimeException)
+{
+ migrateJavarc();
+ if (m_xLayer.is())
+ m_xLayer->readData(this);
+
+ return css::uno::Any();
+}
+
+void JavaMigration::migrateJavarc()
+{
+ if (m_sUserDir.getLength() == 0)
+ return;
+
+ OUString sValue;
+ rtl::Bootstrap javaini(m_sUserDir + OUSTR("/user/config/"SAL_CONFIGFILE("java")));
+ sal_Bool bSuccess = javaini.getFrom(OUSTR("Home"), sValue);
+ OSL_ENSURE(bSuccess, "[Service implementation " IMPL_NAME
+ "] XJob::execute: Could not get Home entry from java.ini/javarc.");
+ if (bSuccess == sal_True && sValue.getLength() > 0)
+ {
+ //get the directory
+ CJavaInfo aInfo;
+ javaFrameworkError err = jfw_getJavaInfoByPath(sValue.pData, &aInfo.pData);
+
+ if (err == JFW_E_NONE)
+ {
+ if (jfw_setSelectedJRE(aInfo) != JFW_E_NONE)
+ {
+ OSL_ENSURE(0, "[Service implementation " IMPL_NAME
+ "] XJob::execute: jfw_setSelectedJRE failed.");
+ fprintf(stderr, "\nCannot migrate Java. An error occured.\n");
+ }
+ }
+ else if (err == JFW_E_FAILED_VERSION)
+ {
+ fprintf(stderr, "\nCannot migrate Java settings because the version of the Java "
+ "is not supported anymore.\n");
+ }
+ }
+}
+
+
+// XLayerHandler
+void SAL_CALL JavaMigration::startLayer()
+ throw(css::lang::WrappedTargetException)
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::endLayer()
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::overrideNode(
+ const ::rtl::OUString&,
+ sal_Int16,
+ sal_Bool)
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+
+{
+
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::addOrReplaceNode(
+ const ::rtl::OUString&,
+ sal_Int16)
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+
+}
+void SAL_CALL JavaMigration::endNode()
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::dropNode(
+ const ::rtl::OUString& )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::overrideProperty(
+ const ::rtl::OUString& aName,
+ sal_Int16,
+ const Type&,
+ sal_Bool )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+ if (aName.equalsAscii("Enable"))
+ m_aStack.push(TElementStack::value_type(aName,ENABLE_JAVA));
+ else if (aName.equalsAscii("UserClassPath"))
+ m_aStack.push(TElementStack::value_type(aName, USER_CLASS_PATH));
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::setPropertyValue(
+ const Any& aValue )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+ if ( !m_aStack.empty())
+ {
+ switch (m_aStack.top().second)
+ {
+ case ENABLE_JAVA:
+ {
+ sal_Bool val = sal_Bool();
+ if ((aValue >>= val) == sal_False)
+ throw MalformedDataException(
+ OUSTR("[Service implementation " IMPL_NAME
+ "] XLayerHandler::setPropertyValue received wrong type for Enable property"), 0, Any());
+ if (jfw_setEnabled(val) != JFW_E_NONE)
+ throw WrappedTargetException(
+ OUSTR("[Service implementation " IMPL_NAME
+ "] XLayerHandler::setPropertyValue: jfw_setEnabled failed."), 0, Any());
+
+ break;
+ }
+ case USER_CLASS_PATH:
+ {
+ OUString cp;
+ if ((aValue >>= cp) == sal_False)
+ throw MalformedDataException(
+ OUSTR("[Service implementation " IMPL_NAME
+ "] XLayerHandler::setPropertyValue received wrong type for UserClassPath property"), 0, Any());
+
+ if (jfw_setUserClassPath(cp.pData) != JFW_E_NONE)
+ throw WrappedTargetException(
+ OUSTR("[Service implementation " IMPL_NAME
+ "] XLayerHandler::setPropertyValue: jfw_setUserClassPath failed."), 0, Any());
+ break;
+ }
+ default:
+ OSL_ASSERT(0);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::setPropertyValueForLocale(
+ const Any&,
+ const ::rtl::OUString& )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::endProperty()
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+ if (!m_aStack.empty())
+ m_aStack.pop();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::addProperty(
+ const rtl::OUString&,
+ sal_Int16,
+ const Type& )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL JavaMigration::addPropertyWithValue(
+ const rtl::OUString&,
+ sal_Int16,
+ const Any& )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+
+void SAL_CALL JavaMigration::addOrReplaceNodeFromTemplate(
+ const rtl::OUString&,
+ const TemplateIdentifier&,
+ sal_Int16 )
+ throw(
+ MalformedDataException,
+ WrappedTargetException )
+{
+}
+
+// -----------------------------------------------------------------------------
+//ToDo enable java, user class path
+
+} //end namespace jfw
+
diff --git a/desktop/source/migration/services/jvmfwk.hxx b/desktop/source/migration/services/jvmfwk.hxx
new file mode 100644
index 000000000000..a79d36b8b86b
--- /dev/null
+++ b/desktop/source/migration/services/jvmfwk.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "cppuhelper/implbase3.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "boost/scoped_array.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/task/XJob.hpp"
+
+
+namespace css = com::sun::star;
+
+namespace migration
+{
+
+rtl::OUString jvmfwk_getImplementationName();
+
+css::uno::Sequence< rtl::OUString > jvmfwk_getSupportedServiceNames();
+
+} //end blind namespace
+
diff --git a/desktop/source/migration/services/makefile.mk b/desktop/source/migration/services/makefile.mk
new file mode 100644
index 000000000000..2f3eb9308ebd
--- /dev/null
+++ b/desktop/source/migration/services/makefile.mk
@@ -0,0 +1,119 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET = migrationoo2.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = migrationoo2
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+.INCLUDE : ..$/..$/deployment/inc/dp_misc.mk
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : cppumaker.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/jvmfwk.obj \
+ $(SLO)$/cexports.obj \
+ $(SLO)$/basicmigration.obj \
+ $(SLO)$/wordbookmigration.obj \
+ $(SLO)$/autocorrmigration.obj \
+ $(SLO)$/oo3extensionmigration.obj \
+ $(SLO)$/cexportsoo3.obj
+
+SHL1OBJS= \
+ $(SLO)$/jvmfwk.obj \
+ $(SLO)$/cexports.obj \
+ $(SLO)$/basicmigration.obj \
+ $(SLO)$/wordbookmigration.obj \
+ $(SLO)$/autocorrmigration.obj
+
+SHL1TARGET=$(TARGET)
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+
+SHL1STDLIBS= \
+ $(DEPLOYMENTMISCLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(I18NISOLANGLIB) \
+ $(JVMFWKLIB) \
+ $(XMLSCRIPTLIB) \
+ $(BERKELEYLIB)
+
+SHL1DEPN=
+SHL1IMPLIB=imigrationoo2
+#SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME=$(SHL1TARGET)
+
+COMP2TYPELIST = migrationoo3
+SHL2TARGET=migrationoo3.uno
+SHL2VERSIONMAP = migrationoo3.map
+
+SHL2OBJS= \
+ $(SLO)$/cexportsoo3.obj \
+ $(SLO)$/oo3extensionmigration.obj
+
+SHL2STDLIBS= \
+ $(DEPLOYMENTMISCLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(I18NISOLANGLIB) \
+ $(JVMFWKLIB) \
+ $(XMLSCRIPTLIB) \
+ $(BERKELEYLIB)
+
+SHL2DEPN=
+SHL2IMPLIB=imigrationoo3
+#SHL2LIBS=$(SLB)$/$(SHL2TARGET).lib
+SHL2DEF=$(MISC)$/$(SHL2TARGET).def
+
+DEF2NAME=$(SHL2TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/migration/services/migrationoo2.xml b/desktop/source/migration/services/migrationoo2.xml
new file mode 100644
index 000000000000..5bda732f0fba
--- /dev/null
+++ b/desktop/source/migration/services/migrationoo2.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> migrationoo2.uno </module-name>
+ <component-description>
+ <author> Joachim Lingner </author>
+ <name> com.sun.star.comp.jvmfwk.MigrationOO2</name>
+ <description>
+Specifies a factory object to create proxy objects.
+These proxy object represent a given target object and can be
+be aggregated. The proxy objects act UNO conform and do NOT provide
+original target interfaces on queryInterface() calls.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.reflection.ProxyFactory </supported-service>
+ <service-dependency> ... </service-dependency>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.WrappedTargetException </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.task.XJob </type>
+ <type> com.sun.star.beans.NamedValue </type>
+ <type> com.sun.star.configuration.backend.XLayer </type>
+ <type> com.sun.star.configuration.backend.XLayerHandler </type>
+ <type> com.sun.star.configuration.backend.MalformedDataException </type>
+ <type> com.sun.star.configuration.backend.TemplateIdentifier </type>
+ </component-description>
+ <component-description>
+ <author>Thomas Benisch</author>
+ <name>com.sun.star.comp.desktop.migration.Basic</name>
+ <description>migration service for OpenOffice.org Basic and dialogs</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="final"/>
+ <supported-service>com.sun.star.migration.Basic</supported-service>
+ <service-dependency>...</service-dependency>
+ <type>com.sun.star.beans.NamedValue</type>
+ <type>com.sun.star.lang.IllegalArgumentException</type>
+ <type>com.sun.star.lang.XInitialization</type>
+ <type>com.sun.star.task.XJob</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.uno.XComponentContext</type>
+ </component-description>
+ <component-description>
+ <author>Thomas Benisch</author>
+ <name>com.sun.star.comp.desktop.migration.Autocorrection</name>
+ <description>migration service for OpenOffice.org autocorrection</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="final"/>
+ <supported-service>com.sun.star.migration.Autocorrection</supported-service>
+ <service-dependency>...</service-dependency>
+ <type>com.sun.star.beans.NamedValue</type>
+ <type>com.sun.star.lang.IllegalArgumentException</type>
+ <type>com.sun.star.lang.XInitialization</type>
+ <type>com.sun.star.task.XJob</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.uno.XComponentContext</type>
+ </component-description>
+ <project-build-dependency>unotools</project-build-dependency>
+ <project-build-dependency>tools</project-build-dependency>
+ <project-build-dependency>cppuhelper</project-build-dependency>
+ <project-build-dependency>cppu</project-build-dependency>
+ <project-build-dependency>sal</project-build-dependency>
+ <runtime-module-dependency>utl</runtime-module-dependency>
+ <runtime-module-dependency>tl</runtime-module-dependency>
+ <runtime-module-dependency>cppuhelper3$(COM)</runtime-module-dependency>
+ <runtime-module-dependency>cppu3</runtime-module-dependency>
+ <runtime-module-dependency>sal3</runtime-module-dependency>
+</module-description>
diff --git a/desktop/source/migration/services/migrationoo3.map b/desktop/source/migration/services/migrationoo3.map
new file mode 100755
index 000000000000..ac2c3750bfe0
--- /dev/null
+++ b/desktop/source/migration/services/migrationoo3.map
@@ -0,0 +1,8 @@
+UDK_3_0_0 {
+ global:
+ component_getImplementationEnvironment;
+ component_writeInfo;
+ component_getFactory;
+ local:
+ *;
+};
diff --git a/desktop/source/migration/services/misc.hxx b/desktop/source/migration/services/misc.hxx
new file mode 100644
index 000000000000..8bab95c09a57
--- /dev/null
+++ b/desktop/source/migration/services/misc.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_MISC_HXX_
+#define _DESKTOP_MISC_HXX_
+
+#include <rtl/ustring.hxx>
+
+#include <vector>
+#include <memory>
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+ typedef ::std::vector< ::rtl::OUString > TStringVector;
+ typedef ::std::auto_ptr< TStringVector > TStringVectorPtr;
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_MISC_HXX_
diff --git a/desktop/source/migration/services/oo3extensionmigration.cxx b/desktop/source/migration/services/oo3extensionmigration.cxx
new file mode 100644
index 000000000000..2e3a8d1d518c
--- /dev/null
+++ b/desktop/source/migration/services/oo3extensionmigration.cxx
@@ -0,0 +1,586 @@
+/*************************************************************************
+ *
+ * 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: extensionmigration.cxx,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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "oo3extensionmigration.hxx"
+#include <rtl/instance.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.h>
+#include <tools/urlobj.hxx>
+#include <unotools/bootstrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/textsearch.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/content.hxx>
+
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/xml/xpath/XXPathAPI.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/deployment/ExtensionManager.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace migration
+{
+
+static ::rtl::OUString sExtensionSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/uno_packages/" ) );
+static ::rtl::OUString sSubDirName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cache" ) );
+static ::rtl::OUString sConfigDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/registry/data" ) );
+static ::rtl::OUString sOrgDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/registry/data/org" ) );
+static ::rtl::OUString sExcludeDir1 = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/registry/data/org" ) );
+static ::rtl::OUString sExcludeDir2 = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/registry/data/org/openoffice" ) );
+static ::rtl::OUString sDescriptionXmlFile = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/description.xml" ) );
+static ::rtl::OUString sExtensionRootSubDirName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/uno_packages" ) );
+
+static ::rtl::OUString sConfigurationDataType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("application/vnd.sun.star.configuration-data"));
+static ::rtl::OUString sConfigurationSchemaType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("application/vnd.sun.star.configuration-schema"));
+
+// =============================================================================
+// component operations
+// =============================================================================
+
+::rtl::OUString OO3ExtensionMigration_getImplementationName()
+{
+ static ::rtl::OUString* pImplName = 0;
+ if ( !pImplName )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pImplName )
+ {
+ static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.OOo3Extensions" ) );
+ pImplName = &aImplName;
+ }
+ }
+ return *pImplName;
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< ::rtl::OUString > OO3ExtensionMigration_getSupportedServiceNames()
+{
+ static Sequence< ::rtl::OUString >* pNames = 0;
+ if ( !pNames )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pNames )
+ {
+ static Sequence< ::rtl::OUString > aNames(1);
+ aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Extensions" ) );
+ pNames = &aNames;
+ }
+ }
+ return *pNames;
+}
+
+// =============================================================================
+// ExtensionMigration
+// =============================================================================
+
+OO3ExtensionMigration::OO3ExtensionMigration(Reference< XComponentContext > const & ctx) :
+m_ctx(ctx)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+OO3ExtensionMigration::~OO3ExtensionMigration()
+{
+}
+
+::osl::FileBase::RC OO3ExtensionMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
+{
+ ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ if ( aResult == ::osl::FileBase::E_NOENT )
+ {
+ INetURLObject aBaseURL( rDirURL );
+ aBaseURL.removeSegment();
+ checkAndCreateDirectory( aBaseURL );
+ return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+ else
+ {
+ return aResult;
+ }
+}
+
+void OO3ExtensionMigration::scanUserExtensions( const ::rtl::OUString& sSourceDir, TStringVector& aMigrateExtensions )
+{
+ osl::Directory aScanRootDir( sSourceDir );
+ osl::FileStatus fs(FileStatusMask_Type | FileStatusMask_FileURL);
+ osl::FileBase::RC nRetCode = aScanRootDir.open();
+ if ( nRetCode == osl::Directory::E_None )
+ {
+ sal_uInt32 nHint( 0 );
+ osl::DirectoryItem aItem;
+ while ( aScanRootDir.getNextItem( aItem, nHint ) == osl::Directory::E_None )
+ {
+ if (( aItem.getFileStatus(fs) == osl::FileBase::E_None ) &&
+ ( fs.getFileType() == osl::FileStatus::Directory ))
+ {
+ //Check next folder as the "real" extension folder is below a temp folder!
+ ::rtl::OUString sExtensionFolderURL = fs.getFileURL();
+
+ osl::DirectoryItem aExtDirItem;
+ osl::Directory aExtensionRootDir( sExtensionFolderURL );
+
+ nRetCode = aExtensionRootDir.open();
+ if (( nRetCode == osl::Directory::E_None ) &&
+ ( aExtensionRootDir.getNextItem( aExtDirItem, nHint ) == osl::Directory::E_None ))
+ {
+ bool bFileStatus = aExtDirItem.getFileStatus(fs) == osl::FileBase::E_None;
+ bool bIsDir = fs.getFileType() == osl::FileStatus::Directory;
+
+ if ( bFileStatus && bIsDir )
+ {
+ sExtensionFolderURL = fs.getFileURL();
+ ScanResult eResult = scanExtensionFolder( sExtensionFolderURL );
+ if ( eResult == SCANRESULT_MIGRATE_EXTENSION )
+ aMigrateExtensions.push_back( sExtensionFolderURL );
+ }
+ }
+ }
+ }
+ }
+}
+
+OO3ExtensionMigration::ScanResult OO3ExtensionMigration::scanExtensionFolder( const ::rtl::OUString& sExtFolder )
+{
+ ScanResult aResult = SCANRESULT_NOTFOUND;
+ osl::Directory aDir(sExtFolder);
+
+ // get sub dirs
+ if (aDir.open() == osl::FileBase::E_None)
+ {
+ // work through directory contents...
+ osl::DirectoryItem item;
+ osl::FileStatus fs(FileStatusMask_Type | FileStatusMask_FileURL);
+ TStringVector aDirectories;
+ while ((aDir.getNextItem(item) == osl::FileBase::E_None ) &&
+ ( aResult == SCANRESULT_NOTFOUND ))
+ {
+ if (item.getFileStatus(fs) == osl::FileBase::E_None)
+ {
+ ::rtl::OUString aDirEntryURL;
+ if (fs.getFileType() == osl::FileStatus::Directory)
+ aDirectories.push_back( fs.getFileURL() );
+ else
+ {
+ aDirEntryURL = fs.getFileURL();
+ if ( aDirEntryURL.indexOf( sDescriptionXmlFile ) > 0 )
+ aResult = scanDescriptionXml( aDirEntryURL ) ? SCANRESULT_MIGRATE_EXTENSION : SCANRESULT_DONTMIGRATE_EXTENSION;
+ }
+ }
+ }
+
+ TStringVector::const_iterator pIter = aDirectories.begin();
+ while ( pIter != aDirectories.end() && aResult == SCANRESULT_NOTFOUND )
+ {
+ aResult = scanExtensionFolder( *pIter );
+ ++pIter;
+ }
+ }
+ return aResult;
+}
+
+bool OO3ExtensionMigration::scanDescriptionXml( const ::rtl::OUString& sDescriptionXmlURL )
+{
+ if ( !m_xDocBuilder.is() )
+ {
+ m_xDocBuilder = uno::Reference< xml::dom::XDocumentBuilder >(
+ m_ctx->getServiceManager()->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.dom.DocumentBuilder")),
+ m_ctx ), uno::UNO_QUERY );
+ }
+
+ if ( !m_xSimpleFileAccess.is() )
+ {
+ m_xSimpleFileAccess = uno::Reference< ucb::XSimpleFileAccess >(
+ m_ctx->getServiceManager()->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")),
+ m_ctx ), uno::UNO_QUERY );
+ }
+
+ ::rtl::OUString aExtIdentifier;
+ if ( m_xDocBuilder.is() && m_xSimpleFileAccess.is() )
+ {
+ try
+ {
+ uno::Reference< io::XInputStream > xIn =
+ m_xSimpleFileAccess->openFileRead( sDescriptionXmlURL );
+
+ if ( xIn.is() )
+ {
+ uno::Reference< xml::dom::XDocument > xDoc = m_xDocBuilder->parse( xIn );
+ if ( xDoc.is() )
+ {
+ uno::Reference< xml::dom::XElement > xRoot = xDoc->getDocumentElement();
+ if ( xRoot.is() &&
+ xRoot->getTagName().equals(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("description"))) )
+ {
+ uno::Reference< xml::xpath::XXPathAPI > xPath(
+ m_ctx->getServiceManager()->createInstanceWithContext(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.xpath.XPathAPI")),
+ m_ctx),
+ uno::UNO_QUERY);
+
+ xPath->registerNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc")),
+ xRoot->getNamespaceURI());
+ xPath->registerNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xlink")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http://www.w3.org/1999/xlink")));
+
+ try
+ {
+ uno::Reference< xml::dom::XNode > xRootNode( xRoot, uno::UNO_QUERY );
+ uno::Reference< xml::dom::XNode > xNode(
+ xPath->selectSingleNode(
+ xRootNode,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:identifier/@value")) ));
+ if ( xNode.is() )
+ aExtIdentifier = xNode->getNodeValue();
+ }
+ catch ( xml::xpath::XPathException& )
+ {
+ }
+ catch ( xml::dom::DOMException& )
+ {
+ }
+ }
+ }
+ }
+
+ if ( aExtIdentifier.getLength() > 0 )
+ {
+ // scan extension identifier and try to match with our black list entries
+ for ( sal_uInt32 i = 0; i < m_aBlackList.size(); i++ )
+ {
+ utl::SearchParam param(m_aBlackList[i], utl::SearchParam::SRCH_REGEXP);
+ utl::TextSearch ts(param, LANGUAGE_DONTKNOW);
+
+ xub_StrLen start = 0;
+ xub_StrLen end = static_cast<USHORT>(aExtIdentifier.getLength());
+ if (ts.SearchFrwrd(aExtIdentifier, &start, &end))
+ return false;
+ }
+ }
+ }
+ catch ( ucb::CommandAbortedException& )
+ {
+ }
+ catch ( uno::RuntimeException& )
+ {
+ }
+
+ if ( aExtIdentifier.getLength() == 0 )
+ {
+ // Fallback:
+ // Try to use the folder name to match our black list
+ // as some extensions don't provide an identifier in the
+ // description.xml!
+ for ( sal_uInt32 i = 0; i < m_aBlackList.size(); i++ )
+ {
+ utl::SearchParam param(m_aBlackList[i], utl::SearchParam::SRCH_REGEXP);
+ utl::TextSearch ts(param, LANGUAGE_DONTKNOW);
+
+ xub_StrLen start = 0;
+ xub_StrLen end = static_cast<USHORT>(sDescriptionXmlURL.getLength());
+ if (ts.SearchFrwrd(sDescriptionXmlURL, &start, &end))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool OO3ExtensionMigration::migrateExtension( const ::rtl::OUString& sSourceDir )
+{
+ if ( !m_xExtensionManager.is() )
+ {
+ try
+ {
+ m_xExtensionManager = deployment::ExtensionManager::get( m_ctx );
+ }
+ catch ( ucb::CommandFailedException & ){}
+ catch ( uno::RuntimeException & ) {}
+ }
+
+ if ( m_xExtensionManager.is() )
+ {
+ try
+ {
+ TmpRepositoryCommandEnv* pCmdEnv = new TmpRepositoryCommandEnv();
+
+ uno::Reference< ucb::XCommandEnvironment > xCmdEnv(
+ static_cast< cppu::OWeakObject* >( pCmdEnv ), uno::UNO_QUERY );
+ uno::Reference< task::XAbortChannel > xAbortChannel;
+ uno::Reference< deployment::XPackage > xPackage =
+ m_xExtensionManager->addExtension(
+ sSourceDir, uno::Sequence<beans::NamedValue>(),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user")), xAbortChannel, xCmdEnv );
+
+ if ( xPackage.is() )
+ return true;
+ }
+ catch ( ucb::CommandFailedException& )
+ {
+ }
+ catch ( ucb::CommandAbortedException& )
+ {
+ }
+ catch ( lang::IllegalArgumentException& )
+ {
+ }
+ }
+
+ return false;
+}
+
+
+// -----------------------------------------------------------------------------
+// XServiceInfo
+// -----------------------------------------------------------------------------
+
+::rtl::OUString OO3ExtensionMigration::getImplementationName() throw (RuntimeException)
+{
+ return OO3ExtensionMigration_getImplementationName();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool OO3ExtensionMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+{
+ Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pNames + aNames.getLength();
+ for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
+ ;
+
+ return pNames != pEnd;
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< ::rtl::OUString > OO3ExtensionMigration::getSupportedServiceNames() throw (RuntimeException)
+{
+ return OO3ExtensionMigration_getSupportedServiceNames();
+}
+
+// -----------------------------------------------------------------------------
+// XInitialization
+// -----------------------------------------------------------------------------
+
+void OO3ExtensionMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const Any* pIter = aArguments.getConstArray();
+ const Any* pEnd = pIter + aArguments.getLength();
+ for ( ; pIter != pEnd ; ++pIter )
+ {
+ beans::NamedValue aValue;
+ *pIter >>= aValue;
+ if ( aValue.Name.equalsAscii( "UserData" ) )
+ {
+ if ( !(aValue.Value >>= m_sSourceDir) )
+ {
+ OSL_ENSURE( false, "ExtensionMigration::initialize: argument UserData has wrong type!" );
+ }
+ }
+ else if ( aValue.Name.equalsAscii( "ExtensionBlackList" ) )
+ {
+ Sequence< ::rtl::OUString > aBlackList;
+ if ( (aValue.Value >>= aBlackList ) && ( aBlackList.getLength() > 0 ))
+ {
+ m_aBlackList.resize( aBlackList.getLength() );
+ ::comphelper::sequenceToArray< ::rtl::OUString >( &m_aBlackList[0], aBlackList );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+TStringVectorPtr getContent( const ::rtl::OUString& rBaseURL )
+{
+ TStringVectorPtr aResult( new TStringVector );
+ ::osl::Directory aDir( rBaseURL);
+ if ( aDir.open() == ::osl::FileBase::E_None )
+ {
+ // iterate over directory content
+ TStringVector aSubDirs;
+ ::osl::DirectoryItem aItem;
+ while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None )
+ {
+ ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
+ if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None )
+ aResult->push_back( aFileStatus.getFileURL() );
+ }
+ }
+
+ return aResult;
+}
+
+Any OO3ExtensionMigration::execute( const Sequence< beans::NamedValue >& )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( m_sTargetDir );
+ if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
+ {
+ // copy all extensions
+ ::rtl::OUString sSourceDir( m_sSourceDir );
+ sSourceDir += sExtensionSubDir;
+ sSourceDir += sSubDirName;
+ sSourceDir += sExtensionRootSubDirName;
+ TStringVector aExtensionToMigrate;
+ scanUserExtensions( sSourceDir, aExtensionToMigrate );
+ if ( aExtensionToMigrate.size() > 0 )
+ {
+ TStringVector::iterator pIter = aExtensionToMigrate.begin();
+ while ( pIter != aExtensionToMigrate.end() )
+ {
+ migrateExtension( *pIter );
+ ++pIter;
+ }
+ }
+ }
+
+ return Any();
+}
+
+// -----------------------------------------------------------------------------
+// TmpRepositoryCommandEnv
+// -----------------------------------------------------------------------------
+
+TmpRepositoryCommandEnv::TmpRepositoryCommandEnv()
+{
+}
+
+TmpRepositoryCommandEnv::~TmpRepositoryCommandEnv()
+{
+}
+// XCommandEnvironment
+//______________________________________________________________________________
+uno::Reference< task::XInteractionHandler > TmpRepositoryCommandEnv::getInteractionHandler()
+throw ( uno::RuntimeException )
+{
+ return this;
+}
+
+//______________________________________________________________________________
+uno::Reference< ucb::XProgressHandler > TmpRepositoryCommandEnv::getProgressHandler()
+throw ( uno::RuntimeException )
+{
+ return this;
+}
+
+// XInteractionHandler
+void TmpRepositoryCommandEnv::handle(
+ uno::Reference< task::XInteractionRequest> const & xRequest )
+ throw ( uno::RuntimeException )
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+ bool approve = true;
+ bool abort = false;
+
+ // select:
+ uno::Sequence< Reference< task::XInteractionContinuation > > conts(
+ xRequest->getContinuations() );
+ 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 TmpRepositoryCommandEnv::push( uno::Any const & /*Status*/ )
+throw (uno::RuntimeException)
+{
+}
+
+
+void TmpRepositoryCommandEnv::update( uno::Any const & /*Status */)
+throw (uno::RuntimeException)
+{
+}
+
+void TmpRepositoryCommandEnv::pop() throw (uno::RuntimeException)
+{
+}
+
+// =============================================================================
+// component operations
+// =============================================================================
+
+Reference< XInterface > SAL_CALL OO3ExtensionMigration_create(
+ Reference< XComponentContext > const & ctx )
+ SAL_THROW( () )
+{
+ return static_cast< lang::XTypeProvider * >( new OO3ExtensionMigration(
+ ctx) );
+}
+
+// -----------------------------------------------------------------------------
+
+} // namespace migration
diff --git a/desktop/source/migration/services/oo3extensionmigration.hxx b/desktop/source/migration/services/oo3extensionmigration.hxx
new file mode 100644
index 000000000000..03995652888c
--- /dev/null
+++ b/desktop/source/migration/services/oo3extensionmigration.hxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * 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: extensionmigration.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 _DESKTOP_OO3EXTENSIONMIGRATION_HXX_
+#define _DESKTOP_OO3EXTENSIONMIGRATION_HXX_
+
+#include "misc.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/deployment/XExtensionManager.hpp>
+
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <ucbhelper/content.hxx>
+#include <xmlscript/xmllib_imexp.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace deployment {
+ class XPackage;
+ }
+}}}
+
+class INetURLObject;
+
+
+namespace migration
+{
+
+ ::rtl::OUString SAL_CALL OO3ExtensionMigration_getImplementationName();
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OO3ExtensionMigration_getSupportedServiceNames();
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL OO3ExtensionMigration_create(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) );
+
+
+ // =============================================================================
+ // class ExtensionMigration
+ // =============================================================================
+
+ typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::task::XJob > ExtensionMigration_BASE;
+
+ class OO3ExtensionMigration : public ExtensionMigration_BASE
+ {
+ private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_ctx;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XDocumentBuilder > m_xDocBuilder;
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > m_xSimpleFileAccess;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XExtensionManager > m_xExtensionManager;
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_sSourceDir;
+ ::rtl::OUString m_sTargetDir;
+ TStringVector m_aBlackList;
+
+ enum ScanResult
+ {
+ SCANRESULT_NOTFOUND,
+ SCANRESULT_MIGRATE_EXTENSION,
+ SCANRESULT_DONTMIGRATE_EXTENSION
+ };
+
+ ::osl::FileBase::RC checkAndCreateDirectory( INetURLObject& rDirURL );
+ ScanResult scanExtensionFolder( const ::rtl::OUString& sExtFolder );
+ void scanUserExtensions( const ::rtl::OUString& sSourceDir, TStringVector& aMigrateExtensions );
+ bool scanDescriptionXml( const ::rtl::OUString& sDescriptionXmlFilePath );
+ bool migrateExtension( const ::rtl::OUString& sSourceDir );
+
+ public:
+ OO3ExtensionMigration(::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > const & ctx);
+ virtual ~OO3ExtensionMigration();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+ };
+
+ class TmpRepositoryCommandEnv
+ : public ::cppu::WeakImplHelper3< ::com::sun::star::ucb::XCommandEnvironment,
+ ::com::sun::star::task::XInteractionHandler,
+ ::com::sun::star::ucb::XProgressHandler >
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler> m_forwardHandler;
+ public:
+ virtual ~TmpRepositoryCommandEnv();
+ TmpRepositoryCommandEnv();
+
+ // XCommandEnvironment
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw ( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw ( ::com::sun::star::uno::RuntimeException );
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest > const & xRequest )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( ::com::sun::star::uno::Any const & Status )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL update( ::com::sun::star::uno::Any const & Status )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL pop() throw (::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_OO3EXTENSIONMIGRATION_HXX_
diff --git a/desktop/source/migration/services/wordbookmigration.cxx b/desktop/source/migration/services/wordbookmigration.cxx
new file mode 100755
index 000000000000..1ac8f38dca56
--- /dev/null
+++ b/desktop/source/migration/services/wordbookmigration.cxx
@@ -0,0 +1,322 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "wordbookmigration.hxx"
+#include <tools/urlobj.hxx>
+#include <unotools/bootstrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+
+ static ::rtl::OUString sSourceSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/wordbook" ) );
+ static ::rtl::OUString sTargetSubDir = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/wordbook" ) );
+ static ::rtl::OUString sBaseName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/wordbook" ) );
+ static ::rtl::OUString sSuffix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".dic" ) );
+
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ ::rtl::OUString WordbookMigration_getImplementationName()
+ {
+ static ::rtl::OUString* pImplName = 0;
+ if ( !pImplName )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pImplName )
+ {
+ static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.desktop.migration.Wordbooks" ) );
+ pImplName = &aImplName;
+ }
+ }
+ return *pImplName;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > WordbookMigration_getSupportedServiceNames()
+ {
+ static Sequence< ::rtl::OUString >* pNames = 0;
+ if ( !pNames )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pNames )
+ {
+ static Sequence< ::rtl::OUString > aNames(1);
+ aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.migration.Wordbooks" ) );
+ pNames = &aNames;
+ }
+ }
+ return *pNames;
+ }
+
+ // =============================================================================
+ // WordbookMigration
+ // =============================================================================
+
+ WordbookMigration::WordbookMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ WordbookMigration::~WordbookMigration()
+ {
+ }
+
+ // -----------------------------------------------------------------------------
+
+ TStringVectorPtr WordbookMigration::getFiles( const ::rtl::OUString& rBaseURL ) const
+ {
+ TStringVectorPtr aResult( new TStringVector );
+ ::osl::Directory aDir( rBaseURL);
+
+ if ( aDir.open() == ::osl::FileBase::E_None )
+ {
+ // iterate over directory content
+ TStringVector aSubDirs;
+ ::osl::DirectoryItem aItem;
+ while ( aDir.getNextItem( aItem ) == ::osl::FileBase::E_None )
+ {
+ ::osl::FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
+ if ( aItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None )
+ {
+ if ( aFileStatus.getFileType() == ::osl::FileStatus::Directory )
+ aSubDirs.push_back( aFileStatus.getFileURL() );
+ else
+ aResult->push_back( aFileStatus.getFileURL() );
+ }
+ }
+
+ // iterate recursive over subfolders
+ TStringVector::const_iterator aI = aSubDirs.begin();
+ while ( aI != aSubDirs.end() )
+ {
+ TStringVectorPtr aSubResult = getFiles( *aI );
+ aResult->insert( aResult->end(), aSubResult->begin(), aSubResult->end() );
+ ++aI;
+ }
+ }
+
+ return aResult;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ ::osl::FileBase::RC WordbookMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
+ {
+ ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ if ( aResult == ::osl::FileBase::E_NOENT )
+ {
+ INetURLObject aBaseURL( rDirURL );
+ aBaseURL.removeSegment();
+ checkAndCreateDirectory( aBaseURL );
+ return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
+ }
+ else
+ {
+ return aResult;
+ }
+ }
+
+#define MAX_HEADER_LENGTH 16
+bool IsUserWordbook( const ::rtl::OUString& rFile )
+{
+ static const sal_Char* pVerStr2 = "WBSWG2";
+ static const sal_Char* pVerStr5 = "WBSWG5";
+ static const sal_Char* pVerStr6 = "WBSWG6";
+ static const sal_Char* pVerOOo7 = "OOoUserDict1";
+
+ bool bRet = false;
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( String(rFile), STREAM_STD_READ );
+ if ( pStream && !pStream->GetError() )
+ {
+ sal_Size nSniffPos = pStream->Tell();
+ static sal_Size nVerOOo7Len = sal::static_int_cast< sal_Size >(strlen( pVerOOo7 ));
+ sal_Char pMagicHeader[MAX_HEADER_LENGTH];
+ pMagicHeader[ nVerOOo7Len ] = '\0';
+ if ((pStream->Read((void *) pMagicHeader, nVerOOo7Len) == nVerOOo7Len))
+ {
+ if ( !strcmp(pMagicHeader, pVerOOo7) )
+ bRet = true;
+ else
+ {
+ USHORT nLen;
+ pStream->Seek (nSniffPos);
+ *pStream >> nLen;
+ if ( nLen < MAX_HEADER_LENGTH )
+ {
+ pStream->Read(pMagicHeader, nLen);
+ pMagicHeader[nLen] = '\0';
+ if ( !strcmp(pMagicHeader, pVerStr2)
+ || !strcmp(pMagicHeader, pVerStr5)
+ || !strcmp(pMagicHeader, pVerStr6) )
+ bRet = true;
+ }
+ }
+ }
+ }
+
+ delete pStream;
+ return bRet;
+}
+
+
+ // -----------------------------------------------------------------------------
+
+ void WordbookMigration::copyFiles()
+ {
+ ::rtl::OUString sTargetDir;
+ ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( sTargetDir );
+ if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
+ {
+ sTargetDir += sTargetSubDir;
+ TStringVectorPtr aFileList = getFiles( m_sSourceDir );
+ TStringVector::const_iterator aI = aFileList->begin();
+ while ( aI != aFileList->end() )
+ {
+ if (IsUserWordbook(*aI) )
+ {
+ ::rtl::OUString sSourceLocalName = aI->copy( m_sSourceDir.getLength() );
+ ::rtl::OUString sTargetName = sTargetDir + sSourceLocalName;
+ INetURLObject aURL( sTargetName );
+ aURL.removeSegment();
+ checkAndCreateDirectory( aURL );
+ ::osl::FileBase::RC aResult = ::osl::File::copy( *aI, sTargetName );
+ if ( aResult != ::osl::FileBase::E_None )
+ {
+ ::rtl::OString aMsg( "WordbookMigration::copyFiles: cannot copy " );
+ aMsg += ::rtl::OUStringToOString( *aI, RTL_TEXTENCODING_UTF8 ) + " to "
+ + ::rtl::OUStringToOString( sTargetName, RTL_TEXTENCODING_UTF8 );
+ OSL_ENSURE( sal_False, aMsg.getStr() );
+ }
+ }
+ ++aI;
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "WordbookMigration::copyFiles: no user installation!" );
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XServiceInfo
+ // -----------------------------------------------------------------------------
+
+ ::rtl::OUString WordbookMigration::getImplementationName() throw (RuntimeException)
+ {
+ return WordbookMigration_getImplementationName();
+ }
+
+ // -----------------------------------------------------------------------------
+
+ sal_Bool WordbookMigration::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
+ const ::rtl::OUString* pNames = aNames.getConstArray();
+ const ::rtl::OUString* pEnd = pNames + aNames.getLength();
+ for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
+ ;
+
+ return pNames != pEnd;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ Sequence< ::rtl::OUString > WordbookMigration::getSupportedServiceNames() throw (RuntimeException)
+ {
+ return WordbookMigration_getSupportedServiceNames();
+ }
+
+ // -----------------------------------------------------------------------------
+ // XInitialization
+ // -----------------------------------------------------------------------------
+
+ void WordbookMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const Any* pIter = aArguments.getConstArray();
+ const Any* pEnd = pIter + aArguments.getLength();
+ for ( ; pIter != pEnd ; ++pIter )
+ {
+ beans::NamedValue aValue;
+ *pIter >>= aValue;
+ if ( aValue.Name.equalsAscii( "UserData" ) )
+ {
+ if ( !(aValue.Value >>= m_sSourceDir) )
+ {
+ OSL_ENSURE( false, "WordbookMigration::initialize: argument UserData has wrong type!" );
+ }
+ m_sSourceDir += sSourceSubDir;
+ break;
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // XJob
+ // -----------------------------------------------------------------------------
+
+ Any WordbookMigration::execute( const Sequence< beans::NamedValue >& )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ copyFiles();
+
+ return Any();
+ }
+
+ // =============================================================================
+ // component operations
+ // =============================================================================
+
+ Reference< XInterface > SAL_CALL WordbookMigration_create(
+ Reference< XComponentContext > const & )
+ SAL_THROW( () )
+ {
+ return static_cast< lang::XTypeProvider * >( new WordbookMigration() );
+ }
+
+ // -----------------------------------------------------------------------------
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
diff --git a/desktop/source/migration/services/wordbookmigration.hxx b/desktop/source/migration/services/wordbookmigration.hxx
new file mode 100755
index 000000000000..f4dc4c0d2628
--- /dev/null
+++ b/desktop/source/migration/services/wordbookmigration.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _DESKTOP_WORDBOOKMIGRATION_HXX_
+#define _DESKTOP_WORDBOOKMIGRATION_HXX_
+
+#include "misc.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+
+
+class INetURLObject;
+
+
+//.........................................................................
+namespace migration
+{
+//.........................................................................
+
+ ::rtl::OUString SAL_CALL WordbookMigration_getImplementationName();
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL WordbookMigration_getSupportedServiceNames();
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL WordbookMigration_create(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) );
+
+
+ // =============================================================================
+ // class WordbookMigration
+ // =============================================================================
+
+ typedef ::cppu::WeakImplHelper3<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::task::XJob > WordbookMigration_BASE;
+
+ class WordbookMigration : public WordbookMigration_BASE
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ ::rtl::OUString m_sSourceDir;
+
+ TStringVectorPtr getFiles( const ::rtl::OUString& rBaseURL ) const;
+ ::osl::FileBase::RC checkAndCreateDirectory( INetURLObject& rDirURL );
+ void copyFiles();
+
+ public:
+ WordbookMigration();
+ virtual ~WordbookMigration();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XJob
+ virtual ::com::sun::star::uno::Any SAL_CALL execute(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+ };
+
+//.........................................................................
+} // namespace migration
+//.........................................................................
+
+#endif // _DESKTOP_AUTOCORRMIGRATION_HXX_
diff --git a/desktop/source/migration/wizard.cxx b/desktop/source/migration/wizard.cxx
new file mode 100644
index 000000000000..81a789a613b9
--- /dev/null
+++ b/desktop/source/migration/wizard.cxx
@@ -0,0 +1,654 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <migration.hxx>
+#include "wizard.hxx"
+#include "wizard.hrc"
+#include "pages.hxx"
+#include "app.hxx"
+
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/string.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/bootstrap.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+#include <tools/datetime.hxx>
+#include <osl/file.hxx>
+#include <osl/time.h>
+#include <osl/module.hxx>
+#include <unotools/bootstrap.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+
+using namespace svt;
+using namespace rtl;
+using namespace osl;
+using namespace utl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::container;
+
+#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace desktop
+{
+
+const FirstStartWizard::WizardState FirstStartWizard::STATE_WELCOME = 0;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_LICENSE = 1;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_MIGRATION = 2;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_USER = 3;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_UPDATE_CHECK = 4;
+const FirstStartWizard::WizardState FirstStartWizard::STATE_REGISTRATION = 5;
+
+static uno::Reference< uno::XComponentContext > getComponentContext( const uno::Reference< lang::XMultiServiceFactory >& rFactory )
+{
+ uno::Reference< uno::XComponentContext > rContext;
+ uno::Reference< beans::XPropertySet > rPropSet( rFactory, uno::UNO_QUERY );
+ uno::Any a = rPropSet->getPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) );
+ a >>= rContext;
+ return rContext;
+}
+
+static sal_Int32 getBuildId()
+{
+ ::rtl::OUString aDefault;
+ ::rtl::OUString aBuildIdData = utl::Bootstrap::getBuildIdData( aDefault );
+ sal_Int32 nBuildId( 0 );
+ sal_Int32 nIndex1 = aBuildIdData.indexOf(':');
+ sal_Int32 nIndex2 = aBuildIdData.indexOf(')');
+ if (( nIndex1 > 0 ) && ( nIndex2 > 0 ) && ( nIndex2-1 > nIndex1+1 ))
+ {
+ ::rtl::OUString aBuildId = aBuildIdData.copy( nIndex1+1, nIndex2-nIndex1-1 );
+ nBuildId = aBuildId.toInt32();
+ }
+ return nBuildId;
+}
+
+WizardResId::WizardResId( USHORT nId ) :
+ ResId( nId, *FirstStartWizard::GetResManager() )
+{
+}
+
+ResMgr *FirstStartWizard::pResMgr = 0;
+
+ResMgr *FirstStartWizard::GetResManager()
+{
+ if ( !FirstStartWizard::pResMgr )
+ {
+ String aMgrName = String::CreateFromAscii( "dkt" );
+ FirstStartWizard::pResMgr = ResMgr::CreateResMgr( OUStringToOString( aMgrName, RTL_TEXTENCODING_UTF8 ));
+ }
+ return FirstStartWizard::pResMgr;
+}
+
+FirstStartWizard::FirstStartWizard( Window* pParent, sal_Bool bLicenseNeedsAcceptance, const rtl::OUString &rLicensePath )
+ :RoadmapWizard( pParent, WizardResId(DLG_FIRSTSTART_WIZARD),
+ WZB_NEXT|WZB_PREVIOUS|WZB_FINISH|WZB_CANCEL|WZB_HELP)
+ ,m_bOverride(sal_False)
+ ,m_aDefaultPath(0)
+ ,m_aMigrationPath(0)
+ ,m_bDone(sal_False)
+ ,m_bLicenseNeedsAcceptance( bLicenseNeedsAcceptance )
+ ,m_bLicenseWasAccepted(sal_False)
+ ,m_bAutomaticUpdChk(sal_True)
+ ,m_aLicensePath( rLicensePath )
+{
+ // ---
+ // FreeResource();
+// enableState(STATE_USER, sal_False);
+// enableState(STATE_REGISTRATION, sal_False);
+
+ try
+ {
+ Point pos(5, 210 );
+ Size size(11, 11 );
+
+ pos = LogicToPixel( pos, MAP_APPFONT );
+ size = LogicToPixel( size, MAP_APPFONT );
+
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ uno::Reference< awt::XToolkit > xToolkit(
+ uno::Reference< lang::XMultiComponentFactory >(
+ xFactory, uno::UNO_QUERY_THROW)->
+ createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")),
+ getComponentContext(xFactory)),
+ uno::UNO_QUERY_THROW);
+
+ m_xThrobber = uno::Reference< awt::XThrobber >(
+ xToolkit->createWindow(
+ awt::WindowDescriptor(
+ awt::WindowClass_SIMPLE,
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Throbber")),
+ GetComponentInterface(), 0,
+ awt::Rectangle(
+ pos.X(), pos.Y(), size.Width(), size.Height()),
+ awt::WindowAttribute::SHOW)),
+ uno::UNO_QUERY_THROW);
+ }
+ catch (uno::RuntimeException &)
+ {
+ throw;
+ }
+ catch (Exception& )
+ {
+ }
+
+ uno::Reference< awt::XWindow > xThrobberWin( m_xThrobber, uno::UNO_QUERY );
+ if ( xThrobberWin.is() )
+ xThrobberWin->setVisible( false );
+
+ Size aTPSize(TP_WIDTH, TP_HEIGHT);
+ SetPageSizePixel(LogicToPixel(aTPSize, MAP_APPFONT));
+
+ //set help id
+ m_pPrevPage->SetHelpId(HID_FIRSTSTART_PREV);
+ m_pNextPage->SetHelpId(HID_FIRSTSTART_NEXT);
+ m_pCancel->SetHelpId(HID_FIRSTSTART_CANCEL);
+ m_pFinish->SetHelpId(HID_FIRSTSTART_FINISH);
+ // m_pHelp->SetUniqueId(UID_FIRSTSTART_HELP);
+ m_pHelp->Hide();
+ m_pHelp->Disable();
+
+ // save button lables
+ m_sNext = m_pNextPage->GetText();
+ m_sCancel = m_pCancel->GetText();
+
+ // save cancel click handler
+ m_lnkCancel = m_pCancel->GetClickHdl();
+
+ m_aDefaultPath = defineWizardPagesDependingFromContext();
+ activatePath(m_aDefaultPath, sal_True);
+
+ enterState(STATE_WELCOME);
+ ActivatePage();
+
+ // set text of finish putton:
+ m_pFinish->SetText(String(WizardResId(STR_FINISH)));
+ // disable "finish button"
+ enableButtons(WZB_FINISH, sal_False);
+ defaultButton(WZB_NEXT);
+}
+
+void FirstStartWizard::DisableButtonsWhileMigration()
+{
+ enableButtons(0xff, sal_False);
+}
+
+::svt::RoadmapWizardTypes::PathId FirstStartWizard::defineWizardPagesDependingFromContext()
+{
+ ::svt::RoadmapWizardTypes::PathId aDefaultPath = 0;
+
+ sal_Bool bPage_Welcome = sal_True;
+ sal_Bool bPage_License = sal_True;
+ sal_Bool bPage_Migration = sal_True;
+ sal_Bool bPage_User = sal_True;
+ sal_Bool bPage_UpdateCheck = sal_True;
+ sal_Bool bPage_Registration = sal_True;
+
+ bPage_License = m_bLicenseNeedsAcceptance;
+ bPage_Migration = Migration::checkMigration();
+ bPage_UpdateCheck = showOnlineUpdatePage();
+
+ WizardPath aPath;
+ if (bPage_Welcome)
+ aPath.push_back(STATE_WELCOME);
+ if (bPage_License)
+ aPath.push_back(STATE_LICENSE);
+ if (bPage_Migration)
+ aPath.push_back(STATE_MIGRATION);
+ if (bPage_User)
+ aPath.push_back(STATE_USER);
+ if (bPage_UpdateCheck)
+ aPath.push_back(STATE_UPDATE_CHECK);
+ if (bPage_Registration)
+ aPath.push_back(STATE_REGISTRATION);
+
+ declarePath(aDefaultPath, aPath);
+
+ // a) If license must be accepted by the user, all direct links
+ // to wizard tab pages must be disabled. Because such pages
+ // should be accessible only in case license was accepted !
+ // b) But if no license should be shown at all ...
+ // such direct links can be enabled by default.
+ sal_Bool bAllowDirectLink = ( ! bPage_License);
+
+ if (bPage_User)
+ enableState(STATE_USER, bAllowDirectLink);
+ if (bPage_UpdateCheck)
+ enableState(STATE_UPDATE_CHECK, bAllowDirectLink);
+ if (bPage_Migration)
+ enableState(STATE_MIGRATION, bAllowDirectLink);
+ if (bPage_Registration)
+ enableState(STATE_REGISTRATION, bAllowDirectLink);
+
+ return aDefaultPath;
+}
+
+// catch F1 and disable help
+long FirstStartWizard::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
+ if( rKey.GetCode() == KEY_F1 && ! rKey.GetModifier() )
+ return TRUE;
+ }
+ return RoadmapWizard::PreNotify(rNEvt);
+}
+
+
+void FirstStartWizard::enterState(WizardState _nState)
+{
+ RoadmapWizard::enterState(_nState);
+ // default state
+ // all on
+ enableButtons(0xff, sal_True);
+ // finish off
+ enableButtons(WZB_FINISH, sal_False);
+ // default text
+ m_pCancel->SetText(m_sCancel);
+ m_pCancel->SetClickHdl(m_lnkCancel);
+ m_pNextPage->SetText(m_sNext);
+
+ // default
+ defaultButton(WZB_NEXT);
+
+ // specialized state
+ switch (_nState)
+ {
+ case STATE_WELCOME:
+ enableButtons(WZB_PREVIOUS, sal_False);
+ break;
+ case STATE_LICENSE:
+ m_pCancel->SetText(String(WizardResId(STR_LICENSE_DECLINE)));
+ m_pNextPage->SetText(String(WizardResId(STR_LICENSE_ACCEPT)));
+ enableButtons(WZB_NEXT, sal_False);
+ // attach warning dialog to cancel/decline button
+ m_pCancel->SetClickHdl( LINK(this, FirstStartWizard, DeclineHdl) );
+ break;
+ case STATE_REGISTRATION:
+ enableButtons(WZB_NEXT, sal_False);
+ enableButtons(WZB_FINISH, sal_True);
+ defaultButton(WZB_FINISH);
+ break;
+ }
+
+ // focus
+
+}
+
+IMPL_LINK( FirstStartWizard, DeclineHdl, PushButton *, EMPTYARG )
+{
+ QueryBox aBox(this, WizardResId(QB_ASK_DECLINE));
+ sal_Int32 ret = aBox.Execute();
+ if ( ret == BUTTON_OK || ret == BUTTON_YES)
+ {
+ Close();
+ return sal_False;
+ }
+ else
+ return sal_True;
+}
+
+
+TabPage* FirstStartWizard::createPage(WizardState _nState)
+{
+ TabPage *pTabPage = 0;
+ switch (_nState)
+ {
+ case STATE_WELCOME:
+ pTabPage = new WelcomePage(this, WizardResId(TP_WELCOME), m_bLicenseNeedsAcceptance);
+ break;
+ case STATE_LICENSE:
+ pTabPage = new LicensePage(this, WizardResId(TP_LICENSE), m_aLicensePath);
+ break;
+ case STATE_MIGRATION:
+ pTabPage = new MigrationPage(this, WizardResId(TP_MIGRATION), m_xThrobber );
+ break;
+ case STATE_USER:
+ pTabPage = new UserPage(this, WizardResId(TP_USER));
+ break;
+ case STATE_UPDATE_CHECK:
+ pTabPage = new UpdateCheckPage(this, WizardResId(TP_UPDATE_CHECK));
+ break;
+ case STATE_REGISTRATION:
+ pTabPage = new RegistrationPage(this, WizardResId(TP_REGISTRATION));
+ break;
+ }
+ pTabPage->Show();
+
+ return pTabPage;
+}
+
+String FirstStartWizard::getStateDisplayName( WizardState _nState ) const
+{
+ String sName;
+ switch(_nState)
+ {
+ case STATE_WELCOME:
+ sName = String(WizardResId(STR_STATE_WELCOME));
+ break;
+ case STATE_LICENSE:
+ sName = String(WizardResId(STR_STATE_LICENSE));
+ break;
+ case STATE_MIGRATION:
+ sName = String(WizardResId(STR_STATE_MIGRATION));
+ break;
+ case STATE_USER:
+ sName = String(WizardResId(STR_STATE_USER));
+ break;
+ case STATE_UPDATE_CHECK:
+ sName = String(WizardResId(STR_STATE_UPDATE_CHECK));
+ break;
+ case STATE_REGISTRATION:
+ sName = String(WizardResId(STR_STATE_REGISTRATION));
+ break;
+ }
+ return sName;
+}
+
+sal_Bool FirstStartWizard::prepareLeaveCurrentState( CommitPageReason _eReason )
+{
+ // the license acceptance is handled here, because it needs to change the state
+ // of the roadmap wizard which the page implementation does not know.
+ if (
+ (_eReason == eTravelForward) &&
+ (getCurrentState() == STATE_LICENSE ) &&
+ (m_bLicenseWasAccepted == sal_False )
+ )
+ {
+ if (Migration::checkMigration())
+ enableState(FirstStartWizard::STATE_MIGRATION, sal_True);
+ if ( showOnlineUpdatePage() )
+ enableState(FirstStartWizard::STATE_UPDATE_CHECK, sal_True);
+ enableState(FirstStartWizard::STATE_USER, sal_True);
+ enableState(FirstStartWizard::STATE_REGISTRATION, sal_True);
+
+ storeAcceptDate();
+ m_bLicenseWasAccepted = sal_True;
+ }
+
+ return svt::RoadmapWizard::prepareLeaveCurrentState(_eReason);
+}
+
+sal_Bool FirstStartWizard::leaveState(WizardState)
+{
+ if (( getCurrentState() == STATE_MIGRATION ) && m_bLicenseWasAccepted )
+ {
+ // Store accept date and patch level now as it has been
+ // overwritten by the migration process!
+ storeAcceptDate();
+ setPatchLevel();
+ }
+
+ return sal_True;
+}
+
+sal_Bool FirstStartWizard::onFinish()
+{
+ // return sal_True;
+ if ( svt::RoadmapWizard::onFinish() )
+ {
+#ifndef OS2 // cannot enable quickstart on first startup, see shutdownicon.cxx comments.
+ enableQuickstart();
+#endif
+ disableWizard();
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+short FirstStartWizard::Execute()
+{
+ return svt::RoadmapWizard::Execute();
+}
+
+static OUString _makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_False)
+{
+ OStringBuffer aDateTimeString;
+ aDateTimeString.append((sal_Int32)aDateTime.GetYear());
+ aDateTimeString.append("-");
+ if (aDateTime.GetMonth()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetMonth());
+ aDateTimeString.append("-");
+ if (aDateTime.GetDay()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetDay());
+ aDateTimeString.append("T");
+ if (aDateTime.GetHour()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetHour());
+ aDateTimeString.append(":");
+ if (aDateTime.GetMin()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetMin());
+ aDateTimeString.append(":");
+ if (aDateTime.GetSec()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetSec());
+ if (bUTC) aDateTimeString.append("Z");
+
+ return OStringToOUString(aDateTimeString.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
+}
+
+static OUString _getCurrentDateString()
+{
+ OUString aString;
+ return _makeDateTimeString(DateTime());
+}
+
+
+static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
+static const OUString sReadSrvc ( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) );
+
+void FirstStartWizard::storeAcceptDate()
+{
+
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"),
+ makeAny(OUString::createFromAscii("org.openoffice.Setup/Office")));
+ theArgs[0] <<= v;
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ Any result = pset->getPropertyValue(OUString::createFromAscii("LicenseAcceptDate"));
+
+ OUString aAcceptDate = _getCurrentDateString();
+ pset->setPropertyValue(OUString::createFromAscii("LicenseAcceptDate"), makeAny(aAcceptDate));
+ Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
+
+ // since the license is accepted the local user registry can be cleaned if required
+ cleanOldOfficeRegKeys();
+ } catch (const Exception&)
+ {
+ }
+
+}
+
+void FirstStartWizard::setPatchLevel()
+{
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"),
+ makeAny(OUString::createFromAscii("org.openoffice.Office.Common/Help/Registration")));
+ theArgs[0] <<= v;
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ Any result = pset->getPropertyValue(OUString::createFromAscii("ReminderDate"));
+
+ OUString aPatchLevel( RTL_CONSTASCII_USTRINGPARAM( "Patch" ));
+ aPatchLevel += OUString::valueOf( getBuildId(), 10 );
+ pset->setPropertyValue(OUString::createFromAscii("ReminderDate"), makeAny(aPatchLevel));
+ Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
+ } catch (const Exception&)
+ {
+ }
+}
+
+#ifdef WNT
+typedef int ( __stdcall * CleanCurUserRegProc ) ( wchar_t* );
+#endif
+
+void FirstStartWizard::cleanOldOfficeRegKeys()
+{
+#ifdef WNT
+ // after the wizard is completed clean OOo1.1.x entries in the current user registry if required
+ // issue i47658
+
+ OUString aBaseLocationPath;
+ OUString aSharedLocationPath;
+ OUString aInstallMode;
+
+ ::utl::Bootstrap::PathStatus aBaseLocateResult =
+ ::utl::Bootstrap::locateBaseInstallation( aBaseLocationPath );
+ ::utl::Bootstrap::PathStatus aSharedLocateResult =
+ ::utl::Bootstrap::locateSharedData( aSharedLocationPath );
+ aInstallMode = ::utl::Bootstrap::getAllUsersValue( ::rtl::OUString() );
+
+ // TODO: replace the checking for install mode
+ if ( aBaseLocateResult == ::utl::Bootstrap::PATH_EXISTS && aSharedLocateResult == ::utl::Bootstrap::PATH_EXISTS
+ && aInstallMode.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1" ) ) ) )
+ {
+ ::rtl::OUString aDeregCompletePath =
+ aBaseLocationPath + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/regcleanold.dll" ) );
+ ::rtl::OUString aExecCompletePath =
+ aSharedLocationPath + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/regdeinstall/userdeinst.exe" ) );
+
+ osl::Module aCleanModule( aDeregCompletePath );
+ CleanCurUserRegProc pNativeProc = ( CleanCurUserRegProc )(
+ aCleanModule.getFunctionSymbol(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CleanCurUserOldSystemRegistry" ) ) ) );
+
+ if( pNativeProc!=NULL )
+ {
+ ::rtl::OUString aExecCompleteSysPath;
+ if ( osl::File::getSystemPathFromFileURL( aExecCompletePath, aExecCompleteSysPath ) == FileBase::E_None
+ && aExecCompleteSysPath.getLength() )
+ {
+ ( *pNativeProc )( (wchar_t*)( aExecCompleteSysPath.getStr() ) );
+ }
+ }
+ }
+#endif
+}
+
+void FirstStartWizard::disableWizard()
+{
+
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"),
+ makeAny(OUString::createFromAscii("org.openoffice.Setup/Office")));
+ theArgs[0] <<= v;
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ pset->setPropertyValue(OUString::createFromAscii("FirstStartWizardCompleted"), makeAny(sal_True));
+ Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
+ } catch (const Exception&)
+ {
+ }
+
+}
+
+
+void FirstStartWizard::enableQuickstart()
+{
+ sal_Bool bQuickstart( sal_True );
+ sal_Bool bAutostart( sal_True );
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= bQuickstart;
+ aSeq[1] <<= bAutostart;
+
+ Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString::createFromAscii( "com.sun.star.office.Quickstart" )),UNO_QUERY );
+ if ( xQuickstart.is() )
+ xQuickstart->initialize( aSeq );
+
+}
+
+sal_Bool FirstStartWizard::showOnlineUpdatePage()
+{
+ try {
+ Reference < XNameReplace > xUpdateAccess;
+ Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+
+ xUpdateAccess = Reference < XNameReplace >(
+ xFactory->createInstance( UNISTRING( "com.sun.star.setup.UpdateCheckConfig" ) ), UNO_QUERY_THROW );
+
+ if ( xUpdateAccess.is() )
+ {
+ sal_Bool bAutoUpdChk = sal_False;
+ Any result = xUpdateAccess->getByName( UNISTRING( "AutoCheckEnabled" ) );
+ result >>= bAutoUpdChk;
+ if ( bAutoUpdChk == sal_False )
+ return sal_True;
+ else
+ return sal_False;
+ }
+ } catch (const Exception&)
+ {
+ }
+ return sal_False;
+}
+
+}
diff --git a/desktop/source/migration/wizard.hrc b/desktop/source/migration/wizard.hrc
new file mode 100644
index 000000000000..fdad97a8174b
--- /dev/null
+++ b/desktop/source/migration/wizard.hrc
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "desktop.hrc"
+#include "helpid.hrc"
+
+#define TP_WIDTH 220
+#define TP_HEIGHT 205
+
+#define DLG_FIRSTSTART_WIZARD RID_FIRSTSTSTART_START+1
+ // FREE
+#define TP_WELCOME RID_FIRSTSTSTART_START+3
+#define TP_REGISTRATION RID_FIRSTSTSTART_START+4
+#define TP_MIGRATION RID_FIRSTSTSTART_START+5
+#define TP_USER RID_FIRSTSTSTART_START+6
+#define TP_LICENSE RID_FIRSTSTSTART_START+7
+#define TP_UPDATE_CHECK RID_FIRSTSTSTART_START+8
+#define ERRBOX_REG_NOSYSBROWSER RID_FIRSTSTSTART_START+29
+#define QB_ASK_DECLINE RID_FIRSTSTSTART_START+30
+
+// local resIDs
+
+#define FT_WELCOME_HEADER 1
+#define FT_WELCOME_BODY 2
+#define FT_LICENSE_HEADER 1
+#define FT_LICENSE_BODY_1 2
+#define FT_LICENSE_BODY_1_TXT 3
+#define FT_LICENSE_BODY_2 4
+#define FT_LICENSE_BODY_2_TXT 5
+#define ML_LICENSE 6
+#define PB_LICENSE_DOWN 7
+#define FT_MIGRATION_HEADER 1
+#define FT_MIGRATION_BODY 2
+#define CB_MIGRATION 3
+#define FT_UPDATE_CHECK_HEADER 1
+#define FT_UPDATE_CHECK_BODY 2
+#define CB_UPDATE_CHECK 3
+#define FT_REGISTRATION_HEADER 1
+#define FT_REGISTRATION_BODY 2
+#define FL_REGISTRATION 3
+#define FT_REGISTRATION_END 4
+#define RB_REGISTRATION_NOW 5
+#define RB_REGISTRATION_LATER 6
+#define RB_REGISTRATION_NEVER 7
+#define RB_REGISTRATION_REG 8
+#define IMG_REGISTRATION 9
+#define FT_USER_HEADER 10
+#define FT_USER_BODY 11
+#define FT_USER_FIRST 12
+#define FT_USER_LAST 13
+#define FT_USER_FATHER 14
+#define FT_USER_INITIALS 15
+#define ED_USER_FIRST 16
+#define ED_USER_LAST 17
+#define ED_USER_FATHER 18
+#define ED_USER_INITIALS 19
+#define TR_WAITING 20
+
+// global strings
+#define STR_STATE_WELCOME RID_FIRSTSTSTART_START+100
+#define STR_STATE_LICENSE RID_FIRSTSTSTART_START+101
+#define STR_STATE_MIGRATION RID_FIRSTSTSTART_START+102
+#define STR_STATE_REGISTRATION RID_FIRSTSTSTART_START+103
+#define STR_WELCOME_MIGRATION RID_FIRSTSTSTART_START+104
+// FREE RID_FIRSTSTSTART_START+105
+// FREE RID_FIRSTSTSTART_START+106
+#define STR_LICENSE_ACCEPT RID_FIRSTSTSTART_START+107
+#define STR_LICENSE_DECLINE RID_FIRSTSTSTART_START+108
+#define STR_FINISH RID_FIRSTSTSTART_START+109
+#define STR_STATE_USER RID_FIRSTSTSTART_START+110
+// FREE RID_FIRSTSTSTART_START+111
+#define STR_STATE_UPDATE_CHECK RID_FIRSTSTSTART_START+112
+#define STR_WELCOME_WITHOUT_LICENSE RID_FIRSTSTSTART_START+113
+#define STR_REGISTRATION_OOO RID_FIRSTSTSTART_START+114
+
diff --git a/desktop/source/migration/wizard.hxx b/desktop/source/migration/wizard.hxx
new file mode 100644
index 000000000000..3317880f8bd6
--- /dev/null
+++ b/desktop/source/migration/wizard.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _WIZARD_HXX_
+#define _WIZARD_HXX_
+
+#include <rtl/ustring.hxx>
+#include <svtools/roadmapwizard.hxx>
+#include <vcl/window.hxx>
+#include <tools/resid.hxx>
+#include <com/sun/star/awt/XThrobber.hpp>
+
+namespace desktop
+{
+
+class WizardResId : public ResId
+{
+public:
+ WizardResId( USHORT nId );
+};
+
+class FirstStartWizard : public svt::RoadmapWizard
+{
+
+public:
+ static const WizardState STATE_WELCOME;
+ static const WizardState STATE_LICENSE;
+ static const WizardState STATE_MIGRATION;
+ static const WizardState STATE_USER;
+ static const WizardState STATE_UPDATE_CHECK;
+ static const WizardState STATE_REGISTRATION;
+
+ static ResMgr* pResMgr;
+ static ResMgr* GetResManager();
+
+ FirstStartWizard( Window* pParent, sal_Bool bLicenseNeedsAcceptance, const rtl::OUString &rLicensePath );
+
+ virtual short Execute();
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ void DisableButtonsWhileMigration();
+
+private:
+ sal_Bool m_bOverride;
+ WizardState _currentState;
+ ::svt::RoadmapWizardTypes::PathId m_aDefaultPath;
+ ::svt::RoadmapWizardTypes::PathId m_aMigrationPath;
+ String m_sNext;
+ String m_sCancel;
+ sal_Bool m_bDone;
+ sal_Bool m_bLicenseNeedsAcceptance;
+ sal_Bool m_bLicenseWasAccepted;
+ sal_Bool m_bAutomaticUpdChk;
+ Link m_lnkCancel;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XThrobber > m_xThrobber;
+
+ rtl::OUString m_aLicensePath;
+
+ void storeAcceptDate();
+ void setPatchLevel();
+ void disableWizard();
+ void enableQuickstart();
+
+ DECL_LINK(DeclineHdl, PushButton*);
+
+ void cleanOldOfficeRegKeys();
+ sal_Bool showOnlineUpdatePage();
+ ::svt::RoadmapWizardTypes::PathId defineWizardPagesDependingFromContext();
+
+protected:
+ // from svt::WizardMachine
+ virtual TabPage* createPage(WizardState _nState);
+ virtual sal_Bool prepareLeaveCurrentState( CommitPageReason _eReason );
+ virtual sal_Bool leaveState(WizardState _nState );
+ virtual sal_Bool onFinish();
+ virtual void enterState(WizardState _nState);
+
+ // from svt::RoadmapWizard
+ virtual String getStateDisplayName( WizardState _nState ) const;
+};
+}
+#endif
diff --git a/desktop/source/migration/wizard.src b/desktop/source/migration/wizard.src
new file mode 100644
index 000000000000..9c1ab5496d39
--- /dev/null
+++ b/desktop/source/migration/wizard.src
@@ -0,0 +1,424 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+ /*
+ * encoding for resources: windows-1252
+ */
+
+#include "wizard.hrc"
+#include <svtools/controldims.hrc>
+
+ModalDialog DLG_FIRSTSTART_WIZARD
+{
+ Text [ en-US ] = "Welcome to %PRODUCTNAME %PRODUCTVERSION";
+
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Hide = TRUE;
+ HelpID = HID_FIRSTSTART_DIALOG;
+};
+
+String STR_STATE_WELCOME
+{
+ Text [ en-US ] = "Welcome";
+};
+String STR_STATE_LICENSE
+{
+ Text [ en-US ] = "License Agreement";
+};
+String STR_STATE_MIGRATION
+{
+ Text [ en-US ] = "Personal Data";
+};
+String STR_STATE_USER
+{
+ Text [ en-US ] = "User name";
+};
+
+String STR_STATE_UPDATE_CHECK
+{
+ Text [ en-US ] = "Online Update";
+};
+
+String STR_STATE_REGISTRATION
+{
+ Text [ en-US ] = "Registration";
+};
+
+String STR_WELCOME_MIGRATION
+{
+ Text [ en-US ] = "This wizard will guide you through the license agreement, the transfer of user data from %OLD_VERSION and the registration of %PRODUCTNAME.\n\nClick 'Next' to continue.";
+
+};
+
+String STR_WELCOME_WITHOUT_LICENSE
+{
+ Text [ en-US ] = "This wizard will guide you through the registration of %PRODUCTNAME.\n\nClick 'Next' to continue.";
+};
+
+String STR_FINISH
+{
+ Text [ en-US ] = "~Finish";
+};
+
+String STR_REGISTRATION_OOO
+{
+ Text [ en-US ] = "You now have the opportunity to support and contribute to the fastest growing open source community in the world.\n\nHelp us prove that %PRODUCTNAME has already gained significant market share by registering.\n\nRegistering is voluntary and without obligation.";
+};
+
+ErrorBox ERRBOX_REG_NOSYSBROWSER
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+
+ Message [ en-US ] = "An error occurred in starting the web browser.\nPlease check the %PRODUCTNAME and web browser settings.";
+};
+
+QueryBox QB_ASK_DECLINE
+{
+ Buttons = WB_YES_NO;
+ DefButton = WB_DEF_NO;
+
+ Message [ en-US ] = "Do you really want to decline?";
+};
+
+
+#define ROWHEIGHT 8
+#define MARGINLEFT 10
+#define MARGINRIGHT 10
+#define BODYWIDTH TP_WIDTH-MARGINLEFT-MARGINRIGHT
+#define MARGINTOP 10
+#define MARGINBOTTOM 2
+#define BODYHEIGHT TP_HEIGHT-MARGINTOP-MARGINBOTTOM
+#define INDENT 10
+#define INDENT2 12
+
+TabPage TP_WELCOME
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_WELCOME;
+ // bold fixedtext for header
+ FixedText FT_WELCOME_HEADER
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINRIGHT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ Text [ en-US ] = "Welcome to %PRODUCTNAME %PRODUCTVERSION";
+ };
+ FixedText FT_WELCOME_BODY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP + 2*ROWHEIGHT);
+ Size = MAP_APPFONT( BODYWIDTH, BODYHEIGHT-MARGINTOP - 2*ROWHEIGHT );
+ WordBreak = TRUE;
+ Text [ en-US ] = "This wizard will guide you through the license agreement and the registration of %PRODUCTNAME.\n\nClick 'Next' to continue.";
+ };
+};
+
+TabPage TP_LICENSE
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_LICENSE;
+ FixedText FT_LICENSE_HEADER
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ NoLabel = TRUE;
+ Text [ en-US ] = "Please follow these steps to accept the license";
+ };
+ FixedText FT_LICENSE_BODY_1
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP + 2*ROWHEIGHT);
+ Size = MAP_APPFONT( INDENT, ROWHEIGHT );
+ NoLabel = TRUE;
+ Text [ en-US ] = "1.";
+ };
+ FixedText FT_LICENSE_BODY_1_TXT
+ {
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT, MARGINTOP +2*ROWHEIGHT);
+ Size = MAP_APPFONT( BODYWIDTH-INDENT, 3*ROWHEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "View the complete License Agreement. Please use the scrollbar or the '%PAGEDOWN' button in this dialog to view the entire license text.";
+ };
+ FixedText FT_LICENSE_BODY_2
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP + 5*ROWHEIGHT);
+ Size = MAP_APPFONT(INDENT, ROWHEIGHT );
+ NoLabel = TRUE;
+ Text [ en-US ] = "2.";
+ };
+ FixedText FT_LICENSE_BODY_2_TXT
+ {
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT, MARGINTOP + 5*ROWHEIGHT);
+ Size = MAP_APPFONT( BODYWIDTH-INDENT, 2*ROWHEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "Click 'Accept' to accept the terms of the Agreement.";
+ };
+ MultiLineEdit ML_LICENSE
+ {
+ PosSize = MAP_APPFONT (MARGINLEFT+INDENT, MARGINTOP + 8*ROWHEIGHT, BODYWIDTH-INDENT , BODYHEIGHT - 8*ROWHEIGHT - 20-2*MARGINBOTTOM) ;
+ Border = TRUE;
+ VScroll = TRUE;
+ ReadOnly = TRUE;
+ };
+ PushButton PB_LICENSE_DOWN
+ {
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( TP_WIDTH-MARGINRIGHT-50 , TP_HEIGHT-MARGINBOTTOM-18 ) ;
+ Size = MAP_APPFONT ( 50, 15 ) ;
+ Text [ en-US ] = "Scroll Do~wn";
+ };
+};
+
+String STR_LICENSE_ACCEPT
+{
+ Text [ en-US ] = "~Accept";
+};
+String STR_LICENSE_DECLINE
+{
+ Text [ en-US ] = "~Decline";
+};
+
+
+TabPage TP_MIGRATION
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_MIGRATION;
+
+ FixedText FT_MIGRATION_HEADER
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ Text [ en-US ] = "Transfer personal data";
+
+ };
+
+ FixedText FT_MIGRATION_BODY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*8);
+ WordBreak = TRUE;
+ Text [ en-US ] = "Most personal data from %OLDPRODUCT installation can be reused in %PRODUCTNAME %PRODUCTVERSION.\n\nIf you do not want to reuse any settings in %PRODUCTNAME %PRODUCTVERSION, unmark the check box.";
+
+ };
+
+ CheckBox CB_MIGRATION
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*10);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*2);
+ Check = TRUE;
+ Text [ en-US ] = "Transfer personal data";
+ };
+};
+
+TabPage TP_UPDATE_CHECK
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_UPDATE_CHECK;
+
+ FixedText FT_UPDATE_CHECK_HEADER
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ Text [ en-US ] = "Online Update";
+
+ };
+
+ FixedText FT_UPDATE_CHECK_BODY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*8);
+ WordBreak = TRUE;
+ Text [ en-US ] = "%PRODUCTNAME searches automatically at regular intervals for new versions.\nIn doing so online update does not transfer personal data.\nAs soon as a new version is available, you will be notified.\n\nYou can configure this feature at Tools / Options... / %PRODUCTNAME / Online Update.";
+
+ };
+
+ CheckBox CB_UPDATE_CHECK
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*10);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*2);
+ Check = TRUE;
+ Text [ en-US ] = "~Check for updates automatically";
+ };
+};
+
+#define USERINDENT 40
+#define EDHEIGHT 12
+#define INITIALSWIDTH 50
+#define FTADD 2
+
+TabPage TP_USER
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_USER;
+
+ FixedText FT_USER_HEADER
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP);
+ Size = MAP_APPFONT( BODYWIDTH, ROWHEIGHT );
+ Text [ en-US ] = "Provide your full name and initials below";
+
+ };
+
+ FixedText FT_USER_BODY
+ {
+ NoLabel = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*3);
+ WordBreak = TRUE;
+ Text [ en-US ] = "The user name will be used in the document properties, templates and when you record changes made to documents.";
+ };
+
+
+ FixedText FT_USER_FIRST
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*7+FTADD);
+ Size = MAP_APPFONT(USERINDENT, ROWHEIGHT);
+ Text [ en-US ] = "~First name";
+ };
+ Edit ED_USER_FIRST
+ {
+ Border = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT, MARGINTOP+ROWHEIGHT*7);
+ Size = MAP_APPFONT(BODYWIDTH-USERINDENT, EDHEIGHT);
+ };
+ FixedText FT_USER_LAST
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*9+FTADD);
+ Size = MAP_APPFONT(USERINDENT, ROWHEIGHT);
+ Text [ en-US ] = "~Last name";
+ };
+ Edit ED_USER_LAST
+ {
+ Border = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT, MARGINTOP+ROWHEIGHT*9);
+ Size = MAP_APPFONT(BODYWIDTH-USERINDENT, EDHEIGHT);
+ };
+ FixedText FT_USER_INITIALS
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*11+FTADD);
+ Size = MAP_APPFONT(USERINDENT, ROWHEIGHT);
+ Text [ en-US ] = "~Initials";
+ };
+ Edit ED_USER_INITIALS
+ {
+ Border = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT, MARGINTOP+ROWHEIGHT*11);
+ Size = MAP_APPFONT(INITIALSWIDTH, EDHEIGHT);
+ };
+
+ FixedText FT_USER_FATHER
+ {
+ Hide = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT+INITIALSWIDTH+10, MARGINTOP+ROWHEIGHT*11+FTADD);
+ Size = MAP_APPFONT(USERINDENT, ROWHEIGHT);
+ Text [ en-US ] = "~Father's name";
+ };
+ Edit ED_USER_FATHER
+ {
+ Border = TRUE;
+ Hide = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT+USERINDENT*2+INITIALSWIDTH+10, MARGINTOP+ROWHEIGHT*11);
+ Size = MAP_APPFONT(BODYWIDTH-10-USERINDENT*2-INITIALSWIDTH, EDHEIGHT);
+ };
+};
+
+#define RB_HEIGHT (RSC_CD_CHECKBOX_HEIGHT+RSC_SP_GRP_SPACE_Y)
+
+TabPage TP_REGISTRATION
+{
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT(TP_WIDTH, TP_HEIGHT);
+ HelpID = HID_FIRSTSTART_REGISTRATION;
+ FixedText FT_REGISTRATION_HEADER
+ {
+ NoLabel = TRUE;
+ Text [ en-US ] = "%PRODUCTNAME Registration";
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINRIGHT);
+ Size = MAP_APPFONT(BODYWIDTH, MARGINRIGHT);
+ };
+ FixedText FT_REGISTRATION_BODY
+ {
+ NoLabel = TRUE;
+ Text [ en-US ] = "You now have the opportunity to register as a %PRODUCTNAME user. Registration is voluntary and is without obligation.\n\nIf you register, we can inform you about new developments concerning this product.";
+ WordBreak = TRUE;
+ Pos = MAP_APPFONT(MARGINLEFT, MARGINTOP+ROWHEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*8);
+ };
+ RadioButton RB_REGISTRATION_NOW
+ {
+ Text [ en-US ] = "I want to register ~now";
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT2, ROWHEIGHT*12+2);
+ Size = MAP_APPFONT(BODYWIDTH-INDENT2, RSC_CD_CHECKBOX_HEIGHT);
+ Check = TRUE;
+ };
+ RadioButton RB_REGISTRATION_LATER
+ {
+ Text [ en-US ] = "I want to register ~later";
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT2, ROWHEIGHT*12+2+RB_HEIGHT);
+ Size = MAP_APPFONT(BODYWIDTH-INDENT2, RSC_CD_CHECKBOX_HEIGHT);
+ };
+ RadioButton RB_REGISTRATION_NEVER
+ {
+ Text [ en-US ] = "I do not want to ~register";
+ Pos = MAP_APPFONT(MARGINLEFT+INDENT2, ROWHEIGHT*12+2+RB_HEIGHT*2);
+ Size = MAP_APPFONT(BODYWIDTH-INDENT2, RSC_CD_CHECKBOX_HEIGHT);
+ };
+ FixedLine FL_REGISTRATION
+ {
+ Pos = MAP_APPFONT(MARGINLEFT, TP_HEIGHT-MARGINBOTTOM-ROWHEIGHT*6);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT);
+ };
+ FixedText FT_REGISTRATION_END
+ {
+ NoLabel = TRUE;
+ Text [ en-US ] = "We hope you enjoy working with %PRODUCTNAME.\n\nTo exit the wizard, click 'Finish'.";
+ Pos = MAP_APPFONT(MARGINLEFT, TP_HEIGHT-MARGINBOTTOM-ROWHEIGHT*4);
+ Size = MAP_APPFONT(BODYWIDTH, ROWHEIGHT*4);
+ };
+};
+
diff --git a/desktop/source/offacc/acceptor.cxx b/desktop/source/offacc/acceptor.cxx
new file mode 100644
index 000000000000..4e100fd99665
--- /dev/null
+++ b/desktop/source/offacc/acceptor.cxx
@@ -0,0 +1,367 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "acceptor.hxx"
+#include <unotools/bootstrap.hxx>
+#include <vos/process.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#ifndef _COM_SUN_STAR_UNO_XNAMEINGSERVICE_HPP_
+#include <com/sun/star/uno/XNamingService.hpp>
+#endif
+
+#include <cppuhelper/factory.hxx>
+
+namespace desktop
+{
+
+extern "C" void workerfunc (void * acc)
+{
+ ((Acceptor*)acc)->run();
+}
+
+static Reference<XInterface> getComponentContext( const Reference<XMultiServiceFactory>& rFactory)
+{
+ Reference<XInterface> rContext;
+ Reference< XPropertySet > rPropSet( rFactory, UNO_QUERY );
+ Any a = rPropSet->getPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) );
+ a >>= rContext;
+ return rContext;
+}
+
+Mutex Acceptor::m_aMutex;
+
+Acceptor::Acceptor( const Reference< XMultiServiceFactory >& rFactory )
+ : m_thread(NULL)
+ , m_aAcceptString()
+ , m_aConnectString()
+ , m_aProtocol()
+ , m_bInit(sal_False)
+ , m_bDying(false)
+{
+ m_rSMgr = rFactory;
+ m_rAcceptor = Reference< XAcceptor > (m_rSMgr->createInstance(
+ rtl::OUString::createFromAscii( "com.sun.star.connection.Acceptor" )),
+ UNO_QUERY );
+ m_rBridgeFactory = Reference < XBridgeFactory > (m_rSMgr->createInstance(
+ rtl::OUString::createFromAscii( "com.sun.star.bridge.BridgeFactory" )),
+ UNO_QUERY );
+ // get component context
+ m_rContext = getComponentContext(m_rSMgr);
+}
+
+
+Acceptor::~Acceptor()
+{
+ m_rAcceptor->stopAccepting();
+ oslThread t;
+ {
+ osl::MutexGuard g(m_aMutex);
+ t = m_thread;
+ }
+ //prevent locking if the thread is still waiting
+ m_bDying = true;
+ m_cEnable.set();
+ osl_joinWithThread(t);
+ {
+ // Make the final state of m_bridges visible to this thread (since
+ // m_thread is joined, the code that follows is the only one left
+ // accessing m_bridges):
+ osl::MutexGuard g(m_aMutex);
+ }
+ for (;;) {
+ com::sun::star::uno::Reference< com::sun::star::bridge::XBridge > b(
+ m_bridges.remove());
+ if (!b.is()) {
+ break;
+ }
+ com::sun::star::uno::Reference< com::sun::star::lang::XComponent >(
+ b, com::sun::star::uno::UNO_QUERY_THROW)->dispose();
+ }
+}
+
+void SAL_CALL Acceptor::run()
+{
+ while ( m_rAcceptor.is() && m_rBridgeFactory.is() )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (lo119109) Acceptor::run" );
+ try
+ {
+ // wait until we get enabled
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109)"\
+ "Acceptor::run waiting for office to come up");
+ m_cEnable.wait();
+ if (m_bDying) //see destructor
+ break;
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109)"\
+ "Acceptor::run now enabled and continuing");
+
+ // accept connection
+ Reference< XConnection > rConnection = m_rAcceptor->accept( m_aConnectString );
+ // if we return without a valid connection we mus assume that the acceptor
+ // is destructed so we break out of the run method terminating the thread
+ if (! rConnection.is()) break;
+ OUString aDescription = rConnection->getDescription();
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "desktop (lo119109) Acceptor::run connection %s",
+ OUStringToOString(aDescription, RTL_TEXTENCODING_ASCII_US).getStr());
+
+ // create instanceprovider for this connection
+ Reference< XInstanceProvider > rInstanceProvider(
+ (XInstanceProvider*)new AccInstanceProvider(m_rSMgr, rConnection));
+ // create the bridge. The remote end will have a reference to this bridge
+ // thus preventing the bridge from being disposed. When the remote end releases
+ // the bridge, it will be destructed.
+ Reference< XBridge > rBridge = m_rBridgeFactory->createBridge(
+ rtl::OUString() ,m_aProtocol ,rConnection ,rInstanceProvider );
+ osl::MutexGuard g(m_aMutex);
+ m_bridges.add(rBridge);
+ } catch (Exception&) {
+ // connection failed...
+ // something went wrong during connection setup.
+ // just wait for a new connection to accept
+ }
+ }
+}
+
+// XInitialize
+void SAL_CALL Acceptor::initialize( const Sequence<Any>& aArguments )
+ throw( Exception )
+{
+ // prevent multiple initialization
+ ClearableMutexGuard aGuard( m_aMutex );
+ RTL_LOGFILE_CONTEXT( aLog, "destop (lo119109) Acceptor::initialize()" );
+
+ sal_Bool bOk = sal_False;
+
+ // arg count
+ int nArgs = aArguments.getLength();
+
+ // not yet initialized and acceptstring
+ if (!m_bInit && nArgs > 0 && (aArguments[0] >>= m_aAcceptString))
+ {
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "desktop (lo119109) Acceptor::initialize string=%s",
+ OUStringToOString(m_aAcceptString, RTL_TEXTENCODING_ASCII_US).getStr());
+
+ // get connect string and protocol from accept string
+ // "<connectString>;<protocol>"
+ sal_Int32 nIndex1 = m_aAcceptString.indexOf( (sal_Unicode) ';' );
+ if (nIndex1 < 0) throw IllegalArgumentException(
+ OUString::createFromAscii("Invalid accept-string format"), m_rContext, 1);
+ m_aConnectString = m_aAcceptString.copy( 0 , nIndex1 ).trim();
+ nIndex1++;
+ sal_Int32 nIndex2 = m_aAcceptString.indexOf( (sal_Unicode) ';' , nIndex1 );
+ if (nIndex2 < 0) nIndex2 = m_aAcceptString.getLength();
+ m_aProtocol = m_aAcceptString.copy( nIndex1, nIndex2 - nIndex1 );
+
+ // start accepting in new thread...
+ m_thread = osl_createThread(workerfunc, this);
+ m_bInit = sal_True;
+ bOk = sal_True;
+ }
+
+ // do we want to enable accepting?
+ sal_Bool bEnable = sal_False;
+ if (((nArgs == 1 && (aArguments[0] >>= bEnable)) ||
+ (nArgs == 2 && (aArguments[1] >>= bEnable))) &&
+ bEnable )
+ {
+ m_cEnable.set();
+ bOk = sal_True;
+ }
+
+ if (!bOk)
+ {
+ throw IllegalArgumentException(
+ OUString::createFromAscii("invalid initialization"), m_rContext, 1);
+ }
+}
+
+// XServiceInfo
+const sal_Char *Acceptor::serviceName = "com.sun.star.office.Acceptor";
+const sal_Char *Acceptor::implementationName = "com.sun.star.office.comp.Acceptor";
+const sal_Char *Acceptor::supportedServiceNames[] = {"com.sun.star.office.Acceptor", NULL};
+OUString Acceptor::impl_getImplementationName()
+{
+ return OUString::createFromAscii( implementationName );
+}
+OUString SAL_CALL Acceptor::getImplementationName()
+ throw (RuntimeException)
+{
+ return Acceptor::impl_getImplementationName();
+}
+Sequence<OUString> Acceptor::impl_getSupportedServiceNames()
+{
+ Sequence<OUString> aSequence;
+ for (int i=0; supportedServiceNames[i]!=NULL; i++) {
+ aSequence.realloc(i+1);
+ aSequence[i]=(OUString::createFromAscii(supportedServiceNames[i]));
+ }
+ return aSequence;
+}
+Sequence<OUString> SAL_CALL Acceptor::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return Acceptor::impl_getSupportedServiceNames();
+}
+sal_Bool SAL_CALL Acceptor::supportsService( const OUString&)
+ throw (RuntimeException)
+{
+ return sal_False;
+}
+
+// Factory
+Reference< XInterface > Acceptor::impl_getInstance( const Reference< XMultiServiceFactory >& aFactory )
+{
+ try {
+ return (XComponent*) new Acceptor( aFactory );
+ } catch ( Exception& ) {
+ return (XComponent*) NULL;
+ }
+}
+
+// InstanceProvider
+AccInstanceProvider::AccInstanceProvider(const Reference<XMultiServiceFactory>& aFactory, const Reference<XConnection>& rConnection)
+{
+ m_rSMgr = aFactory;
+ m_rConnection = rConnection;
+}
+
+AccInstanceProvider::~AccInstanceProvider()
+{
+}
+
+Reference<XInterface> SAL_CALL AccInstanceProvider::getInstance (const OUString& aName )
+ throw ( NoSuchElementException )
+{
+
+ Reference<XInterface> rInstance;
+
+ if ( aName.compareToAscii( "StarOffice.ServiceManager" ) == 0)
+ {
+ rInstance = Reference< XInterface >( m_rSMgr );
+ }
+ else if(aName.compareToAscii( "StarOffice.ComponentContext" ) == 0 )
+ {
+ rInstance = getComponentContext( m_rSMgr );
+ }
+ else if ( aName.compareToAscii("StarOffice.NamingService" ) == 0 )
+ {
+ Reference< XNamingService > rNamingService(
+ m_rSMgr->createInstance( OUString::createFromAscii( "com.sun.star.uno.NamingService" )),
+ UNO_QUERY );
+ if ( rNamingService.is() )
+ {
+ rNamingService->registerObject(
+ OUString::createFromAscii( "StarOffice.ServiceManager" ), m_rSMgr );
+ rNamingService->registerObject(
+ OUString::createFromAscii( "StarOffice.ComponentContext" ), getComponentContext( m_rSMgr ));
+ rInstance = rNamingService;
+ }
+ }
+ /*
+ else if ( aName.compareToAscii("com.sun.star.ucb.RemoteContentProviderAcceptor" ))
+ {
+ Reference< XMultiServiceFactory > rSMgr = ::comphelper::getProcessServiceFactory();
+ if ( rSMgr.is() ) {
+ try {
+ rInstance = rSMgr->createInstance( sObjectName );
+ }
+ catch (Exception const &) {}
+ }
+ }
+ */
+ return rInstance;
+}
+
+}
+
+// component management stuff...
+// ----------------------------------------------------------------------------
+extern "C"
+{
+using namespace desktop;
+
+void SAL_CALL
+component_getImplementationEnvironment(const sal_Char **ppEnvironmentTypeName, uno_Environment **)
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+sal_Bool SAL_CALL
+component_writeInfo(void *pServiceManager, void *pRegistryKey)
+{
+ Reference< XMultiServiceFactory > xMan(reinterpret_cast< XMultiServiceFactory* >(pServiceManager));
+ Reference< XRegistryKey > xKey(reinterpret_cast< XRegistryKey* >(pRegistryKey));
+
+ // register service
+ ::rtl::OUString aTempStr;
+ ::rtl::OUString aImpl(RTL_CONSTASCII_USTRINGPARAM("/"));
+ aImpl += Acceptor::impl_getImplementationName();
+ aImpl += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES"));
+ Reference< XRegistryKey > xNewKey = xKey->createKey(aImpl);
+ xNewKey->createKey(Acceptor::impl_getSupportedServiceNames()[0]);
+
+ return sal_True;
+}
+
+void * SAL_CALL
+component_getFactory(const sal_Char *pImplementationName, void *pServiceManager, void *)
+{
+ void* pReturn = NULL ;
+ if ( pImplementationName && pServiceManager )
+ {
+ // Define variables which are used in following macros.
+ Reference< XSingleServiceFactory > xFactory;
+ Reference< XMultiServiceFactory > xServiceManager(
+ reinterpret_cast< XMultiServiceFactory* >(pServiceManager));
+
+ if (Acceptor::impl_getImplementationName().compareToAscii( pImplementationName ) == COMPARE_EQUAL )
+ {
+ xFactory = Reference< XSingleServiceFactory >( cppu::createSingleFactory(
+ xServiceManager, Acceptor::impl_getImplementationName(),
+ Acceptor::impl_getInstance, Acceptor::impl_getSupportedServiceNames()) );
+ }
+
+ // Factory is valid - service was found.
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pReturn = xFactory.get();
+ }
+ }
+
+ // Return with result of this operation.
+ return pReturn ;
+}
+
+} // extern "C"
diff --git a/desktop/source/offacc/acceptor.hxx b/desktop/source/offacc/acceptor.hxx
new file mode 100644
index 000000000000..87f50db032dd
--- /dev/null
+++ b/desktop/source/offacc/acceptor.hxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/connection/XAcceptor.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/bridge/XInstanceProvider.hpp>
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <rtl/logfile.hxx>
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <comphelper/weakbag.hxx>
+#include <osl/mutex.hxx>
+#include <osl/conditn.hxx>
+#include <osl/thread.hxx>
+
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::connection;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::registry;
+
+namespace desktop {
+
+class Acceptor
+ : public ::cppu::WeakImplHelper2<XServiceInfo, XInitialization>
+{
+private:
+ static const sal_Char *serviceName;
+ static const sal_Char *implementationName;
+ static const sal_Char *supportedServiceNames[];
+
+ static Mutex m_aMutex;
+
+ oslThread m_thread;
+ comphelper::WeakBag< com::sun::star::bridge::XBridge > m_bridges;
+
+ Condition m_cEnable;
+
+ Reference< XMultiServiceFactory > m_rSMgr;
+ Reference< XInterface > m_rContext;
+ Reference< XAcceptor > m_rAcceptor;
+ Reference< XBridgeFactory > m_rBridgeFactory;
+
+ OUString m_aAcceptString;
+ OUString m_aConnectString;
+ OUString m_aProtocol;
+
+ sal_Bool m_bInit;
+ bool m_bDying;
+
+public:
+ Acceptor( const Reference< XMultiServiceFactory >& aFactory );
+ virtual ~Acceptor();
+
+ void SAL_CALL run();
+
+ // XService info
+ static OUString impl_getImplementationName();
+ virtual OUString SAL_CALL getImplementationName()
+ throw (RuntimeException);
+ static Sequence<OUString> impl_getSupportedServiceNames();
+ virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString& aName )
+ throw (RuntimeException);
+
+ // XInitialize
+ virtual void SAL_CALL initialize( const Sequence<Any>& aArguments )
+ throw ( Exception );
+
+ static Reference<XInterface> impl_getInstance( const Reference< XMultiServiceFactory >& aFactory );
+};
+
+class AccInstanceProvider : public ::cppu::WeakImplHelper1<XInstanceProvider>
+{
+private:
+ Reference<XMultiServiceFactory> m_rSMgr;
+ Reference<XConnection> m_rConnection;
+
+public:
+ AccInstanceProvider(const Reference< XMultiServiceFactory >& aFactory,
+ const Reference< XConnection >& rConnection);
+ virtual ~AccInstanceProvider();
+
+ // XInstanceProvider
+ virtual Reference<XInterface> SAL_CALL getInstance (const OUString& aName )
+ throw ( NoSuchElementException );
+};
+
+
+} //namespace desktop
+
diff --git a/desktop/source/offacc/makefile.mk b/desktop/source/offacc/makefile.mk
new file mode 100644
index 000000000000..c2d53930b580
--- /dev/null
+++ b/desktop/source/offacc/makefile.mk
@@ -0,0 +1,62 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=offacc
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = $(SLO)$/acceptor.obj
+
+SHL1DEPN= makefile.mk
+SHL1OBJS= $(SLOFILES)
+
+SHL1TARGET= $(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS= \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/pagein/file_image.h b/desktop/source/pagein/file_image.h
new file mode 100644
index 000000000000..42054291b5fb
--- /dev/null
+++ b/desktop/source/pagein/file_image.h
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_FILE_IMAGE_H
+#define INCLUDED_FILE_IMAGE_H
+
+#ifndef INCLUDED_STDDEF_H
+#include <stddef.h>
+#define INCLUDED_STDDEF_H
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** file_image.
+ */
+struct file_image_st
+{
+ void * m_base;
+ size_t m_size;
+};
+
+typedef struct file_image_st file_image;
+
+#define FILE_IMAGE_INITIALIZER { 0, 0 }
+
+
+/** file_image_open.
+ */
+int file_image_open (
+ file_image * image,
+ const char * filename);
+
+
+/** file_image_pagein.
+ */
+int file_image_pagein (
+ file_image * image);
+
+
+/** file_image_close.
+ */
+int file_image_close (
+ file_image * image);
+
+
+/** Epilog.
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDED_ODEP_IMAGE_H */
diff --git a/desktop/source/pagein/file_image_unx.c b/desktop/source/pagein/file_image_unx.c
new file mode 100644
index 000000000000..92b8f49f0e34
--- /dev/null
+++ b/desktop/source/pagein/file_image_unx.c
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "file_image.h"
+
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+#if defined(LINUX)
+# ifndef __USE_BSD
+# define __USE_BSD /* madvise, MADV_WILLNEED */
+# endif
+#endif /* Linux */
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <string.h>
+
+/*
+ * file_image_open
+ */
+int file_image_open (file_image * image, const char * filename)
+{
+ int result = 0;
+ int fd;
+ struct stat st;
+ void * p;
+
+ if (image == 0)
+ return (EINVAL);
+
+ image->m_base = MAP_FAILED, image->m_size = 0;
+
+ if ((fd = open (filename, O_RDONLY)) == -1)
+ return (errno);
+
+ if (fstat (fd, &st) == -1)
+ {
+ result = errno;
+ goto cleanup_and_leave;
+ }
+
+ p = mmap (0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (p == MAP_FAILED)
+ {
+ result = errno;
+ goto cleanup_and_leave;
+ }
+
+ image->m_base = p, image->m_size = st.st_size;
+
+cleanup_and_leave:
+ close (fd);
+ return (result);
+}
+
+/*
+ * file_image_pagein.
+ */
+int file_image_pagein (file_image * image)
+{
+ file_image w;
+ long s;
+ size_t k;
+ volatile char c = 0;
+
+ if (image == 0)
+ return (EINVAL);
+
+ if ((w.m_base = image->m_base) == 0)
+ return (EINVAL);
+ if ((w.m_size = image->m_size) == 0)
+ return (0);
+
+ if (madvise (w.m_base, w.m_size, MADV_WILLNEED) == -1)
+ {
+#ifndef MACOSX
+ return (errno);
+#else
+ /* madvise MADV_WILLNEED need not succeed here */
+ /* but that is fine */
+#endif
+ }
+
+
+#ifndef MACOSX
+ if ((s = sysconf (_SC_PAGESIZE)) == -1)
+ s = 0x1000;
+#else
+ s = getpagesize();
+#endif
+
+ k = (size_t)(s);
+ while (w.m_size > k)
+ {
+ c ^= ((char*)(w.m_base))[0];
+ w.m_base = (char*)(w.m_base) + k;
+ w.m_size -= k;
+ }
+ if (w.m_size > 0)
+ {
+ c ^= ((char*)(w.m_base))[0];
+ w.m_base = (char*)(w.m_base) + w.m_size;
+ w.m_size -= w.m_size;
+ }
+
+ return (0);
+}
+
+/*
+ * file_image_close
+ */
+int file_image_close (file_image * image)
+{
+ if (image == 0)
+ return (EINVAL);
+
+ if (munmap (image->m_base, image->m_size) == -1)
+ return (errno);
+
+ image->m_base = 0, image->m_size = 0;
+ return (0);
+}
diff --git a/desktop/source/pagein/makefile.mk b/desktop/source/pagein/makefile.mk
new file mode 100644
index 000000000000..01452a858e66
--- /dev/null
+++ b/desktop/source/pagein/makefile.mk
@@ -0,0 +1,165 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=pagein
+TARGETTYPE=CUI
+LIBTARGET=NO
+
+NO_DEFAULT_STL=TRUE
+LIBSALCPPRT=$(0)
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.INCLUDE .IGNORE : icuversion.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= \
+ $(OBJ)$/pagein.obj \
+ $(OBJ)$/file_image_unx.obj
+
+APP1TARGET=$(TARGET)
+APP1OBJS=$(OBJFILES)
+APP1CODETYPE=C
+
+# depends on libc only.
+STDLIB=
+
+# --- Targets ------------------------------------------------------
+
+ALL: \
+ $(MISC)$/$(TARGET)-calc \
+ $(MISC)$/$(TARGET)-draw \
+ $(MISC)$/$(TARGET)-impress \
+ $(MISC)$/$(TARGET)-writer \
+ $(MISC)$/$(TARGET)-common \
+ ALLTAR
+
+.INCLUDE : target.mk
+
+ICUDLLPOST=$(DLLPOST).$(ICU_MAJOR)$(ICU_MINOR)
+UDKDLLPOST=$(DLLPOST).$(UDK_MAJOR)
+UNODLLPOST=.uno$(DLLPOST)
+DFTDLLPOST=$(DLLPOSTFIX)$(DLLPOST) # Default
+
+URELIBPATH=..$/ure-link$/lib
+
+$(MISC)$/$(TARGET)-calc : makefile.mk
+ @echo Making: $@
+ @-echo $(DLLPRE)sc$(DFTDLLPOST) > $@
+ @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
+
+$(MISC)$/$(TARGET)-draw : makefile.mk
+ @echo Making: $@
+ @-echo $(DLLPRE)sd$(DFTDLLPOST) > $@
+ @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
+
+$(MISC)$/$(TARGET)-impress : makefile.mk
+ @echo Making: $@
+ @-echo $(DLLPRE)sd$(DFTDLLPOST) > $@
+ @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
+
+$(MISC)$/$(TARGET)-writer : makefile.mk
+ @echo Making: $@
+ @-echo $(DLLPRE)sw$(DFTDLLPOST) > $@
+ @-echo $(DLLPRE)svx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svxcore$(DFTDLLPOST) >> $@
+
+# sorted in approx. reverse load order (ld.so.1)
+$(MISC)$/$(TARGET)-common : makefile.mk
+ @echo Making: $@
+ @-echo i18npool$(UNODLLPOST) > $@
+.IF "$(SYSTEM_ICU)" != "YES"
+ @-echo $(DLLPRE)icui18n$(ICUDLLPOST) >> $@
+ @-echo $(DLLPRE)icule$(ICUDLLPOST) >> $@
+ @-echo $(DLLPRE)icuuc$(ICUDLLPOST) >> $@
+ @-echo $(DLLPRE)icudata$(ICUDLLPOST) >> $@
+.ENDIF # SYSTEM_ICU
+#
+ @-echo $(DLLPRE)lng$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)xo$(DFTDLLPOST) >> $@
+#
+
+ @-echo $(DLLPRE)fwe$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)fwk$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)fwi$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)fwl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)package2$(DLLPOST) >> $@
+ @-echo $(DLLPRE)ucpfile1$(DLLPOST) >> $@
+ @-echo $(DLLPRE)ucb1$(DLLPOST) >> $@
+ @-echo $(DLLPRE)configmgr$(DLLPOST) >> $@
+#
+ @-echo $(DLLPRE)dtrans$(DLLPOST) >> $@
+ @-echo $(DLLPRE)vclplug_gen$(DFTDLLPOST) >> $@
+.IF "$(ENABLE_GTK)" != ""
+ @-echo $(DLLPRE)vclplug_gtk$(DFTDLLPOST) >> $@
+.ENDIF # ENABLE_GTK
+.IF "$(ENABLE_KDE)" != ""
+ @-echo $(DLLPRE)vclplug_kde$(DFTDLLPOST) >> $@
+.ENDIF # ENABLE_KDE
+#
+ @-echo $(DLLPRE)basegfx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)sot$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)xcr$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)sb$(DFTDLLPOST) >> $@
+#
+# uno runtime environment
+#
+ @-echo $(URELIBPATH)$/stocservices$(UNODLLPOST) >> $@
+ @-echo $(URELIBPATH)$/bootstrap$(UNODLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)reg$(UDKDLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)store$(UDKDLLPOST) >> $@
+.IF "$(USE_SYSTEM_STL)"!="YES"
+.IF "$(COMNAME)" == "gcc2" || "$(COMNAME)" == "gcc3"
+ @-echo $(URELIBPATH)$/$(DLLPRE)stlport_gcc$(DLLPOST) >> $@
+.ENDIF # gcc
+.IF "$(COMNAME)" == "sunpro5"
+ @-echo $(URELIBPATH)$/$(DLLPRE)stlport_sunpro$(DLLPOST) >> $@
+.ENDIF # sunpro5
+.ENDIF # SYSTEM_STL
+ @-echo $(URELIBPATH)$/$(DLLPRE)uno_cppuhelper$(COMID)$(UDKDLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)uno_cppu$(UDKDLLPOST) >> $@
+ @-echo $(URELIBPATH)$/$(DLLPRE)uno_sal$(UDKDLLPOST) >> $@
+#
+ @-echo $(DLLPRE)ucbhelper$(UCBHELPER_MAJOR)$(COMID)$(DLLPOST) >> $@
+ @-echo $(DLLPRE)comphelp$(COMPHLP_MAJOR)$(COMID)$(DLLPOST) >> $@
+ @-echo $(DLLPRE)tl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)utl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)vcl$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)tk$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)svt$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)sfx$(DFTDLLPOST) >> $@
+ @-echo $(DLLPRE)sofficeapp$(DLLPOST) >> $@
diff --git a/desktop/source/pagein/pagein.c b/desktop/source/pagein/pagein.c
new file mode 100644
index 000000000000..0b93eecab7cf
--- /dev/null
+++ b/desktop/source/pagein/pagein.c
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "file_image.h"
+
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+/* do_pagein */
+static int do_pagein (const char * filename, size_t * size)
+{
+ int result;
+ file_image image = FILE_IMAGE_INITIALIZER;
+
+ if ((result = file_image_open (&image, filename)) != 0)
+ return (result);
+
+ if ((result = file_image_pagein (&image)) != 0)
+ {
+ fprintf (stderr, "file_image_pagein: %s\n", strerror(result));
+ goto cleanup_and_leave;
+ }
+
+ if (size)
+ {
+ *size = image.m_size;
+ }
+
+cleanup_and_leave:
+ file_image_close (&image);
+ return (result);
+}
+
+/* main */
+int main (int argc, char **argv)
+{
+ int i, v = 0;
+ size_t nfiles = 0, nbytes = 0;
+
+ if (argc < 2)
+ {
+ fprintf (
+ stderr,
+ "%s: Usage: pagein [-v[v]] [-L<path>] [@]<filename> ...\n",
+ argv[0]);
+ return (1);
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ FILE * fp = 0;
+ size_t k = 0;
+
+ if (argv[i][0] == '-')
+ {
+ /* option */
+ int j = 1;
+ switch (argv[i][j])
+ {
+ case 'v':
+ /* verbosity level */
+ for (v += 1, j += 1; argv[i][j]; j++)
+ v += (argv[i][j] == 'v');
+ break;
+ case 'L':
+ /* search path */
+ if (chdir (&(argv[i][2])) == -1)
+ fprintf (stderr, "chdir: %s\n", strerror(errno));
+ break;
+ default:
+ /* ignored */
+ break;
+ }
+
+ /* next argv */
+ continue;
+ }
+
+
+ if ((argv[i][0] == '@') && ((fp = fopen (argv[i], "r")) == 0))
+ {
+ char path[1024];
+ if ((fp = fopen (&(argv[i][1]), "r")) == 0)
+ {
+ fprintf (stderr, "fopen: %s\n", strerror(errno));
+ continue;
+ }
+ while (fgets (path, sizeof(path), fp) != 0)
+ {
+ path[strlen(path) - 1] = '\0', k = 0;
+ if (do_pagein (path, &k) == 0)
+ {
+ /* accumulate total size */
+ nbytes += k;
+ }
+
+ if (v >= 2)
+ fprintf (stderr, "pagein(\"%s\") = %d bytes\n", path, (int) k);
+ nfiles += 1;
+ }
+ fclose (fp);
+ }
+ else
+ {
+ if (fp != 0)
+ fclose (fp);
+
+ if (do_pagein (argv[i], &k) == 0)
+ {
+ /* accumulate total size */
+ nbytes += k;
+ }
+
+ if (v >= 2)
+ fprintf (stderr, "pagein(\"%s\") = %d bytes\n", argv[i], (int) k);
+ nfiles += 1;
+ }
+ }
+
+ if (v >= 1)
+ fprintf (stderr, "Total: %d files (%d bytes)\n", (int) nfiles, (int) nbytes);
+ return (0);
+}
diff --git a/desktop/source/pkgchk/unopkg/makefile.mk b/desktop/source/pkgchk/unopkg/makefile.mk
new file mode 100644
index 000000000000..8384f1b24372
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/makefile.mk
@@ -0,0 +1,104 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = unopkg
+.IF "$(GUI)" == "OS2"
+TARGETTYPE = CUI
+.ELSE
+TARGETTYPE = GUI
+.ENDIF
+ENABLE_EXCEPTIONS = TRUE
+LIBTARGET=NO
+
+PRJINC += ..$/..$/deployment ..$/..
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+.IF "$(LINK_SO)"!=""
+APP1TARGET = so$/unopkg
+APP1OBJS = $(OBJFILES)
+APP1STDLIBS = $(SALLIB) $(UNOPKGAPPLIB)
+APP1DEPN = $(SHL1TARGETN)
+APP1NOSAL = TRUE
+APP1RPATH = BRAND
+.IF "$(OS)" == "WNT"
+APP1ICON = $(SOLARRESDIR)$/icons/so9_main_app.ico
+APP1LINKRES = $(MISC)$/$(TARGET)1.res
+.ENDIF
+.ENDIF # "$(LINK_SO)"!=""
+
+APP2TARGET = unopkg
+APP2OBJS = $(OBJFILES)
+APP2STDLIBS = $(SALLIB) $(UNOPKGAPPLIB)
+APP2DEPN = $(SHL1TARGETN)
+APP2NOSAL = TRUE
+APP2RPATH = BRAND
+.IF "$(OS)" == "WNT"
+APP2ICON = $(SOLARRESDIR)$/icons/ooo3_main_app.ico
+APP2LINKRES = $(MISC)$/$(TARGET)2.res
+.ENDIF
+
+SHL1TARGET = unopkgapp
+SHL1OBJS = $(SLOFILES) $(SLO)$/lockfile.obj
+SHL1STDLIBS = \
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(VCLLIB) \
+ $(DEPLOYMENTMISCLIB)
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = \
+ $(SLO)$/unopkg_app.obj \
+ $(SLO)$/unopkg_cmdenv.obj \
+ $(SLO)$/unopkg_misc.obj
+
+OBJFILES = $(OBJ)$/unopkg_main.obj
+
+.INCLUDE : target.mk
+
+.IF "$(APP1TARGETN)" != "" # not set during depend=x
+$(APP1TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP1TARGETN)"!=""
+
+$(MISC)$/binso_created.flg:
+ @@-$(MKDIRHIER) $(BIN)$/so && $(TOUCH) $@
+ @@-$(MKDIRHIER) $(MISC)$/so && $(TOUCH) $@
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
new file mode 100644
index 000000000000..a9a0c8271373
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
@@ -0,0 +1,658 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "dp_misc.h"
+#include "unopkg_main.h"
+#include "unopkg_shared.h"
+#include "dp_identifier.hxx"
+#include "sal/main.h"
+#include "tools/extendapplicationenvironment.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/bootstrap.hxx"
+#include "osl/thread.h"
+#include "osl/process.h"
+#include "osl/conditn.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/sequence.hxx"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+
+#include "com/sun/star/deployment/ui/PackageManagerDialog.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "boost/scoped_array.hpp"
+#include "com/sun/star/ui/dialogs/XDialogClosedListener.hpp"
+#include "com/sun/star/bridge/XBridgeFactory.hpp"
+#include <stdio.h>
+#include <vector>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::unopkg;
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+namespace {
+
+struct ExtensionName
+{
+ OUString m_str;
+ ExtensionName( OUString const & str ) : m_str( str ) {}
+ bool operator () ( Reference<deployment::XPackage> const & e ) const
+ {
+ if (m_str.equals(dp_misc::getIdentifier(e))
+ || m_str.equals(e->getName()))
+ return true;
+ return false;
+ }
+};
+
+//------------------------------------------------------------------------------
+const char s_usingText [] =
+"\n"
+"using: " APP_NAME " add <options> extension-path...\n"
+" " APP_NAME " validate <options> extension-identifier...\n"
+" " APP_NAME " remove <options> extension-identifier...\n"
+" " APP_NAME " list <options> extension-identifier...\n"
+" " APP_NAME " reinstall <options>\n"
+" " APP_NAME " gui\n"
+" " APP_NAME " -V\n"
+" " APP_NAME " -h\n"
+"\n"
+"sub-commands:\n"
+" add add extension\n"
+" validate checks the prerequisites of an installed extension and"
+" registers it if possible\n"
+" remove remove extensions by identifier\n"
+" reinstall expert feature: reinstall all deployed extensions\n"
+" list list information about deployed extensions\n"
+" gui raise Extension Manager Graphical User Interface (GUI)\n"
+"\n"
+"options:\n"
+" -h, --help this help\n"
+" -V, --version version information\n"
+" -v, --verbose verbose output to stdout\n"
+" -f, --force force overwriting existing extensions\n"
+" -s, --suppress-license prevents showing the license provided that\n"
+" the extension allows it\n"
+" --log-file <file> custom log file; default: <cache-dir>/log.txt\n"
+" --shared expert feature: operate on shared installation\n"
+" deployment context;\n"
+" run only when no concurrent Office\n"
+" process(es) are running!\n"
+" --bundled expert feature: operate on bundled extensions. Only\n"
+" works with list, validate, reinstall;\n"
+" --deployment-context expert feature: explicit deployment context\n"
+" <context>\n"
+"\n"
+"To learn more about the Extension Manager and extensions, see:\n"
+"http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Extensions/Extensions\n\n";
+
+//------------------------------------------------------------------------------
+const OptionInfo s_option_infos [] = {
+ { RTL_CONSTASCII_STRINGPARAM("help"), 'h', false },
+ { RTL_CONSTASCII_STRINGPARAM("version"), 'V', false },
+ { RTL_CONSTASCII_STRINGPARAM("verbose"), 'v', false },
+ { RTL_CONSTASCII_STRINGPARAM("force"), 'f', false },
+ { RTL_CONSTASCII_STRINGPARAM("log-file"), '\0', true },
+ { RTL_CONSTASCII_STRINGPARAM("shared"), '\0', false },
+ { RTL_CONSTASCII_STRINGPARAM("deployment-context"), '\0', true },
+ { RTL_CONSTASCII_STRINGPARAM("bundled"), '\0', false},
+ { RTL_CONSTASCII_STRINGPARAM("suppress-license"), 's', false},
+
+ { 0, 0, '\0', false }
+};
+
+class DialogClosedListenerImpl :
+ public ::cppu::WeakImplHelper1< ui::dialogs::XDialogClosedListener >
+{
+ osl::Condition & m_rDialogClosedCondition;
+
+public:
+ DialogClosedListenerImpl( osl::Condition & rDialogClosedCondition )
+ : m_rDialogClosedCondition( rDialogClosedCondition ) {}
+
+ // XEventListener (base of XDialogClosedListener)
+ virtual void SAL_CALL disposing( lang::EventObject const & Source )
+ throw (RuntimeException);
+
+ // XDialogClosedListener
+ virtual void SAL_CALL dialogClosed(
+ ui::dialogs::DialogClosedEvent const & aEvent )
+ throw (RuntimeException);
+};
+
+// XEventListener (base of XDialogClosedListener)
+void DialogClosedListenerImpl::disposing( lang::EventObject const & )
+ throw (RuntimeException)
+{
+ // nothing to do
+}
+
+// XDialogClosedListener
+void DialogClosedListenerImpl::dialogClosed(
+ ui::dialogs::DialogClosedEvent const & )
+ throw (RuntimeException)
+{
+ m_rDialogClosedCondition.set();
+}
+
+// If a package had been installed with a pre OOo 2.2, it could not normally be
+// found via its identifier; similarly (and for ease of use), a package
+// installed with OOo 2.2 or later could not normally be found via its file
+// name.
+Reference<deployment::XPackage> findPackage(
+ OUString const & repository,
+ Reference<deployment::XExtensionManager> const & manager,
+ Reference<ucb::XCommandEnvironment > const & environment,
+ OUString const & idOrFileName )
+{
+ Sequence< Reference<deployment::XPackage> > ps(
+ manager->getDeployedExtensions(repository,
+ Reference<task::XAbortChannel>(), environment ) );
+ for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
+ if ( dp_misc::getIdentifier( ps[i] ) == idOrFileName )
+ return ps[i];
+ for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
+ if ( ps[i]->getName() == idOrFileName )
+ return ps[i];
+ return Reference<deployment::XPackage>();
+}
+
+} // anon namespace
+
+
+//workaround for some reason the bridge threads which communicate with the uno.exe
+//process are not releases on time
+void disposeBridges(Reference<css::uno::XComponentContext> ctx)
+{
+ if (!ctx.is())
+ return;
+
+ Reference<css::bridge::XBridgeFactory> bridgeFac(
+ ctx->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.bridge.BridgeFactory"), ctx),
+ UNO_QUERY);
+
+ if (bridgeFac.is())
+ {
+ const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges();
+ for (sal_Int32 i = 0; i < seqBridges.getLength(); i++)
+ {
+ Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY);
+ if (comp.is())
+ {
+ try {
+ comp->dispose();
+ }
+ catch (css::lang::DisposedException& )
+ {
+ }
+ }
+ }
+ }
+}
+
+//##############################################################################
+extern "C" int unopkg_main()
+{
+ tools::extendApplicationEnvironment();
+ DisposeGuard disposeGuard;
+ bool bNoOtherErrorMsg = false;
+ OUString subCommand;
+ bool option_shared = false;
+ bool option_force = false;
+ bool option_verbose = false;
+ bool option_bundled = false;
+ bool option_suppressLicense = false;
+ bool subcmd_add = false;
+ bool subcmd_gui = false;
+ OUString logFile;
+ OUString repository;
+ OUString cmdArg;
+ ::std::vector<OUString> cmdPackages;
+
+ OptionInfo const * info_shared = getOptionInfo(
+ s_option_infos, OUSTR("shared") );
+ OptionInfo const * info_force = getOptionInfo(
+ s_option_infos, OUSTR("force") );
+ OptionInfo const * info_verbose = getOptionInfo(
+ s_option_infos, OUSTR("verbose") );
+ OptionInfo const * info_log = getOptionInfo(
+ s_option_infos, OUSTR("log-file") );
+ OptionInfo const * info_context = getOptionInfo(
+ s_option_infos, OUSTR("deployment-context") );
+ OptionInfo const * info_help = getOptionInfo(
+ s_option_infos, OUSTR("help") );
+ OptionInfo const * info_version = getOptionInfo(
+ s_option_infos, OUSTR("version") );
+ OptionInfo const * info_bundled = getOptionInfo(
+ s_option_infos, OUSTR("bundled") );
+ OptionInfo const * info_suppressLicense = getOptionInfo(
+ s_option_infos, OUSTR("suppress-license") );
+
+
+ Reference<XComponentContext> xComponentContext;
+ Reference<XComponentContext> xLocalComponentContext;
+
+ try {
+ sal_uInt32 nPos = 0;
+ sal_uInt32 nCount = osl_getCommandArgCount();
+ if (nCount == 0 || isOption( info_help, &nPos ))
+ {
+ dp_misc::writeConsole(s_usingText);
+ return 0;
+ }
+ else if (isOption( info_version, &nPos )) {
+ dp_misc::writeConsole("\n"APP_NAME" Version 3.3\n");
+ return 0;
+ }
+ //consume all bootstrap variables which may occur before the subcommannd
+ while(isBootstrapVariable(&nPos));
+
+ if(nPos >= nCount)
+ return 0;
+ //get the sub command
+ osl_getCommandArg( nPos, &subCommand.pData );
+ ++nPos;
+ subCommand = subCommand.trim();
+ subcmd_add = subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("add") );
+ subcmd_gui = subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("gui") );
+
+ // sun-command options and packages:
+ while (nPos < nCount)
+ {
+ if (readArgument( &cmdArg, info_log, &nPos )) {
+ logFile = makeAbsoluteFileUrl(
+ cmdArg.trim(), getProcessWorkingDir() );
+ }
+ else if (!readOption( &option_verbose, info_verbose, &nPos ) &&
+ !readOption( &option_shared, info_shared, &nPos ) &&
+ !readOption( &option_force, info_force, &nPos ) &&
+ !readOption( &option_bundled, info_bundled, &nPos ) &&
+ !readOption( &option_suppressLicense, info_suppressLicense, &nPos ) &&
+ !readArgument( &repository, info_context, &nPos ) &&
+ !isBootstrapVariable(&nPos))
+ {
+ osl_getCommandArg( nPos, &cmdArg.pData );
+ ++nPos;
+ cmdArg = cmdArg.trim();
+ if (cmdArg.getLength() > 0)
+ {
+ if (cmdArg[ 0 ] == '-')
+ {
+ // is option:
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: unexpected option ") +
+ cmdArg +
+ OUSTR("!\n") +
+ OUSTR(" Use " APP_NAME " ") +
+ toString(info_help) +
+ OUSTR(" to print all options.\n"));
+ return 1;
+ }
+ else
+ {
+ // is package:
+ cmdPackages.push_back(
+ subcmd_add || subcmd_gui
+ ? makeAbsoluteFileUrl(
+ cmdArg, getProcessWorkingDir() )
+ : cmdArg );
+ }
+ }
+ }
+ }
+
+ if (repository.getLength() == 0)
+ {
+ if (option_shared)
+ repository = OUSTR("shared");
+ else if (option_bundled)
+ repository = OUSTR("bundled");
+ else
+ repository = OUSTR("user");
+ }
+ else
+ {
+ if (repository.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("shared") )) {
+ option_shared = true;
+ }
+ else if (option_shared) {
+ dp_misc::writeConsoleError(
+ OUSTR("WARNING: explicit context given! ") +
+ OUSTR("Ignoring option ") +
+ toString( info_shared ) +
+ OUSTR("!\n") );
+ }
+ }
+
+ if (subCommand.equals(OUSTR("reinstall")))
+ {
+ //We must prevent that services and types are loaded by UNO,
+ //otherwise we cannot delete the registry data folder.
+ OUString extensionUnorc;
+ if (repository.equals(OUSTR("user")))
+ extensionUnorc = OUSTR("$UNO_USER_PACKAGES_CACHE/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
+ else if (repository.equals(OUSTR("shared")))
+ extensionUnorc = OUSTR("$SHARED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
+ else if (repository.equals(OUSTR("bundled")))
+ extensionUnorc = OUSTR("$BUNDLED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
+ else
+ OSL_ASSERT(0);
+
+ ::rtl::Bootstrap::expandMacros(extensionUnorc);
+ oslFileError e = osl_removeFile(extensionUnorc.pData);
+ if (e != osl_File_E_None && e != osl_File_E_NOENT)
+ throw Exception(OUSTR("Could not delete ") + extensionUnorc, 0);
+ }
+
+ xComponentContext = getUNO(
+ disposeGuard, option_verbose, option_shared, subcmd_gui,
+ xLocalComponentContext );
+
+ Reference<deployment::XExtensionManager> xExtensionManager(
+ deployment::ExtensionManager::get( xComponentContext ) );
+
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv(
+ createCmdEnv( xComponentContext, logFile,
+ option_force, option_verbose) );
+
+ //synchronize bundled/shared extensions
+ //Do not synchronize when command is "reinstall". This could add types and services to UNO and
+ //prevent the deletion of the registry data folder
+ //synching is done in XExtensionManager.reinstall
+ if (!subcmd_gui && ! subCommand.equals(OUSTR("reinstall"))
+ && ! dp_misc::office_is_running())
+ dp_misc::syncRepositories(xCmdEnv);
+
+ if (subcmd_add ||
+ subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("remove") ))
+ {
+ for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
+ {
+ OUString const & cmdPackage = cmdPackages[ pos ];
+ if (subcmd_add)
+ {
+ beans::NamedValue nvSuppress(
+ OUSTR("SUPPRESS_LICENSE"), option_suppressLicense ?
+ makeAny(OUSTR("1")):makeAny(OUSTR("0")));
+ xExtensionManager->addExtension(
+ cmdPackage, Sequence<beans::NamedValue>(&nvSuppress, 1),
+ repository, Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ else
+ {
+ try
+ {
+ xExtensionManager->removeExtension(
+ cmdPackage, cmdPackage, repository,
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ Reference<deployment::XPackage> p(
+ findPackage(repository,
+ xExtensionManager, xCmdEnv, cmdPackage ) );
+ if ( !p.is())
+ throw;
+ else if (p.is())
+ xExtensionManager->removeExtension(
+ ::dp_misc::getIdentifier(p), p->getName(),
+ repository,
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ }
+ }
+ }
+ else if (subCommand.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("reinstall") ))
+ {
+ xExtensionManager->reinstallDeployedExtensions(
+ repository, Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("list") ))
+ {
+ ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted;
+ ::comphelper::sequenceToContainer(vecExtUnaccepted,
+ xExtensionManager->getExtensionsWithUnacceptedLicenses(
+ repository, xCmdEnv));
+
+ //This vector tells what XPackage in allExtensions has an
+ //unaccepted license.
+ std::vector<bool> vecUnaccepted;
+ std::vector<Reference<deployment::XPackage> > allExtensions;
+ if (cmdPackages.empty())
+ {
+ Sequence< Reference<deployment::XPackage> >
+ packages = xExtensionManager->getDeployedExtensions(
+ repository, Reference<task::XAbortChannel>(), xCmdEnv );
+
+ ::std::vector<Reference<deployment::XPackage> > vec_packages;
+ ::comphelper::sequenceToContainer(vec_packages, packages);
+
+ //First copy the extensions with the unaccepted license
+ //to vector allExtensions.
+ allExtensions.resize(vecExtUnaccepted.size() + vec_packages.size());
+
+ ::std::vector<Reference<deployment::XPackage> >::iterator i_all_ext =
+ ::std::copy(vecExtUnaccepted.begin(), vecExtUnaccepted.end(),
+ allExtensions.begin());
+ //Now copy those we got from getDeployedExtensions
+ ::std::copy(vec_packages.begin(), vec_packages.end(), i_all_ext);
+
+ //Now prepare the vector which tells what extension has an
+ //unaccepted license
+ vecUnaccepted.resize(vecExtUnaccepted.size() + vec_packages.size());
+ ::std::vector<bool>::iterator i_unaccepted =
+ ::std::fill_n(vecUnaccepted.begin(),
+ vecExtUnaccepted.size(), true);
+ ::std::fill_n(i_unaccepted, vec_packages.size(), false);
+
+ dp_misc::writeConsole(
+ OUSTR("All deployed ") + repository + OUSTR(" extensions:\n\n"));
+ }
+ else
+ {
+ //The user provided the names (ids or file names) of the extensions
+ //which shall be listed
+ for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
+ {
+ Reference<deployment::XPackage> extension;
+ try
+ {
+ extension = xExtensionManager->getDeployedExtension(
+ repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ extension = findPackage(repository,
+ xExtensionManager, xCmdEnv, cmdPackages[ pos ] );
+ }
+
+ //Now look if the requested extension has an unaccepted license
+ bool bUnacceptedLic = false;
+ if (!extension.is())
+ {
+ ::std::vector<Reference<deployment::XPackage> >::const_iterator
+ i = ::std::find_if(
+ vecExtUnaccepted.begin(),
+ vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos]));
+ if (i != vecExtUnaccepted.end())
+ {
+ extension = *i;
+ bUnacceptedLic = true;
+ }
+ }
+
+ if (extension.is())
+ {
+ allExtensions.push_back(extension);
+ vecUnaccepted.push_back(bUnacceptedLic);
+ }
+
+ else
+ throw lang::IllegalArgumentException(
+ OUSTR("There is no such extension deployed: ") +
+ cmdPackages[pos],0,-1);
+ }
+
+ }
+
+ printf_packages(allExtensions, vecUnaccepted, xCmdEnv );
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("validate") ))
+ {
+ ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted;
+ ::comphelper::sequenceToContainer(
+ vecExtUnaccepted, xExtensionManager->getExtensionsWithUnacceptedLicenses(
+ repository, xCmdEnv));
+
+ for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
+ {
+ Reference<deployment::XPackage> extension;
+ try
+ {
+ extension = xExtensionManager->getDeployedExtension(
+ repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ extension = findPackage(
+ repository, xExtensionManager, xCmdEnv, cmdPackages[ pos ] );
+ }
+
+ if (!extension.is())
+ {
+ ::std::vector<Reference<deployment::XPackage> >::const_iterator
+ i = ::std::find_if(
+ vecExtUnaccepted.begin(),
+ vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos]));
+ if (i != vecExtUnaccepted.end())
+ {
+ extension = *i;
+ }
+ }
+
+ if (extension.is())
+ xExtensionManager->checkPrerequisitesAndEnable(
+ extension, Reference<task::XAbortChannel>(), xCmdEnv);
+ }
+ }
+ else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gui") ))
+ {
+ Reference<ui::dialogs::XAsynchronousExecutableDialog> xDialog(
+ deployment::ui::PackageManagerDialog::createAndInstall(
+ xComponentContext,
+ cmdPackages.size() > 0 ? cmdPackages[0] : OUString() ));
+
+ osl::Condition dialogEnded;
+ dialogEnded.reset();
+
+ Reference< ui::dialogs::XDialogClosedListener > xListener(
+ new DialogClosedListenerImpl( dialogEnded ) );
+
+ xDialog->startExecuteModal(xListener);
+ dialogEnded.wait();
+ }
+ else
+ {
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: unknown sub-command ") +
+ subCommand +
+ OUSTR("!\n") +
+ OUSTR(" Use " APP_NAME " ") +
+ toString(info_help) +
+ OUSTR(" to print all options.\n"));
+ return 1;
+ }
+
+ if (option_verbose)
+ dp_misc::writeConsole(OUSTR("\n"APP_NAME" done.\n"));
+ //Force to release all bridges which connect us to the child processes
+ disposeBridges(xLocalComponentContext);
+ return 0;
+ }
+ catch (ucb::CommandFailedException &e)
+ {
+ dp_misc::writeConsoleError(e.Message + OUSTR("\n"));
+ bNoOtherErrorMsg = true;
+ }
+ catch (ucb::CommandAbortedException &)
+ {
+ dp_misc::writeConsoleError("\n"APP_NAME" aborted!\n");
+ }
+ catch (deployment::DeploymentException & exc)
+ {
+ OUString cause;
+ if (option_verbose)
+ {
+ cause = ::comphelper::anyToString(exc.Cause);
+ }
+ else
+ {
+ css::uno::Exception e;
+ if (exc.Cause >>= e)
+ cause = e.Message;
+ }
+
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") + exc.Message + OUSTR("\n"));
+ if (cause.getLength())
+ dp_misc::writeConsoleError(
+ OUSTR(" Cause: ") + cause + OUSTR("\n"));
+ }
+ catch (LockFileException & e)
+ {
+ if (!subcmd_gui)
+ dp_misc::writeConsoleError(e.Message);
+ bNoOtherErrorMsg = true;
+ }
+ catch (::com::sun::star::uno::Exception & e ) {
+ Any exc( ::cppu::getCaughtException() );
+
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") +
+ OUString(option_verbose ? e.Message + OUSTR("\nException details: \n") +
+ ::comphelper::anyToString(exc) : e.Message) +
+ OUSTR("\n"));
+ }
+ if (!bNoOtherErrorMsg)
+ dp_misc::writeConsoleError("\n"APP_NAME" failed.\n");
+ disposeBridges(xLocalComponentContext);
+ return 1;
+}
+
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
new file mode 100644
index 000000000000..69a973b90a42
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
@@ -0,0 +1,433 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "../../deployment/gui/dp_gui.hrc"
+#include "../../deployment/gui/dp_gui_shared.hxx"
+#include "unopkg_shared.h"
+#include "osl/thread.h"
+#include "rtl/memory.h"
+#include "tools/string.hxx"
+#include "tools/resmgr.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/anytostring.hxx"
+#include "unotools/configmgr.hxx"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/container/ElementExistException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
+#include "com/sun/star/i18n/XCollator.hpp"
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+
+#include <stdio.h>
+#include "deployment.hrc"
+#include "dp_version.hxx"
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::unopkg;
+using ::rtl::OUString;
+
+
+namespace {
+
+//==============================================================================
+struct OfficeLocale :
+ public rtl::StaticWithInit<const lang::Locale, OfficeLocale> {
+ const lang::Locale operator () () {
+ OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw RuntimeException( OUSTR("Cannot determine language!"), 0 );
+ return toLocale(slang);
+ }
+};
+
+//==============================================================================
+class CommandEnvironmentImpl
+ : public ::cppu::WeakImplHelper3< XCommandEnvironment,
+ task::XInteractionHandler,
+ XProgressHandler >
+{
+ sal_Int32 m_logLevel;
+ bool m_option_force_overwrite;
+ bool m_option_verbose;
+ Reference< XComponentContext > m_xComponentContext;
+ Reference< XProgressHandler > m_xLogFile;
+
+ void update_( Any const & Status ) throw (RuntimeException);
+ void printLicense(const OUString & sName,const OUString& sLicense,
+ bool & accept, bool & decline);
+
+public:
+ virtual ~CommandEnvironmentImpl();
+ CommandEnvironmentImpl(
+ Reference<XComponentContext> const & xComponentContext,
+ OUString const & log_file,
+ bool option_force_overwrite,
+ bool option_verbose);
+
+ // 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);
+
+ // 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);
+};
+
+
+//______________________________________________________________________________
+CommandEnvironmentImpl::CommandEnvironmentImpl(
+ Reference<XComponentContext> const & xComponentContext,
+ OUString const & log_file,
+ bool option_force_overwrite,
+ bool option_verbose)
+ : m_logLevel(0),
+ m_option_force_overwrite( option_force_overwrite ),
+ m_option_verbose( option_verbose ),
+ m_xComponentContext(xComponentContext)
+{
+ if (log_file.getLength() > 0) {
+ const Any logfile(log_file);
+ m_xLogFile.set(
+ xComponentContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.comp.deployment.ProgressLog"),
+ Sequence<Any>( &logfile, 1 ), xComponentContext ),
+ UNO_QUERY_THROW );
+ }
+}
+
+//______________________________________________________________________________
+CommandEnvironmentImpl::~CommandEnvironmentImpl()
+{
+ try {
+ Reference< lang::XComponent > xComp( m_xLogFile, UNO_QUERY );
+ if (xComp.is())
+ xComp->dispose();
+ }
+ catch (RuntimeException & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, osl_getThreadTextEncoding() ).getStr() );
+ }
+}
+
+//May throw exceptions
+void CommandEnvironmentImpl::printLicense(
+ const OUString & sName, const OUString& sLicense, bool & accept, bool &decline)
+{
+ ResMgr * pResMgr = DeploymentResMgr::get();
+ String s1tmp(ResId(RID_STR_UNOPKG_ACCEPT_LIC_1, *pResMgr));
+ s1tmp.SearchAndReplaceAllAscii( "$NAME", sName );
+ OUString s1(s1tmp);
+ OUString s2 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_2, *pResMgr));
+ OUString s3 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_3, *pResMgr));
+ OUString s4 = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_4, *pResMgr));
+ OUString sYES = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_YES, *pResMgr));
+ OUString sY = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_Y, *pResMgr));
+ OUString sNO = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_NO, *pResMgr));
+ OUString sN = String(ResId(RID_STR_UNOPKG_ACCEPT_LIC_N, *pResMgr));
+
+ OUString sNewLine(RTL_CONSTASCII_USTRINGPARAM("\n"));
+
+ dp_misc::writeConsole(sNewLine + sNewLine + s1 + sNewLine + sNewLine);
+ dp_misc::writeConsole(sLicense + sNewLine + sNewLine);
+ dp_misc::writeConsole(s2 + sNewLine);
+ dp_misc::writeConsole(s3);
+
+ //the user may enter "yes" or "no", we compare in a case insensitive way
+ Reference< css::i18n::XCollator > xCollator(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.i18n.Collator"),m_xComponentContext),
+ UNO_QUERY_THROW );
+ xCollator->loadDefaultCollator(OfficeLocale::get(),
+ css::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE);
+
+ do
+ {
+ OUString sAnswer = dp_misc::readConsole();
+ if (xCollator->compareString(sAnswer, sYES) == 0
+ || xCollator->compareString(sAnswer, sY) == 0)
+ {
+ accept = true;
+ break;
+ }
+ else if(xCollator->compareString(sAnswer, sNO) == 0
+ || xCollator->compareString(sAnswer, sN) == 0)
+ {
+ decline = true;
+ break;
+ }
+ else
+ {
+ dp_misc::writeConsole(sNewLine + sNewLine + s4 + sNewLine);
+ }
+ }
+ while(true);
+}
+
+// XCommandEnvironment
+//______________________________________________________________________________
+Reference< task::XInteractionHandler >
+CommandEnvironmentImpl::getInteractionHandler() throw (RuntimeException)
+{
+ return this;
+}
+
+//______________________________________________________________________________
+Reference< XProgressHandler > CommandEnvironmentImpl::getProgressHandler()
+ throw (RuntimeException)
+{
+ return this;
+}
+
+// XInteractionHandler
+//______________________________________________________________________________
+void CommandEnvironmentImpl::handle(
+ Reference<task::XInteractionRequest> const & xRequest )
+ throw (RuntimeException)
+{
+ Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == TypeClass_EXCEPTION );
+ dp_misc::TRACE(OUSTR("[unopkg_cmdenv.cxx] incoming request:\n")
+ + ::comphelper::anyToString(request) + OUSTR("\n\n"));
+
+ // selections:
+ bool approve = false;
+ bool abort = false;
+
+ lang::WrappedTargetException wtExc;
+ deployment::LicenseException licExc;
+ deployment::InstallException instExc;
+ deployment::PlatformException platExc;
+ deployment::VersionException verExc;
+
+
+ bool bLicenseException = false;
+ if (request >>= wtExc) {
+ // 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;
+ if (abort) {
+ // notify cause as error:
+ request = wtExc.TargetException;
+ }
+ else {
+ // handable deployment error signalled, e.g.
+ // bundle item registration failed, notify as warning:
+ update_( wtExc.TargetException );
+ }
+ }
+ else if (request >>= licExc)
+ {
+ printLicense(licExc.ExtensionName, licExc.Text, approve, abort);
+ }
+ else if (request >>= instExc)
+ {
+ //Only if the unopgk was started with gui + extension then we user is asked.
+ //In console mode there is no asking.
+ approve = true;
+ }
+ else if (request >>= platExc)
+ {
+ String sMsg(ResId(RID_STR_UNSUPPORTED_PLATFORM, *dp_gui::DeploymentGuiResMgr::get()));
+ sMsg.SearchAndReplaceAllAscii("%Name", platExc.package->getDisplayName());
+ dp_misc::writeConsole(OUSTR("\n") + sMsg + OUSTR("\n\n"));
+ approve = true;
+ }
+ else {
+ deployment::VersionException nc_exc;
+ if (request >>= nc_exc) {
+ approve = m_option_force_overwrite ||
+ (::dp_misc::compareVersions(nc_exc.NewVersion, nc_exc.Deployed->getVersion())
+ == ::dp_misc::GREATER);
+ abort = !approve;
+ }
+ else
+ return; // unknown request => no selection at all
+ }
+
+ //In case of a user declining a license abort is true but this is intended,
+ //therefore no logging
+ if (abort && m_option_verbose && !bLicenseException)
+ {
+ OUString msg = ::comphelper::anyToString(request);
+ dp_misc::writeConsoleError(
+ OUSTR("\nERROR: ") + msg + OUSTR("\n"));
+ }
+
+ // select:
+ Sequence< Reference<task::XInteractionContinuation> > conts(
+ xRequest->getContinuations() );
+ Reference<task::XInteractionContinuation> const * pConts =
+ conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ Reference<task::XInteractionApprove> xInteractionApprove(
+ pConts[ pos ], UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ break;
+ }
+ }
+ else if (abort) {
+ Reference<task::XInteractionAbort> xInteractionAbort(
+ pConts[ pos ], UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ break;
+ }
+ }
+ }
+}
+
+// XProgressHandler
+//______________________________________________________________________________
+void CommandEnvironmentImpl::push( Any const & Status )
+ throw (RuntimeException)
+{
+ update_( Status );
+ OSL_ASSERT( m_logLevel >= 0 );
+ ++m_logLevel;
+ if (m_xLogFile.is())
+ m_xLogFile->push( Status );
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::update_( Any const & Status )
+ throw (RuntimeException)
+{
+ if (! Status.hasValue())
+ return;
+ bool bUseErr = false;
+ OUString msg;
+ if (Status >>= msg) {
+ if (! m_option_verbose)
+ return;
+ }
+ else {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("WARNING: ") );
+ deployment::DeploymentException dp_exc;
+ if (Status >>= dp_exc) {
+ buf.append( dp_exc.Message );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", Cause: ") );
+ buf.append( ::comphelper::anyToString(dp_exc.Cause) );
+ }
+ else {
+ buf.append( ::comphelper::anyToString(Status) );
+ }
+ msg = buf.makeStringAndClear();
+ bUseErr = true;
+ }
+ OSL_ASSERT( m_logLevel >= 0 );
+ for ( sal_Int32 n = 0; n < m_logLevel; ++n )
+ {
+ if (bUseErr)
+ dp_misc::writeConsoleError(" ");
+ else
+ dp_misc::writeConsole(" ");
+ }
+
+ if (bUseErr)
+ dp_misc::writeConsoleError(msg + OUSTR("\n"));
+ else
+ dp_misc::writeConsole(msg + OUSTR("\n"));
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::update( Any const & Status )
+ throw (RuntimeException)
+{
+ update_( Status );
+ if (m_xLogFile.is())
+ m_xLogFile->update( Status );
+}
+
+//______________________________________________________________________________
+void CommandEnvironmentImpl::pop() throw (RuntimeException)
+{
+ OSL_ASSERT( m_logLevel > 0 );
+ --m_logLevel;
+ if (m_xLogFile.is())
+ m_xLogFile->pop();
+}
+
+
+} // anon namespace
+
+namespace unopkg {
+
+//==============================================================================
+Reference< XCommandEnvironment > createCmdEnv(
+ Reference< XComponentContext > const & xContext,
+ OUString const & logFile,
+ bool option_force_overwrite,
+ bool option_verbose)
+{
+ return new CommandEnvironmentImpl(
+ xContext, logFile, option_force_overwrite, option_verbose);
+}
+} // unopkg
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_main.c b/desktop/source/pkgchk/unopkg/unopkg_main.c
new file mode 100644
index 000000000000..6a6cb846972d
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_main.c
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "sal/config.h"
+
+#include "sal/main.h"
+
+#include "unopkg_main.h"
+
+SAL_IMPLEMENT_MAIN() {
+ return unopkg_main();
+}
diff --git a/desktop/source/pkgchk/unopkg/unopkg_main.h b/desktop/source/pkgchk/unopkg/unopkg_main.h
new file mode 100644
index 000000000000..08f02612a818
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_main.h
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_PKGCHK_UNOPKG_UNOPKG_MAIN_H
+#define INCLUDED_DESKTOP_SOURCE_PKGCHK_UNOPKG_UNOPKG_MAIN_H
+
+#include "sal/config.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+int unopkg_main(void);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
new file mode 100644
index 000000000000..3272810afee2
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
@@ -0,0 +1,532 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "deployment.hrc"
+#include "unopkg_shared.h"
+#include "dp_identifier.hxx"
+#include "../../deployment/gui/dp_gui.hrc"
+#include "../../app/lockfile.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+#include "rtl/bootstrap.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "osl/process.h"
+#include "osl/file.hxx"
+#include "osl/thread.hxx"
+#include "tools/getprocessworkingdir.hxx"
+#include "ucbhelper/contentbroker.hxx"
+#include "ucbhelper/configurationkeys.hxx"
+#include "unotools/processfactory.hxx"
+#include "unotools/configmgr.hxx"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "cppuhelper/bootstrap.hxx"
+#include "comphelper/sequence.hxx"
+#include <stdio.h>
+
+using ::rtl::OUString;
+using ::rtl::OString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+
+namespace unopkg {
+
+bool getLockFilePath(OUString & out);
+
+::rtl::OUString toString( OptionInfo const * info )
+{
+ OSL_ASSERT( info != 0 );
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii("--");
+ buf.appendAscii(info->m_name);
+ if (info->m_short_option != '\0')
+ {
+ buf.appendAscii(" (short -" );
+ buf.append(info->m_short_option );
+ buf.appendAscii(")");
+ }
+ if (info->m_has_argument)
+ buf.appendAscii(" <argument>" );
+ return buf.makeStringAndClear();
+}
+
+//==============================================================================
+OptionInfo const * getOptionInfo(
+ OptionInfo const * list,
+ OUString const & opt, sal_Unicode copt )
+{
+ for ( ; list->m_name != 0; ++list )
+ {
+ OptionInfo const & option_info = *list;
+ if (opt.getLength() > 0)
+ {
+ if (opt.equalsAsciiL(
+ option_info.m_name, option_info.m_name_length ) &&
+ (copt == '\0' || copt == option_info.m_short_option))
+ {
+ return &option_info;
+ }
+ }
+ else
+ {
+ OSL_ASSERT( copt != '\0' );
+ if (copt == option_info.m_short_option)
+ {
+ return &option_info;
+ }
+ }
+ }
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ opt, osl_getThreadTextEncoding() ).getStr() );
+ return 0;
+}
+
+//==============================================================================
+bool isOption( OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ OSL_ASSERT( option_info != 0 );
+ if (osl_getCommandArgCount() <= *pIndex)
+ return false;
+
+ OUString arg;
+ osl_getCommandArg( *pIndex, &arg.pData );
+ sal_Int32 len = arg.getLength();
+
+ if (len < 2 || arg[ 0 ] != '-')
+ return false;
+
+ if (len == 2 && arg[ 1 ] == option_info->m_short_option)
+ {
+ ++(*pIndex);
+ dp_misc::TRACE(OUSTR(__FILE__": identified option \'")
+ + OUSTR("\'") + OUString( option_info->m_short_option ) + OUSTR("\n"));
+ return true;
+ }
+ if (arg[ 1 ] == '-' && rtl_ustr_ascii_compare(
+ arg.pData->buffer + 2, option_info->m_name ) == 0)
+ {
+ ++(*pIndex);
+ dp_misc::TRACE(OUSTR( __FILE__": identified option \'")
+ + OUString::createFromAscii(option_info->m_name) + OUSTR("\'\n"));
+ return true;
+ }
+ return false;
+}
+//==============================================================================
+
+bool isBootstrapVariable(sal_uInt32 * pIndex)
+{
+ OSL_ASSERT(osl_getCommandArgCount() >= *pIndex);
+
+ OUString arg;
+ osl_getCommandArg(*pIndex, &arg.pData);
+ if (arg.matchAsciiL("-env:", 5))
+ {
+ ++(*pIndex);
+ return true;
+ }
+ return false;
+}
+
+//==============================================================================
+bool readArgument(
+ OUString * pValue, OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ if (isOption( option_info, pIndex ))
+ {
+ if (*pIndex < osl_getCommandArgCount())
+ {
+ OSL_ASSERT( pValue != 0 );
+ osl_getCommandArg( *pIndex, &pValue->pData );
+ dp_misc::TRACE(OUSTR( __FILE__": argument value: ")
+ + *pValue + OUSTR("\n"));
+ ++(*pIndex);
+ return true;
+ }
+ --(*pIndex);
+ }
+ return false;
+}
+
+//##############################################################################
+
+namespace {
+struct ExecutableDir : public rtl::StaticWithInit<
+ const OUString, ExecutableDir> {
+ const OUString operator () () {
+ OUString path;
+ if (osl_getExecutableFile( &path.pData ) != osl_Process_E_None) {
+ throw RuntimeException(
+ OUSTR("cannot locate executable directory!"),0 );
+ }
+ return path.copy( 0, path.lastIndexOf( '/' ) );
+ }
+};
+struct ProcessWorkingDir : public rtl::StaticWithInit<
+ const OUString, ProcessWorkingDir> {
+ const OUString operator () () {
+ OUString workingDir;
+ tools::getProcessWorkingDir(&workingDir);
+ return workingDir;
+ }
+};
+} // anon namespace
+
+//==============================================================================
+OUString const & getExecutableDir()
+{
+ return ExecutableDir::get();
+}
+
+//==============================================================================
+OUString const & getProcessWorkingDir()
+{
+ return ProcessWorkingDir::get();
+}
+
+//==============================================================================
+OUString makeAbsoluteFileUrl(
+ OUString const & sys_path, OUString const & base_url, bool throw_exc )
+{
+ // system path to file url
+ OUString file_url;
+ oslFileError rc = osl_getFileURLFromSystemPath( sys_path.pData, &file_url.pData );
+ if ( rc != osl_File_E_None) {
+ OUString tempPath;
+ if ( osl_getSystemPathFromFileURL( sys_path.pData, &tempPath.pData) == osl_File_E_None )
+ {
+ file_url = sys_path;
+ }
+ else if (throw_exc)
+ {
+ throw RuntimeException(
+ OUSTR("cannot get file url from system path: ") +
+ sys_path, Reference< XInterface >() );
+ }
+ }
+
+ OUString abs;
+ if (osl_getAbsoluteFileURL(
+ base_url.pData, file_url.pData, &abs.pData ) != osl_File_E_None)
+ {
+ if (throw_exc) {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "making absolute file url failed: \"") );
+ buf.append( base_url );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\" (base-url) and \"") );
+ buf.append( file_url );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" (file-url)!") );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+ return OUString();
+ }
+ return abs[ abs.getLength() -1 ] == '/'
+ ? abs.copy( 0, abs.getLength() -1 ) : abs;
+}
+
+//##############################################################################
+
+namespace {
+
+//------------------------------------------------------------------------------
+inline void printf_space( sal_Int32 space )
+{
+ while (space--)
+ dp_misc::writeConsole(" ");
+}
+
+//------------------------------------------------------------------------------
+void printf_line(
+ OUString const & name, OUString const & value, sal_Int32 level )
+{
+ printf_space( level );
+ dp_misc::writeConsole(name + OUSTR(": ") + value + OUSTR("\n"));
+}
+
+//------------------------------------------------------------------------------
+void printf_package(
+ Reference<deployment::XPackage> const & xPackage,
+ Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level )
+{
+ beans::Optional< OUString > id(
+ level == 0
+ ? beans::Optional< OUString >(
+ true, dp_misc::getIdentifier( xPackage ) )
+ : xPackage->getIdentifier() );
+ if (id.IsPresent)
+ printf_line( OUSTR("Identifier"), id.Value, level );
+ OUString version(xPackage->getVersion());
+ if (version.getLength() != 0)
+ printf_line( OUSTR("Version"), version, level + 1 );
+ printf_line( OUSTR("URL"), xPackage->getURL(), level + 1 );
+
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ xPackage->isRegistered( Reference<task::XAbortChannel>(), xCmdEnv ) );
+ OUString value;
+ if (option.IsPresent) {
+ beans::Ambiguous<sal_Bool> const & reg = option.Value;
+ if (reg.IsAmbiguous)
+ value = OUSTR("unknown");
+ else
+ value = reg.Value ? OUSTR("yes") : OUSTR("no");
+ }
+ else
+ value = OUSTR("n/a");
+ printf_line( OUSTR("is registered"), value, level + 1 );
+
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is()) {
+ printf_line( OUSTR("Media-Type"),
+ xPackageType->getMediaType(), level + 1 );
+ }
+ printf_line( OUSTR("Description"), xPackage->getDescription(), level + 1 );
+ if (xPackage->isBundle()) {
+ Sequence< Reference<deployment::XPackage> > seq(
+ xPackage->getBundle( Reference<task::XAbortChannel>(), xCmdEnv ) );
+ printf_space( level + 1 );
+ dp_misc::writeConsole("bundled Packages: {\n");
+ ::std::vector<Reference<deployment::XPackage> >vec_bundle;
+ ::comphelper::sequenceToContainer(vec_bundle, seq);
+ printf_packages( vec_bundle, ::std::vector<bool>(vec_bundle.size()),
+ xCmdEnv, level + 2 );
+ printf_space( level + 1 );
+ dp_misc::writeConsole("}\n");
+ }
+}
+
+} // anon namespace
+
+void printf_unaccepted_licenses(
+ Reference<deployment::XPackage> const & ext)
+{
+ OUString id(
+ dp_misc::getIdentifier(ext) );
+ printf_line( OUSTR("Identifier"), id, 0 );
+ printf_space(1);
+ dp_misc::writeConsole(OUSTR("License not accepted\n\n"));
+}
+
+//==============================================================================
+void printf_packages(
+ ::std::vector< Reference<deployment::XPackage> > const & allExtensions,
+ ::std::vector<bool> const & vecUnaccepted,
+ Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level )
+{
+ OSL_ASSERT(allExtensions.size() == vecUnaccepted.size());
+
+ if (allExtensions.size() == 0)
+ {
+ printf_space( level );
+ dp_misc::writeConsole("<none>\n");
+ }
+ else
+ {
+ typedef ::std::vector< Reference<deployment::XPackage> >::const_iterator I_EXT;
+ int index = 0;
+ for (I_EXT i = allExtensions.begin(); i != allExtensions.end(); i++, index++)
+ {
+ if (vecUnaccepted[index])
+ printf_unaccepted_licenses(*i);
+ else
+ printf_package( *i, xCmdEnv, level );
+ dp_misc::writeConsole(OUSTR("\n"));
+ }
+ }
+}
+
+
+//##############################################################################
+
+namespace {
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> bootstrapStandAlone(
+ DisposeGuard & disposeGuard, bool /*verbose */)
+{
+ Reference<XComponentContext> xContext =
+ ::cppu::defaultBootstrap_InitialComponentContext();
+
+ // assure disposing of local component context:
+ disposeGuard.reset(
+ Reference<lang::XComponent>( xContext, UNO_QUERY ) );
+
+ Reference<lang::XMultiServiceFactory> xServiceManager(
+ xContext->getServiceManager(), UNO_QUERY_THROW );
+ // set global process service factory used by unotools config helpers
+ ::utl::setProcessServiceFactory( xServiceManager );
+
+ // initialize the ucbhelper ucb,
+ // because the package implementation uses it
+ Sequence<Any> ucb_args( 2 );
+ ucb_args[ 0 ] <<= OUSTR(UCB_CONFIGURATION_KEY1_LOCAL);
+ ucb_args[ 1 ] <<= OUSTR(UCB_CONFIGURATION_KEY2_OFFICE);
+ if (! ::ucbhelper::ContentBroker::initialize( xServiceManager, ucb_args ))
+ throw RuntimeException( OUSTR("cannot initialize UCB!"), 0 );
+
+ return xContext;
+}
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> connectToOffice(
+ Reference<XComponentContext> const & xLocalComponentContext,
+ bool verbose )
+{
+ Sequence<OUString> args( 3 );
+ args[ 0 ] = OUSTR("-nologo");
+ args[ 1 ] = OUSTR("-nodefault");
+
+ OUString pipeId( ::dp_misc::generateRandomPipeId() );
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("-accept=pipe,name=") );
+ buf.append( pipeId );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(";urp;") );
+ args[ 2 ] = buf.makeStringAndClear();
+ OUString appURL( getExecutableDir() + OUSTR("/soffice") );
+
+ if (verbose)
+ {
+ dp_misc::writeConsole(
+ OUSTR("Raising process: ") +
+ appURL +
+ OUSTR("\nArguments: -nologo -nodefault ") +
+ args[2] +
+ OUSTR("\n"));
+ }
+
+ ::dp_misc::raiseProcess( appURL, args );
+
+ if (verbose)
+ dp_misc::writeConsole("Ok. Connecting...");
+
+ OSL_ASSERT( buf.getLength() == 0 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") );
+ buf.append( pipeId );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ ";urp;StarOffice.ComponentContext") );
+ Reference<XComponentContext> xRet(
+ ::dp_misc::resolveUnoURL(
+ buf.makeStringAndClear(), xLocalComponentContext ),
+ UNO_QUERY_THROW );
+ if (verbose)
+ dp_misc::writeConsole("Ok.\n");
+
+ return xRet;
+}
+
+} // anon namespace
+
+/** returns the path to the lock file used by unopkg.
+ @return the path. An empty string signifies an error.
+*/
+OUString getLockFilePath()
+{
+ OUString ret;
+ OUString sBootstrap(RTL_CONSTASCII_USTRINGPARAM("${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}"));
+ rtl::Bootstrap::expandMacros(sBootstrap);
+ OUString sAbs;
+ if (::osl::File::E_None == ::osl::File::getAbsoluteFileURL(
+ sBootstrap, OUSTR(".lock"), sAbs))
+ {
+ if (::osl::File::E_None ==
+ ::osl::File::getSystemPathFromFileURL(sAbs, sBootstrap))
+ {
+ ret = sBootstrap;
+ }
+ }
+
+ return ret;
+}
+//==============================================================================
+Reference<XComponentContext> getUNO(
+ DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
+ Reference<XComponentContext> & out_localContext)
+{
+ // do not create any user data (for the root user) in --shared mode:
+ if (shared) {
+ rtl::Bootstrap::set(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CFG_CacheUrl")),
+ rtl::OUString());
+ }
+
+ // hold lock during process runtime:
+ static ::desktop::Lockfile s_lockfile( false /* no IPC server */ );
+ Reference<XComponentContext> xComponentContext(
+ bootstrapStandAlone( disposeGuard, verbose ) );
+ out_localContext = xComponentContext;
+ if (::dp_misc::office_is_running()) {
+ xComponentContext.set(
+ connectToOffice( xComponentContext, verbose ) );
+ }
+ else
+ {
+ if (! s_lockfile.check( 0 ))
+ {
+ String sMsg(ResId(RID_STR_CONCURRENTINSTANCE, *DeploymentResMgr::get()));
+ //Create this string before we call DeInitVCL, because this will kill
+ //the ResMgr
+ String sError(ResId(RID_STR_UNOPKG_ERROR, *DeploymentResMgr::get()));
+
+ sMsg = sMsg + OUSTR("\n") + getLockFilePath();
+
+ if (bGui)
+ {
+ //We show a message box or print to the console that there
+ //is another instance already running
+ if ( ! InitVCL( Reference<lang::XMultiServiceFactory>(
+ xComponentContext->getServiceManager(),
+ UNO_QUERY_THROW ) ))
+ throw RuntimeException( OUSTR("Cannot initialize VCL!"),
+ NULL );
+ {
+ WarningBox warn(NULL, WB_OK | WB_DEF_OK, sMsg);
+ warn.SetText(::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME).get<OUString>());
+ warn.SetIcon(0);
+ warn.Execute();
+ }
+ DeInitVCL();
+ }
+
+ throw LockFileException(
+ OUSTR("\n") + sError + sMsg + OUSTR("\n"));
+ }
+ }
+
+ return xComponentContext;
+}
+
+}
+
diff --git a/desktop/source/pkgchk/unopkg/unopkg_shared.h b/desktop/source/pkgchk/unopkg/unopkg_shared.h
new file mode 100644
index 000000000000..43f77513b10c
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/unopkg_shared.h
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.h"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "tools/resmgr.hxx"
+#include "rtl/ustring.hxx"
+#include "unotools/configmgr.hxx"
+
+
+#define APP_NAME "unopkg"
+
+namespace css = ::com::sun::star;
+
+namespace unopkg {
+
+ inline ::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang )
+ {
+ ::com::sun::star::lang::Locale locale;
+ sal_Int32 nIndex = 0;
+ locale.Language = slang.getToken( 0, '-', nIndex );
+ locale.Country = slang.getToken( 0, '-', nIndex );
+ locale.Variant = slang.getToken( 0, '-', nIndex );
+ return locale;
+ }
+
+
+ struct OfficeLocale :
+ public rtl::StaticWithInit<const css::lang::Locale, OfficeLocale> {
+ const css::lang::Locale operator () () {
+ ::rtl::OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw css::uno::RuntimeException( OUSTR("Cannot determine language!"), 0 );
+ if (slang.getLength() == 0)
+ slang = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US"));
+ return toLocale(slang);
+ }
+};
+
+struct DeploymentResMgr : public rtl::StaticWithInit< ResMgr *, DeploymentResMgr >
+{
+ ResMgr * operator () () {
+ return ResMgr::CreateResMgr( "deployment", OfficeLocale::get());
+ }
+};
+
+struct OptionInfo
+{
+ char const * m_name;
+ sal_uInt32 m_name_length;
+ sal_Unicode m_short_option;
+ bool m_has_argument;
+};
+
+struct LockFileException : public css::uno::Exception
+{
+ LockFileException(::rtl::OUString const & sMessage) :
+ css::uno::Exception(sMessage, css::uno::Reference< css::uno::XInterface > ()) {}
+};
+
+//==============================================================================
+::rtl::OUString toString( OptionInfo const * info );
+
+//==============================================================================
+OptionInfo const * getOptionInfo(
+ OptionInfo const * list,
+ ::rtl::OUString const & opt, sal_Unicode copt = '\0' );
+
+//==============================================================================
+bool isOption( OptionInfo const * option_info, sal_uInt32 * pIndex );
+
+//==============================================================================
+bool readArgument(
+ ::rtl::OUString * pValue, OptionInfo const * option_info,
+ sal_uInt32 * pIndex );
+
+//==============================================================================
+inline bool readOption(
+ bool * flag, OptionInfo const * option_info, sal_uInt32 * pIndex )
+{
+ if (isOption( option_info, pIndex )) {
+ OSL_ASSERT( flag != 0 );
+ *flag = true;
+ return true;
+ }
+ return false;
+}
+//==============================================================================
+
+/** checks if an argument is a bootstrap variable. These start with -env:. For example
+ -env:UNO_JAVA_JFW_USER_DATA=file:///d:/user
+*/
+bool isBootstrapVariable(sal_uInt32 * pIndex);
+//==============================================================================
+::rtl::OUString const & getExecutableDir();
+
+//==============================================================================
+::rtl::OUString const & getProcessWorkingDir();
+
+//==============================================================================
+::rtl::OUString makeAbsoluteFileUrl(
+ ::rtl::OUString const & sys_path, ::rtl::OUString const & base_url,
+ bool throw_exc = true );
+
+//##############################################################################
+
+//==============================================================================
+class DisposeGuard
+{
+ css::uno::Reference<css::lang::XComponent> m_xComp;
+
+public:
+ inline DisposeGuard() {}
+ inline DisposeGuard(
+ css::uno::Reference<css::lang::XComponent> const & xComp )
+ : m_xComp( xComp ) {}
+
+ inline ~DisposeGuard()
+ {
+ if (m_xComp.is())
+ m_xComp->dispose();
+ }
+
+ inline void reset(
+ css::uno::Reference<css::lang::XComponent> const & xComp )
+ {
+ m_xComp = xComp;
+ }
+};
+
+//==============================================================================
+css::uno::Reference<css::ucb::XCommandEnvironment> createCmdEnv(
+ css::uno::Reference<css::uno::XComponentContext> const & xContext,
+ ::rtl::OUString const & logFile,
+ bool option_force_overwrite,
+ bool option_verbose);
+//==============================================================================
+void printf_packages(
+ ::std::vector<
+ css::uno::Reference<css::deployment::XPackage> > const & allExtensions,
+ ::std::vector<bool> const & vecUnaccepted,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ sal_Int32 level = 0 );
+
+//##############################################################################
+
+//==============================================================================
+css::uno::Reference<css::uno::XComponentContext> getUNO(
+ DisposeGuard & disposeGuard, bool verbose, bool shared, bool bGui,
+ css::uno::Reference<css::uno::XComponentContext> & out_LocalComponentContext);
+
+}
+
diff --git a/desktop/source/pkgchk/unopkg/version.map b/desktop/source/pkgchk/unopkg/version.map
new file mode 100644
index 000000000000..6d34cb662d2c
--- /dev/null
+++ b/desktop/source/pkgchk/unopkg/version.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ unopkg_main;
+
+ local:
+ *;
+};
diff --git a/desktop/source/registration/com/sun/star/registration/Registration.java b/desktop/source/registration/com/sun/star/registration/Registration.java
new file mode 100644
index 000000000000..7fc24b80398f
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/registration/Registration.java
@@ -0,0 +1,339 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+package com.sun.star.registration;
+
+import com.sun.star.beans.NamedValue;
+import com.sun.star.comp.loader.FactoryHelper;
+import com.sun.star.frame.DispatchResultEvent;
+import com.sun.star.frame.DispatchResultState;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+import com.sun.star.registry.*;
+import com.sun.star.servicetag.*;
+import com.sun.star.system.*;
+import com.sun.star.task.*;
+import com.sun.star.uno.*;
+import com.sun.star.uri.XExternalUriReferenceTranslator;
+import com.sun.star.util.XStringSubstitution;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+import java.net.HttpURLConnection;
+
+public class Registration {
+
+ public static XSingleServiceFactory __getServiceFactory(String implName,
+ XMultiServiceFactory multiFactory, XRegistryKey regKey) {
+ XSingleServiceFactory xSingleServiceFactory = null;
+
+ if (implName.equals(Registration.class.getName())) {
+ xSingleServiceFactory = FactoryHelper.getServiceFactory(_Registration.class, _serviceName, multiFactory, regKey);
+ }
+
+ return xSingleServiceFactory;
+ }
+
+ public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+ return FactoryHelper.writeRegistryServiceInfo(Registration.class.getName(), _serviceName, regKey);
+ }
+
+ static final String _serviceName = "com.sun.star.comp.framework.DoRegistrationJob";
+
+ static public class _Registration implements XJob {
+ XComponentContext xComponentContext;
+
+ XStringSubstitution xPathSubstService = null;
+ XExternalUriReferenceTranslator xUriTranslator = null;
+
+ RegistrationData theRegistrationData = null;
+
+ public _Registration(XComponentContext xComponentContext) {
+ this.xComponentContext = xComponentContext;
+ }
+
+ private String resolvePath(String path) {
+ try {
+ if( xPathSubstService == null || xUriTranslator == null ) {
+ XMultiComponentFactory theServiceManager = xComponentContext.getServiceManager();
+ if( xPathSubstService == null ) {
+ Object o = theServiceManager.createInstanceWithContext(
+ "com.sun.star.util.PathSubstitution",
+ xComponentContext );
+ xPathSubstService = (XStringSubstitution)
+ UnoRuntime.queryInterface(XStringSubstitution.class, o);
+ }
+
+ if( xUriTranslator == null ) {
+ Object o = theServiceManager.createInstanceWithContext(
+ "com.sun.star.uri.ExternalUriReferenceTranslator",
+ xComponentContext );
+ xUriTranslator = (XExternalUriReferenceTranslator)
+ UnoRuntime.queryInterface(XExternalUriReferenceTranslator.class, o);
+ }
+ }
+
+ String s = xPathSubstService.substituteVariables(path, true);
+ return xUriTranslator.translateToExternal(s);
+ } catch (java.lang.Exception e) {
+ return path;
+ }
+ }
+
+ private void openBrowser(String url) {
+ try {
+ XMultiComponentFactory theServiceManager = xComponentContext.getServiceManager();
+
+ Object o = theServiceManager.createInstanceWithContext(
+ "com.sun.star.system.SystemShellExecute",
+ xComponentContext );
+
+ XSystemShellExecute xShellExecuteService = (XSystemShellExecute)
+ UnoRuntime.queryInterface(XSystemShellExecute.class, o);
+
+ xShellExecuteService.execute( url, "", SystemShellExecuteFlags.DEFAULTS );
+ } catch (java.lang.Exception e) {
+ }
+ }
+
+ private ServiceTag getServiceTagFromRegistrationData(File xmlFile, String productURN) {
+ try {
+ RegistrationData storedRegData = RegistrationData.loadFromXML(new FileInputStream(xmlFile));
+ Set<ServiceTag> storedServiceTags = storedRegData.getServiceTags();
+
+ Iterator<ServiceTag> tagIterator = storedServiceTags.iterator();
+ while( tagIterator.hasNext() ) {
+ ServiceTag tag = tagIterator.next();
+ if( tag.getProductURN().equals(productURN) ) {
+ theRegistrationData = storedRegData;
+ return tag;
+ }
+ }
+
+ // product URN has changed, remove registration data file
+ xmlFile.delete();
+ } catch (IOException e) {
+ // fall through intentionally
+ } catch (IllegalArgumentException e) {
+ // file is damaged (or a name clash appeared)
+ xmlFile.delete();
+ }
+ return null;
+ }
+
+ /*
+ * XJob
+ *
+ * NOTE: as this Job hets triggered by the the JobExecutor service from first start
+ * wizard and registration reminder code (because their frames do not implement
+ * XDispatchProvider), making this an XAsyncJob doesn't make sense as the
+ * JobExecutor waits for the jobFinished call on the listener passed.
+ */
+ public Object execute(NamedValue[] args)
+ throws com.sun.star.lang.IllegalArgumentException, com.sun.star.uno.Exception {
+
+ final NamedValue[] f_args = args;
+
+ new Thread(
+ new Runnable () {
+ public void run() {
+ try {
+ executeImpl(f_args);
+ } catch(com.sun.star.uno.Exception e) {
+ }
+ }
+ }
+ ).start();
+
+ NamedValue ret[] = new NamedValue[1];
+ ret[0] = new NamedValue( "Deactivate", new Boolean(false) );
+ return ret;
+ }
+
+ public synchronized void executeImpl(NamedValue[] args)
+ throws com.sun.star.lang.IllegalArgumentException, com.sun.star.uno.Exception {
+
+ // extract the interesting part of the argument list
+ NamedValue[] theJobConfig = null;
+ NamedValue[] theEnvironment = null;
+
+ int c = args.length;
+ for (int i=0; i<c; ++i) {
+ if (args[i].Name.equals("JobConfig"))
+ theJobConfig = (NamedValue[]) AnyConverter.toArray(args[i].Value);
+ else if (args[i].Name.equals("Environment"))
+ theEnvironment = (NamedValue[]) AnyConverter.toArray(args[i].Value);
+ }
+
+ if (theEnvironment==null)
+ throw new com.sun.star.lang.IllegalArgumentException("no environment");
+
+ boolean saveConfig = false;
+
+ String productName = "";
+ String productVersion = "";
+ String productURN = "";
+ String productParent = "";
+ String productParentURN = "";
+ String productDefinedInstanceID = "";
+ String productSource = "";
+ String vendor = "";
+
+ String urlRegData = null;
+ String registrationURL = null;
+
+ c = theJobConfig.length;
+ for (int i=0; i<c; ++i) {
+ if( theJobConfig[i].Name.equals("ProductName") ) {
+ productName = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductVersion") ) {
+ productVersion = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductURN") ) {
+ productURN = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductParent") ) {
+ productParent = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductParentURN") ) {
+ productParentURN = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("ProductSource") ) {
+ productSource = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("Vendor") ) {
+ vendor = AnyConverter.toString(theJobConfig[i].Value);
+ } else if( theJobConfig[i].Name.equals("RegistrationData") ) {
+ urlRegData = resolvePath(AnyConverter.toString(theJobConfig[i].Value));
+ } else if( theJobConfig[i].Name.equals("RegistrationURL") ) {
+ registrationURL = AnyConverter.toString(theJobConfig[i].Value);
+ } else {
+ System.err.println( theJobConfig[i].Name + " = " + AnyConverter.toString(theJobConfig[i].Value) );
+ }
+ }
+
+ if (registrationURL==null)
+ throw new com.sun.star.lang.IllegalArgumentException("no registration url");
+
+ boolean local_only = false;
+
+ c = theEnvironment.length;
+ for (int i=0; i<c; ++i) {
+ if( theEnvironment[i].Name.equals("EventName") ) {
+ if( ! AnyConverter.toString(theEnvironment[i].Value).equals("onRegisterNow") ) {
+ local_only = true;
+ }
+ }
+ }
+
+ try {
+
+ /* ensure only one thread accesses/writes registration.xml at a time
+ * regardless how many instances of this Job exist.
+ */
+ synchronized( _serviceName ) {
+
+ File xmlRegData = new File( new URI( urlRegData ) );
+
+ ServiceTag tag = getServiceTagFromRegistrationData(xmlRegData, productURN);
+ if( tag == null ) {
+ tag = ServiceTag.newInstance(
+ ServiceTag.generateInstanceURN(),
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ vendor,
+ System.getProperty("os.arch"),
+ Installer.getZoneName(),
+ productSource);
+
+ theRegistrationData = new RegistrationData();
+ theRegistrationData.addServiceTag(tag);
+ theRegistrationData.storeToXML( new FileOutputStream( xmlRegData ) );
+ }
+
+ // Store the service tag in local registry, which might have been installed later
+ if( Registry.isSupported() ) {
+ // ignore communication failures with local service tag client
+ try {
+ if( Registry.getSystemRegistry().getServiceTag(tag.getInstanceURN()) == null ) {
+ Registry.getSystemRegistry().addServiceTag(tag);
+ }
+ } catch( java.io.IOException e) {
+ e.printStackTrace();
+ } catch (java.lang.RuntimeException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ if( ! local_only ) {
+ registrationURL = registrationURL.replaceAll("\\$\\{registry_urn\\}", theRegistrationData.getRegistrationURN());
+ registrationURL = registrationURL.replaceAll("\\$\\{locale\\}", Locale.getDefault().getLanguage());
+
+ HttpURLConnection con = (HttpURLConnection) new URL(registrationURL).openConnection();
+ con.setDoInput(true);
+ con.setDoOutput(true);
+ con.setUseCaches(false);
+ con.setAllowUserInteraction(false);
+ con.setRequestMethod("POST");
+
+ con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\"");
+ try {
+ con.connect();
+
+ OutputStream out = con.getOutputStream();
+ theRegistrationData.storeToXML(out);
+ out.flush();
+ out.close();
+
+ int returnCode = con.getResponseCode();
+// if (returnCode == HttpURLConnection.HTTP_OK);
+ } catch(java.lang.Exception e) {
+ // IOException and UnknownHostException
+ }
+ openBrowser(registrationURL);
+ }
+ } catch (java.net.MalformedURLException e) {
+ e.printStackTrace();
+ throw new com.sun.star.lang.IllegalArgumentException( e.toString() );
+ } catch (java.net.URISyntaxException e) {
+ e.printStackTrace();
+ throw new com.sun.star.lang.IllegalArgumentException( e.toString() );
+ } catch (java.io.IOException e) {
+ e.printStackTrace();
+ throw new com.sun.star.uno.RuntimeException( e.toString() );
+ } catch (java.lang.RuntimeException e) {
+ e.printStackTrace();
+ throw new com.sun.star.uno.RuntimeException( e.toString() );
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/registration/makefile.mk b/desktop/source/registration/com/sun/star/registration/makefile.mk
new file mode 100644
index 000000000000..9784166eb91b
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/registration/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJNAME = setup_native
+PRJ = ..$/..$/..$/..$/..$/..
+TARGET = productregistration
+PACKAGE = com$/sun$/star$/registration
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(ENABLE_SVCTAGS)" == "YES"
+
+JARFILES = jurt.jar unoil.jar ridl.jar
+JAVAFILES = \
+ Registration.java
+
+JAVACLASSFILES= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
+
+JARTARGET = $(TARGET).jar
+JARCOMPRESS = TRUE
+JARCLASSDIRS = $(PACKAGE) com$/sun$/star$/servicetag
+CUSTOMMANIFESTFILE = manifest
+.ENDIF # "$(ENABLE_SVCTAGS)" == "YES"
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/registration/com/sun/star/registration/manifest b/desktop/source/registration/com/sun/star/registration/manifest
new file mode 100644
index 000000000000..952aaa804e96
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/registration/manifest
@@ -0,0 +1,2 @@
+RegistrationClassName: com.sun.star.registration.Registration
+UNO-Type-Path:
diff --git a/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java b/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java
new file mode 100644
index 000000000000..87d83d5339ac
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.io.IOException;
+import java.net.URI;
+
+/**
+ * BrowserSupport class.
+ *
+ * The implementation of the com.sun.servicetag API needs to be
+ * compiled with JDK 5 as well since the consumer of this API
+ * may require to support JDK 5 (e.g. NetBeans).
+ *
+ * The Desktop.browse() method can be backported in this class
+ * if needed. The current implementation only supports JDK 6.
+ */
+class BrowserSupport {
+ private static boolean isBrowseSupported = false;
+ private static Method browseMethod = null;
+ private static Object desktop = null;
+ private static volatile Boolean result = false;
+
+
+ private static void initX() {
+ if (desktop != null) {
+ return;
+ }
+ boolean supported = false;
+ Method browseM = null;
+ Object desktopObj = null;
+ try {
+ // Determine if java.awt.Desktop is supported
+ Class desktopCls = Class.forName("java.awt.Desktop", true, null);
+ Method getDesktopM = desktopCls.getMethod("getDesktop");
+ browseM = desktopCls.getMethod("browse", URI.class);
+
+ Class actionCls = Class.forName("java.awt.Desktop$Action", true, null);
+ final Method isDesktopSupportedMethod = desktopCls.getMethod("isDesktopSupported");
+ Method isSupportedMethod = desktopCls.getMethod("isSupported", actionCls);
+ Field browseField = actionCls.getField("BROWSE");
+ // isDesktopSupported calls getDefaultToolkit which can block
+ // infinitely, see 6636099 for details, to workaround we call
+ // in a thread and time it out, noting that the issue is specific
+ // to X11, it does not hurt for Windows.
+ Thread xthread = new Thread() {
+ public void run() {
+ try {
+ // support only if Desktop.isDesktopSupported() and
+ // Desktop.isSupported(Desktop.Action.BROWSE) return true.
+ result = (Boolean) isDesktopSupportedMethod.invoke(null);
+ } catch (IllegalAccessException e) {
+ // should never reach here
+ InternalError x =
+ new InternalError("Desktop.getDesktop() method not found");
+ x.initCause(e);
+ } catch (InvocationTargetException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+ // set it to daemon, so that the vm will exit.
+ xthread.setDaemon(true);
+ xthread.start();
+ try {
+ xthread.join(5 * 1000);
+ } catch (InterruptedException ie) {
+ // ignore the exception
+ }
+ if (result.booleanValue()) {
+ desktopObj = getDesktopM.invoke(null);
+ result = (Boolean) isSupportedMethod.invoke(desktopObj, browseField.get(null));
+ supported = result.booleanValue();
+ }
+ } catch (ClassNotFoundException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (NoSuchMethodException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (NoSuchFieldException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (IllegalAccessException e) {
+ // should never reach here
+ InternalError x =
+ new InternalError("Desktop.getDesktop() method not found");
+ x.initCause(e);
+ throw x;
+ } catch (InvocationTargetException e) {
+ // browser not supported
+ if (Util.isVerbose()) {
+ e.printStackTrace();
+ }
+ }
+ isBrowseSupported = supported;
+ browseMethod = browseM;
+ desktop = desktopObj;
+ }
+
+ static boolean isSupported() {
+ initX();
+ return isBrowseSupported;
+ }
+
+ /**
+ * Launches the default browser to display a {@code URI}.
+ * If the default browser is not able to handle the specified
+ * {@code URI}, the application registered for handling
+ * {@code URIs} of the specified type is invoked. The application
+ * is determined from the protocol and path of the {@code URI}, as
+ * defined by the {@code URI} class.
+ * <p>
+ * This method calls the Desktop.getDesktop().browse() method.
+ * <p>
+ * @param uri the URI to be displayed in the user default browser
+ *
+ * @throws NullPointerException if {@code uri} is {@code null}
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#BROWSE} action
+ * @throws IOException if the user default browser is not found,
+ * or it fails to be launched, or the default handler application
+ * failed to be launched
+ * @throws IllegalArgumentException if the necessary permissions
+ * are not available and the URI can not be converted to a {@code URL}
+ */
+ static void browse(URI uri) throws IOException {
+ if (uri == null) {
+ throw new NullPointerException("null uri");
+ }
+ if (!isSupported()) {
+ throw new UnsupportedOperationException("Browse operation is not supported");
+ }
+
+ // Call Desktop.browse() method
+ try {
+ if (Util.isVerbose()) {
+ System.out.println("desktop: " + desktop + ":browsing..." + uri);
+ }
+ browseMethod.invoke(desktop, uri);
+ } catch (IllegalAccessException e) {
+ // should never reach here
+ InternalError x =
+ new InternalError("Desktop.getDesktop() method not found");
+ x.initCause(e);
+ throw x;
+ } catch (InvocationTargetException e) {
+ Throwable x = e.getCause();
+ if (x != null) {
+ if (x instanceof UnsupportedOperationException) {
+ throw (UnsupportedOperationException) x;
+ } else if (x instanceof IllegalArgumentException) {
+ throw (IllegalArgumentException) x;
+ } else if (x instanceof IOException) {
+ throw (IOException) x;
+ } else if (x instanceof SecurityException) {
+ throw (SecurityException) x;
+ } else {
+ // ignore
+ }
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/Installer.java b/desktop/source/registration/com/sun/star/servicetag/Installer.java
new file mode 100644
index 000000000000..ba1b5c4b86d5
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/Installer.java
@@ -0,0 +1,943 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import static com.sun.star.servicetag.Util.*;
+
+/**
+ * Service Tag Installer for Java SE.
+ */
+public class Installer {
+ // System properties for testing
+ private static String SVCTAG_DIR_PATH =
+ "servicetag.dir.path";
+ private static String SVCTAG_ENABLE_REGISTRATION =
+ "servicetag.registration.enabled";
+ private final static String SUN_VENDOR = "Sun Microsystems";
+ private final static String REGISTRATION_XML = "registration.xml";
+ private final static String SERVICE_TAG_FILE = "servicetag";
+ private final static String REGISTRATION_HTML_NAME = "register";
+
+ private final static Locale[] knownSupportedLocales =
+ new Locale[] { Locale.ENGLISH,
+ Locale.JAPANESE,
+ Locale.SIMPLIFIED_CHINESE};
+
+ private final static String javaHome = System.getProperty("java.home");
+ private static File svcTagDir;
+ private static File serviceTagFile;
+ private static File regXmlFile;
+ private static RegistrationData registration;
+ private static boolean supportRegistration;
+ private static String registerHtmlParent;
+ private static Set<Locale> supportedLocales = new HashSet<Locale>();
+ private static Properties swordfishProps = null;
+ private static String[] jreArchs = null;
+ static {
+ String dir = System.getProperty(SVCTAG_DIR_PATH);
+ if (dir == null) {
+ svcTagDir = new File(getJrePath(), "lib" + File.separator + SERVICE_TAG_FILE);
+ } else {
+ svcTagDir = new File(dir);
+ }
+ serviceTagFile = new File(svcTagDir, SERVICE_TAG_FILE);
+ regXmlFile = new File(svcTagDir, REGISTRATION_XML);
+ if (System.getProperty(SVCTAG_ENABLE_REGISTRATION) == null) {
+ supportRegistration = isJdk();
+ } else {
+ supportRegistration = true;
+ }
+ }
+
+ private Installer() {
+ }
+
+ // Implementation of ServiceTag.getJavaServiceTag(String) method
+ static ServiceTag getJavaServiceTag(String source) throws IOException {
+ if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) {
+ // Products bundling this implementation may run on
+ // Mac OS which is not a Sun JDK
+ return null;
+ }
+ boolean cleanup = false;
+ try {
+ // Check if we have the swordfish entries for this JRE version
+ if (loadSwordfishEntries() == null) {
+ return null;
+ }
+
+ ServiceTag st = getJavaServiceTag();
+ // Check if the service tag created by this bundle owner
+ if (st != null && st.getSource().equals(source)) {
+ // Install the system service tag if supported
+ // stclient may be installed after the service tag creation
+ if (Registry.isSupported()) {
+ installSystemServiceTag();
+ }
+ return st;
+ }
+
+ // in case any exception thrown during the cleanup
+ cleanup = true;
+
+ // re-create a new one for this bundle owner
+ // first delete the registration data
+ deleteRegistrationData();
+ cleanup = false;
+
+ // create service tag and generate new register.html pages
+ return createServiceTag(source);
+ } finally {
+ if (cleanup) {
+ if (regXmlFile.exists()) {
+ regXmlFile.delete();
+ }
+ if (serviceTagFile.exists()) {
+ serviceTagFile.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the Java SE registration data located in
+ * the <JRE>/lib/servicetag/registration.xml by default.
+ *
+ * @throws IllegalArgumentException if the registration data
+ * is of invalid format.
+ */
+ private static synchronized RegistrationData getRegistrationData()
+ throws IOException {
+ if (registration != null) {
+ return registration;
+ }
+ if (regXmlFile.exists()) {
+ BufferedInputStream in = null;
+ try {
+ in = new BufferedInputStream(new FileInputStream(regXmlFile));
+ registration = RegistrationData.loadFromXML(in);
+ } catch (IllegalArgumentException ex) {
+ System.err.println("Error: Bad registration data \"" +
+ regXmlFile + "\":" + ex.getMessage());
+ throw ex;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ } else {
+ registration = new RegistrationData();
+ }
+ return registration;
+ }
+
+ /**
+ * Write the registration data to the registration.xml file.
+ *
+ * The offline registration page has to be regenerated with
+ * the new registration data.
+ *
+ * @throws java.io.IOException
+ */
+ private static synchronized void writeRegistrationXml()
+ throws IOException {
+ if (!svcTagDir.exists()) {
+ // This check is for NetBeans or other products that
+ // bundles this com.sun.servicetag implementation for
+ // pre-6u5 release.
+ if (!svcTagDir.mkdir()) {
+ throw new IOException("Failed to create directory: " + svcTagDir);
+ }
+ }
+
+ // regenerate the new offline registration page
+ deleteRegistrationHtmlPage();
+ getRegistrationHtmlPage();
+
+ BufferedOutputStream out = null;
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(regXmlFile));
+ getRegistrationData().storeToXML(out);
+ } catch (IllegalArgumentException ex) {
+ System.err.println("Error: Bad registration data \"" +
+ regXmlFile + "\":" + ex.getMessage());
+ throw ex;
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Returns the instance urn(s) stored in the servicetag file
+ * or empty set if file not exists.
+ */
+ private static Set<String> getInstalledURNs() throws IOException {
+ Set<String> urnSet = new HashSet<String>();
+ if (serviceTagFile.exists()) {
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new FileReader(serviceTagFile));
+ String urn;
+ while ((urn = in.readLine()) != null) {
+ urn = urn.trim();
+ if (urn.length() > 0) {
+ urnSet.add(urn);
+ }
+ }
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+ return urnSet;
+ }
+
+ /**
+ * Return the Java SE service tag(s) if it exists.
+ * Typically only one Java SE service tag but it could have two for
+ * Solaris 32-bit and 64-bit on the same install directory.
+ *
+ * @return the service tag(s) for Java SE
+ */
+ private static ServiceTag[] getJavaServiceTagArray() throws IOException {
+ RegistrationData regData = getRegistrationData();
+ Set<ServiceTag> svcTags = regData.getServiceTags();
+ Set<ServiceTag> result = new HashSet<ServiceTag>();
+
+ Properties props = loadSwordfishEntries();
+ String jdkUrn = props.getProperty("servicetag.jdk.urn");
+ String jreUrn = props.getProperty("servicetag.jre.urn");
+ for (ServiceTag st : svcTags) {
+ if (st.getProductURN().equals(jdkUrn) ||
+ st.getProductURN().equals(jreUrn)) {
+ result.add(st);
+ }
+ }
+ return result.toArray(new ServiceTag[0]);
+ }
+
+ /**
+ * Returns the Java SE service tag for this running platform;
+ * or null if not exist.
+ * This method will return the 64-bit service tag if the JDK
+ * supports both 32-bit and 64-bit if already created.
+ */
+ private static ServiceTag getJavaServiceTag() throws IOException {
+ String definedId = getProductDefinedId();
+ for (ServiceTag st : getJavaServiceTagArray()) {
+ if (st.getProductDefinedInstanceID().equals(definedId)) {
+ return st;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create a service tag for Java SE and install in the system
+ * service tag registry if supported.
+ *
+ * A registration data <JRE>/lib/servicetag/registration.xml
+ * will be created to storeToXML the XML entry for Java SE service tag.
+ * If the system supports service tags, this method will install
+ * the Java SE service tag in the system service tag registry and
+ * its <tt>instance_urn</tt> will be stored to <JRE>/lib/servicetag/servicetag.
+ *
+ * If <JRE>/lib/servicetag/registration.xml exists but is not installed
+ * in the system service tag registry (i.e. servicetag doesn't exist),
+ * this method will install it as described above.
+ *
+ * If the system supports service tag, stclient will be used
+ * to create the Java SE service tag.
+ *
+ * A Solaris 32-bit and 64-bit JDK will be installed in the same
+ * directory but the registration.xml will have 2 service tags.
+ * The servicetag file will also contain 2 instance_urns for that case.
+ */
+ private static ServiceTag createServiceTag(String svcTagSource)
+ throws IOException {
+ // determine if a new service tag is needed to be created
+ ServiceTag newSvcTag = null;
+ if (getJavaServiceTag() == null) {
+ newSvcTag = newServiceTag(svcTagSource);
+ }
+
+ // Add the new service tag in the registration data
+ if (newSvcTag != null) {
+ RegistrationData regData = getRegistrationData();
+
+ // Add the service tag to the registration data in JDK/JRE
+ newSvcTag = regData.addServiceTag(newSvcTag);
+
+ // add if there is a service tag for the OS
+ ServiceTag osTag = SolarisServiceTag.getServiceTag();
+ if (osTag != null && regData.getServiceTag(osTag.getInstanceURN()) == null) {
+ regData.addServiceTag(osTag);
+ }
+ // write to the registration.xml
+ writeRegistrationXml();
+ }
+
+ // Install the system service tag if supported
+ if (Registry.isSupported()) {
+ installSystemServiceTag();
+ }
+ return newSvcTag;
+ }
+
+ private static void installSystemServiceTag() throws IOException {
+ // only install the service tag in the registry if
+ // it has permission to write the servicetag file.
+ if ((!serviceTagFile.exists() && !svcTagDir.canWrite()) ||
+ (serviceTagFile.exists() && !serviceTagFile.canWrite())) {
+ return;
+ }
+
+ Set<String> urns = getInstalledURNs();
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ if (urns.size() < javaSvcTags.length) {
+ for (ServiceTag st : javaSvcTags) {
+ // Add the service tag in the system service tag registry
+ // if not installed
+ String instanceURN = st.getInstanceURN();
+ if (!urns.contains(instanceURN)) {
+ Registry.getSystemRegistry().addServiceTag(st);
+ }
+ }
+ }
+ writeInstalledUrns();
+ }
+
+ private static ServiceTag newServiceTag(String svcTagSource) throws IOException {
+ // Load the swoRDFish information for the service tag creation
+ Properties props = loadSwordfishEntries();
+
+ // Determine the product URN and name
+ String productURN;
+ String productName;
+
+ if (isJdk()) {
+ // <HOME>/jre exists which implies it's a JDK
+ productURN = props.getProperty("servicetag.jdk.urn");
+ productName = props.getProperty("servicetag.jdk.name");
+ } else {
+ // Otherwise, it's a JRE
+ productURN = props.getProperty("servicetag.jre.urn");
+ productName = props.getProperty("servicetag.jre.name");
+ }
+
+ return ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
+ productName,
+ System.getProperty("java.version"),
+ productURN,
+ props.getProperty("servicetag.parent.name"),
+ props.getProperty("servicetag.parent.urn"),
+ getProductDefinedId(),
+ SUN_VENDOR,
+ System.getProperty("os.arch"),
+ getZoneName(),
+ svcTagSource);
+ }
+
+ /**
+ * Delete the registration data, the offline registration pages and
+ * the service tags in the system service tag registry if installed.
+ *
+ * The registration.xml and servicetag file will be removed.
+ */
+ private static synchronized void deleteRegistrationData()
+ throws IOException {
+ try {
+ // delete the offline registration page
+ deleteRegistrationHtmlPage();
+
+ // Remove the service tag from the system ST registry if exists
+ Set<String> urns = getInstalledURNs();
+ if (urns.size() > 0 && Registry.isSupported()) {
+ for (String u : urns) {
+ Registry.getSystemRegistry().removeServiceTag(u);
+ }
+ }
+ registration = null;
+ } finally {
+ // Delete the registration.xml and servicetag files if exists
+ if (regXmlFile.exists()) {
+ if (!regXmlFile.delete()) {
+ throw new IOException("Failed to delete " + regXmlFile);
+ }
+ }
+ if (serviceTagFile.exists()) {
+ if (!serviceTagFile.delete()) {
+ throw new IOException("Failed to delete " + serviceTagFile);
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates the registration data to contain one single service tag
+ * for the running Java runtime.
+ */
+ private static synchronized void updateRegistrationData(String svcTagSource)
+ throws IOException {
+ RegistrationData regData = getRegistrationData();
+ ServiceTag curSvcTag = newServiceTag(svcTagSource);
+
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ Set<String> urns = getInstalledURNs();
+ for (ServiceTag st : javaSvcTags) {
+ if (!st.getProductDefinedInstanceID().equals(curSvcTag.getProductDefinedInstanceID())) {
+ String instanceURN = st.getInstanceURN();
+ regData.removeServiceTag(instanceURN);
+
+ // remove it from the system service tag registry if exists
+ if (urns.contains(instanceURN) && Registry.isSupported()) {
+ Registry.getSystemRegistry().removeServiceTag(instanceURN);
+ }
+ }
+ }
+ writeRegistrationXml();
+ writeInstalledUrns();
+ }
+
+ private static void writeInstalledUrns() throws IOException {
+ // if the Registry is not supported,
+ // remove the servicetag file
+ if (!Registry.isSupported() && serviceTagFile.exists()) {
+ serviceTagFile.delete();
+ return;
+ }
+
+ PrintWriter out = null;
+ try {
+ out = new PrintWriter(serviceTagFile);
+
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ for (ServiceTag st : javaSvcTags) {
+ // Write the instance_run to the servicetag file
+ String instanceURN = st.getInstanceURN();
+ out.println(instanceURN);
+ }
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Load the values associated with the swoRDFish metadata entries
+ * for Java SE. The swoRDFish metadata entries are different for
+ * different release.
+ *
+ * @param version Version of Java SE
+ */
+ private static synchronized Properties loadSwordfishEntries() throws IOException {
+ if (swordfishProps != null) {
+ return swordfishProps;
+ }
+
+ // The version string for Java SE 6 is 1.6.0
+ // We just need the minor number in the version string
+ int version = Util.getJdkVersion();
+
+ String filename = "/com/sun/servicetag/resources/javase_" +
+ version + "_swordfish.properties";
+ InputStream in = Installer.class.getClass().getResourceAsStream(filename);
+ if (in == null) {
+ return null;
+ }
+ swordfishProps = new Properties();
+ try {
+ swordfishProps.load(in);
+ } finally {
+ in.close();
+ }
+ return swordfishProps;
+ }
+
+ /**
+ * Returns the product defined instance ID for Java SE.
+ * It is a list of comma-separated name/value pairs:
+ * "id=<full-version> <arch> [<arch>]*"
+ * "dir=<java.home system property value>"
+ *
+ * where <full-version> is the full version string of the JRE,
+ * <arch> is the architecture that the runtime supports
+ * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list))
+ *
+ * For Solaris, it can be dual mode that can support both
+ * 32-bit and 64-bit. the "id" will be set to
+ * "1.6.0_03-b02 sparc sparcv9"
+ *
+ * The "dir" property is included in the service tag to enable
+ * the Service Tag software to determine if a service tag for
+ * Java SE is invalid and perform appropriate service tag
+ * cleanup if necessary. See RFE# 6574781 Service Tags Enhancement.
+ *
+ */
+ private static String getProductDefinedId() {
+ StringBuilder definedId = new StringBuilder();
+ definedId.append("id=");
+ definedId.append(System.getProperty("java.runtime.version"));
+
+ String[] archs = getJreArchs();
+ for (String name : archs) {
+ definedId.append(" " + name);
+ }
+
+ String location = ",dir=" + javaHome;
+ if ((definedId.length() + location.length()) < 256) {
+ definedId.append(",dir=");
+ definedId.append(javaHome);
+ } else {
+ // if it exceeds the limit, we will not include the location
+ if (isVerbose()) {
+ System.err.println("Warning: Product defined instance ID exceeds the field limit:");
+ }
+ }
+
+ return definedId.toString();
+ }
+
+ /**
+ * Returns the architectures that the runtime supports
+ * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list))
+ * The directory name where libjava.so is located.
+ *
+ * On Windows, returns the "os.arch" system property value.
+ */
+ private synchronized static String[] getJreArchs() {
+ if (jreArchs != null) {
+ return jreArchs;
+ }
+
+ Set<String> archs = new HashSet<String>();
+
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS") || os.equals("Linux")) {
+ // Traverse the directories under <JRE>/lib.
+ // If <JRE>/lib/<arch>/libjava.so exists, add <arch>
+ // to the product defined ID
+ File dir = new File(getJrePath() + File.separator + "lib");
+ if (dir.isDirectory()) {
+ String[] children = dir.list();
+ for (String name : children) {
+ File f = new File(dir, name + File.separator + "libjava.so");
+ if (f.exists()) {
+ archs.add(name);
+ }
+ }
+ }
+ } else {
+ // Windows - append the os.arch
+ archs.add(System.getProperty("os.arch"));
+ }
+ jreArchs = archs.toArray(new String[0]);
+ return jreArchs;
+ }
+
+ /**
+ * Return the zonename if zone is supported; otherwise, return
+ * "global".
+ */
+ public static String getZoneName() throws IOException {
+ String zonename = "global";
+
+ String command = "/usr/bin/zonename";
+ File f = new File(command);
+ // com.sun.servicetag package has to be compiled with JDK 5 as well
+ // JDK 5 doesn't support the File.canExecute() method.
+ // Risk not checking isExecute() for the zonename command is very low.
+ if (f.exists()) {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (p.exitValue() == 0) {
+ zonename = output.trim();
+ }
+
+ }
+ return zonename;
+ }
+
+ private synchronized static String getRegisterHtmlParent() throws IOException {
+ if (registerHtmlParent == null) {
+ File htmlDir; // register.html is put under the JDK directory
+ if (getJrePath().endsWith(File.separator + "jre")) {
+ htmlDir = new File(getJrePath(), "..");
+ } else {
+ // j2se non-image build
+ htmlDir = new File(getJrePath());
+ }
+
+ // initialize the supported locales
+ initSupportedLocales(htmlDir);
+
+ // Determine the location of the offline registration page
+ String path = System.getProperty(SVCTAG_DIR_PATH);
+ if (path == null) {
+ // Default is <JDK>/register.html
+ registerHtmlParent = htmlDir.getCanonicalPath();
+ } else {
+ File f = new File(path);
+ registerHtmlParent = f.getCanonicalPath();
+ if (!f.isDirectory()) {
+ throw new InternalError("Path " + path + " set in \"" +
+ SVCTAG_DIR_PATH + "\" property is not a directory");
+ }
+ }
+ }
+ return registerHtmlParent;
+ }
+
+ /**
+ * Returns the File object of the offline registration page localized
+ * for the default locale in the JDK directory.
+ */
+ static synchronized File getRegistrationHtmlPage() throws IOException {
+ if (!supportRegistration) {
+ // No register.html page generated if JRE
+ return null;
+ }
+
+ String parent = getRegisterHtmlParent();
+
+ // check if the offline registration page is already generated
+ File f = new File(parent, REGISTRATION_HTML_NAME + ".html");
+ if (!f.exists()) {
+ // Generate the localized version of the offline registration Page
+ generateRegisterHtml(parent);
+ }
+
+ String name = REGISTRATION_HTML_NAME;
+ List<Locale> candidateLocales = getCandidateLocales(Locale.getDefault());
+ for (Locale l : candidateLocales) {
+ if (supportedLocales.contains(l)) {
+ name = REGISTRATION_HTML_NAME + "_" + l.toString();
+ break;
+ }
+ }
+ File htmlFile = new File(parent, name + ".html");
+ if (isVerbose()) {
+ System.out.print("Offline registration page: " + htmlFile);
+ System.out.println((htmlFile.exists() ?
+ "" : " not exist. Use register.html"));
+ }
+ if (htmlFile.exists()) {
+ return htmlFile;
+ } else {
+ return new File(parent,
+ REGISTRATION_HTML_NAME + ".html");
+ }
+ }
+
+ private static List<Locale> getCandidateLocales(Locale locale) {
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ String variant = locale.getVariant();
+
+ List<Locale> locales = new ArrayList<Locale>(3);
+ if (variant.length() > 0) {
+ locales.add(locale);
+ }
+ if (country.length() > 0) {
+ locales.add((locales.size() == 0) ?
+ locale : new Locale(language, country, ""));
+ }
+ if (language.length() > 0) {
+ locales.add((locales.size() == 0) ?
+ locale : new Locale(language, "", ""));
+ }
+ return locales;
+ }
+
+ // Remove the offline registration pages
+ private static void deleteRegistrationHtmlPage() throws IOException {
+ String parent = getRegisterHtmlParent();
+ if (parent == null) {
+ return;
+ }
+
+ for (Locale locale : supportedLocales) {
+ String name = REGISTRATION_HTML_NAME;
+ if (!locale.equals(Locale.ENGLISH)) {
+ name += "_" + locale.toString();
+ }
+ File f = new File(parent, name + ".html");
+ if (f.exists()) {
+ if (!f.delete()) {
+ throw new IOException("Failed to delete " + f);
+ }
+ }
+ }
+ }
+
+ private static void initSupportedLocales(File jdkDir) {
+ if (supportedLocales.isEmpty()) {
+ // initialize with the known supported locales
+ for (Locale l : knownSupportedLocales) {
+ supportedLocales.add(l);
+ }
+ }
+
+ // Determine unknown supported locales if any
+ // by finding the localized version of README.html
+ // This prepares if a new locale in JDK is supported in
+ // e.g. in the OpenSource world
+ FilenameFilter ff = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ String fname = name.toLowerCase();
+ if (fname.startsWith("readme") && fname.endsWith(".html")) {
+ return true;
+ }
+ return false;
+ }
+ };
+
+ String[] readmes = jdkDir.list(ff);
+ for (String name : readmes) {
+ String basename = name.substring(0, name.length() - ".html".length());
+ String[] ss = basename.split("_");
+ switch (ss.length) {
+ case 1:
+ // English version
+ break;
+ case 2:
+ supportedLocales.add(new Locale(ss[1]));
+ break;
+ case 3:
+ supportedLocales.add(new Locale(ss[1], ss[2]));
+ break;
+ default:
+ // ignore
+ break;
+ }
+ }
+ if (isVerbose()) {
+ System.out.println("Supported locales: ");
+ for (Locale l : supportedLocales) {
+ System.out.println(l);
+ }
+ }
+ }
+
+ private static final String JDK_HEADER_PNG_KEY = "@@JDK_HEADER_PNG@@";
+ private static final String JDK_VERSION_KEY = "@@JDK_VERSION@@";
+ private static final String REGISTRATION_URL_KEY = "@@REGISTRATION_URL@@";
+ private static final String REGISTRATION_PAYLOAD_KEY = "@@REGISTRATION_PAYLOAD@@";
+
+ @SuppressWarnings("unchecked")
+ private static void generateRegisterHtml(String parent) throws IOException {
+ int version = Util.getJdkVersion();
+ int update = Util.getUpdateVersion();
+ String jdkVersion = "Version " + version;
+ if (update > 0) {
+ // product name is not translated
+ jdkVersion += " Update " + update;
+ }
+ RegistrationData regData = getRegistrationData();
+ String registerURL = SunConnection.getRegistrationURL(
+ regData.getRegistrationURN()).toString();
+ // Make sure it uses the canonical path before getting the URI.
+ File img = new File(svcTagDir.getCanonicalPath(), "jdk_header.png");
+ String headerImageSrc = img.toURI().toString();
+
+ // Format the registration data in one single line
+ StringBuilder payload = new StringBuilder();
+ String xml = regData.toString().replaceAll("\"", "%22");
+ BufferedReader reader = new BufferedReader(new StringReader(xml));
+ try {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ payload.append(line.trim());
+ }
+ } finally {
+ reader.close();
+ }
+
+ String resourceFilename = "/com/sun/servicetag/resources/register";
+ for (Locale locale : supportedLocales) {
+ String name = REGISTRATION_HTML_NAME;
+ String resource = resourceFilename;
+ if (!locale.equals(Locale.ENGLISH)) {
+ name += "_" + locale.toString();
+ resource += "_" + locale.toString();
+ }
+ File f = new File(parent, name + ".html");
+ InputStream in = null;
+ BufferedReader br = null;
+ PrintWriter pw = null;
+ try {
+ in = Installer.class.getClass().getResourceAsStream(resource + ".html");
+ if (in == null) {
+ // if the resource file is missing
+ if (isVerbose()) {
+ System.out.println("Missing resouce file: " + resource + ".html");
+ }
+ continue;
+ }
+ if (isVerbose()) {
+ System.out.println("Generating " + f + " from " + resource + ".html");
+ }
+
+ br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
+ pw = new PrintWriter(f, "UTF-8");
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ String output = line;
+ if (line.contains(JDK_VERSION_KEY)) {
+ output = line.replace(JDK_VERSION_KEY, jdkVersion);
+ } else if (line.contains(JDK_HEADER_PNG_KEY)) {
+ output = line.replace(JDK_HEADER_PNG_KEY, headerImageSrc);
+ } else if (line.contains(REGISTRATION_URL_KEY)) {
+ output = line.replace(REGISTRATION_URL_KEY, registerURL);
+ } else if (line.contains(REGISTRATION_PAYLOAD_KEY)) {
+ output = line.replace(REGISTRATION_PAYLOAD_KEY, payload.toString());
+ }
+ pw.println(output);
+ }
+ f.setReadOnly();
+ pw.flush();
+ } finally {
+ if (pw != null) {
+ pw.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ if (br!= null) {
+ br.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * A utility class to create a service tag for Java SE.
+ * <p>
+ * <b>Usage:</b><br>
+ * <blockquote><tt>
+ * &lt;JAVA_HOME&gt;/bin/java com.sun.servicetag.Installer
+ * </tt></blockquote>
+ * <p>
+ */
+ public static void main(String[] args) {
+ String source = "Manual";
+
+ // Parse the options (arguments starting with "-" )
+ boolean delete = false;
+ boolean update = false;
+ boolean register = false;
+ int count = 0;
+ while (count < args.length) {
+ String arg = args[count];
+ if (arg.trim().length() == 0) {
+ // skip empty arguments
+ count++;
+ continue;
+ }
+
+ if (arg.equals("-source")) {
+ source = args[++count];
+ } else if (arg.equals("-delete")) {
+ delete = true;
+ } else if (arg.equals("-register")) {
+ register = true;
+ } else {
+ usage();
+ return;
+ }
+ count++;
+ }
+ try {
+ if (delete) {
+ deleteRegistrationData();
+ } else {
+ ServiceTag[] javaSvcTags = getJavaServiceTagArray();
+ String[] archs = getJreArchs();
+ if (javaSvcTags.length > archs.length) {
+ // 64-bit has been uninstalled
+ // so remove the service tag
+ updateRegistrationData(source);
+ } else {
+ // create the service tag
+ createServiceTag(source);
+ }
+ }
+
+ if (register) {
+ // Registration is only supported by JDK
+ // For testing purpose, override with a "servicetag.enable.registration" property
+
+ RegistrationData regData = getRegistrationData();
+ if (supportRegistration && !regData.getServiceTags().isEmpty()) {
+ SunConnection.register(regData);
+ }
+ }
+ System.exit(0);
+ } catch (IOException e) {
+ System.err.println("I/O Error: " + e.getMessage());
+ if (isVerbose()) {
+ e.printStackTrace();
+ }
+ } catch (IllegalArgumentException ex) {
+ if (isVerbose()) {
+ ex.printStackTrace();
+ }
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ if (isVerbose()) {
+ e.printStackTrace();
+ }
+ }
+ System.exit(1);
+ }
+
+ private static void usage() {
+ System.out.println("Usage:");
+ System.out.print(" " + Installer.class.getName());
+ System.out.println(" [-delete|-source <source>|-register]");
+ System.out.println(" to create a service tag for the Java platform");
+ System.out.println("");
+ System.out.println("Internal Options:");
+ System.out.println(" -source: to specify the source of the service tag to be created");
+ System.out.println(" -delete: to delete the service tag ");
+ System.out.println(" -register: to register the JDK");
+ System.out.println(" -help: to print this help message");
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java
new file mode 100644
index 000000000000..6f9cc022d223
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java
@@ -0,0 +1,323 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+package com.sun.star.servicetag;
+
+// The Service Tags team maintains the latest version of the implementation
+// for system environment data collection. JDK will include a copy of
+// the most recent released version for a JDK release. We rename
+// the package to com.sun.servicetag so that the Sun Connection
+// product always uses the latest version from the com.sun.scn.servicetags
+// package. JDK and users of the com.sun.servicetag API
+// (e.g. NetBeans and SunStudio) will use the version in JDK.
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Linux implementation of the SystemEnvironment class.
+ */
+class LinuxSystemEnvironment extends SystemEnvironment {
+ LinuxSystemEnvironment() {
+ setHostId(getLinuxHostId());
+
+ setSystemModel(getLinuxModel());
+ setSystemManufacturer(getLinuxSystemManufacturer());
+ setCpuManufacturer(getLinuxCpuManufacturer());
+ setSerialNumber(getLinuxSN());
+ setPhysMem(getLinuxPhysMem());
+ setSockets(getLinuxSockets());
+ setCores(getLinuxCores());
+ setVirtCpus(getLinuxVirtCpus());
+ setCpuName(getLinuxCpuName());
+ setClockRate(getLinuxClockRate());
+ }
+ private String dmiInfo = null;
+ private String kstatCpuInfo = null;
+
+ private static final int SN = 1;
+ private static final int SYS = 2;
+ private static final int CPU = 3;
+ private static final int MODEL = 4;
+
+ private String getLinuxHostId() {
+ String output = getCommandOutput("/usr/bin/hostid");
+ // trim off the leading 0x
+ if (output.startsWith("0x")) {
+ output = output.substring(2);
+ }
+ return output;
+ }
+
+ /**
+ * Tries to obtain and return the cpu manufacturer.
+ * @return The cpu manufacturer (an empty string if not found or an error occurred)
+ */
+ private String getLinuxCpuManufacturer() {
+ String tmp = getLinuxPSNInfo(CPU);
+ if (tmp.length() > 0) {
+ return tmp;
+ }
+
+ String contents = getFileContent("/proc/cpuinfo");
+ for (String line : contents.split("\n")) {
+ if (line.contains("vendor_id")) {
+ String[] ss = line.split(":", 2);
+ if (ss.length > 1) {
+ return ss[1].trim();
+ }
+ }
+ }
+
+ // returns an empty string if it can't be found or an error happened
+ return getLinuxDMIInfo("dmi type 4", "manufacturer");
+ }
+
+ private String getLinuxModel() {
+ String tmp = getLinuxPSNInfo(MODEL);
+ if (tmp.length() > 0) {
+ return tmp + "::" + getCommandOutput("/bin/uname","-v");
+ }
+
+ tmp = getLinuxDMIInfo("dmi type 1", "product name");
+ if (tmp.length() > 0) {
+ return tmp + "::" + getCommandOutput("/bin/uname","-v");
+ }
+
+ return getCommandOutput("/bin/uname","-i")
+ + "::" + getCommandOutput("/bin/uname","-v");
+ }
+
+
+ /**
+ * Tries to obtain and return the system manufacturer.
+ * @return The system manufacturer (an empty string if not found or an error occurred)
+ */
+ private String getLinuxSystemManufacturer() {
+ String tmp = getLinuxPSNInfo(SYS);
+ if (tmp.length() > 0) {
+ return tmp;
+ }
+
+ // returns an empty string if it can't be found or an error happened
+ return getLinuxDMIInfo("dmi type 1", "manufacturer");
+ }
+
+ /**
+ * Tries to obtain and return the serial number of the system.
+ * @return The serial number (an empty string if not found or an error occurred)
+ */
+ private String getLinuxSN() {
+ String tmp = getLinuxPSNInfo(SN);
+ if (tmp.length() > 0) {
+ return tmp;
+ }
+
+ // returns an empty string if it can't be found or an error happened
+ return getLinuxDMIInfo("dmi type 1", "serial number");
+ }
+
+ private String getLinuxPSNInfo(int target) {
+ // try to read from the psn file if it exists
+ String contents = getFileContent("/var/run/psn");
+ String[] ss = contents.split("\n");
+ if (target <= ss.length) {
+ return ss[target-1];
+ }
+
+ // default case is to return ""
+ return "";
+ }
+
+ // reads from dmidecode with the given type and target
+ // returns an empty string if nothing was found or an error occurred
+ //
+ // Sample output segment:
+ // Handle 0x0001
+ // DMI type 1, 25 bytes.
+ // System Information
+ // Manufacturer: System manufacturer
+ // Product Name: System Product Name
+ // Version: System Version
+ // Serial Number: System Serial Number
+ // UUID: 3091D719-B25B-D911-959D-6D1B12C7686E
+ // Wake-up Type: Power Switch
+
+ private synchronized String getLinuxDMIInfo(String dmiType, String target) {
+ // only try to get dmidecode information once, after that, we can
+ // reuse the output
+ if (dmiInfo == null) {
+ Thread dmidecodeThread = new Thread() {
+ public void run() {
+ dmiInfo = getCommandOutput("/usr/sbin/dmidecode");
+ }
+ };
+ dmidecodeThread.start();
+
+ try {
+ dmidecodeThread.join(3000);
+ if (dmidecodeThread.isAlive()) {
+ dmidecodeThread.interrupt();
+ dmiInfo = "";
+ }
+ } catch (InterruptedException ie) {
+ dmidecodeThread.interrupt();
+ }
+ }
+
+ if (dmiInfo.length() == 0) {
+ return "";
+ }
+ boolean dmiFlag = false;
+ for (String s : dmiInfo.split("\n")) {
+ String line = s.toLowerCase();
+ if (dmiFlag) {
+ if (line.contains(target)) {
+ String key = target + ":";
+ int indx = line.indexOf(key) + key.length();
+ if (line.contains(key) && indx < line.length()) {
+ return line.substring(indx).trim();
+ }
+ String[] ss = line.split(":");
+ return ss[ss.length-1];
+ }
+ } else if (line.contains(dmiType)) {
+ dmiFlag = true;
+ }
+ }
+ return "";
+ }
+
+ private String getLinuxClockRate() {
+ String contents = getFileContent("/proc/cpuinfo");
+ String token = "cpu MHz";
+ for (String line : contents.split("\n")) {
+ if (line.contains(token)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ return key[1].trim();
+ }
+ }
+ }
+ return "";
+ }
+
+ private String getLinuxCpuName() {
+ String contents = getFileContent("/proc/cpuinfo");
+ String token = "model name";
+ for (String line : contents.split("\n")) {
+ if (line.contains(token)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ return key[1].trim();
+ }
+ }
+ }
+ return "";
+ }
+
+ private String getLinuxVirtCpus() {
+ Set<String> set = new HashSet<String>();
+ String contents = getFileContent("/proc/cpuinfo");
+ String token = "processor";
+ for (String line : contents.split("\n")) {
+ if (line.contains(token)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ set.add(key[1].trim());
+ }
+ }
+ }
+ return "" + set.size();
+ }
+
+ private String getLinuxCores() {
+ Set<String> set = new HashSet<String>();
+ String contents = getFileContent("/proc/cpuinfo");
+ String token = "core id";
+ for (String line : contents.split("\n")) {
+ if (line.contains(token)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ set.add(key[1].trim());
+ }
+ }
+ }
+ if (set.size() == 0) {
+ return "1";
+ }
+ return "" + set.size();
+ }
+
+ private String getLinuxPhysMem() {
+ String contents = getFileContent("/proc/meminfo");
+ for (String line : contents.split("\n")) {
+ if (line.contains("MemTotal")) {
+ String[] total = line.split(":", 2);
+ if (total.length > 1) {
+ String[] mem = total[1].trim().split(" ");
+ if (mem.length >= 1) {
+ return mem[0].trim();
+ } else {
+ return total[1].trim();
+ }
+ }
+ }
+ }
+
+ return "";
+ }
+
+ private String getLinuxSockets() {
+ Set<String> physIdSet = new HashSet<String>();
+ Set<String> procSet = new HashSet<String>();
+ String contents = getFileContent("/proc/cpuinfo");
+ String physIdToken = "physical id";
+ String procToken = "processor";
+
+ for (String line : contents.split("\n")) {
+ if (line.contains(physIdToken)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ physIdSet.add(key[1].trim());
+ }
+ }
+
+ if (line.contains(procToken)) {
+ String[] key = line.split(":", 2);
+ if (key.length > 1) {
+ procSet.add(key[1].trim());
+ }
+ }
+ }
+ if (physIdSet.size() != 0) {
+ return "" + physIdSet.size();
+ }
+ return "" + procSet.size();
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java b/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java
new file mode 100644
index 000000000000..66eb1933210a
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java
@@ -0,0 +1,531 @@
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static com.sun.star.servicetag.RegistrationDocument.*;
+
+/**
+ * A {@code RegistrationData} object is a container of one or more
+ * {@link #getServiceTags service tags} that identify the
+ * components for product registration.
+ * Each {@code RegistrationData} object has a {@link #getRegistrationURN
+ * uniform resource name} (URN) as its identifier.
+ * <a name="EnvMap"></a>
+ * It also has an <i>environment map</i> with
+ * the following elements:
+ * <blockquote>
+ * <table border=0>
+ * <tr>
+ * <td><tt>hostname</tt></td>
+ * <td>Hostname of the system</td>
+ * <td>e.g. woody</td>
+ * </tr>
+ * <tr>
+ * <td><tt>hostId</tt></td>
+ * <td>Host ID of the system</td>
+ * <td>e.g. 83abc1ab</td>
+ * </tr>
+ * <tr>
+ * <td><tt>osName</tt></td>
+ * <td>Operating system name</td>
+ * <td> e.g. SunOS</td>
+ * </tr>
+ * <tr>
+ * <td><tt>osVersion</tt></td>
+ * <td>Operating system version</td>
+ * <td> e.g. 5.10</td>
+ * </tr>
+ * <tr>
+ * <td><tt>osArchitecture</tt></td>
+ * <td>Operating system architecture</td>
+ * <td> e.g. sparc</td>
+ * </tr>
+ * <tr>
+ * <td><tt>systemModel</tt></td>
+ * <td>System model</td>
+ * <td> e.g. SUNW,Sun-Fire-V440</td>
+ * </tr>
+ * <tr>
+ * <td><tt>systemManufacturer</tt></td>
+ * <td>System manufacturer</td>
+ * <td> e.g. Sun Microsystems</td>
+ * </tr>
+ * <tr>
+ * <td><tt>cpuManufacturer</tt></td>
+ * <td>CPU manufacturer</td>
+ * <td> e.g. Sun Microsystems</td>
+ * </tr>
+ * <tr>
+ * <td><tt>serialNumber</tt></td>
+ * <td>System serial number</td>
+ * <td> e.g. BEL078932</td>
+ * </tr>
+ * <tr>
+ * <td><tt>physmem</tt></td>
+ * <td>Physical memory for the system (in MB)</td>
+ * <td> e.g. 4096</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * The <tt>hostname</tt> and <tt>osName</tt> element must have a non-empty value.
+ * If an element is not available on a system and their value will be
+ * empty.
+ * <p>
+ * <a name="XMLSchema">
+ * <b>Registration XML Schema</b></a>
+ * <p>
+ * A {@code RegistrationData} object can be {@link #loadFromXML loaded} from
+ * and {@link #storeToXML stored} into an XML file in the format described
+ * by the
+ * <a href="https://sn-tools.central.sun.com/twiki/pub/ServiceTags/RegistrationRelayService/product_registration.xsd">
+ * registration data schema</a>. The registration data schema is defined by the
+ * Service Tags Technology.
+ * <p>
+ * Typically the registration data is constructed at installation time
+ * and stored in an XML file for later service tag lookup or registration.
+ *
+ * <p>
+ * <b>Example Usage</b>
+ * <p>
+ * The examples below show how the {@code RegistrationData} can be
+ * used for product registration.
+ * Exception handling is not shown in these examples for clarity.
+ * <ol>
+ * <li>This example shows how the JDK creates a JDK service tag, installs it
+ * in the system service tag registry and adds it to the registration data.
+ * <br>
+ * <blockquote><pre>
+ * // create a service tag object with an instance_urn
+ * ServiceTag st = ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
+ * ....);
+ * // Adds to the system service tag registry if supported
+ * if (Registry.isSupported()) {
+ * Registry.getSystemRegistry().addServiceTag(st);
+ * }
+ *
+ * // add to the registration data
+ * RegistrationData registration = new RegistrationData();
+ * registration.addServiceTag(st);
+ * </pre></blockquote>
+ * </li>
+ * <li>At this point, the registration data is ready to
+ * send to Sun Connection for registration. This example shows how to register
+ * the JDK via the <i>Registration Relay Service</i>.
+ * <p>
+ * There are several registration services for Sun Connection. For example,
+ * the <a href="https://sn-tools.central.sun.com/twiki/bin/view/ServiceTags/RegistrationRelayService">
+ * Registration Relay Service</a> is a web application interface that
+ * processes the registration data payload sent via HTTP post
+ * and hosts the registration user interface for a specified
+ * registration URL. Refer to the
+ * Registration Relay Service Specification for details.
+ * <p>
+ * <blockquote><pre>
+ * // Open the connection to the URL of the registration service
+ * HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ * con.setDoInput(true);
+ * con.setDoOutput(true);
+ * con.setUseCaches(false);
+ * con.setAllowUserInteraction(false);
+ * con.setRequestMethod("POST");
+ * con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\"");
+ * con.connect();
+ *
+ * // send the registration data to the registration service
+ * OutputStream out = con.getOutputStream();
+ * registration.storeToXML(out);
+ * out.close();
+ * </pre></blockquote>
+ * </li>
+ * <li>This example shows how to store the registration data in an XML file.
+ * for later service tag lookup or registration.
+ * <br>
+ * <blockquote><pre>
+ * BufferedOutputStream out = new BufferedOutputStream(
+ * new FileOutputStream(""&lt;JAVA_HOME&gt;/lib/servicetag/registration.xml"));
+ * registration.storeToXML(out);
+ * out.close();
+ * </pre></blockquote>
+ * </li>
+ * <li>This example shows how to install service tags that are in the
+ * registration data in the system service tag registry when determined
+ * to be available. The system service tag registry might not have existed
+ * when the registration data was constructed.
+ * <br>
+ * <blockquote><pre>
+ * if (Registry.isSupported()) {
+ * Set&lt;ServiceTag&gt; svctags = registration.getServiceTags();
+ * for (ServiceTag st : svctags) {
+ * Registry.getSystemRegistry().addServiceTag(st);
+ * }
+ * }
+ * </pre></blockquote>
+ * </li>
+ * </ol>
+ *
+ * @see <a href="https://sunconnection.sun.com/inventory">Sun Connection Inventory Channel</a>
+ */
+public class RegistrationData {
+ private final Map<String, String> environment;
+ private final Map<String, String> cpuInfo;
+ private final Map<String, ServiceTag> svcTagMap;
+ private final String urn;
+
+ /**
+ * Creates a {@code RegistrationData} object with a generated
+ * {@link #getRegistrationURN registration URN}.
+ * The following keys in the {@link #getEnvironmentMap environment map}
+ * will be initialized for the configuration of the
+ * running system:
+ * <blockquote>
+ * <tt>hostname</tt>, <tt>osName</tt>, <tt>osVersion</tt> and
+ * <tt>osArchitecture</tt>
+ * </blockquote>
+ * and the value of other keys may be empty.
+ */
+ public RegistrationData() {
+ this(Util.generateURN());
+ }
+
+ // package private
+ RegistrationData(String urn) {
+ this.urn = urn;
+ SystemEnvironment sysEnv = SystemEnvironment.getSystemEnvironment();
+ this.environment = initEnvironment(sysEnv);
+ this.cpuInfo = initCpuInfo(sysEnv);
+ this.svcTagMap = new LinkedHashMap<String, ServiceTag>();
+ }
+
+ private Map<String, String> initEnvironment(SystemEnvironment sysEnv) {
+ Map<String, String> map = new LinkedHashMap<String, String>();
+ map.put(ST_NODE_HOSTNAME, sysEnv.getHostname());
+ map.put(ST_NODE_HOST_ID, sysEnv.getHostId());
+ map.put(ST_NODE_OS_NAME, sysEnv.getOsName());
+ map.put(ST_NODE_OS_VERSION, sysEnv.getOsVersion());
+ map.put(ST_NODE_OS_ARCH, sysEnv.getOsArchitecture());
+ map.put(ST_NODE_SYSTEM_MODEL, sysEnv.getSystemModel());
+ map.put(ST_NODE_SYSTEM_MANUFACTURER, sysEnv.getSystemManufacturer());
+ map.put(ST_NODE_CPU_MANUFACTURER, sysEnv.getCpuManufacturer());
+ map.put(ST_NODE_SERIAL_NUMBER, sysEnv.getSerialNumber());
+ map.put(ST_NODE_PHYS_MEM, sysEnv.getPhysMem());
+ return map;
+ }
+
+ private Map<String, String> initCpuInfo(SystemEnvironment sysEnv) {
+ Map<String, String> map = new LinkedHashMap<String, String>();
+ map.put(ST_NODE_SOCKETS, sysEnv.getSockets());
+ map.put(ST_NODE_CORES, sysEnv.getCores());
+ map.put(ST_NODE_VIRT_CPUS, sysEnv.getVirtCpus());
+ map.put(ST_NODE_CPU_NAME, sysEnv.getCpuName());
+ map.put(ST_NODE_CLOCK_RATE, sysEnv.getClockRate());
+ return map;
+ }
+
+ /**
+ * Returns the uniform resource name of this registration data
+ * in this format:
+ * <tt>urn:st:&lt;32-char {@link java.util.UUID uuid}&gt;</tt>
+ *
+ * @return the URN of this registration data.
+ */
+ public String getRegistrationURN() {
+ return urn;
+ }
+
+ /**
+ * Returns a map containing the environment information for this
+ * registration data. See the set of <a href="#EnvMap">keys</a>
+ * in the environment map. Subsequent update to the environment
+ * map via the {@link #setEnvironment setEnvironment} method will not be reflected
+ * in the returned map.
+ *
+ * @return an environment map for this registration data.
+ */
+ public Map<String, String> getEnvironmentMap() {
+ return new LinkedHashMap<String,String>(environment);
+ }
+
+ /**
+ * Returns a map containing the cpu information for this
+ * registration data. Subsequent update to the cpu info
+ * map via the {@link #setCpuInfo setCpuInfo} method will not be reflected
+ * in the returned map.
+ *
+ * @return a cpu info map for this registration data.
+ */
+ public Map<String, String> getCpuInfoMap() {
+ return new LinkedHashMap<String,String>(cpuInfo);
+ }
+
+ /**
+ * Sets an element of the specified {@code name} in the environment map
+ * with the given {@code value}.
+ *
+ * @throws IllegalArgumentException if {@code name} is not a valid key
+ * in the environment map, or {@code value} is not valid.
+ */
+ public void setEnvironment(String name, String value) {
+ if (name == null) {
+ throw new NullPointerException("name is null");
+ }
+ if (value == null) {
+ throw new NullPointerException("value is null");
+ }
+ if (environment.containsKey(name)) {
+ if (name.equals(ST_NODE_HOSTNAME) || name.equals(ST_NODE_OS_NAME)) {
+ if (value.length() == 0) {
+ throw new IllegalArgumentException("\"" +
+ name + "\" requires non-empty value.");
+ }
+ }
+ environment.put(name, value);
+ } else {
+ throw new IllegalArgumentException("\"" +
+ name + "\" is not an environment element.");
+ }
+ }
+
+ /**
+ * Sets an element of the specified {@code name} in the cpu info map
+ * with the given {@code value}.
+ *
+ * @throws IllegalArgumentException if {@code name} is not a valid key
+ * in the cpu info map, or {@code value} is not valid.
+ */
+ public void setCpuInfo(String name, String value) {
+ if (name == null) {
+ throw new NullPointerException("name is null");
+ }
+ if (value == null) {
+ throw new NullPointerException("value is null");
+ }
+ if (cpuInfo.containsKey(name)) {
+ cpuInfo.put(name, value);
+ } else {
+ throw new IllegalArgumentException("\"" +
+ name + "\" is not an cpuinfo element.");
+ }
+ }
+
+ /**
+ * Returns all service tags in this registration data.
+ *
+ * @return a {@link Set Set} of the service tags
+ * in this registration data.
+ */
+ public Set<ServiceTag> getServiceTags() {
+ return new HashSet<ServiceTag>(svcTagMap.values());
+ }
+
+ /**
+ * Adds a service tag to this registration data.
+ * If the given service tag has an empty <tt>instance_urn</tt>,
+ * this method will generate a URN and place it in the copy
+ * of the service tag in this registration data.
+ * This method will return the {@code ServiceTag} object
+ * added to this registration data.
+ *
+ * @param st {@code ServiceTag} object to be added.
+ * @return a {@code ServiceTag} object added to this registration data.
+ *
+ * @throws IllegalArgumentException if
+ * a service tag of the same {@link ServiceTag#getInstanceURN
+ * <tt>instance_urn</tt>} already exists in the registry.
+ */
+ public synchronized ServiceTag addServiceTag(ServiceTag st) {
+ ServiceTag svcTag = ServiceTag.newInstanceWithUrnTimestamp(st);
+
+ String instanceURN = svcTag.getInstanceURN();
+ if (svcTagMap.containsKey(instanceURN)) {
+ throw new IllegalArgumentException("Instance_urn = " + instanceURN +
+ " already exists in the registration data.");
+ } else {
+ svcTagMap.put(instanceURN, svcTag);
+ }
+ return svcTag;
+ }
+
+ /**
+ * Returns a service tag of the given <tt>instance_urn</tt> in this registration
+ * data.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * @return the {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * if exists; otherwise return {@code null}.
+ */
+ public synchronized ServiceTag getServiceTag(String instanceURN) {
+ if (instanceURN == null) {
+ throw new NullPointerException("instanceURN is null");
+ }
+ return svcTagMap.get(instanceURN);
+ }
+
+ /**
+ * Removes a service tag of the given <tt>instance_urn</tt> from this
+ * registration data.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of
+ * the service tag to be removed.
+ *
+ * @return the removed {@code ServiceTag} object;
+ * or {@code null} if the service tag does not exist in this
+ * registration data.
+ */
+ public synchronized ServiceTag removeServiceTag(String instanceURN) {
+ if (instanceURN == null) {
+ throw new NullPointerException("instanceURN is null");
+ }
+
+ ServiceTag svcTag = null;
+ if (svcTagMap.containsKey(instanceURN)) {
+ svcTag = svcTagMap.remove(instanceURN);
+ }
+ return svcTag;
+ }
+
+ /**
+ * Updates the <tt>product_defined_instance_id</tt> in the service tag
+ * of the given <tt>instance_urn</tt> in this registration data.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag to be updated.
+ * @param productDefinedInstanceID the value of the
+ * <tt>product_defined_instance_id</tt> to be set.
+ *
+ * @return the updated {@code ServiceTag} object;
+ * or {@code null} if the service tag does not exist in this
+ * registration data.
+ */
+ public synchronized ServiceTag updateServiceTag(String instanceURN,
+ String productDefinedInstanceID) {
+ ServiceTag svcTag = getServiceTag(instanceURN);
+ if (svcTag == null) {
+ return null;
+ }
+
+ svcTag = ServiceTag.newInstanceWithUrnTimestamp(svcTag);
+ // update the product defined instance ID field
+ svcTag.setProductDefinedInstanceID(productDefinedInstanceID);
+ svcTagMap.put(instanceURN, svcTag);
+ return svcTag;
+ }
+
+ /**
+ * Reads the registration data from the XML document on the
+ * specified input stream. The XML document must be
+ * in the format described by the <a href="#XMLSchema">
+ * registration data schema</a>.
+ * The specified stream is closed after this method returns.
+ *
+ * @param in the input stream from which to read the XML document.
+ * @return a {@code RegistrationData} object read from the input
+ * stream.
+ *
+ * @throws IllegalArgumentException if the input stream
+ * contains an invalid registration data.
+ *
+ * @throws IOException if an error occurred when reading from the input stream.
+ */
+ public static RegistrationData loadFromXML(InputStream in) throws IOException {
+ try {
+ return RegistrationDocument.load(in);
+ } finally {
+ in.close();
+ }
+ }
+
+ /**
+ * Writes the registration data to the specified output stream
+ * in the format described by the <a href="#XMLSchema">
+ * registration data schema</a> with "UTF-8" encoding.
+ * The specified stream remains open after this method returns.
+ *
+ * @param os the output stream on which to write the XML document.
+ *
+ * @throws IOException if an error occurred when writing to the output stream.
+ */
+ public void storeToXML(OutputStream os) throws IOException {
+ RegistrationDocument.store(os, this);
+ os.flush();
+ }
+
+ /**
+ * Returns a newly allocated byte array containing the registration
+ * data in XML format.
+ *
+ * @return a newly allocated byte array containing the registration
+ * data in XML format.
+ */
+ public byte[] toXML() {
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ storeToXML(out);
+ return out.toByteArray();
+ } catch (IOException e) {
+ // should not reach here
+ return new byte[0];
+ }
+ }
+
+ /**
+ * Returns a string representation of this registration data in XML
+ * format.
+ *
+ * @return a string representation of this registration data in XML
+ * format.
+ */
+ @Override
+ public String toString() {
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ storeToXML(out);
+ return out.toString("UTF-8");
+ } catch (IOException e) {
+ // should not reach here
+ return "Error creating the return string.";
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java b/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java
new file mode 100644
index 000000000000..fb13b581c0ce
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java
@@ -0,0 +1,440 @@
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+// For write operation
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+/**
+ * XML Support Class for Product Registration.
+ */
+class RegistrationDocument {
+
+ private static final String REGISTRATION_DATA_SCHEMA =
+ "/com/sun/star/servicetag/resources/product_registration.xsd";
+ private static final String REGISTRATION_DATA_VERSION = "1.0";
+ private static final String SERVICE_TAG_VERSION = "1.0";
+ final static String ST_NODE_REGISTRATION_DATA = "registration_data";
+ final static String ST_ATTR_REGISTRATION_VERSION = "version";
+ final static String ST_NODE_ENVIRONMENT = "environment";
+ final static String ST_NODE_HOSTNAME = "hostname";
+ final static String ST_NODE_HOST_ID = "hostId";
+ final static String ST_NODE_OS_NAME = "osName";
+ final static String ST_NODE_OS_VERSION = "osVersion";
+ final static String ST_NODE_OS_ARCH = "osArchitecture";
+ final static String ST_NODE_SYSTEM_MODEL = "systemModel";
+ final static String ST_NODE_SYSTEM_MANUFACTURER = "systemManufacturer";
+ final static String ST_NODE_CPU_MANUFACTURER = "cpuManufacturer";
+ final static String ST_NODE_SERIAL_NUMBER = "serialNumber";
+ final static String ST_NODE_PHYS_MEM = "physmem";
+ final static String ST_NODE_CPU_INFO = "cpuinfo";
+ final static String ST_NODE_SOCKETS = "sockets";
+ final static String ST_NODE_CORES = "cores";
+ final static String ST_NODE_VIRT_CPUS = "virtcpus";
+ final static String ST_NODE_CPU_NAME = "name";
+ final static String ST_NODE_CLOCK_RATE = "clockrate";
+ final static String ST_NODE_REGISTRY = "registry";
+ final static String ST_ATTR_REGISTRY_URN = "urn";
+ final static String ST_ATTR_REGISTRY_VERSION = "version";
+ final static String ST_NODE_SERVICE_TAG = "service_tag";
+ final static String ST_NODE_INSTANCE_URN = "instance_urn";
+ final static String ST_NODE_PRODUCT_NAME = "product_name";
+ final static String ST_NODE_PRODUCT_VERSION = "product_version";
+ final static String ST_NODE_PRODUCT_URN = "product_urn";
+ final static String ST_NODE_PRODUCT_PARENT_URN = "product_parent_urn";
+ final static String ST_NODE_PRODUCT_PARENT = "product_parent";
+ final static String ST_NODE_PRODUCT_DEFINED_INST_ID = "product_defined_inst_id";
+ final static String ST_NODE_PRODUCT_VENDOR = "product_vendor";
+ final static String ST_NODE_PLATFORM_ARCH = "platform_arch";
+ final static String ST_NODE_TIMESTAMP = "timestamp";
+ final static String ST_NODE_CONTAINER = "container";
+ final static String ST_NODE_SOURCE = "source";
+ final static String ST_NODE_INSTALLER_UID = "installer_uid";
+
+ static RegistrationData load(InputStream in) throws IOException {
+ Document document = initializeDocument(in);
+
+ // Gets the registration URN
+ Element root = getRegistrationDataRoot(document);
+ Element registryRoot =
+ getSingletonElementFromRoot(root, ST_NODE_REGISTRY);
+ String urn = registryRoot.getAttribute(ST_ATTR_REGISTRY_URN);
+
+ // Construct a new RegistrationData object from the DOM tree
+ // Initialize the environment map and service tags
+ RegistrationData regData = new RegistrationData(urn);
+ addServiceTags(registryRoot, regData);
+
+ Element envRoot = getSingletonElementFromRoot(root, ST_NODE_ENVIRONMENT);
+ buildEnvironmentMap(envRoot, regData);
+
+ Element cpuInfo = getSingletonElementFromRoot(envRoot, ST_NODE_CPU_INFO);
+ buildCpuInfoMap(cpuInfo, regData);
+ return regData;
+ }
+
+ static void store(OutputStream os, RegistrationData registration)
+ throws IOException {
+ // create a new document with the root node
+ Document document = initializeDocument();
+
+ // create the nodes for the environment map and the service tags
+ // in the registration data
+ addEnvironmentNodes(document,
+ registration.getEnvironmentMap(),
+ registration.getCpuInfoMap());
+ addServiceTagRegistry(document,
+ registration.getRegistrationURN(),
+ registration.getServiceTags());
+ transform(document, os);
+ }
+
+ // initialize a document from an input stream
+ private static Document initializeDocument(InputStream in) throws IOException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ SchemaFactory sf = null;
+ try {
+ // Some Java versions (e.g., 1.5.0_06-b05) fail with a
+ // NullPointerException if SchemaFactory.newInstance is called with
+ // a null context class loader, so work around that here (and the
+ // class loader of this class hopefully is not the null bootstrap
+ // class loader):
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (cl == null) {
+ Thread.currentThread().setContextClassLoader(
+ RegistrationDocument.class.getClassLoader());
+ }
+ try {
+ sf = SchemaFactory.newInstance(
+ XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ } finally {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+
+ Schema schema = null;
+ try {
+ // Even using the workaround above is not enough on some
+ // Java versions. Therefore try to workaround the validation
+ // completely!
+ URL xsdUrl = RegistrationDocument.class.getResource(REGISTRATION_DATA_SCHEMA);
+ schema = sf.newSchema(xsdUrl);
+ }
+ catch (NullPointerException nex) {
+ }
+
+ Validator validator = null;
+ if (schema != null)
+ validator = schema.newValidator();
+
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document doc = builder.parse(new InputSource(in));
+
+ if (validator != null)
+ validator.validate(new DOMSource(doc));
+
+ return doc;
+ } catch (SAXException sxe) {
+ IllegalArgumentException e = new IllegalArgumentException("Error generated in parsing");
+ e.initCause(sxe);
+ throw e;
+ } catch (ParserConfigurationException pce) {
+ // Parser with specific options can't be built
+ // should not reach here
+ InternalError x = new InternalError("Error in creating the new document");
+ x.initCause(pce);
+ throw x;
+ }
+ }
+
+ // initialize a new document for the registration data
+ private static Document initializeDocument() throws IOException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document doc = builder.newDocument();
+
+ // initialize the document with the registration_data root
+ Element root = doc.createElement(ST_NODE_REGISTRATION_DATA);
+ doc.appendChild(root);
+ root.setAttribute(ST_ATTR_REGISTRATION_VERSION, REGISTRATION_DATA_VERSION);
+
+ return doc;
+ } catch (ParserConfigurationException pce) {
+ // Parser with specified options can't be built
+ // should not reach here
+ InternalError x = new InternalError("Error in creating the new document");
+ x.initCause(pce);
+ throw x;
+ }
+ }
+
+ // Transform the current DOM tree with the given output stream.
+ private static void transform(Document document, OutputStream os) {
+ try {
+ // Use a Transformer for output
+ TransformerFactory tFactory = TransformerFactory.newInstance();
+ tFactory.setAttribute("indent-number", new Integer(3));
+
+ Transformer transformer = tFactory.newTransformer();
+
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+ transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
+ transformer.transform(new DOMSource(document),
+ new StreamResult(new BufferedWriter(new OutputStreamWriter(os, "UTF-8"))));
+ } catch (UnsupportedEncodingException ue) {
+ // Should not reach here
+ InternalError x = new InternalError("Error generated during transformation");
+ x.initCause(ue);
+ throw x;
+ } catch (TransformerConfigurationException tce) {
+ // Error generated by the parser
+ // Should not reach here
+ InternalError x = new InternalError("Error in creating the new document");
+ x.initCause(tce);
+ throw x;
+ } catch (TransformerException te) {
+ // Error generated by the transformer
+ InternalError x = new InternalError("Error generated during transformation");
+ x.initCause(te);
+ throw x;
+ }
+ }
+
+ private static void addServiceTagRegistry(Document document,
+ String registryURN,
+ Set<ServiceTag> svcTags) {
+ // add service tag registry node and its attributes
+ Element reg = document.createElement(ST_NODE_REGISTRY);
+ reg.setAttribute(ST_ATTR_REGISTRY_URN, registryURN);
+ reg.setAttribute(ST_ATTR_REGISTRY_VERSION, SERVICE_TAG_VERSION);
+
+ Element root = getRegistrationDataRoot(document);
+ root.appendChild(reg);
+
+ // adds the elements for the service tags
+ for (ServiceTag st : svcTags) {
+ addServiceTagElement(document, reg, st);
+ }
+ }
+
+ private static void addServiceTagElement(Document document,
+ Element registryRoot,
+ ServiceTag st) {
+ Element svcTag = document.createElement(ST_NODE_SERVICE_TAG);
+ registryRoot.appendChild(svcTag);
+ addChildElement(document, svcTag,
+ ST_NODE_INSTANCE_URN, st.getInstanceURN());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_NAME, st.getProductName());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_VERSION, st.getProductVersion());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_URN, st.getProductURN());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_PARENT_URN, st.getProductParentURN());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_PARENT, st.getProductParent());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_DEFINED_INST_ID,
+ st.getProductDefinedInstanceID());
+ addChildElement(document, svcTag,
+ ST_NODE_PRODUCT_VENDOR, st.getProductVendor());
+ addChildElement(document, svcTag,
+ ST_NODE_PLATFORM_ARCH, st.getPlatformArch());
+ addChildElement(document, svcTag,
+ ST_NODE_TIMESTAMP, Util.formatTimestamp(st.getTimestamp()));
+ addChildElement(document, svcTag,
+ ST_NODE_CONTAINER, st.getContainer());
+ addChildElement(document, svcTag,
+ ST_NODE_SOURCE, st.getSource());
+ addChildElement(document, svcTag,
+ ST_NODE_INSTALLER_UID,
+ String.valueOf(st.getInstallerUID()));
+ }
+
+ private static void addChildElement(Document document, Element root,
+ String element, String text) {
+ Element node = document.createElement(element);
+ node.appendChild(document.createTextNode(text));
+ root.appendChild(node);
+ }
+
+ // Constructs service tags from the document
+ private static void addServiceTags(Element registryRoot,
+ RegistrationData registration) {
+ NodeList children = registryRoot.getElementsByTagName(ST_NODE_SERVICE_TAG);
+ int length = (children == null ? 0 : children.getLength());
+ for (int i = 0; i < length; i++) {
+ Element svcTagElement = (Element) children.item(i);
+ ServiceTag st = getServiceTag(svcTagElement);
+ registration.addServiceTag(st);
+ }
+ }
+
+ // build environment map from the document
+ private static void buildEnvironmentMap(Element envRoot,
+ RegistrationData registration) {
+ registration.setEnvironment(ST_NODE_HOSTNAME, getTextValue(envRoot, ST_NODE_HOSTNAME));
+ registration.setEnvironment(ST_NODE_HOST_ID, getTextValue(envRoot, ST_NODE_HOST_ID));
+ registration.setEnvironment(ST_NODE_OS_NAME, getTextValue(envRoot, ST_NODE_OS_NAME));
+ registration.setEnvironment(ST_NODE_OS_VERSION, getTextValue(envRoot, ST_NODE_OS_VERSION));
+ registration.setEnvironment(ST_NODE_OS_ARCH, getTextValue(envRoot, ST_NODE_OS_ARCH));
+ registration.setEnvironment(ST_NODE_SYSTEM_MODEL, getTextValue(envRoot, ST_NODE_SYSTEM_MODEL));
+ registration.setEnvironment(ST_NODE_SYSTEM_MANUFACTURER, getTextValue(envRoot, ST_NODE_SYSTEM_MANUFACTURER));
+ registration.setEnvironment(ST_NODE_CPU_MANUFACTURER, getTextValue(envRoot, ST_NODE_CPU_MANUFACTURER));
+ registration.setEnvironment(ST_NODE_SERIAL_NUMBER, getTextValue(envRoot, ST_NODE_SERIAL_NUMBER));
+ registration.setEnvironment(ST_NODE_PHYS_MEM, getTextValue(envRoot, ST_NODE_PHYS_MEM));
+ }
+
+ private static void buildCpuInfoMap(Element cpuInfoRoot,
+ RegistrationData registration) {
+ registration.setCpuInfo(ST_NODE_SOCKETS, getTextValue(cpuInfoRoot, ST_NODE_SOCKETS));
+ registration.setCpuInfo(ST_NODE_CORES, getTextValue(cpuInfoRoot, ST_NODE_CORES));
+ registration.setCpuInfo(ST_NODE_VIRT_CPUS, getTextValue(cpuInfoRoot, ST_NODE_VIRT_CPUS));
+ registration.setCpuInfo(ST_NODE_CPU_NAME, getTextValue(cpuInfoRoot, ST_NODE_CPU_NAME));
+ registration.setCpuInfo(ST_NODE_CLOCK_RATE, getTextValue(cpuInfoRoot, ST_NODE_CLOCK_RATE));
+ }
+
+ // add the nodes representing the environment map in the document
+ private static void addEnvironmentNodes(Document document,
+ Map<String, String> envMap,
+ Map<String, String> cpuInfoMap) {
+ Element root = getRegistrationDataRoot(document);
+
+ Element env = document.createElement(ST_NODE_ENVIRONMENT);
+ root.appendChild(env);
+ Set<Map.Entry<String, String>> keys = envMap.entrySet();
+ for (Map.Entry<String, String> entry : keys) {
+ addChildElement(document, env, entry.getKey(), entry.getValue());
+ }
+
+ Element cpuInfo = document.createElement(ST_NODE_CPU_INFO);
+ env.appendChild(cpuInfo);
+ keys = cpuInfoMap.entrySet();
+ for (Map.Entry<String, String> entry : keys) {
+ addChildElement(document, cpuInfo, entry.getKey(), entry.getValue());
+ }
+ }
+
+ private static Element getRegistrationDataRoot(Document doc) {
+ Element root = doc.getDocumentElement();
+ if (!root.getNodeName().equals(ST_NODE_REGISTRATION_DATA)) {
+ throw new IllegalArgumentException("Not a " +
+ ST_NODE_REGISTRATION_DATA +
+ " node \"" + root.getNodeName() + "\"");
+ }
+ return root;
+ }
+
+ private static Element getSingletonElementFromRoot(Element root, String name) {
+ NodeList children = root.getElementsByTagName(name);
+ int length = (children == null ? 0 : children.getLength());
+ if (length != 1) {
+ throw new IllegalArgumentException("Invalid number of " + name +
+ " nodes = " + length);
+ }
+ Element e = (Element) children.item(0);
+ if (!e.getNodeName().equals(name)) {
+ throw new IllegalArgumentException("Not a " + name +
+ " node \"" + e.getNodeName() + "\"");
+ }
+ return e;
+ }
+
+ // Constructs one ServiceTag instance from a service tag element root
+ private static ServiceTag getServiceTag(Element svcTagElement) {
+ return new ServiceTag(
+ getTextValue(svcTagElement, ST_NODE_INSTANCE_URN),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_NAME),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_VERSION),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_URN),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_PARENT),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_PARENT_URN),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_DEFINED_INST_ID),
+ getTextValue(svcTagElement, ST_NODE_PRODUCT_VENDOR),
+ getTextValue(svcTagElement, ST_NODE_PLATFORM_ARCH),
+ getTextValue(svcTagElement, ST_NODE_CONTAINER),
+ getTextValue(svcTagElement, ST_NODE_SOURCE),
+ Util.getIntValue(getTextValue(svcTagElement, ST_NODE_INSTALLER_UID)),
+ Util.parseTimestamp(getTextValue(svcTagElement, ST_NODE_TIMESTAMP))
+ );
+ }
+
+ private static String getTextValue(Element e, String tagName) {
+ String value = "";
+ NodeList nl = e.getElementsByTagName(tagName);
+ if (nl != null && nl.getLength() > 0) {
+ Element el = (Element) nl.item(0);
+ Node node = el.getFirstChild();
+ if (node != null) {
+ value = node.getNodeValue();
+ }
+ }
+ return value;
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/Registry.java b/desktop/source/registration/com/sun/star/servicetag/Registry.java
new file mode 100644
index 000000000000..932b0d7e1cb5
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/Registry.java
@@ -0,0 +1,554 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import static com.sun.star.servicetag.Util.*;
+import static com.sun.star.servicetag.RegistrationDocument.*;
+
+/**
+ * A service tag registry is a XML-based registry containing
+ * the list of {@link ServiceTag service tags} installed in the system.
+ * The {@code Registry} class provides interfaces
+ * to add, remove, update, and get a service tag from a service tag
+ * registry.
+ * This {@code Registry} class may not be supported
+ * on all systems. The {@link #isSupported} method
+ * can be called to determine if it is supported.
+ * <p>
+ * A registry may implement restrictions to only allow certain users
+ * to {@link #updateServiceTag update} and
+ * to {@link #removeServiceTag remove} a service tag record. Typically,
+ * only the owner of the service tag, the owner of the registry
+ * and superuser are authorized to update or remove a service tag in
+ * the registry.
+ *
+ * @see <a href="https://sn-tools.central.sun.com/twiki/bin/view/ServiceTags/ServiceTagDevGuideHelper">
+ * Service Tag User Guide</a>
+ */
+public class Registry {
+
+ private static final String STCLIENT_SOLARIS = "/usr/bin/stclient";
+ private static final String STCLIENT_LINUX = "/opt/sun/servicetag/bin/stclient";
+ // stclient exit value (see sthelper.h)
+ private static final int ST_ERR_NOT_AUTH = 245;
+ private static final int ST_ERR_REC_NOT_FOUND = 225;
+
+ // The stclient output has to be an exported interface
+ private static final String INSTANCE_URN_DESC = "Product instance URN=";
+ private static boolean initialized = false;
+ private static boolean supportsHelperClass = true; // default
+ private static File stclient = null;
+ private static String stclientPath = null;
+ private static Registry registry = new Registry();
+
+ // System properties for testing
+ private static String SVCTAG_STCLIENT_CMD = "servicetag.stclient.cmd";
+ private static String SVCTAG_STHELPER_SUPPORTED = "servicetag.sthelper.supported";
+
+ private Registry() {
+ }
+
+ private synchronized static String getSTclient() {
+ if (!initialized) {
+ // the system property always overrides the default setting
+ if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) {
+ supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED);
+ }
+
+ // This is only used for testing
+ stclientPath = System.getProperty(SVCTAG_STCLIENT_CMD);
+ if (stclientPath != null) {
+ return stclientPath;
+ }
+
+ // Initialization to determine the platform's stclient pathname
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS")) {
+ stclient = new File(STCLIENT_SOLARIS);
+ } else if (os.equals("Linux")) {
+ stclient = new File(STCLIENT_LINUX);
+ } else if (os.startsWith("Windows")) {
+ stclient = getWindowsStClientFile();
+ } else {
+ if (isVerbose()) {
+ System.out.println("Running on non-Sun JDK");
+ }
+ }
+ initialized = true;
+ }
+
+ // com.sun.servicetag package has to be compiled with JDK 5 as well
+ // JDK 5 doesn't support the File.canExecute() method.
+ // Risk not checking isExecute() for the stclient command is very low.
+
+ if (stclientPath == null && stclient != null && stclient.exists()) {
+ stclientPath = stclient.getAbsolutePath();
+ }
+ return stclientPath;
+ }
+
+ /**
+ * Returns the system service tag registry. The {@code Registry} class
+ * may not be supported on some platforms; use the {@link #isSupported}
+ * method to determine if it is supported.
+ *
+ * @return the {@code Registry} object for the system service tag registry.
+ *
+ * @throws UnsupportedOperationException if the {@code Registry} class is
+ * not supported.
+ */
+ public static Registry getSystemRegistry() {
+ if (isSupported()) {
+ return registry;
+ } else {
+ throw new UnsupportedOperationException("Registry class is not supported");
+ }
+ }
+
+ /**
+ * Returns {@code true} if the {@code Registry} class is supported on this system.
+ *
+ * @return {@code true} if the {@code Registry} class is supported;
+ * otherwise, return {@code false}.
+ */
+ public static boolean isSupported() {
+ return (getSTclient() != null && supportsHelperClass);
+ }
+
+ private static List<String> getCommandList() {
+ // Set up the arguments to call stclient
+ List<String> command = new ArrayList<String>();
+ if (System.getProperty(SVCTAG_STCLIENT_CMD) != null) {
+ // This is for jtreg testing use. This will be set to something
+ // like:
+ // $JAVA_HOME/bin/java -cp $TEST_DIR \
+ // -Dstclient.registry.path=$TEST_DIR/registry.xml \
+ // SvcTagClient
+ //
+ // On Windows, the JAVA_HOME and TEST_DIR path could contain
+ // space e.g. c:\Program Files\Java\jdk1.6.0_05\bin\java.
+ // The SVCTAG_STCLIENT_CMD must be set with a list of
+ // space-separated parameters. If a parameter contains spaces,
+ // it must be quoted with '"'.
+
+ String cmd = getSTclient();
+ int len = cmd.length();
+ int i = 0;
+ while (i < len) {
+ char separator = ' ';
+ if (cmd.charAt(i) == '"') {
+ separator = '"';
+ i++;
+ }
+ // look for the separator or matched the closing '"'
+ int j;
+ for (j = i+1; j < len; j++) {
+ if (cmd.charAt(j) == separator) {
+ break;
+ }
+ }
+
+ if (i == j-1) {
+ // add an empty parameter
+ command.add("\"\"");
+ } else {
+ // double quotes and space are not included
+ command.add(cmd.substring(i,j));
+ }
+
+ // skip spaces
+ for (i = j+1; i < len; i++) {
+ if (!Character.isSpaceChar(cmd.charAt(i))) {
+ break;
+ }
+ }
+ }
+ if (isVerbose()) {
+ System.out.println("Command list:");
+ for (String s : command) {
+ System.out.println(s);
+ }
+ }
+ } else {
+ command.add(getSTclient());
+ }
+ return command;
+ }
+
+ // Returns null if the service tag record not found;
+ // or throw UnauthorizedAccessException or IOException
+ // based on the exitValue.
+ private static ServiceTag checkReturnError(int exitValue,
+ String output,
+ ServiceTag st) throws IOException {
+ switch (exitValue) {
+ case ST_ERR_REC_NOT_FOUND:
+ return null;
+ case ST_ERR_NOT_AUTH:
+ if (st != null) {
+ throw new UnauthorizedAccessException(
+ "Not authorized to access " + st.getInstanceURN() +
+ " installer_uid=" + st.getInstallerUID());
+ } else {
+ throw new UnauthorizedAccessException(
+ "Not authorized:" + output);
+ }
+ default:
+ throw new IOException("stclient exits with error" +
+ " (" + exitValue + ")\n" + output);
+ }
+ }
+
+ /**
+ * Adds a service tag to this registry.
+ * If the given service tag has an empty <tt>instance_urn</tt>,
+ * this helper class will generate a URN and place it in the
+ * copy of the service tag in this registry.
+ * This method will return the {@code ServiceTag} representing
+ * the service tag entry to this registry.
+ *
+ * @param st {@code ServiceTag} object
+ * @return a {@code ServiceTag} object representing the service tag
+ * entry to this registry.
+ *
+ * @throws IllegalArgumentException if a service tag of the same
+ * <tt>instance_urn</tt> already exists in this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ public ServiceTag addServiceTag(ServiceTag st) throws IOException {
+ List<String> command = getCommandList();
+ command.add("-a");
+ if (st.getInstanceURN().length() > 0) {
+ ServiceTag sysSvcTag = getServiceTag(st.getInstanceURN());
+ if (sysSvcTag != null) {
+ throw new IllegalArgumentException("Instance_urn = " +
+ st.getInstanceURN() + " already exists");
+ }
+ command.add("-i");
+ command.add(st.getInstanceURN());
+ }
+ command.add("-p");
+ command.add(st.getProductName());
+ command.add("-e");
+ command.add(st.getProductVersion());
+ command.add("-t");
+ command.add(st.getProductURN());
+ if (st.getProductParentURN().length() > 0) {
+ command.add("-F");
+ command.add(st.getProductParentURN());
+ }
+ command.add("-P");
+ command.add(st.getProductParent());
+ if (st.getProductDefinedInstanceID().length() > 0) {
+ command.add("-I");
+ command.add(st.getProductDefinedInstanceID());
+ }
+ command.add("-m");
+ command.add(st.getProductVendor());
+ command.add("-A");
+ command.add(st.getPlatformArch());
+ command.add("-z");
+ command.add(st.getContainer());
+ command.add("-S");
+ command.add(st.getSource());
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -a command:");
+ System.out.println(output);
+ }
+ String urn = "";
+ if (p.exitValue() == 0) {
+ // Obtain the instance urn from the stclient output
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ line = line.trim();
+ if (line.startsWith(INSTANCE_URN_DESC)) {
+ urn = line.substring(INSTANCE_URN_DESC.length());
+ break;
+ }
+ }
+ if (urn.length() == 0) {
+ throw new IOException("Error in creating service tag:\n" +
+ output);
+ }
+ return getServiceTag(urn);
+ } else {
+ return checkReturnError(p.exitValue(), output, st);
+ }
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+
+ /**
+ * Removes a service tag of the given <tt>instance_urn</tt> from this
+ * registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * to be removed.
+ *
+ * @return the {@code ServiceTag} object removed from this registry;
+ * or {@code null} if the service tag does not exist in this registry.
+ *
+ * @throws UnauthorizedAccessException if the user is not authorized to
+ * remove the service tag of the given <tt>instance_urn</tt>
+ * from this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ public ServiceTag removeServiceTag(String instanceURN) throws IOException {
+ ServiceTag st = getServiceTag(instanceURN);
+ if (st == null) {
+ return null;
+ }
+
+ List<String> command = getCommandList();
+ command.add("-d");
+ command.add("-i");
+ command.add(instanceURN);
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -d command:");
+ System.out.println(output);
+ }
+ if (p.exitValue() == 0) {
+ return st;
+ } else {
+ return checkReturnError(p.exitValue(), output, st);
+ }
+ }
+
+ /**
+ * Updates the <tt>product_defined_instance_id</tt> in the service tag
+ * of the specified <tt>instance_urn</tt> in this registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag to be updated.
+ * @param productDefinedInstanceID the value of the
+ * <tt>product_defined_instance_id</tt> to be set.
+ *
+ * @return the updated {@code ServiceTag} object;
+ * or {@code null} if the service tag does not exist in this
+ * registry.
+ *
+ * @throws UnauthorizedAccessException if the user is not authorized to
+ * update the service tag from this registry.
+ *
+ * @throws IOException if an I/O error occurs in this operation.
+ */
+ public ServiceTag updateServiceTag(String instanceURN,
+ String productDefinedInstanceID)
+ throws IOException {
+ ServiceTag svcTag = getServiceTag(instanceURN);
+ if (svcTag == null) {
+ return null;
+ }
+
+ List<String> command = getCommandList();
+ command.add("-u");
+ command.add("-i");
+ command.add(instanceURN);
+ command.add("-I");
+ if (productDefinedInstanceID.length() > 0) {
+ command.add(productDefinedInstanceID);
+ } else {
+ command.add("\"\"");
+ }
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -u command:");
+ System.out.println(output);
+ }
+
+ if (p.exitValue() == 0) {
+ return getServiceTag(instanceURN);
+ } else {
+ return checkReturnError(p.exitValue(), output, svcTag);
+ }
+ }
+
+ /**
+ * Returns a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * in this registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * @return a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * in this registry; or {@code null} if not found.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ public ServiceTag getServiceTag(String instanceURN) throws IOException {
+ if (instanceURN == null) {
+ throw new NullPointerException("instanceURN is null");
+ }
+
+ List<String> command = getCommandList();
+ command.add("-g");
+ command.add("-i");
+ command.add(instanceURN);
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -g command:");
+ System.out.println(output);
+ }
+ if (p.exitValue() == 0) {
+ return parseServiceTag(output);
+ } else {
+ return checkReturnError(p.exitValue(), output, null);
+ }
+ }
+
+ private ServiceTag parseServiceTag(String output) throws IOException {
+ BufferedReader in = null;
+ try {
+ Properties props = new Properties();
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ if ((line = line.trim()).length() > 0) {
+ String[] ss = line.trim().split("=", 2);
+ if (ss.length == 2) {
+ props.setProperty(ss[0].trim(), ss[1].trim());
+ } else {
+ props.setProperty(ss[0].trim(), "");
+ }
+ }
+ }
+
+ String urn = props.getProperty(ST_NODE_INSTANCE_URN);
+ String productName = props.getProperty(ST_NODE_PRODUCT_NAME);
+ String productVersion = props.getProperty(ST_NODE_PRODUCT_VERSION);
+ String productURN = props.getProperty(ST_NODE_PRODUCT_URN);
+ String productParent = props.getProperty(ST_NODE_PRODUCT_PARENT);
+ String productParentURN = props.getProperty(ST_NODE_PRODUCT_PARENT_URN);
+ String productDefinedInstanceID =
+ props.getProperty(ST_NODE_PRODUCT_DEFINED_INST_ID);
+ String productVendor = props.getProperty(ST_NODE_PRODUCT_VENDOR);
+ String platformArch = props.getProperty(ST_NODE_PLATFORM_ARCH);
+ String container = props.getProperty(ST_NODE_CONTAINER);
+ String source = props.getProperty(ST_NODE_SOURCE);
+ int installerUID =
+ Util.getIntValue(props.getProperty(ST_NODE_INSTALLER_UID));
+ Date timestamp =
+ Util.parseTimestamp(props.getProperty(ST_NODE_TIMESTAMP));
+
+ return new ServiceTag(urn,
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ productVendor,
+ platformArch,
+ container,
+ source,
+ installerUID,
+ timestamp);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+
+ }
+
+ /**
+ * Returns the service tags of the specified
+ * <tt>product_urn</tt> in this registry.
+ *
+ * @param productURN the <tt>product_urn</tt> to look up
+ * @return a {@code Set} of {@code ServiceTag} objects
+ * of the specified <tt>product_urn</tt> in this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ public Set<ServiceTag> findServiceTags(String productURN) throws IOException {
+ if (productURN == null) {
+ throw new NullPointerException("productURN is null");
+ }
+
+ List<String> command = getCommandList();
+ command.add("-f");
+ command.add("-t");
+ command.add(productURN);
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+
+ Set<ServiceTag> instances = new HashSet<ServiceTag>();
+ if (p.exitValue() == 0) {
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ String s = line.trim();
+ if (s.startsWith("urn:st:")) {
+ instances.add(getServiceTag(s));
+ }
+ }
+ } else {
+ checkReturnError(p.exitValue(), output, null);
+ }
+ return instances;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java b/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java
new file mode 100644
index 000000000000..4adb36772517
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java
@@ -0,0 +1,636 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.util.Date;
+import java.io.IOException;
+import static com.sun.star.servicetag.RegistrationDocument.*;
+
+/**
+ * A service tag is an XML-based data structure that identifies a product or
+ * a component on a system. The service tag schema is defined by the
+ * Service Tags Technology. The location of the DTD file is platform dependent.
+ * On Solaris, see <tt>/usr/share/lib/xml/dtd/servicetag.dtd</tt>.
+ * <p>
+ * A valid {@code ServiceTag} instance must comply to the service tag schema
+ * and contain the following fields:
+ * <ul>
+ * <li>{@link #getInstanceURN <tt>instance_urn</tt>}</li>
+ * <li>{@link #getProductName <tt>product_name</tt>}</li>
+ * <li>{@link #getProductVersion <tt>product_version</tt>}</li>
+ * <li>{@link #getProductURN <tt>product_urn</tt>}</li>
+ * <li>{@link #getProductParent <tt>product_parent</tt>}</li>
+ * <li>{@link #getProductParentURN <tt>product_parent_urn</tt>}</li>
+ * <li>{@link #getProductDefinedInstanceID <tt>product_defined_inst_id</tt>}</li>
+ * <li>{@link #getProductVendor <tt>product_vendor</tt>}</li>
+ * <li>{@link #getPlatformArch <tt>platform_arch</tt>}</li>
+ * <li>{@link #getContainer <tt>container</tt>}</li>
+ * <li>{@link #getSource <tt>source</tt>}</li>
+ * <li>{@link #getInstallerUID <tt>installer_uid</tt>}</li>
+ * <li>{@link #getTimestamp <tt>timestamp</tt>}</li>
+ * </ul>
+ *
+ * The <tt>instance_urn</tt> can be specified when a {@code ServiceTag}
+ * object is created, or it can be generated when it is added to
+ * a {@link RegistrationData} object, or {@link Registry
+ * system service tag registry}. The <tt>installer_uid</tt> and
+ * <tt>timestamp</tt> are set when a {@code ServiceTag} object
+ * is added to a {@link RegistrationData} object, or {@link Registry
+ * system service tag registry}.
+ *
+ * @see <a href="https://sunconnection.sun.com/FAQ/sc_faq.html">Service Tags FAQ</a>
+ */
+public class ServiceTag {
+
+ private String instanceURN;
+ private String productName;
+ private String productVersion;
+ private String productURN;
+ private String productParent;
+ private String productParentURN;
+ private String productDefinedInstanceID;
+ private String productVendor;
+ private String platformArch;
+ private String container;
+ private String source;
+ private int installerUID;
+ private Date timestamp;
+
+ // Service Tag Field Lengths (defined in sthelper.h)
+ // Since the constants defined in sthelper.h includes the null-terminated
+ // character, so minus 1 from the sthelper.h defined values.
+ private final int MAX_URN_LEN = 256 - 1;
+ private final int MAX_PRODUCT_NAME_LEN = 256 - 1;
+ private final int MAX_PRODUCT_VERSION_LEN = 64 - 1;
+ private final int MAX_PRODUCT_PARENT_LEN = 256 - 1;
+ private final int MAX_PRODUCT_VENDOR_LEN = 64 - 1;
+ private final int MAX_PLATFORM_ARCH_LEN = 64 - 1;
+ private final int MAX_CONTAINER_LEN = 64 - 1;
+ private final int MAX_SOURCE_LEN = 64 - 1;
+
+ // private constructors
+ private ServiceTag() {
+ }
+ // package private
+ ServiceTag(String instanceURN,
+ String productName,
+ String productVersion,
+ String productURN,
+ String productParent,
+ String productParentURN,
+ String productDefinedInstanceID,
+ String productVendor,
+ String platformArch,
+ String container,
+ String source,
+ int installerUID,
+ Date timestamp) {
+ setInstanceURN(instanceURN);
+ setProductName(productName);
+ setProductVersion(productVersion);
+ setProductURN(productURN);
+ setProductParentURN(productParentURN);
+ setProductParent(productParent);
+ setProductDefinedInstanceID(productDefinedInstanceID);
+ setProductVendor(productVendor);
+ setPlatformArch(platformArch);
+ setContainer(container);
+ setSource(source);
+ setInstallerUID(installerUID);
+ setTimestamp(timestamp);
+ }
+
+ /**
+ * Creates a service tag object with no <tt>instance_urn</tt>.
+ *
+ * @param productName the name of the product.
+ * @param productVersion the version of the product.
+ * @param productURN the uniform resource name of the product
+ * @param productParent the name of the product's parent.
+ * @param productParentURN the uniform resource name of the product's parent.
+ * @param productDefinedInstanceID the instance identifier.
+ * @param productVendor the vendor of the product.
+ * @param platformArch the operating system architecture.
+ * @param container the container of the product.
+ * @param source the source of the product.
+ *
+ * @throws IllegalArgumentException if any value of the input fields
+ * does not conform to the service tag XML schema.
+ */
+ public static ServiceTag newInstance(String productName,
+ String productVersion,
+ String productURN,
+ String productParent,
+ String productParentURN,
+ String productDefinedInstanceID,
+ String productVendor,
+ String platformArch,
+ String container,
+ String source) {
+ return new ServiceTag("", /* empty instance_urn */
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ productVendor,
+ platformArch,
+ container,
+ source,
+ -1,
+ null);
+ }
+
+ /**
+ * Creates a service tag object with a specified <tt>instance_urn</tt>.
+ *
+ * @param instanceURN the uniform resource name of this instance.
+ * @param productName the name of the product.
+ * @param productVersion the version of the product.
+ * @param productURN the uniform resource name of the product
+ * @param productParent the name of the product's parent.
+ * @param productParentURN the uniform resource name of the product's parent.
+ * @param productDefinedInstanceID the instance identifier.
+ * @param productVendor the vendor of the product.
+ * @param platformArch the operating system architecture.
+ * @param container the container of the product.
+ * @param source the source of the product.
+ *
+ * @throws IllegalArgumentException if any value of the input fields
+ * does not conform to the service tag XML schema.
+ */
+ public static ServiceTag newInstance(String instanceURN,
+ String productName,
+ String productVersion,
+ String productURN,
+ String productParent,
+ String productParentURN,
+ String productDefinedInstanceID,
+ String productVendor,
+ String platformArch,
+ String container,
+ String source) {
+ return new ServiceTag(instanceURN,
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ productVendor,
+ platformArch,
+ container,
+ source,
+ -1,
+ null);
+ }
+
+ // Creates a copy of the ServiceTag instance
+ // with instance_urn and timestamp initialized
+ static ServiceTag newInstanceWithUrnTimestamp(ServiceTag st) {
+ String instanceURN =
+ (st.getInstanceURN().length() == 0 ? Util.generateURN() :
+ st.getInstanceURN());
+ ServiceTag svcTag = new ServiceTag(instanceURN,
+ st.getProductName(),
+ st.getProductVersion(),
+ st.getProductURN(),
+ st.getProductParent(),
+ st.getProductParentURN(),
+ st.getProductDefinedInstanceID(),
+ st.getProductVendor(),
+ st.getPlatformArch(),
+ st.getContainer(),
+ st.getSource(),
+ st.getInstallerUID(),
+ new Date());
+ return svcTag;
+ }
+
+ /**
+ * Returns a uniform resource name (URN) in this format:
+ * <blockquote>
+ * "<tt>urn:st:<32-char {@link java.util.UUID uuid}></tt>"
+ * </blockquote>
+ * @return a URN.
+ */
+ public static String generateInstanceURN() {
+ return Util.generateURN();
+ }
+
+ /**
+ * Returns the uniform resource name of this service tag instance.
+ *
+ * @return the <tt>instance_urn</tt> of this service tag.
+ */
+ public String getInstanceURN() {
+ return instanceURN;
+ }
+
+ /**
+ * Returns the name of the product.
+ *
+ * @return the product name.
+ */
+ public String getProductName() {
+ return productName;
+ }
+
+ /**
+ * Returns the version of the product.
+ *
+ * @return the product version.
+ */
+ public String getProductVersion() {
+ return productVersion;
+ }
+
+ /**
+ * Returns the uniform resource name of the product.
+ *
+ * @return the product URN.
+ */
+ public String getProductURN() {
+ return productURN;
+ }
+
+ /**
+ * Returns the uniform resource name of the product's parent.
+ *
+ * @return the product's parent URN.
+ */
+ public String getProductParentURN() {
+ return productParentURN;
+ }
+
+ /**
+ * Returns the name of the product's parent.
+ *
+ * @return the product's parent name.
+ */
+ public String getProductParent() {
+ return productParent;
+ }
+
+ /**
+ * Returns the identifier defined for this product instance.
+ *
+ * @return the identifier defined for this product instance.
+ */
+ public String getProductDefinedInstanceID() {
+ return productDefinedInstanceID;
+ }
+
+ /**
+ * Returns the vendor of the product.
+ *
+ * @return the product vendor.
+ */
+ public String getProductVendor() {
+ return productVendor;
+ }
+
+ /**
+ * Returns the platform architecture on which the product
+ * is running on.
+ *
+ * @return the platform architecture on which the product is running on.
+ */
+ public String getPlatformArch() {
+ return platformArch;
+ }
+
+ /**
+ * Returns the timestamp. This timestamp is set when this service tag
+ * is added to or updated in a {@code RegistrationData} object or
+ * the system service tag registry.
+ * This method may return {@code null}.
+ *
+ * @return timestamp when this service tag
+ * is added to or updated in a {@code RegistrationData} object or
+ * the system service tag registry, or {@code null}.
+ */
+ public Date getTimestamp() {
+ if (timestamp != null) {
+ return (Date) timestamp.clone();
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Returns the container of the product.
+ *
+ * @return the container of the product.
+ */
+ public String getContainer() {
+ return container;
+ }
+
+ /**
+ * Returns the source of this service tag.
+ *
+ * @return source of this service tag.
+ */
+ public String getSource() {
+ return source;
+ }
+
+ /**
+ * Returns the UID. The UID is set when this service tag
+ * is added to or updated in the system service tag registry.
+ * This is platform dependent whose default value is {@code -1}.
+ * When this service tag is added to a {@code RegistrationData},
+ * the UID is not set.
+ *
+ * @return the UID of whom this service tag
+ * is added to or updated in the system service tag registry,
+ * or {@code -1}.
+ */
+ public int getInstallerUID() {
+ return installerUID;
+ }
+
+ // The following setter methods are used to validate the
+ // input field when constructing a ServiceTag instance
+
+ private void setInstanceURN(String instanceURN) {
+ if (instanceURN == null) {
+ throw new NullPointerException("Parameter instanceURN cannot be null");
+ }
+ if (instanceURN.length() > MAX_URN_LEN) {
+ throw new IllegalArgumentException("instanceURN \"" + instanceURN +
+ "\" exceeds maximum length " + MAX_URN_LEN);
+ }
+ this.instanceURN = instanceURN;
+ }
+
+ private void setProductName(String productName) {
+ if (productName == null) {
+ throw new NullPointerException("Parameter productName cannot be null");
+ }
+ if (productName.length() == 0) {
+ throw new IllegalArgumentException("product name cannot be empty");
+ }
+ if (productName.length() > MAX_PRODUCT_NAME_LEN) {
+ throw new IllegalArgumentException("productName \"" + productName +
+ "\" exceeds maximum length " + MAX_PRODUCT_NAME_LEN);
+ }
+ this.productName = productName;
+ }
+
+ private void setProductVersion(String productVersion) {
+ if (productVersion == null) {
+ throw new NullPointerException("Parameter productVersion cannot be null");
+ }
+
+ if (productVersion.length() == 0) {
+ throw new IllegalArgumentException("product version cannot be empty");
+ }
+ if (productVersion.length() > MAX_PRODUCT_VERSION_LEN) {
+ throw new IllegalArgumentException("productVersion \"" +
+ productVersion + "\" exceeds maximum length " +
+ MAX_PRODUCT_VERSION_LEN);
+ }
+ this.productVersion = productVersion;
+ }
+
+ private void setProductURN(String productURN) {
+ if (productURN == null) {
+ throw new NullPointerException("Parameter productURN cannot be null");
+ }
+ if (productURN.length() == 0) {
+ throw new IllegalArgumentException("product URN cannot be empty");
+ }
+ if (productURN.length() > MAX_URN_LEN) {
+ throw new IllegalArgumentException("productURN \"" + productURN +
+ "\" exceeds maximum length " + MAX_URN_LEN);
+ }
+ this.productURN = productURN;
+ }
+
+ private void setProductParentURN(String productParentURN) {
+ if (productParentURN == null) {
+ throw new NullPointerException("Parameter productParentURN cannot be null");
+ }
+ // optional field - can be empty
+ if (productParentURN.length() > MAX_URN_LEN) {
+ throw new IllegalArgumentException("productParentURN \"" +
+ productParentURN + "\" exceeds maximum length " +
+ MAX_URN_LEN);
+ }
+ this.productParentURN = productParentURN;
+ }
+
+ private void setProductParent(String productParent) {
+ if (productParent == null) {
+ throw new NullPointerException("Parameter productParent cannot be null");
+ }
+ if (productParent.length() == 0) {
+ throw new IllegalArgumentException("product parent cannot be empty");
+ }
+ if (productParent.length() > MAX_PRODUCT_PARENT_LEN) {
+ throw new IllegalArgumentException("productParent \"" +
+ productParent + "\" exceeds maximum length " +
+ MAX_PRODUCT_PARENT_LEN);
+ }
+ this.productParent = productParent;
+ }
+
+ void setProductDefinedInstanceID(String productDefinedInstanceID) {
+ if (productDefinedInstanceID == null) {
+ throw new NullPointerException("Parameter productDefinedInstanceID cannot be null");
+ }
+ if (productDefinedInstanceID.length() > MAX_URN_LEN) {
+ throw new IllegalArgumentException("productDefinedInstanceID \"" +
+ productDefinedInstanceID + "\" exceeds maximum length " +
+ MAX_URN_LEN);
+ }
+ // optional field - can be empty
+ this.productDefinedInstanceID = productDefinedInstanceID;
+ }
+
+ private void setProductVendor(String productVendor) {
+ if (productVendor == null) {
+ throw new NullPointerException("Parameter productVendor cannot be null");
+ }
+ if (productVendor.length() == 0) {
+ throw new IllegalArgumentException("product vendor cannot be empty");
+ }
+ if (productVendor.length() > MAX_PRODUCT_VENDOR_LEN) {
+ throw new IllegalArgumentException("productVendor \"" +
+ productVendor + "\" exceeds maximum length " +
+ MAX_PRODUCT_VENDOR_LEN);
+ }
+ this.productVendor = productVendor;
+ }
+
+ private void setPlatformArch(String platformArch) {
+ if (platformArch == null) {
+ throw new NullPointerException("Parameter platformArch cannot be null");
+ }
+ if (platformArch.length() == 0) {
+ throw new IllegalArgumentException("platform architecture cannot be empty");
+ }
+ if (platformArch.length() > MAX_PLATFORM_ARCH_LEN) {
+ throw new IllegalArgumentException("platformArch \"" +
+ platformArch + "\" exceeds maximum length " +
+ MAX_PLATFORM_ARCH_LEN);
+ }
+ this.platformArch = platformArch;
+ }
+
+ private void setTimestamp(Date timestamp) {
+ // can be null
+ this.timestamp = timestamp;
+ }
+
+ private void setContainer(String container) {
+ if (container == null) {
+ throw new NullPointerException("Parameter container cannot be null");
+ }
+ if (container.length() == 0) {
+ throw new IllegalArgumentException("container cannot be empty");
+ }
+ if (container.length() > MAX_CONTAINER_LEN) {
+ throw new IllegalArgumentException("container \"" +
+ container + "\" exceeds maximum length " +
+ MAX_CONTAINER_LEN);
+ }
+ this.container = container;
+ }
+
+ private void setSource(String source) {
+ if (source == null) {
+ throw new NullPointerException("Parameter source cannot be null");
+ }
+ if (source.length() == 0) {
+ throw new IllegalArgumentException("source cannot be empty");
+ }
+ if (source.length() > MAX_SOURCE_LEN) {
+ throw new IllegalArgumentException("source \"" + source +
+ "\" exceeds maximum length " + MAX_SOURCE_LEN);
+ }
+ this.source = source;
+ }
+
+ private void setInstallerUID(int installerUID) {
+ this.installerUID = installerUID;
+ }
+
+ /**
+ * Compares this service tag to the specified object.
+ * The result is {@code true} if and only if the argument is
+ * not {@code null} and is a {@code ServiceTag} object whose
+ * <tt>instance_urn</tt> is the same as the
+ * <tt>instance_urn</tt> of this service tag.
+ *
+ * @return {@code true} if this service tag is the same as
+ * the specified object.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj instanceof ServiceTag)) {
+ return false;
+ }
+ ServiceTag st = (ServiceTag) obj;
+ if (st == this) {
+ return true;
+ }
+ return st.getInstanceURN().equals(getInstanceURN());
+ }
+
+ /**
+ * Returns the hash code value for this service tag.
+ * @return the hash code value for this service tag.
+ */
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 19 * hash + (this.instanceURN != null ? this.instanceURN.hashCode() : 0);
+ return hash;
+ }
+
+ /**
+ * Returns the string representation of this service tag.
+ * The format is implementation specific.
+ *
+ * @return the string representation of this service tag.
+ */
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ST_NODE_INSTANCE_URN).append("=").append(instanceURN).append("\n");
+ sb.append(ST_NODE_PRODUCT_NAME).append("=").append(productName).append("\n");
+ sb.append(ST_NODE_PRODUCT_VERSION).append("=").append(productVersion).append("\n");
+ sb.append(ST_NODE_PRODUCT_URN).append("=").append(productURN).append("\n");
+ sb.append(ST_NODE_PRODUCT_PARENT_URN).append("=").append(productParentURN).append("\n");
+ sb.append(ST_NODE_PRODUCT_PARENT).append("=").append(productParent).append("\n");
+ sb.append(ST_NODE_PRODUCT_DEFINED_INST_ID).append("=").append(productDefinedInstanceID).append("\n");
+ sb.append(ST_NODE_PRODUCT_VENDOR).append("=").append(productVendor).append("\n");
+ sb.append(ST_NODE_PLATFORM_ARCH).append("=").append(platformArch).append("\n");
+ sb.append(ST_NODE_TIMESTAMP).append("=").append(Util.formatTimestamp(timestamp)).append("\n");
+ sb.append(ST_NODE_CONTAINER).append("=").append(container).append("\n");
+ sb.append(ST_NODE_SOURCE).append("=").append(source).append("\n");
+ sb.append(ST_NODE_INSTALLER_UID).append("=").append(String.valueOf(installerUID)).append("\n");
+ return sb.toString();
+ }
+
+
+ /**
+ * Returns the {@link ServiceTag} instance for the running Java
+ * platform. The {@link ServiceTag#setSource source} field
+ * of the {@code ServiceTag} will be set to the given {@code source}.
+ * This method will return {@code null} if there is no service tag
+ * for the running Java platform.
+ * <p>
+ * This method is designed for Sun software that bundles the JDK
+ * or the JRE to use. It is recommended that the {@code source}
+ * string contains information about the bundling software
+ * such as the name and the version of the software bundle,
+ * for example,
+ * <blockquote>
+ * <tt>NetBeans IDE 6.0 with JDK 6 Update 5 Bundle</tt>
+ * </blockquote>
+ * in a NetBeans/JDK bundle.
+ * <p>
+ * At the first time to call this method the application
+ * is required to have the write permission to the installed
+ * directory of this running JDK or JRE instance.
+ *
+ * @param source the source that bundles the JDK or the JRE.
+ * @return a {@code ServiceTag} object for the Java platform,
+ * or {@code null} if not supported.
+ * @throws IOException if an error occurs in this operation.
+ */
+ public static ServiceTag getJavaServiceTag(String source) throws IOException {
+ return Installer.getJavaServiceTag(source);
+ }
+
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java b/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java
new file mode 100644
index 000000000000..4f99d890577f
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * Utility class to obtain the service tag for the Solaris Operating System.
+ */
+class SolarisServiceTag {
+ private final static String[] SolarisProductURNs = new String[] {
+ "urn:uuid:a7a38948-2bd5-11d6-98ce-9d3ac1c0cfd7", /* Solaris 8 */
+ "urn:uuid:4f82caac-36f3-11d6-866b-85f428ef944e", /* Solaris 9 */
+ "urn:uuid:a19de03b-48bc-11d9-9607-080020a9ed93", /* Solaris 9 sparc */
+ "urn:uuid:4c35c45b-4955-11d9-9607-080020a9ed93", /* Solaris 9 x86 */
+ "urn:uuid:5005588c-36f3-11d6-9cec-fc96f718e113", /* Solaris 10 */
+ "urn:uuid:6df19e63-7ef5-11db-a4bd-080020a9ed93" /* Solaris 11 */
+ };
+
+ /**
+ * Returns null if not found.
+ *
+ * There is only one service tag for the operating system.
+ */
+ static ServiceTag getServiceTag() throws IOException {
+ if (Registry.isSupported()) {
+ Registry streg = Registry.getSystemRegistry();
+ for (String parentURN : SolarisProductURNs) {
+ Set<ServiceTag> instances = streg.findServiceTags(parentURN);
+ for (ServiceTag st : instances) {
+ // there should have only one service tag for the OS
+ return st;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java
new file mode 100644
index 000000000000..fa98580fd6b5
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java
@@ -0,0 +1,421 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+// The Service Tags team maintains the latest version of the implementation
+// for system environment data collection. JDK will include a copy of
+// the most recent released version for a JDK release. We rename
+// the package to com.sun.servicetag so that the Sun Connection
+// product always uses the latest version from the com.sun.scn.servicetags
+// package. JDK and users of the com.sun.servicetag API
+// (e.g. NetBeans and SunStudio) will use the version in JDK.
+
+import java.io.*;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * Solaris implementation of the SystemEnvironment class.
+ */
+class SolarisSystemEnvironment extends SystemEnvironment {
+ private static final int SN = 1;
+ private static final int SYS = 2;
+ private static final int CPU = 3;
+ private static final int MODEL = 4;
+ private String kstatCpuInfo = null;
+
+ SolarisSystemEnvironment() {
+ setHostId(getCommandOutput("/usr/bin/hostid"));
+ setSystemModel(getSolarisModel());
+ setSystemManufacturer(getSolarisSystemManufacturer());
+ setCpuManufacturer(getSolarisCpuManufacturer());
+ setSerialNumber(getSolarisSN());
+ setPhysMem(getSolarisPhysMem());
+ setSockets(getSolarisSockets());
+ setCores(getSolarisCores());
+ setVirtCpus(getSolarisVirtCpus());
+ setCpuName(getSolarisCpuName());
+ setClockRate(getSolarisClockRate());
+ }
+
+ private String getSolarisClockRate() {
+ String data = getSolarisKstatCpuInfo();
+
+ String lines[] = data.split("\n");
+ String token = "clock_MHz";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(token)) {
+ return line.substring(line.indexOf(token) + token.length()).trim();
+ }
+ }
+ return "";
+ }
+
+ private String getSolarisCpuName() {
+ String data = getSolarisKstatCpuInfo();
+
+ String lines[] = data.split("\n");
+ String token = "brand";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(token)) {
+ return line.substring(line.indexOf(token) + token.length()).trim();
+ }
+ }
+ return "";
+ }
+
+ private String getSolarisVirtCpus() {
+ String data = getSolarisKstatCpuInfo();
+
+ int cnt = 0;
+ String lines[] = data.split("\n");
+ String token = " cpu_info ";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.indexOf(token) != -1) {
+ cnt++;
+ }
+ }
+ return "" + cnt;
+ }
+
+ private String getSolarisCores() {
+ String data = getSolarisKstatCpuInfo();
+
+ Set<String> set = new HashSet<String>();
+ String lines[] = data.split("\n");
+ String coreIdToken = "core_id";
+ String coreId = "";
+ String chipIdToken = "chip_id";
+ String chipId = "";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(chipIdToken)) {
+ chipId = line.substring(line.indexOf(chipIdToken) + chipIdToken.length()).trim();
+ }
+ if (line.startsWith(coreIdToken)) {
+ coreId = line.substring(line.indexOf(coreIdToken) + coreIdToken.length()).trim();
+ set.add(chipId + "," + coreId);
+ }
+ }
+ return "" + set.size();
+ }
+
+ private String getSolarisPhysMem() {
+ String data = getCommandOutput("/usr/sbin/prtconf");
+
+ int cnt = 0;
+ String lines[] = data.split("\n");
+ String token = "Memory size:";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(token)) {
+ line = line.substring(line.indexOf(token) + token.length()).trim();
+ if (line.indexOf(" ") != -1) {
+ return line.substring(0, line.indexOf(" ")).trim();
+ }
+ }
+ }
+ return "";
+ }
+
+ private String getSolarisSockets() {
+ String data = getSolarisKstatCpuInfo();
+
+ Set<String> set = new HashSet<String>();
+ String lines[] = data.split("\n");
+ String token = "chip_id";
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.startsWith(token)) {
+ String id = line.substring(line.indexOf(token) + token.length()).trim();
+ set.add(id);
+ }
+ }
+ return "" + set.size();
+ }
+
+ private synchronized String getSolarisKstatCpuInfo() {
+ // only try to get kstat cpu_info information once, after that, we can
+ // reuse the output
+ if (kstatCpuInfo == null) {
+ Thread thread = new Thread() {
+ public void run() {
+ kstatCpuInfo = getCommandOutput("/usr/bin/kstat", "cpu_info");
+ }
+ };
+ thread.start();
+
+ try {
+ thread.join(2000);
+ if (thread.isAlive()) {
+ thread.interrupt();
+ kstatCpuInfo = "";
+ }
+ } catch (InterruptedException ie) {
+ thread.interrupt();
+ }
+ }
+ return kstatCpuInfo;
+ }
+
+ private String getSolarisModel() {
+ String tmp = getFileContent("/var/run/psn");
+ if (tmp.length() > 0) {
+ String[] lines = tmp.split("\n");
+ if (MODEL <= lines.length) {
+ return lines[MODEL-1] + "::"
+ + getCommandOutput("/usr/bin/uname", "-v");
+ }
+ }
+
+ if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
+ return getCommandOutput("/usr/bin/uname", "-i") + "::"
+ + getCommandOutput("/usr/bin/uname", "-v");
+ } else {
+ String model = getSmbiosData("1", "Product: ");
+ if (model == null || model.trim().equals("")) {
+ model = getCommandOutput("/usr/bin/uname", "-i");
+ }
+ if (model == null) {
+ model = "";
+ }
+ return model.trim() + "::"
+ + getCommandOutput("/usr/bin/uname", "-v");
+ }
+ }
+
+ /**
+ * Tries to obtain the cpu manufacturer.
+ * @return The cpu manufacturer (an empty string if not found or an error occurred)
+ */
+ private String getSolarisCpuManufacturer() {
+ String tmp = getFileContent("/var/run/psn");
+ if (tmp.length() > 0) {
+ String[] lines = tmp.split("\n");
+ if (CPU <= lines.length) {
+ return lines[CPU-1];
+ }
+ }
+
+ // not fully accurate, this could be another manufacturer (fujitsu for example)
+ if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
+ return "Sun Microsystems, Inc";
+ }
+
+ // if we're here, then we'll try smbios (type 4)
+ return getSmbiosData("4", "Manufacturer: ");
+ }
+
+ /**
+ * Tries to obtain the system manufacturer.
+ * @return The system manufacturer (an empty string if not found or an error occurred)
+ */
+ private String getSolarisSystemManufacturer() {
+ String tmp = getFileContent("/var/run/psn");
+ if (tmp.length() > 0) {
+ String[] lines = tmp.split("\n");
+ if (SYS <= lines.length) {
+ return lines[SYS-1];
+ }
+ }
+
+ // not fully accurate, this could be another manufacturer (fujitsu for example)
+ if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
+ if (getCommandOutput("/usr/bin/uname", "-m").equals("sun4us")) {
+ return "Fujitsu";
+ }
+ return "Sun Microsystems, Inc";
+ }
+
+ // if we're here, then we'll try smbios (type 1)
+ return getSmbiosData("1", "Manufacturer: ");
+ }
+
+ /**
+ * Tries to obtain the serial number.
+ * @return The serial number (empty string if not found or an error occurred)
+ */
+ private String getSolarisSN() {
+ // try to read from the psn file if it exists
+ String tmp = getFileContent("/var/run/psn");
+ if (tmp.length() > 0) {
+ String[] lines = tmp.split("\n");
+ if (SN <= lines.length) {
+ return lines[SN-1];
+ }
+ }
+
+ // if we're here, then we'll try sneep
+ String tmpSN = getSneepSN();
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+
+ // if we're here, then we'll try smbios (type 1)
+ tmpSN = getSmbiosData("1", "Serial Number: ");
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+
+ // if we're here, then we'll try smbios (type 3)
+ tmpSN = getSmbiosData("3", "Serial Number: ");
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+
+ if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
+ tmpSN = getSNViaPrtfruX();
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+ tmpSN = getSNViaPrtfru();
+ if (tmpSN.length() > 0) {
+ return tmpSN;
+ }
+ }
+
+ // give up and return
+ return "";
+ }
+
+ // Sample smbios output segment:
+ // ID SIZE TYPE
+ // 1 150 SMB_TYPE_SYSTEM (system information)
+ //
+ // Manufacturer: Sun Microsystems
+ // Product: Sun Fire X4600
+ // Version: To Be Filled By O.E.M.
+ // Serial Number: 00:14:4F:45:0C:2A
+ private String getSmbiosData(String type, String target) {
+ String output = getCommandOutput("/usr/sbin/smbios", "-t", type);
+ for (String s : output.split("\n")) {
+ if (s.contains(target)) {
+ int indx = s.indexOf(target) + target.length();
+ if (indx < s.length()) {
+ String tmp = s.substring(indx).trim();
+ String lowerCaseStr = tmp.toLowerCase();
+ if (!lowerCaseStr.startsWith("not available")
+ && !lowerCaseStr.startsWith("to be filled by o.e.m")) {
+ return tmp;
+ }
+ }
+ }
+ }
+
+ return "";
+ }
+
+ private String getSneepSN() {
+ String basedir = getCommandOutput("pkgparam","SUNWsneep","BASEDIR");
+ File f = new File(basedir + "/bin/sneep");
+ if (f.exists()) {
+ String sneepSN = getCommandOutput(basedir + "/bin/sneep");
+ if (sneepSN.equalsIgnoreCase("unknown")) {
+ return "";
+ } else {
+ return sneepSN;
+ }
+ } else {
+ return "";
+ }
+ }
+
+ private String getSNViaPrtfruX() {
+ String data = getCommandOutput("/usr/sbin/prtfru", "-x");
+
+ boolean FRUTREE_FLAG = false;
+ boolean FRUNAME_FLAG = false;
+ boolean MB_LABEL_FLAG = false;
+ boolean SYSTEM_BOARD_FLAG = false;
+
+ String lines[] = data.split("\n");
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i];
+ if (SYSTEM_BOARD_FLAG) {
+ String tok = "<Sun_Serial_No value=\"";
+ int index = line.indexOf(tok);
+ if (index != -1) {
+ String val = line.substring(index+tok.length());
+ String vals[] = val.split("\"");
+ if (vals.length > 0) {
+ return vals[0].trim();
+ }
+ break;
+ }
+ }
+
+ if (line.indexOf("</ContainerData>") != -1) {
+ FRUTREE_FLAG = false;
+ FRUNAME_FLAG = false;
+ SYSTEM_BOARD_FLAG = false;
+ }
+
+ if (FRUNAME_FLAG && line.indexOf("<Container name=\"system-board\">") != -1 ) {
+ SYSTEM_BOARD_FLAG = true;
+ }
+
+ if (FRUTREE_FLAG && line.indexOf("<Fru name=\"chassis\">") != -1 ) {
+ FRUNAME_FLAG = true;
+ }
+
+ if (line.indexOf("<Location name=\"frutree\">") != -1) {
+ FRUTREE_FLAG = true;
+ }
+ }
+
+ return "";
+ }
+
+ private String getSNViaPrtfru() {
+ String data = getCommandOutput("/usr/sbin/prtfru");
+ boolean CHASSIS_FLAG = false;
+
+ String lines[] = data.split("\n");
+ for (int i=0; i<lines.length; i++) {
+ String line = lines[i];
+ if (CHASSIS_FLAG) {
+ String tok = "/ManR/Sun_Serial_No:";
+ int index = line.indexOf(tok);
+ if (index != -1) {
+ String val = line.substring(index+tok.length());
+ return val.trim();
+ }
+ }
+
+ if (line.indexOf("/frutree/chassis/system-board (container)") != -1) {
+ CHASSIS_FLAG = true;
+ } else if (line.indexOf("/frutree/chassis/MB?Label=MB/system-board (container)") != -1) {
+ CHASSIS_FLAG = true;
+ }
+ }
+ return "";
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SunConnection.java b/desktop/source/registration/com/sun/star/servicetag/SunConnection.java
new file mode 100644
index 000000000000..db525ea637f4
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SunConnection.java
@@ -0,0 +1,292 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.io.OutputStreamWriter;
+import java.util.Locale;
+import javax.net.ssl.HttpsURLConnection;
+
+/**
+ * Sun Connection Class for Product Registration.
+ *
+ * Registration Web Application Interface
+ * 1) POST the product registry to the output stream of the registration
+ * relay service.
+ * 2) Open the webapp URL from a browser with the following parameters:
+ * registry-urn
+ * product=jdk
+ * locale=<locale-lang>
+ *
+ * @see https://sn-tools.central.sun.com/twiki/pub/ServiceTags/RegistrationRelayService/
+ *
+ */
+class SunConnection {
+
+ private static String JDK_REGISTRATION_URL =
+ "https://inventory.sun.com/RegistrationWeb/register";
+ private static String SANDBOX_TESTING_URL =
+ "https://connection-tst.sun.com/RegistrationWeb/register";
+
+ // System properties for testing
+ private static String SVCTAG_REGISTER_TESTING = "servicetag.register.testing";
+ private static String SVCTAG_REGISTRATION_URL = "servicetag.registration.url";
+ private static String SVCTAG_CONNECTION_TIMEOUT = "servicetag.connection.timeout";
+
+ private SunConnection() {
+ }
+
+ /**
+ * Returns a URL for JDK registration interfacing with the Sun Connection
+ * registration relay service in this form:
+ * <registration-url>/<registry_urn>?product=jdk&locale=<locale-lang>
+ *
+ * The <registration-url> can be overridden by an environment
+ * variable or a system property.
+ *
+ * 1) "servicetag.register.testing" system property to switch to the
+ * Sun Connection registration sandbox testing.
+ * 2) "servicetag.registration.url" system property to override
+ * the URL
+ * 3) Default production URL
+ *
+ */
+ static URL getRegistrationURL(String registrationURN) {
+ String url = System.getProperty(SVCTAG_REGISTRATION_URL);
+ if (url == null) {
+ if (System.getProperty(SVCTAG_REGISTER_TESTING) != null) {
+ url = SANDBOX_TESTING_URL;
+ } else {
+ url = JDK_REGISTRATION_URL;
+ }
+ }
+
+ // trim whitespaces
+ url = url.trim();
+ if (url.length() == 0) {
+ throw new InternalError("Empty registration url set");
+ }
+
+ // Add the registry_urn in the URL's query
+ String registerURL = rewriteURL(url, registrationURN);
+ try {
+ return new URL(registerURL);
+ } catch (MalformedURLException ex) {
+ // should never reach here
+ InternalError x =
+ new InternalError(ex.getMessage());
+ x.initCause(ex);
+ throw x;
+ }
+ }
+
+ private static String rewriteURL(String url, String registryURN) {
+ StringBuilder sb = new StringBuilder(url.trim());
+ int len = sb.length();
+ if (sb.charAt(len-1) != '/') {
+ sb.append('/');
+ }
+ sb.append(registryURN);
+ sb.append("?");
+ sb.append("product=jdk");
+ sb.append("&");
+ sb.append("locale=").append(Locale.getDefault().getLanguage());
+ return sb.toString();
+ }
+
+ /**
+ * Registers all products in the given product registry. If it fails
+ * to post the service tag registry, open the browser with the offline
+ * registration page.
+ *
+ * @param regData registration data to be posted to the Sun Connection
+ * for registration.
+ *
+ * @throws IOException if I/O error occurs in this operation
+ */
+ public static void register(RegistrationData regData) throws IOException {
+ // Gets the URL for SunConnection registration relay service
+ URL url = getRegistrationURL(regData.getRegistrationURN());
+
+ // Post the Product Registry to Sun Connection
+ boolean succeed = postRegistrationData(url, regData);
+ if (succeed) {
+ // service tags posted successfully
+ // now prompt for registration
+ openBrowser(url);
+ } else {
+ // open browser with the offline registration page
+ openOfflineRegisterPage();
+ }
+ }
+
+ /**
+ * Opens a browser for JDK product registration.
+ * @param url Registration Webapp URL
+ */
+ private static void openBrowser(URL url) throws IOException {
+ if (!BrowserSupport.isSupported()) {
+ if (Util.isVerbose()) {
+ System.out.println("Browser is not supported");
+ }
+ return;
+ }
+
+ try {
+ BrowserSupport.browse(url.toURI());
+ } catch (URISyntaxException ex) {
+ InternalError x = new InternalError("Error in registering: " + ex.getMessage());
+ x.initCause(ex);
+ throw x;
+ } catch (IllegalArgumentException ex) {
+ if (Util.isVerbose()) {
+ ex.printStackTrace();
+ }
+ } catch (UnsupportedOperationException ex) {
+ // ignore if not supported
+ if (Util.isVerbose()) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * POST service tag registry to Sun Connection
+ * @param loc the URL of the webapp to handle the POST request
+ * @param streg the Service Tag registry
+ * @return true if posting succeeds; otherwise, false.
+ */
+ private static boolean postRegistrationData(URL url,
+ RegistrationData registration) {
+ try {
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
+ con.setDoInput(true);
+ con.setDoOutput(true);
+ con.setUseCaches(false);
+ con.setAllowUserInteraction(false);
+
+ // default 10 seconds timeout
+ String timeout = System.getProperty(SVCTAG_CONNECTION_TIMEOUT, "10");
+ con.setConnectTimeout(Util.getIntValue(timeout) * 1000);
+
+ if (Util.isVerbose()) {
+ System.out.println("Connecting to post registration data at " + url);
+ }
+
+ con.setRequestMethod("POST");
+ con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\"");
+ con.connect();
+
+ OutputStream out = con.getOutputStream();
+ registration.storeToXML(out);
+ out.flush();
+ out.close();
+
+ int returnCode = con.getResponseCode();
+ if (Util.isVerbose()) {
+ System.out.println("POST return status = " + returnCode);
+ printReturnData(con, returnCode);
+ }
+ return (returnCode == HttpURLConnection.HTTP_OK);
+ } catch (MalformedURLException me) {
+ // should never reach here
+ InternalError x = new InternalError("Error in registering: " + me.getMessage());
+ x.initCause(me);
+ throw x;
+ } catch (Exception ioe) {
+ // SocketTimeoutException, IOException or UnknownHostException
+ if (Util.isVerbose()) {
+ ioe.printStackTrace();
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Opens the offline registratioin page in the browser.
+ *
+ */
+ private static void openOfflineRegisterPage()
+ throws IOException {
+ if (!BrowserSupport.isSupported()) {
+ if (Util.isVerbose()) {
+ System.out.println("Browser is not supported");
+ }
+ return;
+ }
+
+ File registerPage = Installer.getRegistrationHtmlPage();
+ try {
+ BrowserSupport.browse(registerPage.toURI());
+ } catch (FileNotFoundException ex) {
+ // should never reach here
+ InternalError x =
+ new InternalError("Error in launching " + registerPage + ": " + ex.getMessage());
+ x.initCause(ex);
+ throw x;
+ } catch (IllegalArgumentException ex) {
+ if (Util.isVerbose()) {
+ ex.printStackTrace();
+ }
+ } catch (UnsupportedOperationException ex) {
+ // ignore if not supported
+ if (Util.isVerbose()) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private static void printReturnData(HttpURLConnection con, int returnCode)
+ throws IOException {
+ BufferedReader reader = null;
+ try {
+ if (returnCode < 400) {
+ reader = new BufferedReader(
+ new InputStreamReader(con.getInputStream()));
+ } else {
+ reader = new BufferedReader(
+ new InputStreamReader(con.getErrorStream()));
+ }
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line).append("\n");
+ }
+ System.out.println("Response is : ");
+ System.out.println(sb.toString());
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java b/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java
new file mode 100644
index 000000000000..ca0a16858670
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java
@@ -0,0 +1,376 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import static com.sun.star.servicetag.Util.*;
+import static com.sun.star.servicetag.RegistrationDocument.*;
+
+/**
+ * Class containing additional methods that are not yet
+ * in the JDK Registry class. Note that all methods in this class
+ * will be superceeded by the JDK classes.
+ */
+public class SysnetRegistryHelper {
+
+ private static final String STCLIENT_SOLARIS = "/usr/bin/stclient";
+ private static final String STCLIENT_LINUX = "/opt/sun/servicetag/bin/stclient";
+ // stclient exit value (see sthelper.h)
+ private static final int ST_ERR_NOT_AUTH = 245;
+ private static final int ST_ERR_REC_NOT_FOUND = 225;
+
+ // The stclient output has to be an exported interface
+ private static final String INSTANCE_URN_OPEN_ELEMENT = "<instance_urn>";
+ private static final String INSTANCE_URN_CLOSE_ELEMENT = "</instance_urn>";
+ private static final String REGISTRY_URN = "<registry urn=\"";
+ private static final String INSTANCE_URN_DESC = "Product instance URN=";
+ private static boolean initialized = false;
+ private static boolean supportsHelperClass = true; // default
+ private static File stclient = null;
+ private static String stclientPath = null;
+
+ // System properties for testing
+ private static String SVCTAG_STCLIENT_CMD = "servicetag.stclient.cmd";
+ private static String SVCTAG_STHELPER_SUPPORTED = "servicetag.sthelper.supported";
+
+ private synchronized static String getSTclient() {
+ if (!initialized) {
+ // the system property always overrides the default setting
+ if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) {
+ supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED);
+ }
+
+ // This is only used for testing
+ stclientPath = System.getProperty(SVCTAG_STCLIENT_CMD);
+ if (stclientPath != null) {
+ return stclientPath;
+ }
+
+ // Initialization to determine the platform's stclient pathname
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS")) {
+ stclient = new File(STCLIENT_SOLARIS);
+ } else if (os.equals("Linux")) {
+ stclient = new File(STCLIENT_LINUX);
+ } else if (os.startsWith("Windows")) {
+ stclient = getWindowsStClientFile();
+ } else {
+ if (isVerbose()) {
+ System.out.println("Running on non-Sun JDK");
+ }
+ }
+ initialized = true;
+ }
+
+ // com.sun.servicetag package has to be compiled with JDK 5 as well
+ // JDK 5 doesn't support the File.canExecute() method.
+ // Risk not checking isExecute() for the stclient command is very low.
+
+ if (stclientPath == null && stclient != null && stclient.exists()) {
+ stclientPath = stclient.getAbsolutePath();
+ }
+ return stclientPath;
+ }
+
+ private static List<String> getCommandList() {
+ // Set up the arguments to call stclient
+ List<String> command = new ArrayList<String>();
+ if (System.getProperty(SVCTAG_STCLIENT_CMD) != null) {
+ // This is for jtreg testing use. This will be set to something
+ // like:
+ // $JAVA_HOME/bin/java -cp $TEST_DIR \
+ // -Dstclient.registry.path=$TEST_DIR/registry.xml \
+ // SvcTagClient
+ //
+ // On Windows, the JAVA_HOME and TEST_DIR path could contain
+ // space e.g. c:\Program Files\Java\jdk1.6.0_05\bin\java.
+ // The SVCTAG_STCLIENT_CMD must be set with a list of
+ // space-separated parameters. If a parameter contains spaces,
+ // it must be quoted with '"'.
+
+ String cmd = getSTclient();
+ int len = cmd.length();
+ int i = 0;
+ while (i < len) {
+ char separator = ' ';
+ if (cmd.charAt(i) == '"') {
+ separator = '"';
+ i++;
+ }
+ // look for the separator or matched the closing '"'
+ int j;
+ for (j = i+1; j < len; j++) {
+ if (cmd.charAt(j) == separator) {
+ break;
+ }
+ }
+
+ if (i == j-1) {
+ // add an empty parameter
+ command.add("\"\"");
+ } else {
+ // double quotes and space are not included
+ command.add(cmd.substring(i,j));
+ }
+
+ // skip spaces
+ for (i = j+1; i < len; i++) {
+ if (!Character.isSpaceChar(cmd.charAt(i))) {
+ break;
+ }
+ }
+ }
+ if (isVerbose()) {
+ System.out.println("Command list:");
+ for (String s : command) {
+ System.out.println(s);
+ }
+ }
+ } else {
+ command.add(getSTclient());
+ }
+ return command;
+ }
+
+ // Returns null if the service tag record not found;
+ // or throw UnauthorizedAccessException or IOException
+ // based on the exitValue.
+ private static ServiceTag checkReturnError(int exitValue,
+ String output,
+ ServiceTag st) throws IOException {
+ switch (exitValue) {
+ case ST_ERR_REC_NOT_FOUND:
+ return null;
+ case ST_ERR_NOT_AUTH:
+ if (st != null) {
+ throw new UnauthorizedAccessException(
+ "Not authorized to access " + st.getInstanceURN() +
+ " installer_uid=" + st.getInstallerUID());
+ } else {
+ throw new UnauthorizedAccessException(
+ "Not authorized:" + output);
+ }
+ default:
+ throw new IOException("stclient exits with error" +
+ " (" + exitValue + ")\n" + output);
+ }
+ }
+
+ /**
+ * Returns a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * in this registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * @return a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * in this registry; or {@code null} if not found.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ private static ServiceTag getServiceTag(String instanceURN) throws IOException {
+ if (instanceURN == null) {
+ throw new NullPointerException("instanceURN is null");
+ }
+
+ List<String> command = getCommandList();
+ command.add("-g");
+ command.add("-i");
+ command.add(instanceURN);
+
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+ if (isVerbose()) {
+ System.out.println("Output from stclient -g command:");
+ System.out.println(output);
+ }
+ if (p.exitValue() == 0) {
+ return parseServiceTag(output);
+ } else {
+ return checkReturnError(p.exitValue(), output, null);
+ }
+ }
+
+ private static ServiceTag parseServiceTag(String output) throws IOException {
+ BufferedReader in = null;
+ try {
+ Properties props = new Properties();
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ if ((line = line.trim()).length() > 0) {
+ String[] ss = line.trim().split("=", 2);
+ if (ss.length == 2) {
+ props.setProperty(ss[0].trim(), ss[1].trim());
+ } else {
+ props.setProperty(ss[0].trim(), "");
+ }
+ }
+ }
+
+ String urn = props.getProperty(ST_NODE_INSTANCE_URN);
+ String productName = props.getProperty(ST_NODE_PRODUCT_NAME);
+ String productVersion = props.getProperty(ST_NODE_PRODUCT_VERSION);
+ String productURN = props.getProperty(ST_NODE_PRODUCT_URN);
+ String productParent = props.getProperty(ST_NODE_PRODUCT_PARENT);
+ String productParentURN = props.getProperty(ST_NODE_PRODUCT_PARENT_URN);
+ String productDefinedInstanceID =
+ props.getProperty(ST_NODE_PRODUCT_DEFINED_INST_ID);
+ String productVendor = props.getProperty(ST_NODE_PRODUCT_VENDOR);
+ String platformArch = props.getProperty(ST_NODE_PLATFORM_ARCH);
+ String container = props.getProperty(ST_NODE_CONTAINER);
+ String source = props.getProperty(ST_NODE_SOURCE);
+ int installerUID =
+ Util.getIntValue(props.getProperty(ST_NODE_INSTALLER_UID));
+ Date timestamp =
+ Util.parseTimestamp(props.getProperty(ST_NODE_TIMESTAMP));
+
+ return new ServiceTag(urn,
+ productName,
+ productVersion,
+ productURN,
+ productParent,
+ productParentURN,
+ productDefinedInstanceID,
+ productVendor,
+ platformArch,
+ container,
+ source,
+ installerUID,
+ timestamp);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+
+ }
+
+ /**
+ * Returns the urn of this registry.
+ *
+ * @return a {@code String} for the urn of this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ // Once JDK makes this method available, we'll deprecate this method
+ // @deprecated Use the JDK version when available.
+ public static String getRegistryURN() throws IOException {
+ List<String> command = getCommandList();
+ command.add("-x");
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+
+ String registryURN = null;
+ if (p.exitValue() == 0) {
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ String s = line.trim();
+ if (s.indexOf(REGISTRY_URN) != -1) {
+ s = s.substring(s.indexOf(REGISTRY_URN)
+ + REGISTRY_URN.length());
+ if (s.indexOf("\"") != -1) {
+ s = s.substring(0, s.indexOf("\""));
+ registryURN = s;
+ break;
+ }
+ }
+ }
+ } else {
+ checkReturnError(p.exitValue(), output, null);
+ }
+ return registryURN;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+
+ /**
+ * Returns all the service tags in this registry.
+ *
+ * @return a {@code Set} of {@code ServiceTag} objects
+ * in this registry.
+ *
+ * @throws java.io.IOException if an I/O error occurs in this operation.
+ */
+ // Once JDK makes this method available, we'll deprecate this method
+ // @deprecated Use the JDK version when available.
+ public static Set<ServiceTag> getServiceTags() throws IOException {
+ List<String> command = getCommandList();
+ command.add("-x");
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+
+ Set<ServiceTag> instances = new HashSet<ServiceTag>();
+ if (p.exitValue() == 0) {
+ // parse the service tag output from stclient
+ in = new BufferedReader(new StringReader(output));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ String s = line.trim();
+ if (s.indexOf(INSTANCE_URN_OPEN_ELEMENT) != -1
+ && s.indexOf(INSTANCE_URN_CLOSE_ELEMENT) != -1) {
+ s = s.substring(s.indexOf(INSTANCE_URN_OPEN_ELEMENT)
+ + INSTANCE_URN_OPEN_ELEMENT.length(),
+ s.indexOf(INSTANCE_URN_CLOSE_ELEMENT));
+ try {
+ instances.add(getServiceTag(s));
+ } catch (Exception e) {
+ }
+ }
+ }
+ } else {
+ checkReturnError(p.exitValue(), output, null);
+ }
+ return instances;
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java
new file mode 100644
index 000000000000..76eaca37e39a
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java
@@ -0,0 +1,436 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+// The Service Tags team maintains the latest version of the implementation
+// for system environment data collection. JDK will include a copy of
+// the most recent released version for a JDK release. We rename
+// the package to com.sun.servicetag so that the Sun Connection
+// product always uses the latest version from the com.sun.scn.servicetags
+// package. JDK and users of the com.sun.servicetag API
+// (e.g. NetBeans and SunStudio) will use the version in JDK.
+
+import java.io.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * SystemEnvironment class collects the environment data with the
+ * best effort from the underlying platform.
+ */
+public class SystemEnvironment {
+ private String hostname;
+ private String hostId;
+ private String osName;
+ private String osVersion;
+ private String osArchitecture;
+ private String systemModel;
+ private String systemManufacturer;
+ private String cpuManufacturer;
+ private String serialNumber;
+ private String physmem;
+ private String sockets;
+ private String cores;
+ private String virtcpus;
+ private String cpuname;
+ private String clockrate;
+ private static SystemEnvironment sysEnv = null;
+
+ public static synchronized SystemEnvironment getSystemEnvironment() {
+ if (sysEnv == null) {
+ String os = System.getProperty("os.name");
+ if (os.equals("SunOS")) {
+ sysEnv = new SolarisSystemEnvironment();
+ } else if (os.equals("Linux")) {
+ sysEnv = new LinuxSystemEnvironment();
+ } else if (os.startsWith("Windows")) {
+ sysEnv = new WindowsSystemEnvironment();
+ } else {
+ sysEnv = new SystemEnvironment();
+ }
+ }
+ return sysEnv;
+ }
+
+ // package-private
+ SystemEnvironment() {
+ try {
+ this.hostname = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException ex) {
+ this.hostname = "Unknown host";
+ }
+ this.hostId = "";
+ this.osName = System.getProperty("os.name");
+ this.osVersion = System.getProperty("os.version");
+ this.osArchitecture = System.getProperty("os.arch");
+ this.systemModel = "";
+ this.systemManufacturer = "";
+ this.cpuManufacturer = "";
+ this.serialNumber = "";
+ this.physmem = "0";
+ this.sockets = "0";
+ this.cores = "0";
+ this.virtcpus = "0";
+ this.cpuname = "";
+ this.clockrate = "0";
+ }
+
+
+ /**
+ * Sets the hostname.
+ * @param hostname The hostname to set.
+ */
+ public void setHostname(String hostname) {
+ this.hostname = hostname;
+ }
+
+ /**
+ * Sets the OS name.
+ * @param osName The osName to set.
+ */
+ public void setOsName(String osName) {
+ this.osName = osName;
+ }
+
+ /**
+ * Sets the OS version.
+ * @param osVersion The osVersion to set.
+ */
+ public void setOsVersion(String osVersion) {
+ this.osVersion = osVersion;
+ }
+
+ /**
+ * Sets the OS architecture.
+ * @param osArchitecture The osArchitecture to set.
+ */
+ public void setOsArchitecture(String osArchitecture) {
+ this.osArchitecture = osArchitecture;
+ }
+
+ /**
+ * Sets the system model.
+ * @param systemModel The systemModel to set.
+ */
+ public void setSystemModel(String systemModel) {
+ this.systemModel = systemModel;
+ }
+
+ /**
+ * Sets the system manufacturer.
+ * @param systemManufacturer The systemManufacturer to set.
+ */
+ public void setSystemManufacturer(String systemManufacturer) {
+ this.systemManufacturer = systemManufacturer;
+ }
+
+ /**
+ * Sets the cpu manufacturer.
+ * @param cpuManufacturer The cpuManufacturer to set.
+ */
+ public void setCpuManufacturer(String cpuManufacturer) {
+ this.cpuManufacturer = cpuManufacturer;
+ }
+
+ /**
+ * Sets the serial number.
+ * @param serialNumber The serialNumber to set.
+ */
+ public void setSerialNumber(String serialNumber) {
+ this.serialNumber = serialNumber;
+ }
+
+ /**
+ * Sets the physmem
+ * @param physmem The physmem to set.
+ */
+ public void setPhysMem(String physmem) {
+ if (physmem.length() == 0)
+ physmem = "0";
+ this.physmem = physmem;
+ }
+
+ /**
+ * Sets the sockets
+ * @param sockets The sockets to set.
+ */
+ public void setSockets(String sockets) {
+ if (sockets.length() == 0)
+ sockets = "0";
+ this.sockets = sockets;
+ }
+
+ /**
+ * Sets the cores
+ * @param cores The cores to set.
+ */
+ public void setCores(String cores) {
+ if (cores.length() == 0)
+ cores ="0";
+ this.cores = cores;
+ }
+
+ /**
+ * Sets the virtcpus
+ * @param virtcpus The virtcpus to set.
+ */
+ public void setVirtCpus(String virtcpus) {
+ if (virtcpus.length() == 0)
+ virtcpus = "0";
+ this.virtcpus = virtcpus;
+ }
+
+ /**
+ * Sets the cpuname
+ * @param cpuname The cpuname to set.
+ */
+ public void setCpuName(String cpuname) {
+ this.cpuname = cpuname;
+ }
+
+ /**
+ * Sets the clockrate
+ * @param clockrate The clockrate to set.
+ */
+ public void setClockRate(String clockrate) {
+ if (clockrate.length() == 0)
+ this.clockrate = "0";
+ else
+ {
+ Float f = Float.parseFloat(clockrate);
+ Integer nClockrate = f.intValue();
+ this.clockrate = nClockrate.toString();
+ }
+ }
+
+ /**
+ * Sets the hostid. Truncates to a max length of 16 chars.
+ * @param hostId The hostid to set.
+ */
+ public void setHostId(String hostId) {
+ if (hostId == null || hostId.equals("null")) {
+ hostId = "";
+ }
+ if (hostId.length() > 16) {
+ hostId = hostId.substring(0,16);
+ }
+ this.hostId = hostId;
+ }
+
+ /**
+ * Returns the hostname.
+ * @return The hostname.
+ */
+ public String getHostname() {
+ return hostname;
+ }
+
+ /**
+ * Returns the osName.
+ * @return The osName.
+ */
+ public String getOsName() {
+ return osName;
+ }
+
+ /**
+ * Returns the osVersion.
+ * @return The osVersion.
+ */
+ public String getOsVersion() {
+ return osVersion;
+ }
+
+ /**
+ * Returns the osArchitecture.
+ * @return The osArchitecture.
+ */
+ public String getOsArchitecture() {
+ return osArchitecture;
+ }
+
+ /**
+ * Returns the systemModel.
+ * @return The systemModel.
+ */
+ public String getSystemModel() {
+ return systemModel;
+ }
+
+ /**
+ * Returns the systemManufacturer.
+ * @return The systemManufacturer.
+ */
+ public String getSystemManufacturer() {
+ return systemManufacturer;
+ }
+
+ /**
+ * Returns the serialNumber.
+ * @return The serialNumber.
+ */
+ public String getSerialNumber() {
+ return serialNumber;
+ }
+
+ public String getPhysMem() {
+ return physmem;
+ }
+
+ public String getSockets() {
+ return sockets;
+ }
+
+ public String getCores() {
+ return cores;
+ }
+
+ public String getVirtCpus() {
+ return virtcpus;
+ }
+
+ public String getCpuName() {
+ return cpuname;
+ }
+
+ public String getClockRate() {
+ return clockrate;
+ }
+
+ /**
+ * Returns the hostId.
+ * @return The hostId.
+ */
+ public String getHostId() {
+ return hostId;
+ }
+
+ /**
+ * Returns the cpuManufacturer.
+ * @return The cpuManufacturer.
+ */
+ public String getCpuManufacturer() {
+ return cpuManufacturer;
+ }
+
+ protected String getCommandOutput(String... command) {
+ StringBuilder sb = new StringBuilder();
+ BufferedReader br = null;
+ Process p = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ p = pb.start();
+ p.waitFor();
+
+ if (p.exitValue() == 0) {
+ br = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ line = line.trim();
+ if (line.length() > 0) {
+ if (sb.length() > 0) {
+ sb.append("\n");
+ }
+ sb.append(line);
+ }
+ }
+ }
+ return sb.toString();
+ } catch (InterruptedException ie) {
+ // in case the command hangs
+ if (p != null) {
+ p.destroy();
+ }
+ return "";
+ } catch (Exception e) {
+ // ignore exception
+ return "";
+ } finally {
+ if (p != null) {
+ try {
+ p.getErrorStream().close();
+ } catch (IOException e) {
+ // ignore
+ }
+ try {
+ p.getInputStream().close();
+ } catch (IOException e) {
+ // ignore
+ }
+ try {
+ p.getOutputStream().close();
+ } catch (IOException e) {
+ // ignore
+ }
+ p = null;
+ }
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ protected String getFileContent(String filename) {
+ File f = new File(filename);
+ if (!f.exists()) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new FileReader(f));
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ line = line.trim();
+ if (line.length() > 0) {
+ if (sb.length() > 0) {
+ sb.append("\n");
+ }
+ sb.append(line);
+ }
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ // ignore exception
+ return "";
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java b/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java
new file mode 100644
index 000000000000..898fb614c267
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+/**
+ * Thrown if the user is not authorized to
+ * {@link Registry#updateServiceTag update} or
+ * {@link Registry#removeServiceTag remove}
+ * a service tag from a {@link Registry}.
+ */
+public class UnauthorizedAccessException extends RuntimeException {
+
+ /**
+ * Constructs an <code>UnauthorizedAccessException</code> object
+ * without detail message.
+ */
+ public UnauthorizedAccessException() {
+ }
+
+
+ /**
+ * Constructs an <code>UnauthorizedAccessException</code> object
+ * with the specified detail message.
+ *
+ * @param msg the detail message.
+ */
+ public UnauthorizedAccessException(String msg) {
+ super(msg);
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/Util.java b/desktop/source/registration/com/sun/star/servicetag/Util.java
new file mode 100644
index 000000000000..1f54775e7d3c
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/Util.java
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+import java.io.*;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+// Utility class for com.sun.servicetag package
+class Util {
+ private static boolean verbose = (System.getProperty("servicetag.verbose") != null);
+ private static String jrepath = null;
+
+ // for debugging and tracing
+ static boolean isVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Gets the pathname of JRE in the running platform
+ * This can be a JDK or JRE.
+ */
+ static synchronized String getJrePath() {
+ if (jrepath == null) {
+ // Determine the JRE path by checking the existence of
+ // <HOME>/jre/lib and <HOME>/lib.
+ String javaHome = System.getProperty("java.home");
+ jrepath = javaHome + File.separator + "jre";
+ File f = new File(jrepath, "lib");
+ if (!f.exists()) {
+ // java.home usually points to the JRE path
+ jrepath = javaHome;
+ }
+ }
+ return jrepath;
+ }
+
+ /**
+ * Tests if the running platform is a JDK.
+ */
+ static boolean isJdk() {
+ // <HOME>/jre exists which implies it's a JDK
+ return getJrePath().endsWith(File.separator + "jre");
+ }
+
+ /**
+ * Generates the URN string of "urn:st" namespace
+ */
+ static String generateURN() {
+ return "urn:st:" + UUID.randomUUID().toString();
+ }
+
+ static int getIntValue(String value) {
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("\"" + value + "\"" +
+ " expected to be an integer");
+ }
+ }
+
+ /**
+ * Formats the Date into a timestamp string in YYYY-MM-dd HH:mm:ss GMT.
+ * @param timestamp Date
+ * @return a string representation of the timestamp
+ * in the YYYY-MM-dd HH:mm:ss GMT format.
+ */
+ static String formatTimestamp(Date timestamp) {
+ if (timestamp == null) {
+ return "[No timestamp]";
+ }
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+ df.setTimeZone(TimeZone.getTimeZone("GMT"));
+ return df.format(timestamp);
+ }
+
+ /**
+ * Parses a timestamp string in YYYY-MM-dd HH:mm:ss GMT format.
+ * @param timestamp Timestamp in the YYYY-MM-dd HH:mm:ss GMT format.
+ * @return Date
+ */
+ static Date parseTimestamp(String timestamp) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+ df.setTimeZone(TimeZone.getTimeZone("GMT"));
+ try {
+ return df.parse(timestamp);
+ } catch (ParseException e) {
+ // should not reach here
+ e.printStackTrace();
+ return new Date();
+ }
+ }
+
+ static String commandOutput(Process p) throws IOException {
+ Reader r = null;
+ Reader err = null;
+ try {
+ r = new InputStreamReader(p.getInputStream());
+ err = new InputStreamReader(p.getErrorStream());
+ String output = commandOutput(r);
+ String errorMsg = commandOutput(err);
+ p.waitFor();
+ return output + errorMsg.trim();
+ } catch (InterruptedException e) {
+ if (isVerbose()) {
+ e.printStackTrace();
+ }
+ return e.getMessage();
+ } finally {
+ if (r != null) {
+ r.close();
+ }
+ if (err != null) {
+ err.close();
+ }
+ }
+ }
+
+ static String commandOutput(Reader r) throws IOException {
+ StringBuilder sb = new StringBuilder();
+ int c;
+ while ((c = r.read()) > 0) {
+ if (c != '\r') {
+ sb.append((char) c);
+ }
+ }
+ return sb.toString();
+ }
+
+ static int getJdkVersion() {
+ parseVersion();
+ return jdkVersion;
+ }
+
+ static int getUpdateVersion() {
+ parseVersion();
+ return jdkUpdate;
+ }
+
+ private static int jdkVersion = 0;
+ private static int jdkUpdate = 0;
+ private static synchronized void parseVersion() {
+ if (jdkVersion > 0) {
+ return;
+ }
+
+ // parse java.runtime.version
+ // valid format of the version string is:
+ // n.n.n[_uu[c]][-<identifer>]-bxx
+ String cs = System.getProperty("java.runtime.version");
+ if (cs.length() >= 5 &&
+ Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' &&
+ Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' &&
+ Character.isDigit(cs.charAt(4))) {
+ jdkVersion = Character.digit(cs.charAt(2), 10);
+ cs = cs.substring(5, cs.length());
+ if (cs.charAt(0) == '_' && cs.length() >= 3 &&
+ Character.isDigit(cs.charAt(1)) &&
+ Character.isDigit(cs.charAt(2))) {
+ int nextChar = 3;
+ try {
+ String uu = cs.substring(1, 3);
+ jdkUpdate = Integer.valueOf(uu).intValue();
+ } catch (NumberFormatException e) {
+ // not conforming to the naming convention
+ return;
+ }
+ }
+ } else {
+ throw new InternalError("Invalid java.runtime.version" + cs);
+ }
+ }
+
+ /**
+ * Returns this java string as a null-terminated byte array
+ */
+ private static byte[] stringToByteArray(String str) {
+ return (str + "\u0000").getBytes();
+ }
+
+ /**
+ * Converts a null-terminated byte array to java string
+ */
+ private static String byteArrayToString(byte[] array) {
+ return new String(array, 0, array.length -1);
+ }
+
+ /**
+ * Gets the stclient path using a well known location from
+ * the Windows platform Registry, otherwise it will return null.
+ */
+ static File getWindowsStClientFile() {
+ File out = null;
+ String regKey = "software\\microsoft\\windows\\currentversion\\app paths\\stclient.exe";
+ String keyName = "" ; // use the default key
+ String path = getRegistryKey(regKey, keyName);
+
+ if (path != null && (new File(path)).exists()) {
+ out = new File(path);
+ }
+ if (isVerbose()) {
+ System.out.println("stclient=" + out);
+ }
+ return out;
+ }
+
+ /**
+ * This uses reflection to access a private java windows registry
+ * interface, any changes to that Class must be appropriately adjusted.
+ * Returns a null if unsuccessful.
+ */
+ private static String getRegistryKey(String regKey, String keyName) {
+ String out = null;
+ try {
+ Class<?> clazz = Class.forName("java.util.prefs.WindowsPreferences");
+
+ // Get the registry methods
+ Method winRegOpenKeyM = clazz.getDeclaredMethod("WindowsRegOpenKey",
+ int.class, byte[].class, int.class);
+ winRegOpenKeyM.setAccessible(true);
+
+ Method winRegCloseKeyM = clazz.getDeclaredMethod("WindowsRegCloseKey",
+ int.class);
+ winRegCloseKeyM.setAccessible(true);
+
+ Method winRegQueryValueM = clazz.getDeclaredMethod("WindowsRegQueryValueEx",
+ int.class, byte[].class);
+ winRegQueryValueM.setAccessible(true);
+
+ // Get all the constants we need
+ int HKLM = getValueFromStaticField("HKEY_LOCAL_MACHINE", clazz);
+ int KEY_READ = getValueFromStaticField("KEY_READ", clazz);
+ int ERROR_CODE = getValueFromStaticField("ERROR_CODE", clazz);
+ int NATIVE_HANDLE = getValueFromStaticField("NATIVE_HANDLE", clazz);
+ int ERROR_SUCCESS = getValueFromStaticField("ERROR_SUCCESS", clazz);
+
+ // Convert keys
+ byte[] reg = stringToByteArray(regKey);
+ byte[] key = stringToByteArray(keyName);
+
+ // Open the registry
+ int[] result = (int[]) winRegOpenKeyM.invoke(null, HKLM, reg, KEY_READ);
+
+ if (result[ERROR_CODE] == ERROR_SUCCESS) {
+ byte[] stvalue = (byte[]) winRegQueryValueM.invoke(null,
+ result[NATIVE_HANDLE], key);
+ out = byteArrayToString(stvalue);
+ winRegCloseKeyM.invoke(null, result[NATIVE_HANDLE]);
+ }
+ } catch (Exception ex) {
+ if (isVerbose()) {
+ ex.printStackTrace();
+ }
+ }
+ return out;
+ }
+
+ private static int getValueFromStaticField(String fldName, Class<?> klass) throws Exception {
+ Field f = klass.getDeclaredField(fldName);
+ f.setAccessible(true);
+ return f.getInt(null);
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java
new file mode 100644
index 000000000000..3aa799e16d5e
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.servicetag;
+
+// The Service Tags team maintains the latest version of the implementation
+// for system environment data collection. JDK will include a copy of
+// the most recent released version for a JDK release. We rename
+// the package to com.sun.servicetag so that the Sun Connection
+// product always uses the latest version from the com.sun.scn.servicetags
+// package. JDK and users of the com.sun.servicetag API
+// (e.g. NetBeans and SunStudio) will use the version in JDK.
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Windows implementation of the SystemEnvironment class.
+ */
+class WindowsSystemEnvironment extends SystemEnvironment {
+ WindowsSystemEnvironment() {
+ super();
+
+ // run a call to make sure things are initialized
+ // ignore the first call result as the system may
+ // give inconsistent data on the first invocation ever
+ getWmicResult("computersystem", "get", "model");
+
+ setSystemModel(getWmicResult("computersystem", "get", "model"));
+ setSystemManufacturer(getWmicResult("computersystem", "get", "manufacturer"));
+ setSerialNumber(getWmicResult("bios", "get", "serialnumber"));
+
+ String cpuMfr = getWmicResult("cpu", "get", "manufacturer");
+ // this isn't as good an option, but if we couldn't get anything
+ // from wmic, try the processor_identifier
+ if (cpuMfr.length() == 0) {
+ String procId = System.getenv("processor_identifer");
+ if (procId != null) {
+ String[] s = procId.split(",");
+ cpuMfr = s[s.length - 1].trim();
+ }
+ }
+ setCpuManufacturer(cpuMfr);
+
+ setSockets(getWindowsSockets());
+ setCores(getWindowsCores());
+ setVirtCpus(getWindowsVirtCpus());
+ setPhysMem(getWindowsPhysMem());
+ setCpuName(getWmicResult("cpu", "get", "Name"));
+ setClockRate(getWmicResult("cpu", "get", "MaxClockSpeed"));
+
+ // try to remove the temp file that gets created from running wmic cmds
+ try {
+ // look in the current working directory
+ File f = new File("TempWmicBatchFile.bat");
+ if (f.exists()) {
+ f.delete();
+ }
+ } catch (Exception e) {
+ // ignore the exception
+ }
+ }
+
+ private String getWindowsVirtCpus() {
+ String res = getWmicResult("cpu", "get", "NumberOfLogicalProcessors");
+ if (res == null || res.equals("")) {
+ res = "1";
+ }
+ return res;
+ }
+
+ private String getWindowsCores() {
+ String res = getWmicResult("cpu", "get", "NumberOfCores");
+ if (res == null || res.equals("")) {
+ res = "1";
+ }
+ return res;
+ }
+
+ private String getWindowsSockets() {
+ String res = getFullWmicResult("cpu", "get", "DeviceID");
+ Set<String> set = new HashSet<String>();
+ for (String line : res.split("\n")) {
+ line = line.trim();
+ if (line.equals("")) {
+ continue;
+ }
+ set.add(line);
+ }
+ if (set.size() == 0) {
+ return "1";
+ }
+ return "" + set.size();
+ }
+
+ private String getWindowsPhysMem() {
+ String mem = getWmicResult("computersystem", "get", "TotalPhysicalMemory");
+ long l = Long.parseLong(mem);
+ return "" + ((long) (l / (1024*1024)));
+ }
+
+
+ /**
+ * This method invokes wmic outside of the normal environment
+ * collection routines.
+ *
+ * An initial call to wmic can be costly in terms of time.
+ *
+ * <code>
+ * Details of why the first call is costly can be found at:
+ *
+ * http://support.microsoft.com/kb/290216/en-us
+ *
+ * "When you run the Wmic.exe utility for the first time, the utility
+ * compiles its .mof files into the repository. To save time during
+ * Windows installation, this operation takes place as necessary."
+ * </code>
+ */
+ private String getWmicResult(String alias, String verb, String property) {
+ String res = "";
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "WMIC", alias, verb, property);
+ Process p = pb.start();
+ // need this for executing windows commands (at least
+ // needed for executing wmic command)
+ BufferedWriter bw = new BufferedWriter(
+ new OutputStreamWriter(p.getOutputStream()));
+ bw.write(13);
+ bw.flush();
+ bw.close();
+
+ p.waitFor();
+ if (p.exitValue() == 0) {
+ in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ line = line.trim();
+ if (line.length() == 0) {
+ continue;
+ }
+ res = line;
+ }
+ // return the *last* line read
+ return res;
+ }
+
+ } catch (Exception e) {
+ // ignore the exception
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ return res.trim();
+ }
+
+ private String getFullWmicResult(String alias, String verb, String property) {
+ String res = "";
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "WMIC", alias, verb, property);
+ Process p = pb.start();
+ // need this for executing windows commands (at least
+ // needed for executing wmic command)
+ BufferedWriter bw = new BufferedWriter(
+ new OutputStreamWriter(p.getOutputStream()));
+ bw.write(13);
+ bw.flush();
+ bw.close();
+
+ p.waitFor();
+ if (p.exitValue() == 0) {
+ in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ line = line.trim();
+ if (line.length() == 0) {
+ continue;
+ }
+ if (line.toLowerCase().indexOf(property.toLowerCase()) != -1) {
+ continue;
+ }
+ res += line + "\n";
+ }
+ }
+
+ } catch (Exception e) {
+ // ignore the exception
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ return res;
+ }
+}
diff --git a/desktop/source/registration/com/sun/star/servicetag/makefile.mk b/desktop/source/registration/com/sun/star/servicetag/makefile.mk
new file mode 100644
index 000000000000..784964652950
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/makefile.mk
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJNAME = setup_native
+PRJ = ..$/..$/..$/..$/..$/..
+TARGET = servicetag
+PACKAGE = com$/sun$/star$/servicetag
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(ENABLE_SVCTAGS)" == "YES"
+
+JARFILES = jurt.jar unoil.jar ridl.jar
+JAVAFILES = \
+ BrowserSupport.java \
+ Installer.java \
+ LinuxSystemEnvironment.java \
+ RegistrationData.java \
+ RegistrationDocument.java \
+ Registry.java \
+ ServiceTag.java \
+ SolarisServiceTag.java \
+ SolarisSystemEnvironment.java \
+ SunConnection.java \
+ SysnetRegistryHelper.java \
+ SystemEnvironment.java \
+ UnauthorizedAccessException.java \
+ Util.java \
+ WindowsSystemEnvironment.java
+
+JAVACLASSFILES= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
+
+JARTARGET = $(TARGET).jar
+JARCOMPRESS = TRUE
+JARCLASSDIRS = $(PACKAGE)
+
+JAVARES= $(CLASSDIR)$/$(PACKAGE)$/resources$/product_registration.xsd
+
+.ENDIF # "$(ENABLE_SVCTAGS)" == "YES"
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_SVCTAGS)" == "YES"
+ALLTAR: $(JAVARES)
+
+$(JAVARES) : $$(@:d:d:f)$/$$(@:f)
+ $(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+
+.ENDIF # "$(ENABLE_SVCTAGS)" == "YES"
diff --git a/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd b/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd
new file mode 100644
index 000000000000..6681a563a01e
--- /dev/null
+++ b/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<xs:element name="registration_data">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="environment"
+ minOccurs="1"
+ maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="hostname"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="hostId"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osName"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osVersion"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osArchitecture"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="systemModel"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="systemManufacturer"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="cpuManufacturer"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="serialNumber"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="physmem"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element name="cpuinfo"
+ minOccurs='0'
+ maxOccurs='1'>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="sockets"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element ref="cores"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element ref="virtcpus"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element ref="name"
+ minOccurs='0'
+ maxOccurs='1'/>
+ <xs:element ref="clockrate"
+ minOccurs='0'
+ maxOccurs='1'/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="registry"
+ minOccurs="1"
+ maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="service_tag"
+ minOccurs="0"
+ maxOccurs="1024">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="instance_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_name"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_version"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_parent_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_parent"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_defined_inst_id"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_vendor"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="platform_arch"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="timestamp"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="container"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="source"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="installer_uid"
+ minOccurs='1'
+ maxOccurs='1'/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="urn"
+ type="xs:string"
+ use="required"/>
+ <xs:attribute name="version"
+ type="xs:string"
+ use="required"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="version"
+ type="xs:string"
+ use="required"/>
+ </xs:complexType>
+</xs:element>
+
+ <!-- definition of simple elements -->
+ <xs:element name="hostname">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="hostId">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="16"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osName">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osVersion">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osArchitecture">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="systemModel">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="systemManufacturer">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="cpuManufacturer">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="serialNumber">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="instance_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_name">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_version">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_parent_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_parent">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_defined_inst_id">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_vendor">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="platform_arch">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="timestamp">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="24"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="container">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="source">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="installer_uid">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="physmem">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="sockets">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="cores">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="virtcpus">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="name">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="128"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="clockrate">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer"/>
+ </xs:simpleType>
+ </xs:element>
+
+</xs:schema>
diff --git a/desktop/source/so_comp/evaluation.cxx b/desktop/source/so_comp/evaluation.cxx
new file mode 100644
index 000000000000..4cbb38931d37
--- /dev/null
+++ b/desktop/source/so_comp/evaluation.cxx
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "evaluation.hxx"
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <uno/environment.h>
+#include <cppuhelper/factory.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/resid.hxx>
+#include "../app/desktop.hrc"
+
+
+using namespace rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+
+namespace desktop {
+
+static SOEvaluation* pSOEval=0;
+
+const char* SOEvaluation::interfaces[] =
+{
+ "com.sun.star.beans.XExactName",
+ "com.sun.star.beans.XMaterialHolder",
+ "com.sun.star.lang.XComponent",
+ "com.sun.star.lang.XServiceInfo",
+ NULL,
+};
+
+const char* SOEvaluation::implementationName = "com.sun.star.comp.desktop.Evaluation";
+const char* SOEvaluation::serviceName = "com.sun.star.office.Evaluation";
+
+OUString SOEvaluation::GetImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( implementationName));
+}
+
+Sequence< OUString > SOEvaluation::GetSupportedServiceNames()
+{
+ sal_Int32 nSize = (sizeof( interfaces ) / sizeof( const char *)) - 1;
+ Sequence< OUString > aResult( nSize );
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ aResult[i] = OUString::createFromAscii( interfaces[i] );
+ return aResult;
+}
+
+Reference< XInterface > SAL_CALL SOEvaluation::CreateInstance(
+ const Reference< XMultiServiceFactory >& rSMgr )
+{
+ static osl::Mutex aMutex;
+ if ( pSOEval == 0 )
+ {
+ osl::MutexGuard guard( aMutex );
+ if ( pSOEval == 0 )
+ return (XComponent*) ( new SOEvaluation( rSMgr ) );
+ }
+ return (XComponent*)0;
+}
+
+SOEvaluation::SOEvaluation( const Reference< XMultiServiceFactory >& xFactory ) :
+ m_aListeners( m_aMutex ),
+ m_xServiceManager( xFactory )
+{
+}
+
+SOEvaluation::~SOEvaluation()
+{
+}
+
+// XComponent
+void SAL_CALL SOEvaluation::dispose() throw ( RuntimeException )
+{
+ EventObject aObject;
+ aObject.Source = (XComponent*)this;
+ m_aListeners.disposeAndClear( aObject );
+}
+
+void SAL_CALL SOEvaluation::addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException )
+{
+ m_aListeners.addInterface( aListener );
+}
+
+void SAL_CALL SOEvaluation::removeEventListener( const Reference< XEventListener > & aListener ) throw ( RuntimeException )
+{
+ m_aListeners.removeInterface( aListener );
+}
+
+// XExactName
+rtl::OUString SAL_CALL SOEvaluation::getExactName( const rtl::OUString& rApproximateName ) throw ( RuntimeException )
+{
+ // get the tabreg service for an evaluation version
+ // without this service office shouldn't run at all
+ OUString aTitle = rApproximateName;
+ OUString aEval;
+ sal_Bool bExpired = sal_True;
+ Reference < XMaterialHolder > xHolder( m_xServiceManager->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.tab.tabreg" ) ) ), UNO_QUERY );
+ if ( xHolder.is() )
+ {
+ // get a sequence of strings for the defined locales
+ // a registered version doesn't provide data
+ bExpired = sal_False;
+ Any aData = xHolder->getMaterial();
+ Sequence < NamedValue > aSeq;
+ if ( aData >>= aSeq )
+ {
+ // this is an evaluation version, because it provides "material"
+ bExpired = sal_True;
+ for (int i=0; i<aSeq.getLength(); i++ )
+ {
+ NamedValue& rValue = aSeq[i];
+ if ( rValue.Name.equalsAscii("expired") )
+ rValue.Value >>= bExpired;
+ else if (rValue.Name.equalsAscii("title") )
+ rValue.Value >>= aEval;
+ }
+ // append eval string to title
+ aTitle += OUString::createFromAscii(" ") + aEval;
+ if ( bExpired )
+ throw RuntimeException();
+ }
+ }
+
+ return aTitle;
+}
+
+// XMaterialHolder
+Any SAL_CALL SOEvaluation::getMaterial() throw( RuntimeException )
+{
+ // Time bomb implementation. Return empty Any to do nothing or
+ // provide a com::sun::star::util::Date with the time bomb date.
+ Any a;
+
+ // change here to force recompile 00002
+#ifdef TIMEBOMB
+ // Code for extracting/providing time bomb date!
+ int nDay = TIMEBOMB % 100;
+ int nMonth = ( TIMEBOMB % 10000 ) / 100;
+ int nYear = TIMEBOMB / 10000;
+ com::sun::star::util::Date aDate( nDay, nMonth, nYear );
+ a <<= aDate;
+#endif
+ return a;
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL SOEvaluation::getImplementationName()
+throw ( RuntimeException )
+{
+ return SOEvaluation::GetImplementationName();
+}
+
+sal_Bool SAL_CALL SOEvaluation::supportsService( const ::rtl::OUString& rServiceName )
+throw ( RuntimeException )
+{
+ sal_Int32 nSize = (sizeof( interfaces ) / sizeof( const char *))-1;
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ if ( rServiceName.equalsAscii( interfaces[i] ))
+ return sal_True;
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL SOEvaluation::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ return SOEvaluation::GetSupportedServiceNames();
+}
+
+}
diff --git a/desktop/source/so_comp/evaluation.hxx b/desktop/source/so_comp/evaluation.hxx
new file mode 100644
index 000000000000..a1225029b297
--- /dev/null
+++ b/desktop/source/so_comp/evaluation.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+/* makefile.mk changed 20030409, LO */
+
+#ifndef _SOCOMP_EVALUATION_HXX_
+#define _SOCOMP_EVALUATION_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+
+namespace desktop {
+
+class SOEvaluation : public ::cppu::WeakImplHelper4< XExactName, XMaterialHolder, XComponent, XServiceInfo >
+{
+ ::osl::Mutex m_aMutex;
+ ::cppu::OInterfaceContainerHelper m_aListeners;
+ Reference< XMultiServiceFactory > m_xServiceManager;
+
+public:
+ SOEvaluation( const Reference < XMultiServiceFactory >& xFactory );
+ virtual ~SOEvaluation();
+
+ static Reference< XSingleServiceFactory > GetSOEvaluationFactory( Reference< XMultiServiceFactory > & xSMgr );
+ static ::rtl::OUString GetImplementationName();
+ static Sequence< rtl::OUString > GetSupportedServiceNames();
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw ( RuntimeException );
+ virtual void SAL_CALL addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException );
+ virtual void SAL_CALL removeEventListener(const Reference< XEventListener > & aListener) throw ( RuntimeException );
+
+ // XExactName
+ virtual rtl::OUString SAL_CALL getExactName( const rtl::OUString& rApproximateName ) throw ( RuntimeException );
+
+ // XMaterialHolder
+ virtual Any SAL_CALL getMaterial() throw ( RuntimeException );
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw ( RuntimeException );
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( RuntimeException );
+
+ static const char* interfaces[];
+ static const char* implementationName;
+ static const char* serviceName;
+ static Reference<XInterface> SAL_CALL CreateInstance(
+ const Reference< XMultiServiceFactory >&);
+
+
+
+};
+}
+#endif // _SOCOMP_EVALUATION_HXX_
diff --git a/desktop/source/so_comp/makefile.mk b/desktop/source/so_comp/makefile.mk
new file mode 100644
index 000000000000..590f99518c68
--- /dev/null
+++ b/desktop/source/so_comp/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=socomp
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Define time bomb date. Not active for OOo --------------------
+# --- Change something in evaluation.cxx!!! (e.g. line 313)
+# --- You must use the yyyymmdd format!!! --------------------------
+#CDEFS+=-DTIMEBOMB=20050930
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = $(SLO)$/evaluation.obj \
+ $(SLO)$/oemjob.obj \
+ $(SLO)$/services.obj
+
+SHL1DEPN= makefile.mk
+SHL1OBJS= $(SLOFILES)
+
+
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS= \
+ $(FWELIB) \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(SVTOOLLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/so_comp/oemjob.cxx b/desktop/source/so_comp/oemjob.cxx
new file mode 100644
index 000000000000..1b78da694ff7
--- /dev/null
+++ b/desktop/source/so_comp/oemjob.cxx
@@ -0,0 +1,280 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "oemjob.hxx"
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+#include <unotools/bootstrap.hxx>
+#include <tools/config.hxx>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+using namespace rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::util;
+
+namespace desktop{
+
+char const OEM_PRELOAD_SECTION[] = "Bootstrap";
+char const OEM_PRELOAD[] = "Preload";
+char const STR_TRUE[] = "1";
+char const STR_FALSE[] = "0";
+
+const char* OEMPreloadJob::interfaces[] =
+{
+ "com.sun.star.task.XJob",
+ NULL,
+};
+const char* OEMPreloadJob::implementationName = "com.sun.star.comp.desktop.OEMPreloadJob";
+const char* OEMPreloadJob::serviceName = "com.sun.star.office.OEMPreloadJob";
+
+OUString OEMPreloadJob::GetImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( implementationName));
+}
+
+Sequence< OUString > OEMPreloadJob::GetSupportedServiceNames()
+{
+ sal_Int32 nSize = (sizeof( interfaces ) / sizeof( const char *)) - 1;
+ Sequence< OUString > aResult( nSize );
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ aResult[i] = OUString::createFromAscii( interfaces[i] );
+ return aResult;
+}
+
+Reference< XInterface > SAL_CALL OEMPreloadJob::CreateInstance(
+ const Reference< XMultiServiceFactory >& rSMgr )
+{
+ static osl::Mutex aMutex;
+ osl::MutexGuard guard( aMutex );
+ return (XComponent*) ( new OEMPreloadJob( rSMgr ) );
+}
+
+OEMPreloadJob::OEMPreloadJob( const Reference< XMultiServiceFactory >& xFactory ) :
+ m_aListeners( m_aMutex ),
+ m_xServiceManager( xFactory )
+{
+}
+
+OEMPreloadJob::~OEMPreloadJob()
+{
+}
+
+// XComponent
+void SAL_CALL OEMPreloadJob::dispose() throw ( RuntimeException )
+{
+ EventObject aObject;
+ aObject.Source = (XComponent*)this;
+ m_aListeners.disposeAndClear( aObject );
+}
+
+void SAL_CALL OEMPreloadJob::addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException )
+{
+ m_aListeners.addInterface( aListener );
+}
+
+void SAL_CALL OEMPreloadJob::removeEventListener( const Reference< XEventListener > & aListener ) throw ( RuntimeException )
+{
+ m_aListeners.removeInterface( aListener );
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL OEMPreloadJob::getImplementationName()
+throw ( RuntimeException )
+{
+ return OEMPreloadJob::GetImplementationName();
+}
+
+sal_Bool SAL_CALL OEMPreloadJob::supportsService( const ::rtl::OUString& rServiceName )
+throw ( RuntimeException )
+{
+ sal_Int32 nSize = sizeof( interfaces ) / sizeof( const char *);
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ if ( rServiceName.equalsAscii( interfaces[i] ))
+ return sal_True;
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL OEMPreloadJob::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ return OEMPreloadJob::GetSupportedServiceNames();
+}
+
+// XJob
+Any SAL_CALL OEMPreloadJob::execute(const Sequence<NamedValue>&)
+throw ( RuntimeException )
+{
+ sal_Bool bCont = sal_False;
+ // are we an OEM version at all?
+ if (checkOEMPreloadFlag())
+ {
+ // create OEM preload service dialog
+ Reference <XExecutableDialog> xDialog( m_xServiceManager->createInstance(
+ OUString::createFromAscii("org.openoffice.comp.preload.OEMPreloadWizard")),
+ UNO_QUERY );
+ if ( xDialog.is() ){
+ // execute OEM preload dialog and check return value
+ if ( xDialog->execute() == ExecutableDialogResults::OK ) {
+ // user accepted.
+ // make sure the job does not get called again.
+ bCont = sal_True;
+ disableOEMPreloadFlag();
+ } else {
+ // user declined...
+ // terminate.
+ /*
+ Reference< XDesktop > xDesktop( m_xServiceManager->createInstance(
+ OUString::createFromAscii("com.sun.star.frame.Desktop")),
+ UNO_QUERY );
+ xDesktop->terminate();
+ */
+ /*
+ OUString aName;
+ OUString aEnvType;
+ Reference<XFrame> rFrame;
+ Reference<XModel> rModel;
+ Reference<XCloseable> rClose;
+ for (int i=0; i<args.getLength(); i++)
+ {
+ if (args[i].Name.equalsAscii("EnvType"))
+ args[i].Value >>= aEnvType;
+ else if (args[i].Name.equalsAscii("Frame")) {
+ args[i].Value >>= rFrame;
+ rClose = Reference<XCloseable>(rFrame, UNO_QUERY);
+ }
+ else if (args[i].Name.equalsAscii("Model")) {
+ args[i].Value >>= rModel;
+ rClose = Reference<XCloseable>(rModel, UNO_QUERY);
+ }
+ }
+ if (rClose.is()) rClose->close(sal_True);
+ */
+ bCont = sal_False;
+ }
+ }
+ } else {
+ // don't try again
+ bCont = sal_True;
+ }
+ /*
+ NamedValue nv;
+ nv.Name = OUString::createFromAscii("Deactivate");
+ nv.Value <<= bDeactivate;
+ Sequence<NamedValue> s(1);
+ s[0] = nv;
+ */
+ Any r;
+ r <<= bCont;
+ return r;
+}
+
+
+static sal_Bool existsURL( OUString const& _sURL )
+{
+ using namespace osl;
+ DirectoryItem aDirItem;
+
+ if (_sURL.getLength() != 0)
+ return ( DirectoryItem::get( _sURL, aDirItem ) == DirectoryItem::E_None );
+
+ return sal_False;
+}
+
+
+// locate soffice.ini/.rc file
+static OUString locateIniFile()
+{
+ OUString aUserDataPath;
+ OUString aSofficeIniFileURL;
+
+ // Retrieve the default file URL for the soffice.ini/rc
+ Bootstrap().getIniName( aSofficeIniFileURL );
+
+ if ( utl::Bootstrap::locateUserData( aUserDataPath ) == utl::Bootstrap::PATH_EXISTS )
+ {
+ const char CONFIG_DIR[] = "/config";
+
+ sal_Int32 nIndex = aSofficeIniFileURL.lastIndexOf( '/');
+ if ( nIndex > 0 )
+ {
+ OUString aUserSofficeIniFileURL;
+ OUStringBuffer aBuffer( aUserDataPath );
+ aBuffer.appendAscii( CONFIG_DIR );
+ aBuffer.append( aSofficeIniFileURL.copy( nIndex ));
+ aUserSofficeIniFileURL = aBuffer.makeStringAndClear();
+
+ if ( existsURL( aUserSofficeIniFileURL ))
+ return aUserSofficeIniFileURL;
+ }
+ }
+ // Fallback try to use the soffice.ini/rc from program folder
+ return aSofficeIniFileURL;
+}
+
+// check whether the OEMPreload flag was set in soffice.ini/.rc
+sal_Bool OEMPreloadJob::checkOEMPreloadFlag()
+{
+ OUString aSofficeIniFileURL;
+ aSofficeIniFileURL = locateIniFile();
+ Config aConfig(aSofficeIniFileURL);
+ aConfig.SetGroup( OEM_PRELOAD_SECTION );
+ ByteString sResult = aConfig.ReadKey( OEM_PRELOAD );
+ if ( sResult == STR_TRUE )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+void OEMPreloadJob::disableOEMPreloadFlag()
+{
+ OUString aSofficeIniFileURL = locateIniFile();
+ if ( aSofficeIniFileURL.getLength() > 0 )
+ {
+ Config aConfig(aSofficeIniFileURL);
+ aConfig.SetGroup( OEM_PRELOAD_SECTION );
+ aConfig.WriteKey( OEM_PRELOAD, STR_FALSE );
+ aConfig.Flush();
+ }
+}
+
+} // namespace desktop
diff --git a/desktop/source/so_comp/oemjob.hxx b/desktop/source/so_comp/oemjob.hxx
new file mode 100644
index 000000000000..16a111badab9
--- /dev/null
+++ b/desktop/source/so_comp/oemjob.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _SOCOMP_OEMJOB_HXX_
+#define _SOCOMP_OEMJOB_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::task;
+
+namespace desktop{
+
+class OEMPreloadJob : public ::cppu::WeakImplHelper3< XJob, XComponent, XServiceInfo >
+{
+
+private:
+ ::osl::Mutex m_aMutex;
+ ::cppu::OInterfaceContainerHelper m_aListeners;
+ Reference< XMultiServiceFactory > m_xServiceManager;
+
+ sal_Bool checkOEMPreloadFlag();
+ void disableOEMPreloadFlag();
+
+public:
+ OEMPreloadJob( const Reference < XMultiServiceFactory >& xFactory );
+ virtual ~OEMPreloadJob();
+
+ static ::rtl::OUString GetImplementationName();
+ static Sequence< rtl::OUString > GetSupportedServiceNames();
+
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw ( RuntimeException );
+ virtual void SAL_CALL addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException );
+ virtual void SAL_CALL removeEventListener(const Reference< XEventListener > & aListener) throw ( RuntimeException );
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw ( RuntimeException );
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( RuntimeException );
+
+ //XJob
+ virtual Any SAL_CALL execute(const Sequence<NamedValue>& args)throw ( RuntimeException );
+
+
+ static const char* interfaces[];
+ static const char* implementationName;
+ static const char* serviceName;
+ static Reference<XInterface> SAL_CALL CreateInstance(
+ const Reference< XMultiServiceFactory >&);
+
+
+};
+}
+
+#endif // _SOCOMP_OEMJOB_HXX_
diff --git a/desktop/source/so_comp/services.cxx b/desktop/source/so_comp/services.cxx
new file mode 100644
index 000000000000..d1a2b3139e91
--- /dev/null
+++ b/desktop/source/so_comp/services.cxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "evaluation.hxx"
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <uno/environment.h>
+#include <cppuhelper/factory.hxx>
+#include <unotools/configmgr.hxx>
+
+#include "oemjob.hxx"
+#include "evaluation.hxx"
+
+#include <string.h>
+
+using namespace rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+using namespace ::desktop;
+
+static const char* pServices[] =
+{
+ SOEvaluation::serviceName,
+ OEMPreloadJob::serviceName,
+ NULL
+};
+
+static const char* pImplementations[] =
+{
+ SOEvaluation::implementationName,
+ OEMPreloadJob::implementationName,
+ NULL
+};
+
+typedef Reference<XInterface>(* fProvider)(const Reference<XMultiServiceFactory>&);
+
+static const fProvider pInstanceProviders[] =
+{
+ SOEvaluation::CreateInstance,
+ OEMPreloadJob::CreateInstance,
+ NULL
+};
+
+
+static const char** pSupportedServices[] =
+{
+ SOEvaluation::interfaces,
+ OEMPreloadJob::interfaces,
+ NULL
+};
+
+static Sequence<OUString>
+getSupportedServiceNames(int p) {
+ const char **names = pSupportedServices[p];
+ Sequence<OUString> aSeq;
+ for(int i = 0; names[i] != NULL; i++) {
+ aSeq.realloc(i+1);
+ aSeq[i] = OUString::createFromAscii(names[i]);
+ }
+ return aSeq;
+}
+
+extern "C"
+{
+void SAL_CALL
+component_getImplementationEnvironment(
+ const sal_Char** ppEnvironmentTypeName,
+ uno_Environment**)
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+sal_Bool SAL_CALL
+component_writeInfo(
+ void* pServiceManager,
+ void* pRegistryKey)
+{
+ Reference<XMultiServiceFactory> xMan(
+ reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+ Reference<XRegistryKey> xKey(
+ reinterpret_cast< XRegistryKey* >( pRegistryKey ) ) ;
+
+ // iterate over service names and register them...
+ OUString aImpl;
+ const char* pServiceName = NULL;
+ const char* pImplName = NULL;
+ for (int i = 0; (pServices[i]!=NULL)&&(pImplementations[i]!=NULL); i++) {
+ pServiceName= pServices[i];
+ pImplName = pImplementations[i];
+ aImpl = OUString::createFromAscii("/")
+ + OUString::createFromAscii(pImplName)
+ + OUString::createFromAscii("/UNO/SERVICES");
+ Reference<XRegistryKey> xNewKey = xKey->createKey(aImpl);
+ xNewKey->createKey(OUString::createFromAscii(pServiceName));
+ }
+ return sal_True;
+}
+
+void* SAL_CALL
+component_getFactory(
+ const sal_Char* pImplementationName,
+ void* pServiceManager,
+ void*)
+{
+ // Set default return value for this operation - if it failed.
+ if ( pImplementationName && pServiceManager )
+ {
+ Reference< XSingleServiceFactory > xFactory;
+ Reference< XMultiServiceFactory > xServiceManager(
+ reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+
+ // search implementation
+ for (int i = 0; (pImplementations[i]!=NULL); i++) {
+ if ( strcmp(pImplementations[i], pImplementationName ) == 0 ) {
+ // found implementation
+ xFactory = Reference<XSingleServiceFactory>(cppu::createSingleFactory(
+ xServiceManager, OUString::createFromAscii(pImplementationName),
+ pInstanceProviders[i], getSupportedServiceNames(i)));
+ if ( xFactory.is() ) {
+ // Factory is valid - service was found.
+ xFactory->acquire();
+ return xFactory.get();
+ }
+ }
+ } // for()
+ }
+ // Return with result of this operation.
+ return NULL;
+}
+} // extern "C"
diff --git a/desktop/source/splash/firststart.cxx b/desktop/source/splash/firststart.cxx
new file mode 100755
index 000000000000..21a0a562269a
--- /dev/null
+++ b/desktop/source/splash/firststart.cxx
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "firststart.hxx"
+#include "../migration/wizard.hxx"
+#include <comphelper/sequenceashashmap.hxx>
+
+using namespace rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+
+namespace desktop{
+
+
+const char* FirstStart::interfaces[] =
+{
+ "com.sun.star.task.XJob",
+ NULL,
+};
+const char* FirstStart::implementationName = "com.sun.star.comp.desktop.FirstStart";
+const char* FirstStart::serviceName = "com.sun.star.task.Job";
+
+OUString FirstStart::GetImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( implementationName));
+}
+
+Sequence< OUString > FirstStart::GetSupportedServiceNames()
+{
+ sal_Int32 nSize = (sizeof( interfaces ) / sizeof( const char *)) - 1;
+ Sequence< OUString > aResult( nSize );
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ aResult[i] = OUString::createFromAscii( interfaces[i] );
+ return aResult;
+}
+
+Reference< XInterface > SAL_CALL FirstStart::CreateInstance(
+ const Reference< XMultiServiceFactory >& rSMgr )
+{
+ static osl::Mutex aMutex;
+ osl::MutexGuard guard( aMutex );
+ return (XComponent*) ( new FirstStart( rSMgr ) );
+}
+
+FirstStart::FirstStart( const Reference< XMultiServiceFactory >& xFactory ) :
+ m_aListeners( m_aMutex ),
+ m_xServiceManager( xFactory )
+{
+}
+
+FirstStart::~FirstStart()
+{
+}
+
+// XComponent
+void SAL_CALL FirstStart::dispose() throw ( RuntimeException )
+{
+ EventObject aObject;
+ aObject.Source = (XComponent*)this;
+ m_aListeners.disposeAndClear( aObject );
+}
+
+void SAL_CALL FirstStart::addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException )
+{
+ m_aListeners.addInterface( aListener );
+}
+
+void SAL_CALL FirstStart::removeEventListener( const Reference< XEventListener > & aListener ) throw ( RuntimeException )
+{
+ m_aListeners.removeInterface( aListener );
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL FirstStart::getImplementationName()
+throw ( RuntimeException )
+{
+ return FirstStart::GetImplementationName();
+}
+
+sal_Bool SAL_CALL FirstStart::supportsService( const ::rtl::OUString& rServiceName )
+throw ( RuntimeException )
+{
+ sal_Int32 nSize = sizeof( interfaces ) / sizeof( const char *);
+
+ for( sal_Int32 i = 0; i < nSize; i++ )
+ if ( rServiceName.equalsAscii( interfaces[i] ))
+ return sal_True;
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL FirstStart::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ return FirstStart::GetSupportedServiceNames();
+}
+
+// XJob
+Any SAL_CALL FirstStart::execute(const Sequence<NamedValue>& args)
+throw ( RuntimeException )
+{
+ static const ::rtl::OUString ARG_LICENSENEEDED( RTL_CONSTASCII_USTRINGPARAM( "LicenseNeedsAcceptance" ) );
+ static const ::rtl::OUString ARG_LICENSEPATH( RTL_CONSTASCII_USTRINGPARAM( "LicensePath" ) );
+
+ ::comphelper::SequenceAsHashMap lArgs(args);
+
+ sal_Bool bLicenseNeeded = lArgs.getUnpackedValueOrDefault( ARG_LICENSENEEDED, (sal_Bool)sal_True );
+ rtl::OUString aLicensePath = lArgs.getUnpackedValueOrDefault( ARG_LICENSEPATH, rtl::OUString() );
+
+ FirstStartWizard fsw( NULL, bLicenseNeeded && ( aLicensePath.getLength() > 0 ), aLicensePath );
+ return makeAny( (sal_Bool)fsw.Execute() );
+}
+
+// XJobExecutor
+void SAL_CALL FirstStart::trigger(const OUString&)
+throw ( RuntimeException )
+{
+ // trigger wizard with override, so it gets started regardless of
+ // configuration
+ Sequence<NamedValue> seq(1);
+ seq[0] = NamedValue(
+ OUString::createFromAscii("Override"),
+ makeAny(sal_True));
+ execute(seq);
+}
+
+
+} // namespace desktop
diff --git a/desktop/source/splash/firststart.hxx b/desktop/source/splash/firststart.hxx
new file mode 100755
index 000000000000..fe45833cfae7
--- /dev/null
+++ b/desktop/source/splash/firststart.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _SOCOMP_FIRSTSTART_HXX_
+#define _SOCOMP_FIRSTSTART_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::task;
+
+namespace desktop{
+
+class FirstStart : public ::cppu::WeakImplHelper4< XJob, XJobExecutor, XComponent, XServiceInfo >
+{
+
+private:
+ ::osl::Mutex m_aMutex;
+ ::cppu::OInterfaceContainerHelper m_aListeners;
+ Reference< XMultiServiceFactory > m_xServiceManager;
+
+public:
+ FirstStart( const Reference < XMultiServiceFactory >& xFactory );
+ virtual ~FirstStart();
+
+ static ::rtl::OUString GetImplementationName();
+ static Sequence< rtl::OUString > GetSupportedServiceNames();
+
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw ( RuntimeException );
+ virtual void SAL_CALL addEventListener( const Reference< XEventListener > & aListener) throw ( RuntimeException );
+ virtual void SAL_CALL removeEventListener(const Reference< XEventListener > & aListener) throw ( RuntimeException );
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw ( RuntimeException );
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( RuntimeException );
+
+ //XJob
+ virtual Any SAL_CALL execute(const Sequence<NamedValue>& args)throw ( RuntimeException );
+ //XJobExecutor
+ virtual void SAL_CALL trigger(const rtl::OUString& arg)throw ( RuntimeException );
+
+ static const char* interfaces[];
+ static const char* implementationName;
+ static const char* serviceName;
+ static Reference<XInterface> SAL_CALL CreateInstance(
+ const Reference< XMultiServiceFactory >&);
+
+
+};
+}
+
+#endif // _SOCOMP_FIRSTSTART_HXX_
diff --git a/desktop/source/splash/makefile.mk b/desktop/source/splash/makefile.mk
new file mode 100644
index 000000000000..89609687438c
--- /dev/null
+++ b/desktop/source/splash/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=spl
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = $(SLO)$/splash.obj \
+ $(SLO)$/firststart.obj \
+ $(SLO)$/services_spl.obj
+
+SHL1DEPN= makefile.mk
+SHL1OBJS= $(SLOFILES) \
+ $(SLO)$/pages.obj \
+ $(SLO)$/wizard.obj \
+ $(SLO)$/migration.obj \
+ $(SLO)$/cfgfilter.obj
+
+
+SHL1TARGET=$(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1STDLIBS= \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(SVTOOLLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(VOSLIB) \
+ $(SALLIB) \
+ $(SFXLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/splash.obj : $(INCCOM)$/introbmpnames.hxx
+
+.INCLUDE .IGNORE : $(MISC)$/intro_bmp_names.mk
+
+.IF "$(INTRO_BITMAPS:f)"!="$(LASTTIME_INTRO_BITMAPS)"
+DO_PHONY=.PHONY
+.ENDIF # "$(INTRO_BITMAPS:f)"!="$(LASTTIME_INTRO_BITMAPS)"
+
+$(INCCOM)$/introbmpnames.hxx $(DO_PHONY):
+ echo const char INTRO_BITMAP_STRINGLIST[]=$(EMQ)"$(INTRO_BITMAPS:f:t",")$(EMQ)"$(EMQ); > $@
+ echo LASTTIME_INTRO_BITMAPS=$(INTRO_BITMAPS:f) > $(MISC)$/intro_bmp_names.mk
diff --git a/desktop/source/splash/services_spl.cxx b/desktop/source/splash/services_spl.cxx
new file mode 100755
index 000000000000..349ec2ec0a78
--- /dev/null
+++ b/desktop/source/splash/services_spl.cxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <uno/environment.h>
+#include <cppuhelper/factory.hxx>
+#include <unotools/configmgr.hxx>
+
+#include "splash.hxx"
+#include "firststart.hxx"
+
+
+using namespace rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+using namespace ::desktop;
+
+static const char* pServices[] =
+{
+ SplashScreen::serviceName,
+ FirstStart::serviceName,
+ NULL
+};
+
+static const char* pImplementations[] =
+{
+ SplashScreen::implementationName,
+ FirstStart::implementationName,
+ NULL
+};
+
+typedef Reference<XInterface>(* fProvider)(const Reference<XMultiServiceFactory>&);
+
+static const fProvider pInstanceProviders[] =
+{
+ SplashScreen::getInstance,
+ FirstStart::CreateInstance,
+ NULL
+};
+
+
+static const char** pSupportedServices[] =
+{
+ SplashScreen::interfaces,
+ FirstStart::interfaces,
+ NULL
+};
+
+static Sequence<OUString>
+getSupportedServiceNames(int p) {
+ const char **names = pSupportedServices[p];
+ Sequence<OUString> aSeq;
+ for(int i = 0; names[i] != NULL; i++) {
+ aSeq.realloc(i+1);
+ aSeq[i] = OUString::createFromAscii(names[i]);
+ }
+ return aSeq;
+}
+
+extern "C"
+{
+void SAL_CALL
+component_getImplementationEnvironment(
+ const sal_Char** ppEnvironmentTypeName,
+ uno_Environment**)
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+sal_Bool SAL_CALL
+component_writeInfo(
+ void* pServiceManager,
+ void* pRegistryKey)
+{
+ Reference<XMultiServiceFactory> xMan(
+ reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+ Reference<XRegistryKey> xKey(
+ reinterpret_cast< XRegistryKey* >( pRegistryKey ) ) ;
+
+ // iterate over service names and register them...
+ OUString aImpl;
+ const char* pServiceName = NULL;
+ const char* pImplName = NULL;
+ for (int i = 0; (pServices[i]!=NULL)&&(pImplementations[i]!=NULL); i++) {
+ pServiceName= pServices[i];
+ pImplName = pImplementations[i];
+ aImpl = OUString::createFromAscii("/")
+ + OUString::createFromAscii(pImplName)
+ + OUString::createFromAscii("/UNO/SERVICES");
+ Reference<XRegistryKey> xNewKey = xKey->createKey(aImpl);
+ xNewKey->createKey(OUString::createFromAscii(pServiceName));
+ }
+ return sal_True;
+}
+
+void* SAL_CALL
+component_getFactory(
+ const sal_Char* pImplementationName,
+ void* pServiceManager,
+ void*)
+{
+ // Set default return value for this operation - if it failed.
+ if ( pImplementationName && pServiceManager )
+ {
+ Reference< XSingleServiceFactory > xFactory;
+ Reference< XMultiServiceFactory > xServiceManager(
+ reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+
+ // search implementation
+ for (int i = 0; (pImplementations[i]!=NULL); i++) {
+ if ( strcmp(pImplementations[i], pImplementationName ) == 0 ) {
+ // found implementation
+ xFactory = Reference<XSingleServiceFactory>(cppu::createSingleFactory(
+ xServiceManager, OUString::createFromAscii(pImplementationName),
+ pInstanceProviders[i], getSupportedServiceNames(i)));
+ if ( xFactory.is() ) {
+ // Factory is valid - service was found.
+ xFactory->acquire();
+ return xFactory.get();
+ }
+ }
+ } // for()
+ }
+ // Return with result of this operation.
+ return NULL;
+}
+} // extern "C"
diff --git a/desktop/source/splash/splash.cxx b/desktop/source/splash/splash.cxx
new file mode 100644
index 000000000000..c6a185b8e54d
--- /dev/null
+++ b/desktop/source/splash/splash.cxx
@@ -0,0 +1,715 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <introbmpnames.hxx>
+#include "splash.hxx"
+#include <stdio.h>
+#include <unotools/bootstrap.hxx>
+#include <vos/process.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <sfx2/sfx.hrc>
+#include <vcl/svapp.hxx>
+#include <vcl/salnativewidgets.hxx>
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <rtl/bootstrap.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/math.hxx>
+#include <vcl/graph.hxx>
+#include <svtools/filter.hxx>
+
+#define NOT_LOADED ((long)-1)
+
+using namespace ::rtl;
+using namespace ::com::sun::star::registry;
+
+namespace desktop
+{
+
+SplashScreen::SplashScreen(const Reference< XMultiServiceFactory >& rSMgr)
+ : IntroWindow()
+ , _vdev(*((IntroWindow*)this))
+ , _cProgressFrameColor(sal::static_int_cast< ColorData >(NOT_LOADED))
+ , _cProgressBarColor(sal::static_int_cast< ColorData >(NOT_LOADED))
+ , _bNativeProgress(true)
+ , _iMax(100)
+ , _iProgress(0)
+ , _eBitmapMode(BM_DEFAULTMODE)
+ , _bPaintBitmap(sal_True)
+ , _bPaintProgress(sal_False)
+ , _bShowLogo(sal_True)
+ , _bFullScreenSplash(sal_False)
+ , _bProgressEnd(sal_False)
+ , _tlx(NOT_LOADED)
+ , _tly(NOT_LOADED)
+ , _barwidth(NOT_LOADED)
+ , _barheight(NOT_LOADED)
+ , _barspace(2)
+ , _fXPos(-1.0)
+ , _fYPos(-1.0)
+ , _fWidth(-1.0)
+ , _fHeight(-1.0)
+ , _xoffset(12)
+ , _yoffset(18)
+{
+ _rFactory = rSMgr;
+
+ loadConfig();
+}
+
+SplashScreen::~SplashScreen()
+{
+ Application::RemoveEventListener(
+ LINK( this, SplashScreen, AppEventListenerHdl ) );
+ Hide();
+
+}
+
+void SAL_CALL SplashScreen::start(const OUString&, sal_Int32 nRange)
+ throw (RuntimeException)
+{
+ _iMax = nRange;
+ if (_bVisible) {
+ _bProgressEnd = sal_False;
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ ShowFullScreenMode( TRUE );
+ Show();
+ Paint(Rectangle());
+ Flush();
+ }
+}
+
+void SAL_CALL SplashScreen::end()
+ throw (RuntimeException)
+{
+ _iProgress = _iMax;
+ if (_bVisible )
+ {
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ EndFullScreenMode();
+ Hide();
+ }
+ _bProgressEnd = sal_True;
+}
+
+void SAL_CALL SplashScreen::reset()
+ throw (RuntimeException)
+{
+ _iProgress = 0;
+ if (_bVisible && !_bProgressEnd )
+ {
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ ShowFullScreenMode( TRUE );
+ Show();
+ updateStatus();
+ }
+}
+
+void SAL_CALL SplashScreen::setText(const OUString& rText)
+ throw (RuntimeException)
+{
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ if ( _sProgressText != rText )
+ {
+ _sProgressText = rText;
+
+ if (_bVisible && !_bProgressEnd)
+ {
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ ShowFullScreenMode( TRUE );
+ Show();
+ updateStatus();
+ }
+ }
+}
+
+void SAL_CALL SplashScreen::setValue(sal_Int32 nValue)
+ throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "::SplashScreen::setValue (lo119109)" );
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "value=%d", nValue );
+
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ if (_bVisible && !_bProgressEnd) {
+ if ( _eBitmapMode == BM_FULLSCREEN )
+ ShowFullScreenMode( TRUE );
+ Show();
+ if (nValue >= _iMax) _iProgress = _iMax;
+ else _iProgress = nValue;
+ updateStatus();
+ }
+}
+
+// XInitialize
+void SAL_CALL
+SplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
+ throw (RuntimeException)
+{
+ ::osl::ClearableMutexGuard aGuard( _aMutex );
+ if (aArguments.getLength() > 0)
+ {
+ aArguments[0] >>= _bVisible;
+ if (aArguments.getLength() > 1 )
+ aArguments[1] >>= _sAppName;
+
+ // start to determine bitmap and all other required value
+ initBitmap();
+ Size aSize = _aIntroBmp.GetSizePixel();
+ SetOutputSizePixel( aSize );
+ _vdev.SetOutputSizePixel( aSize );
+ _height = aSize.Height();
+ _width = aSize.Width();
+ if (_width > 500)
+ {
+ Point xtopleft(212,216);
+ if ( NOT_LOADED == _tlx || NOT_LOADED == _tly )
+ {
+ _tlx = xtopleft.X(); // top-left x
+ _tly = xtopleft.Y(); // top-left y
+ }
+ if ( NOT_LOADED == _barwidth )
+ _barwidth = 263;
+ if ( NOT_LOADED == _barheight )
+ _barheight = 8;
+ if (( _eBitmapMode == BM_FULLSCREEN ) &&
+ _bFullScreenSplash )
+ {
+ if( ( _fXPos >= 0.0 ) && ( _fYPos >= 0.0 ))
+ {
+ _tlx = sal_Int32( double( aSize.Width() ) * _fXPos );
+ _tly = sal_Int32( double( aSize.Height() ) * _fYPos );
+ }
+ if ( _fWidth >= 0.0 )
+ _barwidth = sal_Int32( double( aSize.Width() ) * _fWidth );
+ if ( _fHeight >= 0.0 )
+ _barheight = sal_Int32( double( aSize.Width() ) * _fHeight );
+ }
+ }
+ else
+ {
+ if ( NOT_LOADED == _barwidth )
+ _barwidth = _width - (2 * _xoffset);
+ if ( NOT_LOADED == _barheight )
+ _barheight = 6;
+ if ( NOT_LOADED == _tlx || NOT_LOADED == _tly )
+ {
+ _tlx = _xoffset; // top-left x
+ _tly = _height - _yoffset; // top-left y
+ }
+ }
+
+ if ( sal::static_int_cast< ColorData >(NOT_LOADED) ==
+ _cProgressFrameColor.GetColor() )
+ _cProgressFrameColor = Color( COL_LIGHTGRAY );
+
+ if ( sal::static_int_cast< ColorData >(NOT_LOADED) ==
+ _cProgressBarColor.GetColor() )
+ {
+ // progress bar: new color only for big bitmap format
+ if ( _width > 500 )
+ _cProgressBarColor = Color( 157, 202, 18 );
+ else
+ _cProgressBarColor = Color( COL_BLUE );
+ }
+
+ Application::AddEventListener(
+ LINK( this, SplashScreen, AppEventListenerHdl ) );
+
+ SetBackgroundBitmap( _aIntroBmp );
+ }
+}
+
+void SplashScreen::updateStatus()
+{
+ if (!_bVisible || _bProgressEnd) return;
+ if (!_bPaintProgress) _bPaintProgress = sal_True;
+ //_bPaintBitmap=sal_False;
+ Paint(Rectangle());
+ //_bPaintBitmap=sal_True;
+ Flush();
+}
+
+// internal private methods
+IMPL_LINK( SplashScreen, AppEventListenerHdl, VclWindowEvent *, inEvent )
+{
+ if ( inEvent != 0 )
+ {
+ // Paint( Rectangle() );
+ switch ( inEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_SHOW:
+ Paint( Rectangle() );
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+// Read keys from edition/edition.ini or soffice{.ini|rc}:
+OUString implReadBootstrapKey( const OUString& _rKey )
+{
+ OUString sValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${.override:${BRAND_BASE_DIR}/program/edition/edition.ini:")) +
+ _rKey + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("}")));
+ rtl::Bootstrap::expandMacros(sValue);
+ return sValue;
+}
+
+void SplashScreen::loadConfig()
+{
+ _bShowLogo = !implReadBootstrapKey(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Logo"))).
+ equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("0"));
+
+ OUString sProgressFrameColor = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressFrameColor" ) ) );
+ OUString sProgressBarColor = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressBarColor" ) ) );
+ OUString sSize = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressSize" ) ) );
+ OUString sPosition = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressPosition" ) ) );
+ OUString sFullScreenSplash = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "FullScreenSplash" ) ) );
+ OUString sNativeProgress = implReadBootstrapKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "NativeProgress" ) ) );
+
+
+ // Determine full screen splash mode
+ _bFullScreenSplash = (( sFullScreenSplash.getLength() > 0 ) &&
+ ( !sFullScreenSplash.equalsAsciiL( "0", 1 )));
+
+ // Try to retrieve the relative values for the progress bar. The current
+ // schema uses the screen ratio to retrieve the associated values.
+ if ( _bFullScreenSplash )
+ determineProgressRatioValues( _fXPos, _fYPos, _fWidth, _fHeight );
+
+ if ( sProgressFrameColor.getLength() )
+ {
+ UINT8 nRed = 0;
+ UINT8 nGreen = 0;
+ UINT8 nBlue = 0;
+ sal_Int32 idx = 0;
+ sal_Int32 temp = sProgressFrameColor.getToken( 0, ',', idx ).toInt32();
+ if ( idx != -1 )
+ {
+ nRed = static_cast< UINT8 >( temp );
+ temp = sProgressFrameColor.getToken( 0, ',', idx ).toInt32();
+ }
+ if ( idx != -1 )
+ {
+ nGreen = static_cast< UINT8 >( temp );
+ nBlue = static_cast< UINT8 >( sProgressFrameColor.getToken( 0, ',', idx ).toInt32() );
+ _cProgressFrameColor = Color( nRed, nGreen, nBlue );
+ }
+ }
+
+ if ( sProgressBarColor.getLength() )
+ {
+ UINT8 nRed = 0;
+ UINT8 nGreen = 0;
+ UINT8 nBlue = 0;
+ sal_Int32 idx = 0;
+ sal_Int32 temp = sProgressBarColor.getToken( 0, ',', idx ).toInt32();
+ if ( idx != -1 )
+ {
+ nRed = static_cast< UINT8 >( temp );
+ temp = sProgressBarColor.getToken( 0, ',', idx ).toInt32();
+ }
+ if ( idx != -1 )
+ {
+ nGreen = static_cast< UINT8 >( temp );
+ nBlue = static_cast< UINT8 >( sProgressBarColor.getToken( 0, ',', idx ).toInt32() );
+ _cProgressBarColor = Color( nRed, nGreen, nBlue );
+ }
+ }
+
+ if( sNativeProgress.getLength() )
+ {
+ _bNativeProgress = sNativeProgress.toBoolean();
+ }
+
+ if ( sSize.getLength() )
+ {
+ sal_Int32 idx = 0;
+ sal_Int32 temp = sSize.getToken( 0, ',', idx ).toInt32();
+ if ( idx != -1 )
+ {
+ _barwidth = temp;
+ _barheight = sSize.getToken( 0, ',', idx ).toInt32();
+ }
+ }
+
+ if ( _barheight >= 10 )
+ _barspace = 3; // more space between frame and bar
+
+ if ( sPosition.getLength() )
+ {
+ sal_Int32 idx = 0;
+ sal_Int32 temp = sPosition.getToken( 0, ',', idx ).toInt32();
+ if ( idx != -1 )
+ {
+ _tlx = temp;
+ _tly = sPosition.getToken( 0, ',', idx ).toInt32();
+ }
+ }
+}
+
+void SplashScreen::initBitmap()
+{
+ if ( _bShowLogo )
+ {
+ OUString sExecutePath;
+ ::rtl::Bootstrap::get(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "BRAND_BASE_DIR" ) ),
+ sExecutePath );
+ sExecutePath += OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/" ) );
+
+ bool haveBitmap = false;
+
+ // Try all bitmaps in INTRO_BITMAP_NAMES
+ sal_Int32 nIndex = 0;
+ OUString aIntroBitmapFiles( RTL_CONSTASCII_USTRINGPARAM( INTRO_BITMAP_STRINGLIST ));
+ do
+ {
+ haveBitmap = loadBitmap( sExecutePath, aIntroBitmapFiles.getToken( 0, ',', nIndex ) );
+ }
+ while ( !haveBitmap && ( nIndex >= 0 ) );
+
+ if (!haveBitmap) {
+ rtl::OUString edition(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${BRAND_BASE_DIR}/program/edition")));
+ rtl::Bootstrap::expandMacros(edition);
+ haveBitmap = findBitmap(edition);
+ }
+ if (!haveBitmap) {
+ findBitmap(sExecutePath);
+ }
+ }
+}
+
+bool SplashScreen::loadBitmap(
+ rtl::OUString const & path, const rtl::OUString &rBmpFileName )
+{
+ if ( rBmpFileName.getLength() == 0 )
+ return false;
+
+ INetURLObject aObj( path, INET_PROT_FILE );
+ aObj.insertName( rBmpFileName );
+
+ SvFileStream aStrm( aObj.PathToFileName(), STREAM_STD_READ );
+ if ( !aStrm.GetError() )
+ {
+ // Use graphic class to also support more graphic formats (bmp,png,...)
+ Graphic aGraphic;
+
+ GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
+ pGF->ImportGraphic( aGraphic, String(), aStrm, GRFILTER_FORMAT_DONTKNOW );
+
+ // Default case, we load the intro bitmap from a seperate file
+ // (e.g. staroffice_intro.bmp or starsuite_intro.bmp)
+ _aIntroBmp = aGraphic.GetBitmapEx();
+ return true;
+ }
+
+ return false;
+}
+
+bool SplashScreen::findBitmap(rtl::OUString const & path) {
+ bool haveBitmap = false;
+ if ( _bFullScreenSplash )
+ {
+ haveBitmap = findScreenBitmap(path);
+ if ( haveBitmap )
+ _eBitmapMode = BM_FULLSCREEN;
+ else
+ haveBitmap = findAppBitmap(path);
+ }
+ if ( !haveBitmap )
+ {
+ haveBitmap = loadBitmap(
+ path, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("intro.png")));
+ if ( !haveBitmap )
+ haveBitmap = loadBitmap(
+ path, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("intro.bmp")));
+ }
+
+ return haveBitmap;
+}
+
+bool SplashScreen::findScreenBitmap(rtl::OUString const & path)
+{
+ sal_Int32 nWidth( 0 );
+ sal_Int32 nHeight( 0 );
+
+ // determine desktop resolution
+ sal_uInt32 nCount = Application::GetScreenCount();
+ if ( nCount > 0 )
+ {
+ // retrieve size from first screen
+ Rectangle aScreenArea = Application::GetScreenPosSizePixel((unsigned int)0);
+ nWidth = aScreenArea.GetWidth();
+ nHeight = aScreenArea.GetHeight();
+ }
+
+ // create file name from screen resolution information
+ OUStringBuffer aStrBuf( 128 );
+ aStrBuf.appendAscii( "intro_" );
+ if ( _sAppName.getLength() > 0 )
+ {
+ aStrBuf.append( _sAppName );
+ aStrBuf.appendAscii( "_" );
+ }
+ aStrBuf.append( OUString::valueOf( nWidth ));
+ aStrBuf.appendAscii( "x" );
+ aStrBuf.append( OUString::valueOf( nHeight ));
+
+ OUString aRootIntroFileName = aStrBuf.makeStringAndClear();
+ OUString aBmpFileName = aRootIntroFileName + OUString::createFromAscii(".png");
+
+ bool haveBitmap = loadBitmap( path, aBmpFileName );
+ if ( !haveBitmap )
+ {
+ aBmpFileName = aRootIntroFileName + OUString::createFromAscii(".bmp");
+ haveBitmap = loadBitmap( path, aBmpFileName );
+ }
+
+ if ( !haveBitmap )
+ {
+ aStrBuf.appendAscii( "intro_" );
+ aStrBuf.appendAscii( "_" );
+ aStrBuf.append( OUString::valueOf( nWidth ));
+ aStrBuf.appendAscii( "x" );
+ aStrBuf.append( OUString::valueOf( nHeight ));
+
+ aRootIntroFileName = aStrBuf.makeStringAndClear();
+ aBmpFileName = aRootIntroFileName + OUString::createFromAscii(".png");
+
+ haveBitmap = loadBitmap( path, aBmpFileName );
+ if ( !haveBitmap )
+ {
+ aBmpFileName = aRootIntroFileName + OUString::createFromAscii(".bmp");
+ haveBitmap = loadBitmap( path, aBmpFileName );
+ }
+ }
+ return haveBitmap;
+}
+
+bool SplashScreen::findAppBitmap(rtl::OUString const & path)
+{
+ bool haveBitmap = false;
+
+ if ( _sAppName.getLength() > 0 )
+ {
+ OUStringBuffer aStrBuf( 128 );
+ aStrBuf.appendAscii( "intro_" );
+ aStrBuf.appendAscii( "_" );
+ aStrBuf.append( _sAppName );
+
+ OUString aRootIntroFileName = aStrBuf.makeStringAndClear();
+
+ OUString aBmpFileName = aRootIntroFileName + OUString::createFromAscii( ".png" );
+ haveBitmap = loadBitmap( path, aBmpFileName );
+ if ( !haveBitmap )
+ {
+ aBmpFileName = aRootIntroFileName + OUString::createFromAscii( ".bmp" );
+ haveBitmap = loadBitmap( path, aBmpFileName );
+ }
+ }
+ return haveBitmap;
+}
+
+void SplashScreen::determineProgressRatioValues(
+ double& rXRelPos, double& rYRelPos,
+ double& rRelWidth, double& rRelHeight )
+{
+ sal_Int32 nWidth( 0 );
+ sal_Int32 nHeight( 0 );
+ sal_Int32 nScreenRatio( 0 );
+
+ // determine desktop resolution
+ sal_uInt32 nCount = Application::GetScreenCount();
+ if ( nCount > 0 )
+ {
+ // retrieve size from first screen
+ Rectangle aScreenArea = Application::GetScreenPosSizePixel((unsigned int)0);
+ nWidth = aScreenArea.GetWidth();
+ nHeight = aScreenArea.GetHeight();
+ nScreenRatio = sal_Int32( math::round( double( nWidth ) / double( nHeight ), 2 ) * 100 );
+ }
+
+ char szFullScreenProgressRatio[] = "FullScreenProgressRatio0";
+ char szFullScreenProgressPos[] = "FullScreenProgressPos0";
+ char szFullScreenProgressSize[] = "FullScreenProgressSize0";
+ for ( sal_Int32 i = 0; i <= 9; i++ )
+ {
+ char cNum = '0' + char( i );
+ szFullScreenProgressRatio[23] = cNum;
+ szFullScreenProgressPos[21] = cNum;
+ szFullScreenProgressSize[22] = cNum;
+
+ OUString sFullScreenProgressRatio = implReadBootstrapKey(
+ OUString::createFromAscii( szFullScreenProgressRatio ) );
+
+ if ( sFullScreenProgressRatio.getLength() > 0 )
+ {
+ double fRatio = sFullScreenProgressRatio.toDouble();
+ sal_Int32 nRatio = sal_Int32( math::round( fRatio, 2 ) * 100 );
+ if ( nRatio == nScreenRatio )
+ {
+ OUString sFullScreenProgressPos = implReadBootstrapKey(
+ OUString::createFromAscii( szFullScreenProgressPos ) );
+ OUString sFullScreenProgressSize = implReadBootstrapKey(
+ OUString::createFromAscii( szFullScreenProgressSize ) );
+
+ if ( sFullScreenProgressPos.getLength() )
+ {
+ sal_Int32 idx = 0;
+ double temp = sFullScreenProgressPos.getToken( 0, ',', idx ).toDouble();
+ if ( idx != -1 )
+ {
+ rXRelPos = temp;
+ rYRelPos = sFullScreenProgressPos.getToken( 0, ',', idx ).toDouble();
+ }
+ }
+
+ if ( sFullScreenProgressSize.getLength() )
+ {
+ sal_Int32 idx = 0;
+ double temp = sFullScreenProgressSize.getToken( 0, ',', idx ).toDouble();
+ if ( idx != -1 )
+ {
+ rRelWidth = temp;
+ rRelHeight = sFullScreenProgressSize.getToken( 0, ',', idx ).toDouble();
+ }
+ }
+ }
+ }
+ else
+ break;
+ }
+}
+
+void SplashScreen::Paint( const Rectangle&)
+{
+ if(!_bVisible) return;
+
+ //native drawing
+ BOOL bNativeOK = FALSE;
+
+ // in case of native controls we need to draw directly to the window
+ if( _bNativeProgress && IsNativeControlSupported( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL ) )
+ {
+ DrawBitmapEx( Point(), _aIntroBmp );
+
+ ImplControlValue aValue( _iProgress * _barwidth / _iMax);
+ Rectangle aDrawRect( Point(_tlx, _tly), Size( _barwidth, _barheight ) );
+ Rectangle aNativeControlRegion, aNativeContentRegion;
+
+ if( GetNativeControlRegion( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aDrawRect,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) )
+ {
+ long nProgressHeight = aNativeControlRegion.GetHeight();
+ aDrawRect.Top() -= (nProgressHeight - _barheight)/2;
+ aDrawRect.Bottom() += (nProgressHeight - _barheight)/2;
+ }
+
+ if( (bNativeOK = DrawNativeControl( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aDrawRect,
+ CTRL_STATE_ENABLED, aValue, _sProgressText )) != FALSE )
+ {
+ return;
+ }
+ }
+ //non native drawing
+ // draw bitmap
+ if (_bPaintBitmap)
+ _vdev.DrawBitmapEx( Point(), _aIntroBmp );
+
+ if (_bPaintProgress) {
+ // draw progress...
+ long length = (_iProgress * _barwidth / _iMax) - (2 * _barspace);
+ if (length < 0) length = 0;
+
+ // border
+ _vdev.SetFillColor();
+ _vdev.SetLineColor( _cProgressFrameColor );
+ _vdev.DrawRect(Rectangle(_tlx, _tly, _tlx+_barwidth, _tly+_barheight));
+ _vdev.SetFillColor( _cProgressBarColor );
+ _vdev.SetLineColor();
+ _vdev.DrawRect(Rectangle(_tlx+_barspace, _tly+_barspace, _tlx+_barspace+length, _tly+_barheight-_barspace));
+ _vdev.DrawText( Rectangle(_tlx, _tly+_barheight+5, _tlx+_barwidth, _tly+_barheight+5+20), _sProgressText, TEXT_DRAW_CENTER );
+ }
+ Size aSize = GetOutputSizePixel();
+ Size bSize = _vdev.GetOutputSizePixel();
+ //_vdev.Flush();
+ //_vdev.DrawOutDev(Point(), GetOutputSize(), Point(), GetOutputSize(), *((IntroWindow*)this) );
+ DrawOutDev(Point(), GetOutputSizePixel(), Point(), _vdev.GetOutputSizePixel(), _vdev );
+ //Flush();
+}
+
+
+// get service instance...
+SplashScreen *SplashScreen::_pINSTANCE = NULL;
+osl::Mutex SplashScreen::_aMutex;
+
+Reference< XInterface > SplashScreen::getInstance(const Reference< XMultiServiceFactory >& rSMgr)
+{
+ if ( _pINSTANCE == 0 )
+ {
+ osl::MutexGuard guard(_aMutex);
+ if (_pINSTANCE == 0)
+ return (XComponent*)new SplashScreen(rSMgr);
+ }
+
+ return (XComponent*)0;
+}
+
+// static service info...
+const char* SplashScreen::interfaces[] =
+{
+ "com.sun.star.task.XStartusIndicator",
+ "com.sun.star.lang.XInitialization",
+ NULL,
+};
+const sal_Char *SplashScreen::serviceName = "com.sun.star.office.SplashScreen";
+const sal_Char *SplashScreen::implementationName = "com.sun.star.office.comp.SplashScreen";
+const sal_Char *SplashScreen::supportedServiceNames[] = {"com.sun.star.office.SplashScreen", NULL};
+
+}
diff --git a/desktop/source/splash/splash.hxx b/desktop/source/splash/splash.hxx
new file mode 100644
index 000000000000..8480ed3df9ae
--- /dev/null
+++ b/desktop/source/splash/splash.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <vcl/introwin.hxx>
+#include <vcl/bitmapex.hxx>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <osl/mutex.hxx>
+#include <vcl/virdev.hxx>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::task;
+
+namespace desktop {
+
+class SplashScreen
+ : public ::cppu::WeakImplHelper2< XStatusIndicator, XInitialization >
+ , public IntroWindow
+{
+private:
+ struct FullScreenProgressRatioValue
+ {
+ double _fXRelPos;
+ double _fYRelPos;
+ double _fRelWidth;
+ double _fRelHeight;
+ };
+ enum BitmapMode { BM_FULLSCREEN, BM_DEFAULTMODE };
+
+ // don't allow anybody but ourselves to create instances of this class
+ SplashScreen(const SplashScreen&);
+ SplashScreen(void);
+ SplashScreen operator =(const SplashScreen&);
+
+ SplashScreen(const Reference< XMultiServiceFactory >& xFactory);
+
+ DECL_LINK( AppEventListenerHdl, VclWindowEvent * );
+ virtual ~SplashScreen();
+ void loadConfig();
+ void initBitmap();
+ void updateStatus();
+ bool findScreenBitmap(rtl::OUString const & path);
+ bool findAppBitmap(rtl::OUString const & path);
+ bool findBitmap(rtl::OUString const & path);
+ bool loadBitmap(
+ rtl::OUString const & path, const rtl::OUString &rBmpFileName );
+ void determineProgressRatioValues( double& rXRelPos, double& rYRelPos, double& rRelWidth, double& rRelHeight );
+
+ static SplashScreen *_pINSTANCE;
+
+ static osl::Mutex _aMutex;
+ Reference< XMultiServiceFactory > _rFactory;
+
+ VirtualDevice _vdev;
+ BitmapEx _aIntroBmp;
+ Color _cProgressFrameColor;
+ Color _cProgressBarColor;
+ bool _bNativeProgress;
+ OUString _sAppName;
+ OUString _sProgressText;
+ std::vector< FullScreenProgressRatioValue > _sFullScreenProgressRatioValues;
+
+ sal_Int32 _iMax;
+ sal_Int32 _iProgress;
+ BitmapMode _eBitmapMode;
+ sal_Bool _bPaintBitmap;
+ sal_Bool _bPaintProgress;
+ sal_Bool _bVisible;
+ sal_Bool _bShowLogo;
+ sal_Bool _bFullScreenSplash;
+ sal_Bool _bProgressEnd;
+ long _height, _width, _tlx, _tly, _barwidth;
+ long _barheight, _barspace;
+ double _fXPos, _fYPos;
+ double _fWidth, _fHeight;
+ const long _xoffset, _yoffset;
+
+public:
+ static const char* interfaces[];
+ static const sal_Char *serviceName;
+ static const sal_Char *implementationName;
+ static const sal_Char *supportedServiceNames[];
+
+ static Reference< XInterface > getInstance(const Reference < XMultiServiceFactory >& xFactory);
+
+ // XStatusIndicator
+ virtual void SAL_CALL end() throw ( RuntimeException );
+ virtual void SAL_CALL reset() throw ( RuntimeException );
+ virtual void SAL_CALL setText(const OUString& aText) throw ( RuntimeException );
+ virtual void SAL_CALL setValue(sal_Int32 nValue) throw ( RuntimeException );
+ virtual void SAL_CALL start(const OUString& aText, sal_Int32 nRange) throw ( RuntimeException );
+
+ // XInitialize
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
+ throw ( RuntimeException );
+
+ // workwindow
+ virtual void Paint( const Rectangle& );
+
+};
+
+}
diff --git a/desktop/test/deployment/boxt/Addons.xcu b/desktop/test/deployment/boxt/Addons.xcu
new file mode 100644
index 000000000000..3df7e2de274c
--- /dev/null
+++ b/desktop/test/deployment/boxt/Addons.xcu
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* 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.
+*
+**********************************************************************-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="Addons">
+ <node o:name="AddonUI">
+ <node o:name="OfficeMenuBar">
+ <node o:name="org.openoffice.test.desktop.deployment.boxt" o:op="replace">
+ <prop o:name="Title" xml:lang="en-US">
+ <value>boxt</value>
+ </prop>
+ <node o:name="Submenu">
+ <node o:name="1" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.openoffice.test.desktop.deployment.boxt:</value>
+ </prop>
+ <prop o:name="Title" xml:lang="en-US">
+ <value>boxt</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/boxt/ProtocolHandler.xcu b/desktop/test/deployment/boxt/ProtocolHandler.xcu
new file mode 100644
index 000000000000..fe448aedbe17
--- /dev/null
+++ b/desktop/test/deployment/boxt/ProtocolHandler.xcu
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* 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.
+*
+**********************************************************************-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="ProtocolHandler">
+ <node o:name="HandlerSet">
+ <node o:name="com.sun.star.test.deployment.boxt" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.openoffice.test.desktop.deployment.boxt:*</value>
+ </prop>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/boxt/boxt.cxx b/desktop/test/deployment/boxt/boxt.cxx
new file mode 100644
index 000000000000..dc82c0c004d6
--- /dev/null
+++ b/desktop/test/deployment/boxt/boxt.cxx
@@ -0,0 +1,235 @@
+/*************************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* 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 "precompiled_desktop.hxx"
+#include "sal/config.h"
+
+#include "boost/noncopyable.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/frame/DispatchDescriptor.hpp"
+#include "com/sun/star/frame/XDispatch.hpp"
+#include "com/sun/star/frame/XDispatchProvider.hpp"
+#include "com/sun/star/frame/XStatusListener.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleComponentFactory.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/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/URL.hpp"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/weak.hxx"
+#include "filter/msfilter/countryid.hxx"
+#include "osl/diagnose.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "uno/lbnames.h"
+#include "vcl/svapp.hxx"
+
+namespace {
+
+namespace css = com::sun::star;
+
+namespace service {
+
+rtl::OUString getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.test.deployment.boxt"));
+}
+
+css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
+ rtl::OUString name(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.test.deployment.boxt"));
+ return css::uno::Sequence< rtl::OUString >(&name, 1);
+}
+
+}
+
+class Service:
+ public cppu::WeakImplHelper3<
+ css::lang::XServiceInfo, css::frame::XDispatchProvider,
+ css::frame::XDispatch >,
+ private boost::noncopyable
+{
+public:
+ Service() {}
+
+private:
+ virtual ~Service() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return service::getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
+ throw (css::uno::RuntimeException)
+ { return ServiceName == getSupportedServiceNames()[0]; } //TODO
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return service::getSupportedServiceNames(); }
+
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(
+ css::util::URL const &, rtl::OUString const &, sal_Int32)
+ throw (css::uno::RuntimeException)
+ { return this; }
+
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
+ SAL_CALL queryDispatches(
+ css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL dispatch(
+ css::util::URL const &,
+ css::uno::Sequence< css::beans::PropertyValue > const &)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL addStatusListener(
+ css::uno::Reference< css::frame::XStatusListener > const &,
+ css::util::URL const &)
+ throw (css::uno::RuntimeException)
+ {}
+
+ virtual void SAL_CALL removeStatusListener(
+ css::uno::Reference< css::frame::XStatusListener > const &,
+ css::util::URL const &)
+ throw (css::uno::RuntimeException)
+ {}
+};
+
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > >
+Service::queryDispatches(
+ css::uno::Sequence< css::frame::DispatchDescriptor > const & Requests)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > s(
+ Requests.getLength());
+ for (sal_Int32 i = 0; i < s.getLength(); ++i) {
+ s[i] = queryDispatch(
+ Requests[i].FeatureURL, Requests[i].FrameName,
+ Requests[i].SearchFlags);
+ }
+ return s;
+}
+
+void Service::dispatch(
+ css::util::URL const &,
+ css::uno::Sequence< css::beans::PropertyValue > const &)
+ throw (css::uno::RuntimeException)
+{
+ msfilter::ConvertCountryToLanguage(msfilter::COUNTRY_DONTKNOW);
+ // link against some obscure library that is unlikely already loaded
+ Application::ShowNativeErrorBox(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("boxt")),
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test")));
+}
+
+class Factory:
+ public cppu::WeakImplHelper1< css::lang::XSingleComponentFactory >,
+ private boost::noncopyable
+{
+public:
+ Factory() {}
+
+private:
+ virtual ~Factory() {}
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
+ createInstanceWithContext(
+ css::uno::Reference< css::uno::XComponentContext > const &)
+ throw (css::uno::Exception, css::uno::RuntimeException)
+ { return static_cast< cppu::OWeakObject * >(new Service); }
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
+ createInstanceWithArgumentsAndContext(
+ css::uno::Sequence< css::uno::Any > const &,
+ css::uno::Reference< css::uno::XComponentContext > const & Context)
+ throw (css::uno::Exception, css::uno::RuntimeException)
+ { return createInstanceWithContext(Context); }
+};
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL dummy(
+ css::uno::Reference< css::uno::XComponentContext > const &)
+ SAL_THROW((css::uno::Exception))
+{
+ OSL_ASSERT(false);
+ return css::uno::Reference< css::uno::XInterface >();
+}
+
+rtl::OUString SAL_CALL getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.test.deployment.boxt"));
+}
+
+css::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() {
+ rtl::OUString name(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.test.deployment.boxt"));
+ return css::uno::Sequence< rtl::OUString >(&name, 1);
+}
+
+css::uno::Reference< css::lang::XSingleComponentFactory > SAL_CALL
+createFactory(
+ cppu::ComponentFactoryFunc, rtl::OUString const &,
+ css::uno::Sequence< rtl::OUString > const &, rtl_ModuleCount *)
+ SAL_THROW(())
+{
+ return new Factory;
+}
+
+static cppu::ImplementationEntry const services[] = {
+ { &dummy, &service::getImplementationName,
+ &service::getSupportedServiceNames, &createFactory, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+}
+
+extern "C" void * SAL_CALL component_getFactory(
+ char const * pImplName, void * pServiceManager, void * pRegistryKey)
+{
+ return cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, services);
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ char const ** ppEnvTypeName, uno_Environment **)
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey)
+{
+ return component_writeInfoHelper(pServiceManager, pRegistryKey, services);
+}
diff --git a/desktop/test/deployment/boxt/description.xml b/desktop/test/deployment/boxt/description.xml
new file mode 100644
index 000000000000..5a67bf3e949f
--- /dev/null
+++ b/desktop/test/deployment/boxt/description.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* 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.
+*
+**********************************************************************-->
+
+<d:description xmlns:d="http://openoffice.org/extensions/description/2006">
+ <d:identifier value="org.openoffice/framework/desktop/test/deployment/boxt"/>
+ <d:version value="@VERSION@"/>
+ <d:platform value="@PLATFORM@"/>
+ <d:dependencies>
+ <d:OpenOffice.org-minimal-version d:name="OpenOffice.org @VERSION@"
+ value="@VERSION@"/>
+ <d:OpenOffice.org-maximal-version d:name="OpenOffice.org @VERSION@ or older"
+ d:OpenOffice.org-minimal-version="2.3" value="@VERSION@"/>
+ </d:dependencies>
+</d:description>
diff --git a/desktop/test/deployment/boxt/makefile.mk b/desktop/test/deployment/boxt/makefile.mk
new file mode 100644
index 000000000000..63f123fcc608
--- /dev/null
+++ b/desktop/test/deployment/boxt/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#***********************************************************************/
+
+PRJ = ../../..
+PRJNAME = desktop
+TARGET = test_deployment_boxt
+
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE: settings.mk
+.INCLUDE: rtlbootstrap.mk
+
+#TODO: The underlying OOo base version needed here is currently only available
+# as instsetoo_native/util/openoffice.lst OOOBASEVERSION, so hard-coding it here
+# for now (see issue 110653):
+my_version = 3.3
+
+DLLPRE =
+
+SLOFILES = $(SHL1OBJS)
+
+SHL1TARGET = boxt.uno
+SHL1OBJS = $(SLO)/boxt.obj
+SHL1RPATH = BOXT
+SHL1STDLIBS = \
+ $(CPPUHELPERLIB) $(CPPULIB) $(MSFILTERLIB) $(SALLIB) $(TOOLSLIB) $(VCLLIB)
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+DEF1NAME = $(SHL1TARGET)
+
+.INCLUDE: target.mk
+
+ALLTAR : $(MISC)/boxt.oxt
+
+$(MISC)/boxt.oxt .ERRREMOVE : manifest.xml description.xml Addons.xcu \
+ ProtocolHandler.xcu $(SHL1TARGETN)
+ $(RM) -r $@ $(MISC)/$(TARGET).zip
+ $(MKDIR) $(MISC)/$(TARGET).zip
+ $(MKDIR) $(MISC)/$(TARGET).zip/META-INF
+ $(SED) -e 's|@PATH@|$(SHL1TARGETN:f)|g' < manifest.xml \
+ > $(MISC)/$(TARGET).zip/META-INF/manifest.xml
+ $(SED) -e 's|@PLATFORM@|$(RTL_OS:l)_$(RTL_ARCH:l)|g' \
+ -e 's|@VERSION@|$(my_version)|g' < description.xml \
+ > $(MISC)/$(TARGET).zip/description.xml
+ $(COPY) Addons.xcu ProtocolHandler.xcu $(SHL1TARGETN) $(MISC)/$(TARGET).zip
+ cd $(MISC)/$(TARGET).zip && zip ../boxt.oxt META-INF/manifest.xml \
+ description.xml Addons.xcu ProtocolHandler.xcu $(SHL1TARGETN:f)
diff --git a/desktop/test/deployment/boxt/manifest.xml b/desktop/test/deployment/boxt/manifest.xml
new file mode 100644
index 000000000000..73ebfc306e30
--- /dev/null
+++ b/desktop/test/deployment/boxt/manifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* 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.
+*
+**********************************************************************-->
+
+<m:manifest xmlns:m="http://openoffice.org/2001/manifest">
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="Addons.xcu"/>
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="ProtocolHandler.xcu"/>
+ <m:file-entry
+ m:media-type="application/vnd.sun.star.uno-component;type=native"
+ m:full-path="@PATH@"/>
+</m:manifest>
diff --git a/desktop/test/deployment/dependencies/broken-dependency.oxt b/desktop/test/deployment/dependencies/broken-dependency.oxt
new file mode 100644
index 000000000000..11bab0a95092
--- /dev/null
+++ b/desktop/test/deployment/dependencies/broken-dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/double-dependencies.oxt b/desktop/test/deployment/dependencies/double-dependencies.oxt
new file mode 100644
index 000000000000..055c27ea53ba
--- /dev/null
+++ b/desktop/test/deployment/dependencies/double-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/empty-dependencies.oxt b/desktop/test/deployment/dependencies/empty-dependencies.oxt
new file mode 100644
index 000000000000..ebb18dcbf51b
--- /dev/null
+++ b/desktop/test/deployment/dependencies/empty-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/funny-dependency.oxt b/desktop/test/deployment/dependencies/funny-dependency.oxt
new file mode 100644
index 000000000000..9b683e6d1e4b
--- /dev/null
+++ b/desktop/test/deployment/dependencies/funny-dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/license-dependency.oxt b/desktop/test/deployment/dependencies/license-dependency.oxt
new file mode 100644
index 000000000000..b01da4b5ca8a
--- /dev/null
+++ b/desktop/test/deployment/dependencies/license-dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/many-dependencies.oxt b/desktop/test/deployment/dependencies/many-dependencies.oxt
new file mode 100644
index 000000000000..367568143778
--- /dev/null
+++ b/desktop/test/deployment/dependencies/many-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/minattr22.oxt b/desktop/test/deployment/dependencies/minattr22.oxt
new file mode 100644
index 000000000000..a6c8e3758cf4
--- /dev/null
+++ b/desktop/test/deployment/dependencies/minattr22.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/minattr23.oxt b/desktop/test/deployment/dependencies/minattr23.oxt
new file mode 100644
index 000000000000..83d17938c425
--- /dev/null
+++ b/desktop/test/deployment/dependencies/minattr23.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/minattr24.oxt b/desktop/test/deployment/dependencies/minattr24.oxt
new file mode 100644
index 000000000000..00f053f487ec
--- /dev/null
+++ b/desktop/test/deployment/dependencies/minattr24.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/no-dependencies.oxt b/desktop/test/deployment/dependencies/no-dependencies.oxt
new file mode 100644
index 000000000000..6487eb66ae14
--- /dev/null
+++ b/desktop/test/deployment/dependencies/no-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/no-description.oxt b/desktop/test/deployment/dependencies/no-description.oxt
new file mode 100644
index 000000000000..1e6579cd7dd4
--- /dev/null
+++ b/desktop/test/deployment/dependencies/no-description.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/readme.txt b/desktop/test/deployment/dependencies/readme.txt
new file mode 100644
index 000000000000..a99fade00225
--- /dev/null
+++ b/desktop/test/deployment/dependencies/readme.txt
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+no-description.oxt, no-dependencies.oxt, empty-dependencies.oxt effectively have
+no dependencies and should thus install successfully.
+
+broken-dependencies.oxt contains a malformed description.xml and should thus
+display an error and not install.
+
+double-dependencies.oxt contains a description.xml with two dependencies
+elements. This is not allowed by the spec but behaviour is unspecified. In the
+current implementation, it combines the two elements, and thus finds two
+unsatisfied dependencies, displays the Unsatisfied Dependencies dialog and does
+not install.
+
+version21.oxt contains a dependency on OOo 2.1 (and should thus only install in
+OOo 2.1 or later); version21ns.oxt is the same, but with a different way of
+using XML namespaces; version21other.oxt additionally contains an unsatisfied
+dependency (and should thus not install in any OOo version). version22.oxt
+contains a dependency on OOo 2.2 (and should thus only install in OOo 2.2 or
+later). version23.oxt contains a dependency on OOo 2.3 (and should thus only
+install in OOo 2.3 or later). version10000.oxt contains a dependency on the
+hypothetical OOo version 10000 (and should thus not install in any OOo version).
+versionempty.oxt contains an empty value attribute and versionnone.oxt lacks the
+value attribute; neither is allowed by the spec, but the current implementation
+treats both as pre OOo 2.1 versions (and the extensions should thus install in
+OOo 2.1 or later).
+
+maxversion30.oxt contains a maximal version dependency on OOo 3.0 (and should
+thus only install in OOo 3.0 or earlier, back to OOo 2.3, thanks to the
+additionally specified OpenOffice.org-minimal-version attribute).
+maxversion10000.oxt contains a maximal version dependency on the hypothetical
+OOo version 10000 (and should thus install in any OOo version 3.1 or later;
+OpenOffice.org-maximal-version was introduced in OOo 3.1, and no OpenOffice.org-
+minimal-version attribute is specified). bad-minmaxversion.oxt contains a
+minimal version dependency on OOo 3.2 and a maximal version dependency on
+OOo 3.1 (and should thus not install in any OOo version).
+
+minattr22.oxt contains a (hypothetical, most probably never satisfied)
+UNSATISFIED dependency with an OpenOffice.org-minimal-version attribute of
+"2.2" (and should thus install in OOo 2.3 or later); minattr23.oxt is similar,
+but with an OpenOffice.org-minimal-version attribute of "2.3" (and should thus
+also install in OOo 2.3 or later); minattr24.oxt is similar, but with an
+OpenOffice.org-minimal-version attribute of "2.4" (and should thus only install
+in OOo 2.4 or later).
+
+All of the following testcases should result in the Unsatisfied Dependencies
+dialog being displayed and the extension not being installed:
+
+unknown-dependency.oxt contains a dependency without a name attribute, and
+should thus display "Unknown" (localized).
+
+funny-dependency.oxt, many-dependencies.oxt contain somewhat extreme input.
+
+license-dependency.oxt contains both a license to be accepted by the user and
+dependencies. What is important here is that the Unsatisfied Dependencies
+dialog is displayed, but not the license (as installation aborts as soon as
+unsatisfied dependencies are found).
diff --git a/desktop/test/deployment/dependencies/unknown-dependency.oxt b/desktop/test/deployment/dependencies/unknown-dependency.oxt
new file mode 100644
index 000000000000..7c2a22c6d5da
--- /dev/null
+++ b/desktop/test/deployment/dependencies/unknown-dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version10000.oxt b/desktop/test/deployment/dependencies/version10000.oxt
new file mode 100644
index 000000000000..c15b7a117c8c
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version10000.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version21.oxt b/desktop/test/deployment/dependencies/version21.oxt
new file mode 100644
index 000000000000..922b2795555c
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version21.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version21ns.oxt b/desktop/test/deployment/dependencies/version21ns.oxt
new file mode 100644
index 000000000000..5efb2ed90220
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version21ns.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version21other.oxt b/desktop/test/deployment/dependencies/version21other.oxt
new file mode 100644
index 000000000000..d88a8155af65
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version21other.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version22.oxt b/desktop/test/deployment/dependencies/version22.oxt
new file mode 100644
index 000000000000..4c8a207b68ba
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version22.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/version23.oxt b/desktop/test/deployment/dependencies/version23.oxt
new file mode 100644
index 000000000000..6c08d2949ced
--- /dev/null
+++ b/desktop/test/deployment/dependencies/version23.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/versionempty.oxt b/desktop/test/deployment/dependencies/versionempty.oxt
new file mode 100644
index 000000000000..a06bb01294f4
--- /dev/null
+++ b/desktop/test/deployment/dependencies/versionempty.oxt
Binary files differ
diff --git a/desktop/test/deployment/dependencies/versionnone.oxt b/desktop/test/deployment/dependencies/versionnone.oxt
new file mode 100644
index 000000000000..ace2a11651ff
--- /dev/null
+++ b/desktop/test/deployment/dependencies/versionnone.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc1.oxt b/desktop/test/deployment/description/desc1.oxt
new file mode 100644
index 000000000000..e447fd6eae78
--- /dev/null
+++ b/desktop/test/deployment/description/desc1.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc2.oxt b/desktop/test/deployment/description/desc2.oxt
new file mode 100644
index 000000000000..8df2f33fa6de
--- /dev/null
+++ b/desktop/test/deployment/description/desc2.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc3.oxt b/desktop/test/deployment/description/desc3.oxt
new file mode 100644
index 000000000000..fbd1136b039a
--- /dev/null
+++ b/desktop/test/deployment/description/desc3.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc4.oxt b/desktop/test/deployment/description/desc4.oxt
new file mode 100644
index 000000000000..0c97f5fd4426
--- /dev/null
+++ b/desktop/test/deployment/description/desc4.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/desc5.oxt b/desktop/test/deployment/description/desc5.oxt
new file mode 100644
index 000000000000..8110073499ca
--- /dev/null
+++ b/desktop/test/deployment/description/desc5.oxt
Binary files differ
diff --git a/desktop/test/deployment/description/readme.txt b/desktop/test/deployment/description/readme.txt
new file mode 100755
index 000000000000..bb133ba516ce
--- /dev/null
+++ b/desktop/test/deployment/description/readme.txt
@@ -0,0 +1,23 @@
+The folder contains extensions which use in the description.xml the following:
+-The <extension-description> element The element contains localized child
+elements.
+
+The following table shows what localized item is used, when the Office the locale
+en-US uses. The displayed extension description contains the locale.
+
+
+Localization:
+
+Installed office: en-US
+ | locale
+=========================
+desc1.oxt | en-US
+-------------------------
+desc2.oxt | en-US-region1
+--------------------------
+desc3.oxt | en
+--------------------------
+desc4.oxt | en-GB
+--------------------------
+desc5.oxt | de
+
diff --git a/desktop/test/deployment/display_name/name1.oxt b/desktop/test/deployment/display_name/name1.oxt
new file mode 100644
index 000000000000..5a53690d6935
--- /dev/null
+++ b/desktop/test/deployment/display_name/name1.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/name2.oxt b/desktop/test/deployment/display_name/name2.oxt
new file mode 100644
index 000000000000..f6cbcae3bcbd
--- /dev/null
+++ b/desktop/test/deployment/display_name/name2.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/name3.oxt b/desktop/test/deployment/display_name/name3.oxt
new file mode 100644
index 000000000000..8df750ce62a5
--- /dev/null
+++ b/desktop/test/deployment/display_name/name3.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/name4.oxt b/desktop/test/deployment/display_name/name4.oxt
new file mode 100644
index 000000000000..6ce4822e3701
--- /dev/null
+++ b/desktop/test/deployment/display_name/name4.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/name5.oxt b/desktop/test/deployment/display_name/name5.oxt
new file mode 100644
index 000000000000..56973be7817b
--- /dev/null
+++ b/desktop/test/deployment/display_name/name5.oxt
Binary files differ
diff --git a/desktop/test/deployment/display_name/readme.txt b/desktop/test/deployment/display_name/readme.txt
new file mode 100644
index 000000000000..23173bde63dd
--- /dev/null
+++ b/desktop/test/deployment/display_name/readme.txt
@@ -0,0 +1,26 @@
+The folder contains extensions which use in the description.xml the following:
+-The <display-name> element
+The element contains localized child elements.
+
+To test the display name in the update dialog use the extensions in
+desktop/test/deployment/update/simple
+
+
+The following table shows what localized item is used, when the Office the locale
+en-US uses.
+
+
+Localization:
+
+Installed office: en-US
+ | publisher | release notes
+=============================================
+name1.oxt | en-US | en-US
+---------------------------------------------
+name2.oxt | en-US-region1 | en-US-region1
+---------------------------------------------
+name3.oxt | en | en
+---------------------------------------------
+name4.oxt | en-GB | en-GB
+---------------------------------------------
+name5.oxt | de | de
diff --git a/desktop/test/deployment/executable_content/build/hello.c b/desktop/test/deployment/executable_content/build/hello.c
new file mode 100644
index 000000000000..e9442450923a
--- /dev/null
+++ b/desktop/test/deployment/executable_content/build/hello.c
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <stdio.h>
+
+int main(int argc , char** argv, char** envp)
+{
+ //prevent warning about unused parameters
+ //we need to provide parameter names in C
+ argc = argc;
+ argv = argv;
+ envp = envp;
+
+ fprintf(stdout,"Hello world!\n");
+ return 0;
+}
+
+
diff --git a/desktop/test/deployment/executable_content/build/makefile.mk b/desktop/test/deployment/executable_content/build/makefile.mk
new file mode 100644
index 000000000000..038051c97499
--- /dev/null
+++ b/desktop/test/deployment/executable_content/build/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = hello
+LIBTARGET=NO
+NO_DEFAULT_STL=TRUE
+LIBSALCPPRT=
+
+.INCLUDE : settings.mk
+
+
+APP1NOSAL = TRUE
+APP1OBJS = \
+ $(OBJ)$/hello.obj
+
+
+APP1TARGET = $(TARGET)
+
+DEPOBJFILES = \
+ $(OBJ)$/hello.obj
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/test/deployment/executable_content/build/readme.txt b/desktop/test/deployment/executable_content/build/readme.txt
new file mode 100644
index 000000000000..4f956e573e07
--- /dev/null
+++ b/desktop/test/deployment/executable_content/build/readme.txt
@@ -0,0 +1,2 @@
+This folder contains the sources to build the hello executable which is contained
+in the hello.oxt.
diff --git a/desktop/test/deployment/executable_content/hello.oxt b/desktop/test/deployment/executable_content/hello.oxt
new file mode 100644
index 000000000000..97d6d14a3128
--- /dev/null
+++ b/desktop/test/deployment/executable_content/hello.oxt
Binary files differ
diff --git a/desktop/test/deployment/executable_content/readme.txt b/desktop/test/deployment/executable_content/readme.txt
new file mode 100644
index 000000000000..ad3c01097e14
--- /dev/null
+++ b/desktop/test/deployment/executable_content/readme.txt
@@ -0,0 +1,12 @@
+When the executable is installed try to execute the executable "hello". The executable
+file attribute (not on Windows) should be set.
+
+CD into the extension directory in /user|share)/uno_packages/cache/uno_packages/xyz_
+Then there are the directories for different platforms:
+
+windows,
+solaris,
+linux
+
+Each directory contains a hello executable. On linux one should execute it in a
+shell with an build environment, so that the c++ runtime is found.
diff --git a/desktop/test/deployment/identifier/explicit/identifier.oxt b/desktop/test/deployment/identifier/explicit/identifier.oxt
new file mode 100644
index 000000000000..3851e291c970
--- /dev/null
+++ b/desktop/test/deployment/identifier/explicit/identifier.oxt
Binary files differ
diff --git a/desktop/test/deployment/identifier/legacy/identifier.oxt b/desktop/test/deployment/identifier/legacy/identifier.oxt
new file mode 100644
index 000000000000..df8bb8449241
--- /dev/null
+++ b/desktop/test/deployment/identifier/legacy/identifier.oxt
Binary files differ
diff --git a/desktop/test/deployment/identifier/readme.txt b/desktop/test/deployment/identifier/readme.txt
new file mode 100644
index 000000000000..8a791c586a78
--- /dev/null
+++ b/desktop/test/deployment/identifier/readme.txt
@@ -0,0 +1,33 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+legacy/identifier.oxt and explicit/identifier.oxt are two different extensions
+that happen to have the same file name. legacy/identifier.oxt does not have an
+explicit extension identifier, so it gets the implicit one "org.openoffice.
+legacy.identifier.oxt". explicit/identifier.oxt has the
+explicit extension identifier "org.openoffice/framework/desktop/test/deployment/
+identifier/explicit/identifier.oxt".
diff --git a/desktop/test/deployment/locationtest/LocationTest.idl b/desktop/test/deployment/locationtest/LocationTest.idl
new file mode 100644
index 000000000000..2bcc6818c168
--- /dev/null
+++ b/desktop/test/deployment/locationtest/LocationTest.idl
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _com_sun_star_comp_smoketest_LocationTest_idl_
+#define _com_sun_star_comp_smoketest_LocationTest_idl_
+
+#include <com/sun/star/lang/XServiceInfo.idl>
+
+
+module com { module sun { module star { module comp { module smoketest {
+ // example service, XServiceInfo is implemented here for demonstration
+ // issues. XServiceInfo must be implemented by all components.
+ service TestExtension: ::com::sun::star::lang::XServiceInfo;
+};};};};};
+
+#endif
diff --git a/desktop/test/deployment/locationtest/LocationTest.java b/desktop/test/deployment/locationtest/LocationTest.java
new file mode 100644
index 000000000000..c5d24f4b0ecc
--- /dev/null
+++ b/desktop/test/deployment/locationtest/LocationTest.java
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ *************************************************************************/
+package com.sun.star.comp.smoketest;
+
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.registry.XRegistryKey;
+import com.sun.star.lang.XInitialization;
+import com.sun.star.lang.XTypeProvider;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.uno.Type;
+
+/** This class capsulates the class, that implements the minimal component, a
+ * factory for creating the service (<CODE>__getComponentFactory</CODE>) and a
+ * method, that writes the information into the given registry key
+ * (<CODE>__writeRegistryServiceInfo</CODE>).
+ */
+public class LocationTest {
+ /** This class implements the component. At least the interfaces XServiceInfo,
+ * XTypeProvider, and XInitialization should be provided by the service.
+ */
+ public static class _LocationTest extends WeakBase
+ implements XServiceInfo {
+ /** The service name, that must be used to get an instance of this service.
+ */
+ static private final String __serviceName =
+ "com.sun.star.comp.smoketest.LocationTest";
+
+ /** The initial component contextr, that gives access to
+ * the service manager, supported singletons, ...
+ * It's often later used
+ */
+ private XComponentContext m_cmpCtx;
+
+ /** The service manager, that gives access to all registered services.
+ * It's often later used
+ */
+ private XMultiComponentFactory m_xMCF;
+
+ /** The constructor of the inner class has a XMultiServiceFactory parameter.
+ * @param xmultiservicefactoryInitialization A special service factory
+ * could be introduced while initializing.
+ */
+ public _LocationTest(XComponentContext xCompContext) {
+ try {
+ m_cmpCtx = xCompContext;
+ m_xMCF = m_cmpCtx.getServiceManager();
+ }
+ catch( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method returns an array of all supported service names.
+ * @return Array of supported service names.
+ */
+ public String[] getSupportedServiceNames() {
+ return getServiceNames();
+ }
+
+ /** This method is a simple helper function to used in the
+ * static component initialisation functions as well as in
+ * getSupportedServiceNames.
+ */
+ public static String[] getServiceNames() {
+ String[] sSupportedServiceNames = { __serviceName };
+ return sSupportedServiceNames;
+ }
+
+ /** This method returns true, if the given service will be
+ * supported by the component.
+ * @param sServiceName Service name.
+ * @return True, if the given service name will be supported.
+ */
+ public boolean supportsService( String sServiceName ) {
+ return sServiceName.equals( __serviceName );
+ }
+
+ /** Return the class name of the component.
+ * @return Class name of the component.
+ */
+ public String getImplementationName() {
+ return _LocationTest.class.getName();
+ }
+ }
+
+
+ /**
+ * Gives a factory for creating the service.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns a <code>XSingleComponentFactory</code> for creating
+ * the component
+ * @param sImplName the name of the implementation for which a
+ * service is desired
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static XSingleComponentFactory __getComponentFactory(String sImplName)
+ {
+ XSingleComponentFactory xFactory = null;
+
+ if ( sImplName.equals( _LocationTest.class.getName() ) )
+ xFactory = Factory.createComponentFactory(_LocationTest.class,
+ _LocationTest.getServiceNames());
+
+ return xFactory;
+ }
+
+ /**
+ * Writes the service information into the given registry key.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns true if the operation succeeded
+ * @param regKey the registryKey
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+ return Factory.writeRegistryServiceInfo(_LocationTest.class.getName(),
+ _LocationTest.getServiceNames(),
+ regKey);
+ }
+
+ /** This method is a member of the interface for initializing an object
+ * directly after its creation.
+ * @param object This array of arbitrary objects will be passed to the
+ * component after its creation.
+ * @throws Exception Every exception will not be handled, but will be
+ * passed to the caller.
+ */
+ public void initialize( Object[] object )
+ throws com.sun.star.uno.Exception {
+ /* The component describes what arguments its expected and in which
+ * order!At this point you can read the objects and can intialize
+ * your component using these objects.
+ */
+ }
+}
diff --git a/desktop/test/deployment/locationtest/LocationTest.odt b/desktop/test/deployment/locationtest/LocationTest.odt
new file mode 100644
index 000000000000..8e1aa70078db
--- /dev/null
+++ b/desktop/test/deployment/locationtest/LocationTest.odt
Binary files differ
diff --git a/desktop/test/deployment/locationtest/MANIFEST.MF b/desktop/test/deployment/locationtest/MANIFEST.MF
new file mode 100644
index 000000000000..a2fa8c34b7f9
--- /dev/null
+++ b/desktop/test/deployment/locationtest/MANIFEST.MF
@@ -0,0 +1,2 @@
+RegistrationClassName: com.sun.star.comp.smoketest.LocationTest
+
diff --git a/desktop/test/deployment/locationtest/delzip b/desktop/test/deployment/locationtest/delzip
new file mode 100644
index 000000000000..636fda90bfcb
--- /dev/null
+++ b/desktop/test/deployment/locationtest/delzip
@@ -0,0 +1 @@
+ECHO is OFF
diff --git a/desktop/test/deployment/locationtest/description.xml b/desktop/test/deployment/locationtest/description.xml
new file mode 100644
index 000000000000..b8874dd4da85
--- /dev/null
+++ b/desktop/test/deployment/locationtest/description.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:d="http://openoffice.org/extensions/description/2006" >
+ <identifier value="org.openoffice.extensions.testarea.desktop.location"/>
+ <version value="1.0" />
+ <dependencies >
+ <OpenOffice.org-minimal-version value="2.2" d:name="OpenOffice.org 2.2"/>
+ </dependencies>
+ <update-information>
+ <src xlink:href="http://update.services.openoffice.org/ProductUpdateService/check.Update?product=extension&amp;extensionid=org.openoffice.extensions.testarea.desktop.updateinfo&amp;refresh=true"/>
+ </update-information>
+</description>
diff --git a/desktop/test/deployment/locationtest/makefile.mk b/desktop/test/deployment/locationtest/makefile.mk
new file mode 100644
index 000000000000..8fe189791961
--- /dev/null
+++ b/desktop/test/deployment/locationtest/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+PRJNAME = location_test
+PACKAGE = com$/sun$/star$/comp$/smoketest
+TARGET = com_sun_star_comp_smoketest
+
+no_common_build_zip:=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES = ridl.jar jurt.jar unoil.jar juh.jar
+
+JARTARGET = LocationTest.jar
+JARCOMPRESS = TRUE
+CUSTOMMANIFESTFILE = MANIFEST.MF
+
+ZIP1TARGET=locationtest
+ZIP1LIST=*
+ZIPFLAGS=-r
+ZIP1DIR=$(MISC)$/$(TARGET)
+ZIP1EXT=.oxt
+
+# --- Files --------------------------------------------------------
+
+COPY_OXT_MANIFEST:= $(MISC)$/$(TARGET)$/META-INF$/manifest.xml
+JAVAFILES = LocationTest.java
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(JARTARGETN) : $(MISC)$/$(TARGET).javamaker.done
+
+$(JAVACLASSFILES) : $(MISC)$/$(TARGET).javamaker.done
+
+$(MISC)$/$(TARGET).javamaker.done: $(BIN)$/LocationTest.rdb
+ $(JAVAMAKER) -O$(CLASSDIR) -BUCR -nD -X$(SOLARBINDIR)/types.rdb $<
+ $(TOUCH) $@
+
+$(BIN)$/LocationTest.rdb: LocationTest.idl
+ $(IDLC) -O$(MISC) -I$(SOLARIDLDIR) -cid -we $<
+ +-$(RM) $@
+ $(REGMERGE) $@ /UCR $(MISC)$/LocationTest.urd
+
+$(MISC)$/$(ZIP1TARGET).createdir :
+ +$(MKDIRHIER) $(MISC)$/$(TARGET)$/META-INF >& $(NULLDEV) && $(TOUCH) $@
+
+$(MISC)$/$(TARGET)_resort : manifest.xml $(JARTARGETN) $(MISC)$/$(ZIP1TARGET).createdir $(BIN)$/LocationTest.rdb description.xml
+ $(COPY) manifest.xml $(MISC)$/$(TARGET)$/META-INF$/manifest.xml
+ $(COPY) $(JARTARGETN) $(MISC)$/$(TARGET)$/$(JARTARGET)
+ $(COPY) $(BIN)$/LocationTest.rdb $(MISC)$/$(TARGET)$/LocationTest.rdb
+ $(COPY) description.xml $(MISC)$/$(TARGET)$/description.xml
+ $(TOUCH) $@
+
+$(ZIP1TARGETN) : $(MISC)$/$(TARGET)_resort $(MISC)$/$(ZIP1TARGET).createdir
+
diff --git a/desktop/test/deployment/locationtest/manifest.xml b/desktop/test/deployment/locationtest/manifest.xml
new file mode 100644
index 000000000000..8791582798bd
--- /dev/null
+++ b/desktop/test/deployment/locationtest/manifest.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest:manifest>
+ <manifest:file-entry manifest:full-path="LocationTest.jar" manifest:media-type="application/vnd.sun.star.uno-component;type=Java"/>
+ <manifest:file-entry manifest:full-path="LocationTest.rdb" manifest:media-type="application/vnd.sun.star.uno-typelibrary;type=RDB"/>
+</manifest:manifest> \ No newline at end of file
diff --git a/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/MANIFEST.MF b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/MANIFEST.MF
new file mode 100644
index 000000000000..fba55a6e0d5a
--- /dev/null
+++ b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/MANIFEST.MF
@@ -0,0 +1,2 @@
+RegistrationClassName: com.sun.star.comp.extensionoptions.OptionsEventHandler
+
diff --git a/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/OptionsEventHandler.java b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/OptionsEventHandler.java
new file mode 100644
index 000000000000..bb38108e5eea
--- /dev/null
+++ b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/OptionsEventHandler.java
@@ -0,0 +1,449 @@
+*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ *************************************************************************/
+package com.sun.star.comp.extensionoptions;
+
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.XInitialization;
+import com.sun.star.lang.XTypeProvider;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.Exception;
+import com.sun.star.registry.XRegistryKey;
+import com.sun.star.awt.XContainerWindowEventHandler;
+import com.sun.star.awt.XControl;
+import com.sun.star.awt.XControlModel;
+import com.sun.star.awt.XControlContainer;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.container.NoSuchElementException;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.beans.PropertyState;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.util.XChangesBatch;
+
+/** A handler which supports multiple options pages which all
+ * have the same controls.
+ */
+public class OptionsEventHandler {
+
+ public static class _OptionsEventHandler extends WeakBase
+ implements XServiceInfo, XContainerWindowEventHandler {
+
+ static private final String __serviceName =
+ "com.sun.star.comp.extensionoptions.OptionsEventHandler";
+
+ private XComponentContext m_cmpCtx;
+
+ private XMultiComponentFactory m_xMCF;
+
+ private XNameAccess m_xAccessLeaves;
+
+ /**Names of supported options pages.
+ */
+ private String[] m_arWindowNames = {
+ "Writer1", "Writer2", "Writer3", "Calc1", "Calc2", "Calc3",
+ "Draw1", "Draw2", "Draw3", "Node1_1", "Node1_2", "Node1_3",
+ "Node2_1", "Node2_2", "Node2_3", "Node3_1", "Node3_2", "Node3_3"};
+
+ /**Names of the controls which are supported by this handler. All these
+ *controls must have a "Text" property.
+ */
+ private String[] m_arStringControls = {
+ "String0", "String1", "String2", "String3", "String4"};
+
+ public _OptionsEventHandler(XComponentContext xCompContext) {
+ m_cmpCtx = xCompContext;
+ m_xMCF = m_cmpCtx.getServiceManager();
+
+ //Create the com.sun.star.configuration.ConfigurationUpdateAccess
+ //for the registry node which contains the data for our option
+ //pages.
+ XMultiServiceFactory xConfig;
+ try {
+ xConfig = (XMultiServiceFactory) UnoRuntime.queryInterface(
+ XMultiServiceFactory.class,
+ m_cmpCtx.getServiceManager().createInstanceWithContext(
+ "com.sun.star.configuration.ConfigurationProvider", m_cmpCtx));
+ } catch (com.sun.star.uno.Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ //One argument for creating the ConfigurationUpdateAccess is the "nodepath".
+ //Our nodepath point to the node of which the direct subnodes represent the
+ //different options pages.
+ Object[] args = new Object[1];
+ args[0] = new PropertyValue(
+ "nodepath", 0, "/org.openoffice.desktop.deployment.options.ExtensionData/Leaves",
+ PropertyState.DIRECT_VALUE);
+
+ //We get the com.sun.star.container.XNameAccess from the instance of
+ //ConfigurationUpdateAccess and save it for later use.
+ try {
+ m_xAccessLeaves = (XNameAccess) UnoRuntime.queryInterface(
+ XNameAccess.class, xConfig.createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess", args));
+
+ } catch (com.sun.star.uno.Exception e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+
+ /** This method returns an array of all supported service names.
+ * @return Array of supported service names.
+ */
+ public String[] getSupportedServiceNames() {
+ return getServiceNames();
+ }
+
+ /** This method is a simple helper function to used in the
+ * static component initialisation functions as well as in
+ * getSupportedServiceNames.
+ */
+ public static String[] getServiceNames() {
+ String[] sSupportedServiceNames = { __serviceName };
+ return sSupportedServiceNames;
+ }
+
+ /** This method returns true, if the given service will be
+ * supported by the component.
+ * @param sServiceName Service name.
+ * @return True, if the given service name will be supported.
+ */
+ public boolean supportsService( String sServiceName ) {
+ return sServiceName.equals( __serviceName );
+ }
+
+ /** Return the class name of the component.
+ * @return Class name of the component.
+ */
+ public String getImplementationName() {
+ return _OptionsEventHandler.class.getName();
+ }
+
+ //XContainerWindowEventHandler
+ public boolean callHandlerMethod(com.sun.star.awt.XWindow aWindow,
+ Object aEventObject, String sMethod)
+ throws WrappedTargetException {
+ if (sMethod.equals("external_event") ){
+ try {
+ return handleExternalEvent(aWindow, aEventObject);
+ } catch (com.sun.star.uno.RuntimeException re) {
+ throw re;
+ } catch (com.sun.star.uno.Exception e) {
+ throw new WrappedTargetException(sMethod, this, e);
+ }
+ }
+
+ return true;
+ }
+
+ //XContainerWindowEventHandler
+ public String[] getSupportedMethodNames() {
+ return new String[] {"external_event"};
+ }
+
+ private boolean handleExternalEvent(com.sun.star.awt.XWindow aWindow, Object aEventObject)
+ throws com.sun.star.uno.Exception {
+ try {
+ String sMethod = AnyConverter.toString(aEventObject);
+ if (sMethod.equals("ok")) {
+ saveData(aWindow);
+ } else if (sMethod.equals("back") || sMethod.equals("initialize")) {
+ loadData(aWindow);
+ }
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "Method external_event requires a string in the event object argument.",
+ this, (short) -1);
+ }
+
+ return true;
+ }
+
+ private void saveData(com.sun.star.awt.XWindow aWindow)
+ throws com.sun.star.lang.IllegalArgumentException,
+ com.sun.star.uno.Exception {
+
+ //Determine the name of the options page. This serves two purposes. First, if this
+ //options page is supported by this handler and second we use the name two locate
+ //the corresponding data in the registry.
+ String sWindowName = getWindowName(aWindow);
+ if (sWindowName == null)
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "This window is not supported by this handler", this, (short) -1);
+
+ //To access the separate controls of the window we need to obtain the
+ //XControlContainer from the window implementation
+ XControlContainer xContainer = (XControlContainer) UnoRuntime.queryInterface(
+ XControlContainer.class, aWindow);
+ if (xContainer == null)
+ throw new com.sun.star.uno.Exception(
+ "Could not get XControlContainer from window.", this);
+
+ //This is an implementation which will be used for several options pages
+ //which all have the same controls. m_arStringControls is an array which
+ //contains the names.
+ for (int i = 0; i < m_arStringControls.length; i++) {
+
+ //To obtain the data from the controls we need to get their model.
+ //First get the respective control from the XControlContainer.
+ XControl xControl = xContainer.getControl(m_arStringControls[i]);
+
+ //This generic handler and the corresponding registry schema support
+ //up to five text controls. However, if a options page does not use all
+ //five controls then we will not complain here.
+ if (xControl == null)
+ continue;
+
+ //From the control we get the model, which in turn supports the
+ //XPropertySet interface, which we finally use to get the data from
+ //the control.
+ XPropertySet xProp = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, xControl.getModel());
+
+ if (xProp == null)
+ throw new com.sun.star.uno.Exception(
+ "Could not get XPropertySet from control.", this);
+ //Get the "Text" property.
+ Object aText = xProp.getPropertyValue("Text");
+ String sValue = null;
+
+ //The value is still contained in a com.sun.star.uno.Any - so convert it.
+ try {
+ sValue = AnyConverter.toString(aText);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "Wrong property type.", this, (short) -1);
+ }
+
+ //Now we have the actual string value of the control. What we need now is
+ //the XPropertySet of the respective property in the registry, so that we
+ //can store the value.
+ //To access the registry we have previously created a service instance
+ //of com.sun.star.configuration.ConfigurationUpdateAccess which supports
+ //com.sun.star.container.XNameAccess. The XNameAccess is used to get the
+ //particular registry node which represents this options page.
+ //Fortunately the name of the window is the same as the registry node.
+ XPropertySet xLeaf = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, m_xAccessLeaves.getByName(sWindowName));
+ if (xLeaf == null)
+ throw new com.sun.star.uno.Exception(
+ "XPropertySet not supported.", this);
+
+ //Finally we can set the value
+ xLeaf.setPropertyValue(m_arStringControls[i], sValue);
+ }
+
+ //Committing the changes will cause or changes to be written to the registry.
+ XChangesBatch xUpdateCommit =
+ (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class, m_xAccessLeaves);
+ xUpdateCommit.commitChanges();
+ }
+
+ private void loadData(com.sun.star.awt.XWindow aWindow)
+ throws com.sun.star.uno.Exception {
+
+ //Determine the name of the window. This serves two purposes. First, if this
+ //window is supported by this handler and second we use the name two locate
+ //the corresponding data in the registry.
+ String sWindowName = getWindowName(aWindow);
+ if (sWindowName == null)
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "The window is not supported by this handler", this, (short) -1);
+
+ //To acces the separate controls of the window we need to obtain the
+ //XControlContainer from window implementation
+ XControlContainer xContainer = (XControlContainer) UnoRuntime.queryInterface(
+ XControlContainer.class, aWindow);
+ if (xContainer == null)
+ throw new com.sun.star.uno.Exception(
+ "Could not get XControlContainer from window.", this);
+
+ //This is an implementation which will be used for several options pages
+ //which all have the same controls. m_arStringControls is an array which
+ //contains the names.
+ for (int i = 0; i < m_arStringControls.length; i++) {
+
+ //load the values from the registry
+ //To access the registry we have previously created a service instance
+ //of com.sun.star.configuration.ConfigurationUpdateAccess which supports
+ //com.sun.star.container.XNameAccess. We obtain now the section
+ //of the registry which is assigned to this options page.
+ XPropertySet xLeaf = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, m_xAccessLeaves.getByName(sWindowName));
+ if (xLeaf == null)
+ throw new com.sun.star.uno.Exception(
+ "XPropertySet not supported.", this);
+
+ //The properties in the registry have the same name as the respective
+ //controls. We use the names now to obtain the property values.
+ Object aValue = xLeaf.getPropertyValue(m_arStringControls[i]);
+
+ //Now that we have the value we need to set it at the corresponding
+ //control in the window. The XControlContainer, which we obtained earlier
+ //is the means to get hold of all the controls.
+ XControl xControl = xContainer.getControl(m_arStringControls[i]);
+
+ //This generic handler and the corresponding registry schema support
+ //up to five text controls. However, if a options page does not use all
+ //five controls then we will not complain here.
+ if (xControl == null)
+ continue;
+
+ //From the control we get the model, which in turn supports the
+ //XPropertySet interface, which we finally use to set the data at the
+ //control
+ XPropertySet xProp = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, xControl.getModel());
+
+ if (xProp == null)
+ throw new com.sun.star.uno.Exception(
+ "Could not get XPropertySet from control.", this);
+
+ //This handler supports only text controls, which are named "Pattern Field"
+ //in the dialog editor. We set the "Text" property.
+ xProp.setPropertyValue("Text", aValue);
+ }
+ }
+
+ //Checks if the name property of the window is one of the supported names and returns
+ //always a valid string or null
+ private String getWindowName(com.sun.star.awt.XWindow aWindow)
+ throws com.sun.star.uno.Exception {
+
+ if (aWindow == null)
+ new com.sun.star.lang.IllegalArgumentException(
+ "Method external_event requires that a window is passed as argument",
+ this, (short) -1);
+
+ //We need to get the control model of the window. Therefore the first step is
+ //to query for it.
+ XControl xControlDlg = (XControl) UnoRuntime.queryInterface(
+ XControl.class, aWindow);
+
+ if (xControlDlg == null)
+ throw new com.sun.star.uno.Exception(
+ "Cannot obtain XControl from XWindow in method external_event.");
+ //Now get model
+ XControlModel xModelDlg = xControlDlg.getModel();
+
+ if (xModelDlg == null)
+ throw new com.sun.star.uno.Exception(
+ "Cannot obtain XControlModel from XWindow in method external_event.", this);
+ //The model itself does not provide any information except that its
+ //implementation supports XPropertySet which is used to access the data.
+ XPropertySet xPropDlg = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, xModelDlg);
+ if (xPropDlg == null)
+ throw new com.sun.star.uno.Exception(
+ "Cannot obtain XPropertySet from window in method external_event.", this);
+
+ //Get the "Name" property of the window
+ Object aWindowName = xPropDlg.getPropertyValue("Name");
+
+ //Get the string from the returned com.sun.star.uno.Any
+ String sName = null;
+ try {
+ sName = AnyConverter.toString(aWindowName);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ throw new com.sun.star.uno.Exception(
+ "Name - property of window is not a string.", this);
+ }
+
+ //Eventually we can check if we this handler can "handle" this options page.
+ //The class has a member m_arWindowNames which contains all names of windows
+ //for which it is intended
+ for (int i = 0; i < m_arWindowNames.length; i++) {
+ if (m_arWindowNames[i].equals(sName)) {
+ return sName;
+ }
+ }
+ return null;
+ }
+ }
+
+
+ /**
+ * Gives a factory for creating the service.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns a <code>XSingleComponentFactory</code> for creating
+ * the component
+ * @param sImplName the name of the implementation for which a
+ * service is desired
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static XSingleComponentFactory __getComponentFactory(String sImplName)
+ {
+ XSingleComponentFactory xFactory = null;
+
+ if ( sImplName.equals( _OptionsEventHandler.class.getName() ) )
+ xFactory = Factory.createComponentFactory(_OptionsEventHandler.class,
+ _OptionsEventHandler.getServiceNames());
+
+ return xFactory;
+ }
+
+ /**
+ * Writes the service information into the given registry key.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns true if the operation succeeded
+ * @param regKey the registryKey
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+ return Factory.writeRegistryServiceInfo(_OptionsEventHandler.class.getName(),
+ _OptionsEventHandler.getServiceNames(),
+ regKey);
+ }
+
+ /** This method is a member of the interface for initializing an object
+ * directly after its creation.
+ * @param object This array of arbitrary objects will be passed to the
+ * component after its creation.
+ * @throws Exception Every exception will not be handled, but will be
+ * passed to the caller.
+ */
+ public void initialize( Object[] object )
+ throws com.sun.star.uno.Exception {
+ }
+
+}
diff --git a/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/makefile.mk b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/makefile.mk
new file mode 100644
index 000000000000..662fffce407c
--- /dev/null
+++ b/desktop/test/deployment/options/handler/com/sun/star/comp/extensionoptions/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..$/..$/..$/..$/..$/..
+PRJNAME = desktop
+PACKAGE = com$/sun$/star$/comp$/extensionoptions
+TARGET = options
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES = ridl.jar jurt.jar unoil.jar juh.jar
+
+
+JARTARGET = extensionoptions.jar
+JARCOMPRESS = TRUE
+CUSTOMMANIFESTFILE = MANIFEST.MF
+JARCLASSDIRS=com
+
+
+# --- Files --------------------------------------------------------
+
+JAVAFILES = OptionsEventHandler.java
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/test/deployment/options/leaf1.oxt b/desktop/test/deployment/options/leaf1.oxt
new file mode 100644
index 000000000000..9c3ff86985b6
--- /dev/null
+++ b/desktop/test/deployment/options/leaf1.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaf1mod.oxt b/desktop/test/deployment/options/leaf1mod.oxt
new file mode 100644
index 000000000000..d5d9fe6896f8
--- /dev/null
+++ b/desktop/test/deployment/options/leaf1mod.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaf2.oxt b/desktop/test/deployment/options/leaf2.oxt
new file mode 100644
index 000000000000..b95628900c40
--- /dev/null
+++ b/desktop/test/deployment/options/leaf2.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaves1.oxt b/desktop/test/deployment/options/leaves1.oxt
new file mode 100644
index 000000000000..037389a018b8
--- /dev/null
+++ b/desktop/test/deployment/options/leaves1.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaves2.oxt b/desktop/test/deployment/options/leaves2.oxt
new file mode 100644
index 000000000000..531b38566352
--- /dev/null
+++ b/desktop/test/deployment/options/leaves2.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/leaves3.oxt b/desktop/test/deployment/options/leaves3.oxt
new file mode 100644
index 000000000000..f5bb0f226239
--- /dev/null
+++ b/desktop/test/deployment/options/leaves3.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/modules1.oxt b/desktop/test/deployment/options/modules1.oxt
new file mode 100644
index 000000000000..bae652ffbc39
--- /dev/null
+++ b/desktop/test/deployment/options/modules1.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/modules2.oxt b/desktop/test/deployment/options/modules2.oxt
new file mode 100644
index 000000000000..d6d7956d459c
--- /dev/null
+++ b/desktop/test/deployment/options/modules2.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes1.oxt b/desktop/test/deployment/options/nodes1.oxt
new file mode 100644
index 000000000000..b1dfa18d3efa
--- /dev/null
+++ b/desktop/test/deployment/options/nodes1.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes2.oxt b/desktop/test/deployment/options/nodes2.oxt
new file mode 100644
index 000000000000..a35cfaba9dc8
--- /dev/null
+++ b/desktop/test/deployment/options/nodes2.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes3.oxt b/desktop/test/deployment/options/nodes3.oxt
new file mode 100644
index 000000000000..db0bc49da522
--- /dev/null
+++ b/desktop/test/deployment/options/nodes3.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes4.oxt b/desktop/test/deployment/options/nodes4.oxt
new file mode 100644
index 000000000000..fe0550fdc655
--- /dev/null
+++ b/desktop/test/deployment/options/nodes4.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/nodes5.oxt b/desktop/test/deployment/options/nodes5.oxt
new file mode 100644
index 000000000000..893e9ee3e216
--- /dev/null
+++ b/desktop/test/deployment/options/nodes5.oxt
Binary files differ
diff --git a/desktop/test/deployment/options/readme.txt b/desktop/test/deployment/options/readme.txt
new file mode 100644
index 000000000000..9879a72ceffa
--- /dev/null
+++ b/desktop/test/deployment/options/readme.txt
@@ -0,0 +1,200 @@
+Important: The hander component extensionoptions.jar in the extensions may not
+contain exactly the same sources as the one build in the handler directory. To
+make sure that debugging works build the handler directory and put the
+extensionoptions.jar into the extension.
+
+
+
+leaf1.oxt: Defines a leaf under the node WriterNode
+================================================================================
+
+leaf1mod.oxt: Defines a leaf under the node WriterNode
+
+It has a douplicate entry in the manifest.xml (OptionsDialog.xcu). This would cause a DisposedException when uninstalling on OOo 3.0 and prevent the extension from being uninstalled. This is actually a bug of the extensions. However, the error is difficult to investigate. Therefore this was fixed to make OOo more robust (i96690).
+================================================================================
+
+leaf2.oxt: Defines a leaf under a node that has a name which requires special
+"xml encoding". The name is "My Writer's & Settings". The node is not assigned
+to a Module and the Node/AllModules property is not true. This is a typical
+scenario when a Node had been added to an existing Module and later the Module
+was removed. This is a situation which actually should not occur. In this case
+DO NOT show the Node in the OOo's options dialog, because it shows only nodes
+for a particular module and in this case the Module for the Node is unknown.
+In the Extension Manager's
+options dialog this Node can be shown because the Module is irrelevant.
+See also nodes5.oxt.
+================================================================================
+
+leaves1.oxt: multiple ordered leaves under available nodes. The leaves Lables are
+localized for en-US and de. The following leaves should appear:
+
+Writer:
+-leaves1 Writer 1 en-US
+-leaves1 Writer 2 en-US
+-leaves1 Writer 3 en-US
+
+Calc:
+-leaves1 Calc 3 en-US
+-leaves1 Calc 3 en-US
+-leaves1 Calc 3 en-US
+
+Draw:
+-leaves1 Draw 3 en-US
+-leaves1 Draw 3 en-US
+-leaves1 Draw 3 en-US
+
+If a german office is used then the strings contain "de" instead of "en-US".
+================================================================================
+
+leaves2.oxt: Same as leaves1.oxt. Use together with leaves1.oxt to test the
+grouping of leaves.
+================================================================================
+
+leaves3.oxt: Same as leaves1.oxt, but the leaves are not ordered.
+================================================================================
+
+nodes1.oxt: Defines one node which has AllModules set and which has
+no children. Therefore this node should not be displayed.
+================================================================================
+
+nodes2.oxt: Defines 3 nodes which use AllModules and which form an
+ordered group. Every node defines also 3 nodes which have a determined order.
+
+-nodes2 node 1 en-US
+ -nodes2 node 1 leaf 1 en-US
+ -nodes2 node 1 leaf 2 en-US
+ -nodes2 node 1 leaf 3 en-US
+
+-nodes2 node 2 en-US
+ -nodes2 node 2 leaf 1 en-US
+ -nodes2 node 2 leaf 2 en-US
+ -nodes2 node 2 leaf 3 en-US
+
+-nodes2 node 3 en-US
+ -nodes2 node 3 leaf 1 en-US
+ -nodes2 node 3 leaf 2 en-US
+ -nodes2 node 3 leaf 3 en-US
+
+================================================================================
+
+nodes3.oxt: Defines 3 nodes which are placed under different existing Modules.
+The nodes and there leaves are ordered.
+
+Context Writer:
+- nodes3 node 1
+ nodes3 node 1 leaf 1 en-US
+ nodes3 node 1 leaf 2 en-US
+ nodes3 node 1 leaf 3 en-US
+
+- nodes3 node 2
+ nodes3 node 2 leaf 1 en-US
+ nodes3 node 2 leaf 2 en-US
+ nodes3 node 2 leaf 3 en-US
+
+- nodes3 node 3
+ nodes3 node 3 leaf 1 en-US
+ nodes3 node 3 leaf 2 en-US
+ nodes3 node 3 leaf 3 en-US
+
+Context Calc:
+- nodes3 node 1
+ nodes3 node 1 leaf 1 en-US
+ nodes3 node 1 leaf 2 en-US
+ nodes3 node 1 leaf 3 en-US
+
+- nodes3 node 3
+ nodes3 node 3 leaf 1 en-US
+ nodes3 node 3 leaf 2 en-US
+ nodes3 node 3 leaf 3 en-US
+
+Context Draw:
+- nodes3 node 2
+ nodes3 node 2 leaf 1 en-US
+ nodes3 node 2 leaf 2 en-US
+ nodes3 node 2 leaf 3 en-US
+
+================================================================================
+
+nodes4.oxt: Same as nodes3.oxt. Use together with nodes3.txt to test the
+grouping of nodes.
+================================================================================
+
+nodes5.oxt: Defines a node which in turn defines 3 leaves. The Node
+is not assigned to a Module and the AllModule property is false (which is the
+default).This may happen when a node
+had been added to an already existing Module and then this Module was removed. For
+example, an extension adds a node to the "Writer Module" and the
+next office update removes the "Writer Module" (which is rather inconceivable).
+Then the node and its leaves MUST NOT be displayed in OOo's options dialog,
+because the Module is not known. However, it can be displayed in the
+options dialog of the Extension Manager. See also the description for leaf2.oxt.
+================================================================================
+
+modules1.oxt: Defines two Modules and three Nodes. The Nodes may not
+be displayed in OOo's options dialog because there is currently no application
+which uses this Module. However the Nodes are displayed in the options dialog
+of the Extension Manager.
+There are three Nodes defined. The relation ship is this:
+
+-module1
+ -node 1
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 2
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 3
+ -leaf 1
+ -leaf 2
+ -leaf 3
+
+-module2
+ -node1
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node3
+ -leaf 1
+ -leaf 2
+ -leaf 3
+
+The options dialog of the Extension Manager shall display only three nodes:
+
+ -node 1
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 2
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 3
+ -leaf 1
+ -leaf 2
+ -leaf 3
+
+or
+
+ -node 1
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 3
+ -leaf 1
+ -leaf 2
+ -leaf 3
+ -node 2
+ -leaf 1
+ -leaf 2
+ -leaf 3
+
+Since the order of Module|s is not defined, the dialog may display first the
+Nodes from module2 and then from module1. If a node is already displayed then
+it is not shown again.
+
+================================================================================
+
+modules2.oxt: Same as modules1, except that the order of nodes and leaves
+is not defined.
diff --git a/desktop/test/deployment/simple_license/BadDesc.oxt b/desktop/test/deployment/simple_license/BadDesc.oxt
new file mode 100644
index 000000000000..436778d54dd4
--- /dev/null
+++ b/desktop/test/deployment/simple_license/BadDesc.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/BadNamespace.oxt b/desktop/test/deployment/simple_license/BadNamespace.oxt
new file mode 100644
index 000000000000..e439c9e171de
--- /dev/null
+++ b/desktop/test/deployment/simple_license/BadNamespace.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/BadRoot.oxt b/desktop/test/deployment/simple_license/BadRoot.oxt
new file mode 100644
index 000000000000..1f6c60c992ba
--- /dev/null
+++ b/desktop/test/deployment/simple_license/BadRoot.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale1.oxt b/desktop/test/deployment/simple_license/Locale1.oxt
new file mode 100644
index 000000000000..51ecb5c75c6c
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale1.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale2.oxt b/desktop/test/deployment/simple_license/Locale2.oxt
new file mode 100644
index 000000000000..bb6b236a5d07
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale2.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale3.oxt b/desktop/test/deployment/simple_license/Locale3.oxt
new file mode 100644
index 000000000000..56bfedc24025
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale3.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale4.oxt b/desktop/test/deployment/simple_license/Locale4.oxt
new file mode 100644
index 000000000000..9a465bc7cff3
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale4.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale5.oxt b/desktop/test/deployment/simple_license/Locale5.oxt
new file mode 100644
index 000000000000..ce16830c13fa
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale5.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Locale6.oxt b/desktop/test/deployment/simple_license/Locale6.oxt
new file mode 100644
index 000000000000..770d32506ee3
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Locale6.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/LongLic.oxt b/desktop/test/deployment/simple_license/LongLic.oxt
new file mode 100644
index 000000000000..a0a49daebacf
--- /dev/null
+++ b/desktop/test/deployment/simple_license/LongLic.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/MissingLic.oxt b/desktop/test/deployment/simple_license/MissingLic.oxt
new file mode 100644
index 000000000000..04d58fd117a2
--- /dev/null
+++ b/desktop/test/deployment/simple_license/MissingLic.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/MissingLicRef.oxt b/desktop/test/deployment/simple_license/MissingLicRef.oxt
new file mode 100644
index 000000000000..01c9d19a2833
--- /dev/null
+++ b/desktop/test/deployment/simple_license/MissingLicRef.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/NoDefLang.oxt b/desktop/test/deployment/simple_license/NoDefLang.oxt
new file mode 100644
index 000000000000..3eadd5254ccc
--- /dev/null
+++ b/desktop/test/deployment/simple_license/NoDefLang.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/NoDesc.oxt b/desktop/test/deployment/simple_license/NoDesc.oxt
new file mode 100644
index 000000000000..ac83dac97eba
--- /dev/null
+++ b/desktop/test/deployment/simple_license/NoDesc.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/NoLang.oxt b/desktop/test/deployment/simple_license/NoLang.oxt
new file mode 100644
index 000000000000..a4f3dd43a079
--- /dev/null
+++ b/desktop/test/deployment/simple_license/NoLang.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/Prefix.oxt b/desktop/test/deployment/simple_license/Prefix.oxt
new file mode 100644
index 000000000000..3e09b8d804e9
--- /dev/null
+++ b/desktop/test/deployment/simple_license/Prefix.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/ShortLicense.oxt b/desktop/test/deployment/simple_license/ShortLicense.oxt
new file mode 100644
index 000000000000..efcfdc98e125
--- /dev/null
+++ b/desktop/test/deployment/simple_license/ShortLicense.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/ShortLicenseShared.oxt b/desktop/test/deployment/simple_license/ShortLicenseShared.oxt
new file mode 100644
index 000000000000..775559a2c7a3
--- /dev/null
+++ b/desktop/test/deployment/simple_license/ShortLicenseShared.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/suppress_license.oxt b/desktop/test/deployment/simple_license/suppress_license.oxt
new file mode 100755
index 000000000000..2bacd6aa378b
--- /dev/null
+++ b/desktop/test/deployment/simple_license/suppress_license.oxt
Binary files differ
diff --git a/desktop/test/deployment/simple_license/tests_simple_license.odt b/desktop/test/deployment/simple_license/tests_simple_license.odt
new file mode 100644
index 000000000000..b0c86e11c69b
--- /dev/null
+++ b/desktop/test/deployment/simple_license/tests_simple_license.odt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/change1.oxt b/desktop/test/deployment/update/changing_display_name/change1.oxt
new file mode 100644
index 000000000000..c919129ab6d7
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/change1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/change1_mod.oxt b/desktop/test/deployment/update/changing_display_name/change1_mod.oxt
new file mode 100644
index 000000000000..5ab99d7bf224
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/change1_mod.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/readme.txt b/desktop/test/deployment/update/changing_display_name/readme.txt
new file mode 100644
index 000000000000..905f0be9a962
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/readme.txt
@@ -0,0 +1,13 @@
+
+The default display name, if nothing is provided by the extension, is the file name.
+The display name could be changed in different versions. There are three versions
+of change1.oxt available:
+
+v1: no display name
+v2: change1 de
+v3: change1 de - changed display name -
+
+change1_mod.oxt is the same as change1.oxt version 1 except that is has a display name.
+This situation should actually never arise, because the version should always be
+changed when the extension is changed - and be it only the display name.
+
diff --git a/desktop/test/deployment/update/changing_display_name/update1/change1.oxt b/desktop/test/deployment/update/changing_display_name/update1/change1.oxt
new file mode 100644
index 000000000000..ef034f94459f
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/update1/change1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/update1/change1.update.xml b/desktop/test/deployment/update/changing_display_name/update1/change1.update.xml
new file mode 100644
index 000000000000..a4fefb6d96ba
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/update1/change1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice/framework/desktop/changing_display_name/change1" />
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/changing_display_name/update1/change1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/changing_display_name/update2/change1.oxt b/desktop/test/deployment/update/changing_display_name/update2/change1.oxt
new file mode 100644
index 000000000000..551f5a3f48c3
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/update2/change1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/changing_display_name/update2/change1.update.xml b/desktop/test/deployment/update/changing_display_name/update2/change1.update.xml
new file mode 100644
index 000000000000..8e52ce3c2b2d
--- /dev/null
+++ b/desktop/test/deployment/update/changing_display_name/update2/change1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice/framework/desktop/changing_display_name/change1" />
+ <version value="3.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/changing_display_name/update2/change1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/default_url/default1.oxt b/desktop/test/deployment/update/default_url/default1.oxt
new file mode 100644
index 000000000000..3fa8c9f08f8d
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/default1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/default_url/default2.oxt b/desktop/test/deployment/update/default_url/default2.oxt
new file mode 100644
index 000000000000..d54ce88c51d6
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/default2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/default_url/readme.txt b/desktop/test/deployment/update/default_url/readme.txt
new file mode 100644
index 000000000000..4ae7936bfc18
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/readme.txt
@@ -0,0 +1,9 @@
+Tests for using the default URL for update information. This URL is currently contained in
+the version.ini (ExtensionUpdateURL) and is used to obtain update information for extensions which do not provide
+an URL themselves.
+
+The extensions default1.oxt and default2.oxt do not have a URL for update information.
+
+To test this one has to put this entry into the version.ini:
+
+ExtensionUpdateURL=http://extensions.openoffice.org/testarea/desktop/default_url/update/feed1.xml
diff --git a/desktop/test/deployment/update/default_url/update/default1.oxt b/desktop/test/deployment/update/default_url/update/default1.oxt
new file mode 100644
index 000000000000..198395c76e5d
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/default1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/default_url/update/default1.update.xml b/desktop/test/deployment/update/default_url/update/default1.update.xml
new file mode 100644
index 000000000000..b3d78e29e814
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/default1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.default1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/default_url/update/default1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/default_url/update/default2.oxt b/desktop/test/deployment/update/default_url/update/default2.oxt
new file mode 100644
index 000000000000..198395c76e5d
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/default2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/default_url/update/default2.update.xml b/desktop/test/deployment/update/default_url/update/default2.update.xml
new file mode 100644
index 000000000000..a5894a18b05b
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/default2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.default2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/default_url/update/default2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/default_url/update/feed1.xml b/desktop/test/deployment/update/default_url/update/feed1.xml
new file mode 100644
index 000000000000..b504b7b4b00c
--- /dev/null
+++ b/desktop/test/deployment/update/default_url/update/feed1.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
+
+ <title>OpenOffice.org Update Feed</title>
+ <link rel="alternate" type="text/html" href="http://update.services.openoffice.org/ooo/snapshot.html"/>
+ <updated>2006-11-06T18:30:02Z</updated>
+ <author>
+ <name>The OpenOffice.org Project</name>
+ <uri>http://openoffice.org</uri>
+ <email>updatefeed@openoffice.org</email>
+ </author>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566e9d</id>
+ <entry>
+ <title>default1.oxt version 2.0 available</title>
+ <link rel="alternate" type="text/html"
+ href="http://extensions.openoffice.org"/>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566e9f</id>
+ <category term="org.openoffice.legacy.default1.oxt" label="default1.oxt" />
+ <updated>2006-11-06T18:30:02Z</updated>
+ <summary>Click here to go to the download page.</summary>
+ <content type="application/xml" src="http://extensions.openoffice.org/testarea/desktop/default_url/update/default1.update.xml" />
+ </entry>
+ <entry>
+ <title>default2.oxt version 2.0 available</title>
+ <link rel="alternate" type="text/html"
+ href="http://extensions.openoffice.org"/>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566eaf</id>
+ <category term="org.openoffice.legacy.default2.oxt" label="default2.oxt" />
+ <updated>2006-11-06T18:30:02Z</updated>
+ <summary>Click here to go to the download page.</summary>
+ <content type="application/xml" src="http://extensions.openoffice.org/testarea/desktop/default_url/update/default2.update.xml" />
+ </entry>
+</feed>
diff --git a/desktop/test/deployment/update/defect/fail1.oxt b/desktop/test/deployment/update/defect/fail1.oxt
new file mode 100644
index 000000000000..5b5cdba2cdbc
--- /dev/null
+++ b/desktop/test/deployment/update/defect/fail1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/fail2.oxt b/desktop/test/deployment/update/defect/fail2.oxt
new file mode 100644
index 000000000000..61b0306f0947
--- /dev/null
+++ b/desktop/test/deployment/update/defect/fail2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/fail3.oxt b/desktop/test/deployment/update/defect/fail3.oxt
new file mode 100644
index 000000000000..9da26d48a636
--- /dev/null
+++ b/desktop/test/deployment/update/defect/fail3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/fail4.oxt b/desktop/test/deployment/update/defect/fail4.oxt
new file mode 100644
index 000000000000..66b87caa14b7
--- /dev/null
+++ b/desktop/test/deployment/update/defect/fail4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/info1.oxt b/desktop/test/deployment/update/defect/info1.oxt
new file mode 100644
index 000000000000..9ffd373fa11f
--- /dev/null
+++ b/desktop/test/deployment/update/defect/info1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/info2.oxt b/desktop/test/deployment/update/defect/info2.oxt
new file mode 100644
index 000000000000..229a52c3bc69
--- /dev/null
+++ b/desktop/test/deployment/update/defect/info2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/info3.oxt b/desktop/test/deployment/update/defect/info3.oxt
new file mode 100644
index 000000000000..b702f3e00417
--- /dev/null
+++ b/desktop/test/deployment/update/defect/info3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/readme.txt b/desktop/test/deployment/update/defect/readme.txt
new file mode 100644
index 000000000000..5e8322f5cf26
--- /dev/null
+++ b/desktop/test/deployment/update/defect/readme.txt
@@ -0,0 +1,15 @@
+The updates, that is the newer versions, are defect. However, only fail2.oxt fails to install. The other extensions can be installed directly and through an update.
+
+fail1.oxt: in version2 the contained t.rdb was renamed so that it is not found (t.rdb is referenced in the manifest.xml).
+
+fail2.oxt: in version 2 the contained t.rdb is corrupted. It is a renamed .txt file which contains some text.
+
+fail3.oxt: in version 2 the contained t.rdb is corrupted. It is a renamed .txt file which does not contain any text.
+
+fail4.oxt: the version 2 references by fail4.update.xml is empty.
+
+info1.oxt: The update information file has length null.
+
+info2.oxt: The update information does not contain xml.
+
+info3.oxt: The update information contain an error: the tag update information contains two opening brackets (<<update-information>) \ No newline at end of file
diff --git a/desktop/test/deployment/update/defect/update/fail1.oxt b/desktop/test/deployment/update/defect/update/fail1.oxt
new file mode 100644
index 000000000000..dbcc7cd73eb9
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/update/fail1.update.xml b/desktop/test/deployment/update/defect/update/fail1.update.xml
new file mode 100644
index 000000000000..40f2d1c7df9f
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.fail1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/fail1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/defect/update/fail2.oxt b/desktop/test/deployment/update/defect/update/fail2.oxt
new file mode 100644
index 000000000000..6df0c3cf9977
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/update/fail2.update.xml b/desktop/test/deployment/update/defect/update/fail2.update.xml
new file mode 100644
index 000000000000..d6bdaccb30e9
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.fail2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/fail2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/defect/update/fail3.oxt b/desktop/test/deployment/update/defect/update/fail3.oxt
new file mode 100644
index 000000000000..2d340f41443b
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/update/fail3.update.xml b/desktop/test/deployment/update/defect/update/fail3.update.xml
new file mode 100644
index 000000000000..e7f2606d604c
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail3.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.fail3.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/fail3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/defect/update/fail4.oxt b/desktop/test/deployment/update/defect/update/fail4.oxt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail4.oxt
diff --git a/desktop/test/deployment/update/defect/update/fail4.update.xml b/desktop/test/deployment/update/defect/update/fail4.update.xml
new file mode 100644
index 000000000000..4b293f28e034
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/fail4.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.fail4.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/fail4.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/defect/update/info1.update.xml b/desktop/test/deployment/update/defect/update/info1.update.xml
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/info1.update.xml
diff --git a/desktop/test/deployment/update/defect/update/info2.update.xml b/desktop/test/deployment/update/defect/update/info2.update.xml
new file mode 100644
index 000000000000..1446608022f0
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/info2.update.xml
@@ -0,0 +1 @@
+This is a invalid update information file!!!
diff --git a/desktop/test/deployment/update/defect/update/info3.oxt b/desktop/test/deployment/update/defect/update/info3.oxt
new file mode 100644
index 000000000000..60debac57c4e
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/info3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/defect/update/info3.update.xml b/desktop/test/deployment/update/defect/update/info3.update.xml
new file mode 100644
index 000000000000..62306e55b693
--- /dev/null
+++ b/desktop/test/deployment/update/defect/update/info3.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.info3.oxt"/>
+ <version value="2.0" />
+ <<update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/defect/update/info3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/dependencies/publisher_en.html b/desktop/test/deployment/update/dependencies/publisher_en.html
new file mode 100644
index 000000000000..37dbc2b9d6ce
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/publisher_en.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My Extension Company</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/dependencies/readme.txt b/desktop/test/deployment/update/dependencies/readme.txt
new file mode 100644
index 000000000000..3c71da24884d
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/readme.txt
@@ -0,0 +1,32 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+update-dependencies.oxt is an extension that itself has no dependencies, but
+whose update has unsatisfied dependencies (and also uses update-website).
+
+The update information contain also publisher and release notes information,
+which should be displayed in the update dialog.
diff --git a/desktop/test/deployment/update/dependencies/release-notes_en.html b/desktop/test/deployment/update/dependencies/release-notes_en.html
new file mode 100644
index 000000000000..0971f78d1484
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/release-notes_en.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/dependencies/update-dependencies.oxt b/desktop/test/deployment/update/dependencies/update-dependencies.oxt
new file mode 100644
index 000000000000..513b25d20763
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/update-dependencies.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/dependencies/update/update-dependencies.update.xml b/desktop/test/deployment/update/dependencies/update/update-dependencies.update.xml
new file mode 100644
index 000000000000..bf8a399da116
--- /dev/null
+++ b/desktop/test/deployment/update/dependencies/update/update-dependencies.update.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************************
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ Copyright 2000, 2010 Oracle and/or its affiliates.
+
+ 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.
+
+ ************************************************************************ -->
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:d="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/dependencies/update-dependencies.oxt"/>
+ <version value="2.0"/>
+ <dependencies>
+ <dependency d:name="&amp; &lt; &gt; &apos; &quot; > ' tab&#x9;. crlf&#xD;&#xA;. em-dash&#x2014;. line-separator&#x2028;. paragraph-separator&#x2029;. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/>
+ <dependency d:name="Dependency 1"/>
+ <dependency d:name="Dependency 2"/>
+ <dependency d:name="Dependency 3"/>
+ <dependency d:name="Dependency 4"/>
+ <dependency d:name="Dependency 5"/>
+ <dependency d:name="Dependency 6"/>
+ <dependency d:name="Dependency 7"/>
+ <dependency d:name="Dependency 8"/>
+ <dependency d:name="Dependency 9"/>
+ <dependency d:name="Dependency 10"/>
+ <dependency d:name="Dependency 11"/>
+ <dependency d:name="Dependency 12"/>
+ <dependency d:name="Dependency 13"/>
+ <dependency d:name="Dependency 14"/>
+ <dependency d:name="Dependency 15"/>
+ <dependency d:name="Dependency 16"/>
+ <dependency d:name="Dependency 17"/>
+ <dependency d:name="Dependency 18"/>
+ <dependency d:name="Dependency 19"/>
+ <dependency d:name="Dependency 20"/>
+ <dependency/>
+ <d:OpenOffice.org-minimal-version value="2.1" d:name="OpenOffice.org 2.1"/>
+ </dependencies>
+ <update-website>
+ <src xlink:href="http://nowhere.openoffice.org"/>
+ <src xlink:href="http://nowhere.openoffice.org/2"/>
+ </update-website>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/dependencies/publisher_en.html" lang="en">My Extension Company</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/dependencies/release-notes_en.html" lang="en" />
+ </release-notes>
+
+</description>
diff --git a/desktop/test/deployment/update/license/lic1.oxt b/desktop/test/deployment/update/license/lic1.oxt
new file mode 100644
index 000000000000..43bfe3b77b2d
--- /dev/null
+++ b/desktop/test/deployment/update/license/lic1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/lic2.oxt b/desktop/test/deployment/update/license/lic2.oxt
new file mode 100644
index 000000000000..266a45e9a857
--- /dev/null
+++ b/desktop/test/deployment/update/license/lic2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/lic3.oxt b/desktop/test/deployment/update/license/lic3.oxt
new file mode 100644
index 000000000000..3f1b98960043
--- /dev/null
+++ b/desktop/test/deployment/update/license/lic3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/readme.txt b/desktop/test/deployment/update/license/readme.txt
new file mode 100644
index 000000000000..03123d2c5812
--- /dev/null
+++ b/desktop/test/deployment/update/license/readme.txt
@@ -0,0 +1,9 @@
+The extensions contain a license which is displayed during installaion. If a the license is displayed during a update can be determined by the attribute
+/description/registration/simple-license/@suppress-on-update
+
+The default value is false, which means that the attribute is not set, then the license is displayed during an update.
+
+lic1.oxt: attribute not set
+lic2.oxt: attribute set to false
+lic3.oxt: attribute set to true
+
diff --git a/desktop/test/deployment/update/license/update/lic1.oxt b/desktop/test/deployment/update/license/update/lic1.oxt
new file mode 100644
index 000000000000..cc91e1ff16fe
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/update/lic1.update.xml b/desktop/test/deployment/update/license/update/lic1.update.xml
new file mode 100644
index 000000000000..6b23b97890fc
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.lic1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/license/update/lic1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/license/update/lic2.oxt b/desktop/test/deployment/update/license/update/lic2.oxt
new file mode 100644
index 000000000000..351000792487
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/update/lic2.update.xml b/desktop/test/deployment/update/license/update/lic2.update.xml
new file mode 100644
index 000000000000..40f3fa47bc99
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.lic2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/license/update/lic2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/license/update/lic3.oxt b/desktop/test/deployment/update/license/update/lic3.oxt
new file mode 100644
index 000000000000..6ac6e0fd0fd1
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/license/update/lic3.update.xml b/desktop/test/deployment/update/license/update/lic3.update.xml
new file mode 100644
index 000000000000..a9c2a7995d7c
--- /dev/null
+++ b/desktop/test/deployment/update/license/update/lic3.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.lic3.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/license/update/lic3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/platform/all1.oxt b/desktop/test/deployment/update/platform/all1.oxt
new file mode 100644
index 000000000000..ad9662a7c226
--- /dev/null
+++ b/desktop/test/deployment/update/platform/all1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/all2.oxt b/desktop/test/deployment/update/platform/all2.oxt
new file mode 100644
index 000000000000..632d11b42938
--- /dev/null
+++ b/desktop/test/deployment/update/platform/all2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/all3.oxt b/desktop/test/deployment/update/platform/all3.oxt
new file mode 100644
index 000000000000..ab781552a5aa
--- /dev/null
+++ b/desktop/test/deployment/update/platform/all3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/freebsd_x86.oxt b/desktop/test/deployment/update/platform/freebsd_x86.oxt
new file mode 100644
index 000000000000..338f5761deb1
--- /dev/null
+++ b/desktop/test/deployment/update/platform/freebsd_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/freebsd_x86_64.oxt b/desktop/test/deployment/update/platform/freebsd_x86_64.oxt
new file mode 100644
index 000000000000..39fee6de1a77
--- /dev/null
+++ b/desktop/test/deployment/update/platform/freebsd_x86_64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/invalid1.oxt b/desktop/test/deployment/update/platform/invalid1.oxt
new file mode 100644
index 000000000000..13d709f438fc
--- /dev/null
+++ b/desktop/test/deployment/update/platform/invalid1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/invalid2.oxt b/desktop/test/deployment/update/platform/invalid2.oxt
new file mode 100644
index 000000000000..f14257191b81
--- /dev/null
+++ b/desktop/test/deployment/update/platform/invalid2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/invalid3.oxt b/desktop/test/deployment/update/platform/invalid3.oxt
new file mode 100644
index 000000000000..cadffa4f2ac1
--- /dev/null
+++ b/desktop/test/deployment/update/platform/invalid3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_arm_eabi.oxt b/desktop/test/deployment/update/platform/linux_arm_eabi.oxt
new file mode 100644
index 000000000000..9c504e841b98
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_arm_eabi.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_arm_oabi.oxt b/desktop/test/deployment/update/platform/linux_arm_oabi.oxt
new file mode 100644
index 000000000000..f2c987f645a7
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_arm_oabi.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_ia64.oxt b/desktop/test/deployment/update/platform/linux_ia64.oxt
new file mode 100644
index 000000000000..f579a18ab90d
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_ia64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_mips_eb.oxt b/desktop/test/deployment/update/platform/linux_mips_eb.oxt
new file mode 100644
index 000000000000..bf0bd942332b
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_mips_eb.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_mips_el.oxt b/desktop/test/deployment/update/platform/linux_mips_el.oxt
new file mode 100644
index 000000000000..6bd56446831b
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_mips_el.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_powerpc.oxt b/desktop/test/deployment/update/platform/linux_powerpc.oxt
new file mode 100644
index 000000000000..e301a3fb3ad1
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_powerpc.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_powerpc64.oxt b/desktop/test/deployment/update/platform/linux_powerpc64.oxt
new file mode 100644
index 000000000000..e5f3ae063923
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_powerpc64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_s390.oxt b/desktop/test/deployment/update/platform/linux_s390.oxt
new file mode 100644
index 000000000000..199702ebf056
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_s390.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_s390x.oxt b/desktop/test/deployment/update/platform/linux_s390x.oxt
new file mode 100644
index 000000000000..2ed250833fb1
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_s390x.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_sparc.oxt b/desktop/test/deployment/update/platform/linux_sparc.oxt
new file mode 100644
index 000000000000..53dfc71e0c4e
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_sparc.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_x86.oxt b/desktop/test/deployment/update/platform/linux_x86.oxt
new file mode 100644
index 000000000000..8379539cad34
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_x86_64.oxt b/desktop/test/deployment/update/platform/linux_x86_64.oxt
new file mode 100644
index 000000000000..0fb18227522f
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_x86_64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/macosx_powerpc.oxt b/desktop/test/deployment/update/platform/macosx_powerpc.oxt
new file mode 100644
index 000000000000..7c146347127a
--- /dev/null
+++ b/desktop/test/deployment/update/platform/macosx_powerpc.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/macosx_x86.oxt b/desktop/test/deployment/update/platform/macosx_x86.oxt
new file mode 100644
index 000000000000..a20aadfefffd
--- /dev/null
+++ b/desktop/test/deployment/update/platform/macosx_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/mul1.oxt b/desktop/test/deployment/update/platform/mul1.oxt
new file mode 100644
index 000000000000..b3b555969bdf
--- /dev/null
+++ b/desktop/test/deployment/update/platform/mul1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/os2_x86.oxt b/desktop/test/deployment/update/platform/os2_x86.oxt
new file mode 100644
index 000000000000..1c7fd40bef9f
--- /dev/null
+++ b/desktop/test/deployment/update/platform/os2_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/readme.txt b/desktop/test/deployment/update/platform/readme.txt
new file mode 100644
index 000000000000..2ab102a27d3c
--- /dev/null
+++ b/desktop/test/deployment/update/platform/readme.txt
@@ -0,0 +1,49 @@
+Extension which only support one platform
+========================================================
+
+freebsd_x86.oxt: freebsd_x86
+freebsd_x86_86.oxt: freebsd_x86_64
+linux_arm_eabi.oxt: linux_arm_eabi
+linux_arm_oabi.oxt: linux_arm_oabi
+linux_ia64.oxt: linux_ia64
+linux_mips_eb.oxt: linux_mips_eb
+linux_mips_el.oxt: linux_mips_el
+linux_powerpc64.oxt: linux_powerpc64
+linux_powerpc.oxt: linux_powerpc
+linux_s390.oxt: linux_s390
+linux_s390x.oxt: linux_s390x
+linux_sparc.oxt: linux_sparc
+linux_x86.oxt: linux_x86
+linux_x86_64.oxt: linux_x86_64
+macos_powerpc.oxt: macos_powerpc
+macos_x86.oxt: macos_x86
+solaris_sparc.oxt: solaris_sparc
+solaris_x86.oxt: solaris_x86
+windows_x86.oxt: windows_x86
+os2_x86.oxt: os/2_x86
+
+Extensions which support multiple platforms
+=======================================================
+mul1.oxt: windows_x86, linux_x86, solaris_x86
+
+
+All platforms
+=========================================================
+all1.oxt: all, The <platform> element is missing. Default is "all".
+
+all2.oxt: all, <platform value="all" />
+
+all3.oxt: all, no description.xml
+
+
+
+Invalid platforms
+=========================================================
+The following extensions cannot be installed because the platform element
+is not correct. We assume that no valid platform is defined.
+
+invalid1.oxt: <platform />
+
+invalid2.oxt: <platform value=""/>
+
+invalid3.oxt: <platform value="," />
diff --git a/desktop/test/deployment/update/platform/solaris_sparc.oxt b/desktop/test/deployment/update/platform/solaris_sparc.oxt
new file mode 100644
index 000000000000..a61f81f43942
--- /dev/null
+++ b/desktop/test/deployment/update/platform/solaris_sparc.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/solaris_x86.oxt b/desktop/test/deployment/update/platform/solaris_x86.oxt
new file mode 100644
index 000000000000..44d43df69184
--- /dev/null
+++ b/desktop/test/deployment/update/platform/solaris_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/windows_x86.oxt b/desktop/test/deployment/update/platform/windows_x86.oxt
new file mode 100644
index 000000000000..c66a9b1418fa
--- /dev/null
+++ b/desktop/test/deployment/update/platform/windows_x86.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub1.oxt b/desktop/test/deployment/update/publisher/pub1.oxt
new file mode 100644
index 000000000000..c44ee9f3bc56
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub10.oxt b/desktop/test/deployment/update/publisher/pub10.oxt
new file mode 100644
index 000000000000..1e7410ec1b2e
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub10.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub11.oxt b/desktop/test/deployment/update/publisher/pub11.oxt
new file mode 100644
index 000000000000..ef7fbca5e63a
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub11.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub2.oxt b/desktop/test/deployment/update/publisher/pub2.oxt
new file mode 100644
index 000000000000..438bcae830a3
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub3.oxt b/desktop/test/deployment/update/publisher/pub3.oxt
new file mode 100644
index 000000000000..62fd69f5595a
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub4.oxt b/desktop/test/deployment/update/publisher/pub4.oxt
new file mode 100644
index 000000000000..4f6224f780cd
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub5.oxt b/desktop/test/deployment/update/publisher/pub5.oxt
new file mode 100644
index 000000000000..1774e6cd35c3
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub5.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub6.oxt b/desktop/test/deployment/update/publisher/pub6.oxt
new file mode 100644
index 000000000000..791a37f8e710
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub6.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub7.oxt b/desktop/test/deployment/update/publisher/pub7.oxt
new file mode 100644
index 000000000000..96e96887d0b1
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub7.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub8.oxt b/desktop/test/deployment/update/publisher/pub8.oxt
new file mode 100644
index 000000000000..dc9f0ce34d95
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub8.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/pub9.oxt b/desktop/test/deployment/update/publisher/pub9.oxt
new file mode 100644
index 000000000000..5e8ba9ebc154
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/pub9.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/publisher_de-DE-altmark.html b/desktop/test/deployment/update/publisher/publisher_de-DE-altmark.html
new file mode 100644
index 000000000000..c770b914ad78
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_de-DE-altmark.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-DE-altmark</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_de-DE.html b/desktop/test/deployment/update/publisher/publisher_de-DE.html
new file mode 100644
index 000000000000..b06ed7088f08
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_de-DE.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice de-DE</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_de.html b/desktop/test/deployment/update/publisher/publisher_de.html
new file mode 100644
index 000000000000..4cba9f423d5b
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_de.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice de</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-GB.html b/desktop/test/deployment/update/publisher/publisher_en-GB.html
new file mode 100644
index 000000000000..c73cf6219b78
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-GB.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-GB</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-US-region1.html b/desktop/test/deployment/update/publisher/publisher_en-US-region1.html
new file mode 100644
index 000000000000..68beac724894
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-US-region1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-US-region1</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-US-region2.html b/desktop/test/deployment/update/publisher/publisher_en-US-region2.html
new file mode 100644
index 000000000000..501adb659664
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-US-region2.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-US-region2</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-US.html b/desktop/test/deployment/update/publisher/publisher_en-US.html
new file mode 100644
index 000000000000..fd2575150315
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-US.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-US</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en-region3.html b/desktop/test/deployment/update/publisher/publisher_en-region3.html
new file mode 100644
index 000000000000..b9fdc9d657b4
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en-region3.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en-region3</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/publisher_en.html b/desktop/test/deployment/update/publisher/publisher_en.html
new file mode 100644
index 000000000000..416ab8124314
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/publisher_en.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>My OpenOffice en</H1>
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/publisher/readme.txt b/desktop/test/deployment/update/publisher/readme.txt
new file mode 100644
index 000000000000..1a659d8e875d
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/readme.txt
@@ -0,0 +1,212 @@
+--The folder contains extensions which use in the description.xml the following:
+
+-The <publisher> element
+-The <release-notes> element
+
+Both element contain localized child elements.
+
+The following table shows what localized item is used, when the Office the locale
+en-US uses.
+
+
+Localization:
+
+Installed office en-US
+ | publisher | release notes
+=============================================
+pub1.oxt | en-US | en-US
+---------------------------------------------
+pub2.oxt | en-US-region1 | en-US-region1
+---------------------------------------------
+pub3.oxt | en | en
+---------------------------------------------
+pub4.oxt | en-GB | en-GB
+---------------------------------------------
+pub5.oxt | de | de
+
+
+================================================================================
+pub6.oxt
+================================================================================
+like pub1 but without release notes.
+
+
+================================================================================
+pub7.oxt
+================================================================================
+like pub1 but without publisher name.
+
+================================================================================
+pub8.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+pub8.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+pub8.oxt provides <publisher> and <release-notes>. These information should be transferred
+in the update feed and not those entered in the repository.
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. This setting should be ignored
+ when generating the udpate feed. Instead the publisher name from the extension is used.
+ Enter "Publisher Title" : some arbitrary company
+ "Publisher URL": any arbitrary URL but not:
+ http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html
+
+-Create a new release for the extension. Upload the version 2.0 (update/pub8.oxt).
+ Provide release notes. These release notes should later not be seen when clicking on
+ the release notes link.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/publisher/pub8.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in the description.xml. For example,
+when lang=en-US was selected: My OpenOffice en-US
+
+A release notes link is displayed with an URL to the release notes as provided in
+the description.xml. For example, when lang=en-US was selected:
+"http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html
+
+
+================================================================================
+pub9.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+pub9.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+pub9.oxt provides <publisher>. That means the update feed should
+contain the <publisher> as provided by the extension and the release notes as entered
+in the repository.
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. This setting should be ignored
+ when generating the udpate feed. Instead the publisher name from the extension is used.
+ Enter "Publisher Title" : some arbitrary company name
+ "Publisher URL": any arbitrary URL but not:
+ http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html
+
+-Create a new release for the extension. Upload the version 2.0 (update/pub9.oxt).
+ Provide release notes. These release notes should later be displayed when clicking on
+ the release notes link.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/publisher/pub9.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in the description.xml. For example,
+when lang=en-US was selected: My OpenOffice en-US
+
+A release notes link is displayed with an URL to the release notes as provided in the release notes
+field on the edit page for the extension in the repository.
+
+================================================================================
+pub10.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+pub10.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+pub10.oxt provides <release-notes>. That means the update feed should
+contain the <release-notes> as provided by the extension and the publisher name/URLs as entered
+in the repository.
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. They should then be in the udpate
+ feed.
+
+-Create a new release for the extension. Upload the version 2.0 (update/pub10.oxt).
+ Provide release notes. These release notes should NOT be displayed when clicking on
+ the release notes link. Instead the release notes provided by pub10.oxt should be displayed.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/publisher/pub10.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in the repository.
+
+A release notes link is displayed with an URL to the release notes as provided in the
+pub10.oxt. For example, when the locale of the office is en-US then this page will be
+displayed:
+For example,
+when lang=en-US was selected: My OpenOffice en-US
+
+================================================================================
+pub11.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+pub11.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+pub10.oxt neither provides <release-notes> nor <publisher>. That means the update feed should
+contain these data as provided by the user on the repository web site.
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. They should then be in the udpate
+ feed.
+
+-Create a new release for the extension. Upload the version 2.0 (update/pub11.oxt).
+ Provide release notes. These release notes should be displayed when clicking on
+ the release notes link.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/publisher/pub11.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in the repository.
+
+A release notes link is displayed which leads to the release notes kept in the repository.
+
diff --git a/desktop/test/deployment/update/publisher/release-notes_de-DE-altmark.html b/desktop/test/deployment/update/publisher/release-notes_de-DE-altmark.html
new file mode 100644
index 000000000000..81b38a9f5b44
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_de-DE-altmark.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes de-DE-altmark</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_de-DE.html b/desktop/test/deployment/update/publisher/release-notes_de-DE.html
new file mode 100644
index 000000000000..f8f0121f0215
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_de-DE.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes de-DE</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_de.html b/desktop/test/deployment/update/publisher/release-notes_de.html
new file mode 100644
index 000000000000..a9e1dc3647eb
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_de.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes de</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-GB.html b/desktop/test/deployment/update/publisher/release-notes_en-GB.html
new file mode 100644
index 000000000000..ca72ec1b9c6e
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-GB.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-GB</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-US-region1.html b/desktop/test/deployment/update/publisher/release-notes_en-US-region1.html
new file mode 100644
index 000000000000..0e6f99ce4c35
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-US-region1.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-US-region1</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-US-region2.html b/desktop/test/deployment/update/publisher/release-notes_en-US-region2.html
new file mode 100644
index 000000000000..597bca0ebeef
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-US-region2.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-US-region2</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-US.html b/desktop/test/deployment/update/publisher/release-notes_en-US.html
new file mode 100644
index 000000000000..7f9d73e338f8
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-US.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-US</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en-region3.html b/desktop/test/deployment/update/publisher/release-notes_en-region3.html
new file mode 100644
index 000000000000..5d62c7bcb4cf
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en-region3.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en-region3</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/release-notes_en.html b/desktop/test/deployment/update/publisher/release-notes_en.html
new file mode 100644
index 000000000000..d02e4f3330ee
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/release-notes_en.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Release Notes en</H1>
+</BODY>
+</HTML>
diff --git a/desktop/test/deployment/update/publisher/update/pub1.oxt b/desktop/test/deployment/update/publisher/update/pub1.oxt
new file mode 100644
index 000000000000..cd04a58d5585
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub1.update.xml b/desktop/test/deployment/update/publisher/update/pub1.update.xml
new file mode 100644
index 000000000000..db25b56a8847
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub1.update.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub1"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html" lang="en-US">My OpenOffice en-US</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region1.html" lang="en-US-region1">My OpenOffice en-US-region1</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region2.html" lang="en-US-region2">My OpenOffice en-US-region2</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US.html" lang="en-US" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub10.oxt b/desktop/test/deployment/update/publisher/update/pub10.oxt
new file mode 100644
index 000000000000..501a843381a8
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub10.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub11.oxt b/desktop/test/deployment/update/publisher/update/pub11.oxt
new file mode 100644
index 000000000000..692c0401f4a5
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub11.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub2.oxt b/desktop/test/deployment/update/publisher/update/pub2.oxt
new file mode 100644
index 000000000000..2a0bd6c21fed
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub2.update.xml b/desktop/test/deployment/update/publisher/update/pub2.update.xml
new file mode 100644
index 000000000000..d856348df87f
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub2.update.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub2"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region1.html" lang="en-US-region1">My OpenOffice en-US-region1</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region2.html" lang="en-US-region2">My OpenOffice en-US-region2</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub3.oxt b/desktop/test/deployment/update/publisher/update/pub3.oxt
new file mode 100644
index 000000000000..60675fc4d21e
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub3.update.xml b/desktop/test/deployment/update/publisher/update/pub3.update.xml
new file mode 100644
index 000000000000..29a8e16b2ce4
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub3.update.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub3"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub4.oxt b/desktop/test/deployment/update/publisher/update/pub4.oxt
new file mode 100644
index 000000000000..19f7b7991bd4
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub4.update.xml b/desktop/test/deployment/update/publisher/update/pub4.update.xml
new file mode 100644
index 000000000000..67b79f782412
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub4.update.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub4"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub4.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub5.oxt b/desktop/test/deployment/update/publisher/update/pub5.oxt
new file mode 100644
index 000000000000..afc632d570f1
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub5.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub5.update.xml b/desktop/test/deployment/update/publisher/update/pub5.update.xml
new file mode 100644
index 000000000000..3a58b298b549
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub5.update.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub5"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub5.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub6.oxt b/desktop/test/deployment/update/publisher/update/pub6.oxt
new file mode 100644
index 000000000000..a68b445b8a1a
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub6.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub6.update.xml b/desktop/test/deployment/update/publisher/update/pub6.update.xml
new file mode 100644
index 000000000000..ef187ce6cb5a
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub6.update.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub6"/>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html" lang="en-US">My OpenOffice en-US</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region1.html" lang="en-US-region1">My OpenOffice en-US-region1</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region2.html" lang="en-US-region2">My OpenOffice en-US-region2</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub6.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub7.oxt b/desktop/test/deployment/update/publisher/update/pub7.oxt
new file mode 100644
index 000000000000..1b4bee0442bb
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub7.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub7.update.xml b/desktop/test/deployment/update/publisher/update/pub7.update.xml
new file mode 100644
index 000000000000..10984e08d72f
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub7.update.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/publisher/pub7"/>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US.html" lang="en-US" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/update/pub7.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/publisher/update/pub8.oxt b/desktop/test/deployment/update/publisher/update/pub8.oxt
new file mode 100644
index 000000000000..5688ab9d24f5
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub8.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/publisher/update/pub9.oxt b/desktop/test/deployment/update/publisher/update/pub9.oxt
new file mode 100644
index 000000000000..752cfbbcf0b0
--- /dev/null
+++ b/desktop/test/deployment/update/publisher/update/pub9.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/readme.txt b/desktop/test/deployment/update/readme.txt
new file mode 100644
index 000000000000..b3fd9126cae3
--- /dev/null
+++ b/desktop/test/deployment/update/readme.txt
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+The extensions in the subdirectories of the update folder are used for
+testing the online update feature of extensions. The folder such as
+simple,
+license,
+defect, etc. contain extensions which can be installed in OOo. The
+corresponding update information file and the update are located on
+the extensions.openoffice.org website (cvs: extensions/www/testarea). For example:
+
+desktop/test/deployment/update/simple/plain1.oxt
+
+is version 1 of this extension and it references
+
+http://extensions.openoffice.org/testarea/desktop/simple/update/plain1.update.xml
+
+which in turn references version 2 at
+
+http://extensions.openoffice.org/testarea/desktop/simple/update/plain1.oxt
+
+
+To have all in one place the update information file and the update are also contained
+in the desktop project. They are in the update subfolder of the different test folders.
+For example
+
+.../update/simple/update
+.../update/license/update
+.../update/updatefeed/udpate
+
+
+The different test folders for the update are also commited in project extensions/www
+so that the files can be obtain via an URL. The structure and the contents is about the
+same as the content
+of desktop/test/deployment/udpate
+For example in
+
+extensions/www/testarea/desktop
+
+are the subfolder defect, simple, updatefeed, wrong_url, etc.
+they contain the extensions which are installed directly by the Extension Manager.
+These folders contain also the update subfolder which contains the update information
+and the actual updates.
diff --git a/desktop/test/deployment/update/simple/plain1.oxt b/desktop/test/deployment/update/simple/plain1.oxt
new file mode 100644
index 000000000000..6256f99d5e9c
--- /dev/null
+++ b/desktop/test/deployment/update/simple/plain1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/plain2.oxt b/desktop/test/deployment/update/simple/plain2.oxt
new file mode 100644
index 000000000000..03249c27774c
--- /dev/null
+++ b/desktop/test/deployment/update/simple/plain2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/plain3.oxt b/desktop/test/deployment/update/simple/plain3.oxt
new file mode 100644
index 000000000000..64838932d1ae
--- /dev/null
+++ b/desktop/test/deployment/update/simple/plain3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/readme.txt b/desktop/test/deployment/update/simple/readme.txt
new file mode 100644
index 000000000000..34ad6bedabf9
--- /dev/null
+++ b/desktop/test/deployment/update/simple/readme.txt
@@ -0,0 +1,31 @@
+The folder contains only simple extension. That is, they only contain
+- META-INF
+-t.rdb
+-description.xml
+
+The description.xml contains a version, a display name, and one URL to the update data
+
+For example:
+
+
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="1.0" />
+
+ <display-name>
+ <name lang="de">plain1 de</name>
+ </display-name>
+
+ <update-information>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/simple/plain1.update.xml" />
+ </update-information>
+</description>
+
+There is only one language as display name available, which will therefore always be displayed.
+
+The update information which is referenced in the update-information and the update is committed in the extensions/www project. To modify them get the project:
+
+cvs co extensions/wwww
+
+the files can be found under extensions/www/testarea/desktop
diff --git a/desktop/test/deployment/update/simple/update/plain1.oxt b/desktop/test/deployment/update/simple/update/plain1.oxt
new file mode 100644
index 000000000000..d73362e873bc
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/update/plain1.update.xml b/desktop/test/deployment/update/simple/update/plain1.update.xml
new file mode 100644
index 000000000000..c9eb679cdba0
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.plain1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/simple/update/plain1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/simple/update/plain2.oxt b/desktop/test/deployment/update/simple/update/plain2.oxt
new file mode 100644
index 000000000000..3dc02aa97aa4
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/update/plain2.update.xml b/desktop/test/deployment/update/simple/update/plain2.update.xml
new file mode 100644
index 000000000000..5aeb8080446f
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.plain2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/simple/update/plain2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/simple/update/plain3.oxt b/desktop/test/deployment/update/simple/update/plain3.oxt
new file mode 100644
index 000000000000..575152403bfe
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/simple/update/plain3.update.xml b/desktop/test/deployment/update/simple/update/plain3.update.xml
new file mode 100644
index 000000000000..6c1241dbdede
--- /dev/null
+++ b/desktop/test/deployment/update/simple/update/plain3.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.plain3.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/simple/update/plain3.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/updatefeed/feed1.oxt b/desktop/test/deployment/update/updatefeed/feed1.oxt
new file mode 100644
index 000000000000..b1b11ecceabb
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/feed1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updatefeed/feed2.oxt b/desktop/test/deployment/update/updatefeed/feed2.oxt
new file mode 100644
index 000000000000..47dca1676c6a
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/feed2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updatefeed/update/feed1.oxt b/desktop/test/deployment/update/updatefeed/update/feed1.oxt
new file mode 100644
index 000000000000..82bb9665ae3d
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updatefeed/update/feed1.update.xml b/desktop/test/deployment/update/updatefeed/update/feed1.update.xml
new file mode 100644
index 000000000000..31d0cfa61d3b
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed1.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.feed1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/updatefeed/update/feed1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/updatefeed/update/feed1.xml b/desktop/test/deployment/update/updatefeed/update/feed1.xml
new file mode 100644
index 000000000000..1c31851d8cfd
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed1.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
+
+ <title>OpenOffice.org Update Feed</title>
+ <link rel="alternate" type="text/html" href="http://update.services.openoffice.org/ooo/snapshot.html"/>
+ <updated>2006-11-06T18:30:02Z</updated>
+ <author>
+ <name>The OpenOffice.org Project</name>
+ <uri>http://openoffice.org</uri>
+ <email>updatefeed@openoffice.org</email>
+ </author>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566e9d</id>
+ <entry>
+ <title>feed1.oxt version 2.0 available</title>
+ <link rel="alternate" type="text/html"
+ href="http://extensions.openoffice.org"/>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566e9f</id>
+ <category term="org.openoffice.legacy.feed1.oxt" label="feed1.oxt" />
+ <updated>2006-11-06T18:30:02Z</updated>
+ <summary>Click here to go to the download page.</summary>
+ <content type="application/xml" src="http://extensions.openoffice.org/testarea/desktop/updatefeed/update/feed1.update.xml" />
+ </entry>
+ <entry>
+ <title>feed2.oxt version 2.0 available</title>
+ <link rel="alternate" type="text/html"
+ href="http://extensions.openoffice.org"/>
+ <id>urn:uuid:a4ccd383-1dd1-11b2-a95c-0003ba566eaf</id>
+ <category term="org.openoffice.legacy.feed2.oxt" label="feed2.oxt" />
+ <updated>2006-11-06T18:30:02Z</updated>
+ <summary>Click here to go to the download page.</summary>
+ <content type="application/xml" src="http://extensions.openoffice.org/testarea/desktop/updatefeed/update/feed2.update.xml" />
+ </entry>
+</feed>
diff --git a/desktop/test/deployment/update/updatefeed/update/feed2.oxt b/desktop/test/deployment/update/updatefeed/update/feed2.oxt
new file mode 100644
index 000000000000..9c867ae4a812
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updatefeed/update/feed2.update.xml b/desktop/test/deployment/update/updatefeed/update/feed2.update.xml
new file mode 100644
index 000000000000..8cbc5045fd5d
--- /dev/null
+++ b/desktop/test/deployment/update/updatefeed/update/feed2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.feed2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/updatefeed/update/feed2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/updateinfocreation/build/MANIFEST.MF b/desktop/test/deployment/update/updateinfocreation/build/MANIFEST.MF
new file mode 100755
index 000000000000..09e2f42ca0f6
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/MANIFEST.MF
@@ -0,0 +1,2 @@
+RegistrationClassName: com.sun.star.comp.smoketest.TestExtension
+
diff --git a/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl
new file mode 100755
index 000000000000..3f5fc3b53bbe
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _com_sun_star_comp_smoketest_TestExtension_idl_
+#define _com_sun_star_comp_smoketest_TestExtension_idl_
+
+#include <com/sun/star/lang/XServiceInfo.idl>
+
+
+module com { module sun { module star { module comp { module smoketest {
+ // example service, XServiceInfo is implemented here for demonstration
+ // issues. XServiceInfo must be implemented by all components.
+ service TestExtension: ::com::sun::star::lang::XServiceInfo;
+};};};};};
+
+#endif
diff --git a/desktop/test/deployment/update/updateinfocreation/build/TestExtension.java b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.java
new file mode 100755
index 000000000000..059715845c32
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.java
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ *************************************************************************/
+package com.sun.star.comp.smoketest;
+
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.registry.XRegistryKey;
+import com.sun.star.lang.XInitialization;
+import com.sun.star.lang.XTypeProvider;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.uno.Type;
+
+/** This class capsulates the class, that implements the minimal component, a
+ * factory for creating the service (<CODE>__getComponentFactory</CODE>) and a
+ * method, that writes the information into the given registry key
+ * (<CODE>__writeRegistryServiceInfo</CODE>).
+ */
+public class TestExtension {
+ /** This class implements the component. At least the interfaces XServiceInfo,
+ * XTypeProvider, and XInitialization should be provided by the service.
+ */
+ public static class _TestExtension extends WeakBase
+ implements XServiceInfo {
+ /** The service name, that must be used to get an instance of this service.
+ */
+ static private final String __serviceName =
+ "com.sun.star.comp.smoketest.TestExtension";
+
+ /** The initial component contextr, that gives access to
+ * the service manager, supported singletons, ...
+ * It's often later used
+ */
+ private XComponentContext m_cmpCtx;
+
+ /** The service manager, that gives access to all registered services.
+ * It's often later used
+ */
+ private XMultiComponentFactory m_xMCF;
+
+ /** The constructor of the inner class has a XMultiServiceFactory parameter.
+ * @param xmultiservicefactoryInitialization A special service factory
+ * could be introduced while initializing.
+ */
+ public _TestExtension(XComponentContext xCompContext) {
+ try {
+ m_cmpCtx = xCompContext;
+ m_xMCF = m_cmpCtx.getServiceManager();
+ }
+ catch( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method returns an array of all supported service names.
+ * @return Array of supported service names.
+ */
+ public String[] getSupportedServiceNames() {
+ return getServiceNames();
+ }
+
+ /** This method is a simple helper function to used in the
+ * static component initialisation functions as well as in
+ * getSupportedServiceNames.
+ */
+ public static String[] getServiceNames() {
+ String[] sSupportedServiceNames = { __serviceName };
+ return sSupportedServiceNames;
+ }
+
+ /** This method returns true, if the given service will be
+ * supported by the component.
+ * @param sServiceName Service name.
+ * @return True, if the given service name will be supported.
+ */
+ public boolean supportsService( String sServiceName ) {
+ return sServiceName.equals( __serviceName );
+ }
+
+ /** Return the class name of the component.
+ * @return Class name of the component.
+ */
+ public String getImplementationName() {
+ return _TestExtension.class.getName();
+ }
+ }
+
+
+ /**
+ * Gives a factory for creating the service.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns a <code>XSingleComponentFactory</code> for creating
+ * the component
+ * @param sImplName the name of the implementation for which a
+ * service is desired
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static XSingleComponentFactory __getComponentFactory(String sImplName)
+ {
+ XSingleComponentFactory xFactory = null;
+
+ if ( sImplName.equals( _TestExtension.class.getName() ) )
+ xFactory = Factory.createComponentFactory(_TestExtension.class,
+ _TestExtension.getServiceNames());
+
+ return xFactory;
+ }
+
+ /**
+ * Writes the service information into the given registry key.
+ * This method is called by the <code>JavaLoader</code>
+ * <p>
+ * @return returns true if the operation succeeded
+ * @param regKey the registryKey
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+ return Factory.writeRegistryServiceInfo(_TestExtension.class.getName(),
+ _TestExtension.getServiceNames(),
+ regKey);
+ }
+ /** This method is a member of the interface for initializing an object
+ * directly after its creation.
+ * @param object This array of arbitrary objects will be passed to the
+ * component after its creation.
+ * @throws Exception Every exception will not be handled, but will be
+ * passed to the caller.
+ */
+ public void initialize( Object[] object )
+ throws com.sun.star.uno.Exception {
+ /* The component describes what arguments its expected and in which
+ * order!At this point you can read the objects and can intialize
+ * your component using these objects.
+ */
+ }
+
+}
diff --git a/desktop/test/deployment/update/updateinfocreation/build/delzip b/desktop/test/deployment/update/updateinfocreation/build/delzip
new file mode 100755
index 000000000000..636fda90bfcb
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/delzip
@@ -0,0 +1 @@
+ECHO is OFF
diff --git a/desktop/test/deployment/update/updateinfocreation/build/description.xml b/desktop/test/deployment/update/updateinfocreation/build/description.xml
new file mode 100644
index 000000000000..257c48a79b79
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/description.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:d="http://openoffice.org/extensions/description/2006" >
+ <identifier value="org.openoffice.extensions.testarea.desktop.updateinfo"/>
+ <version value="2.0" />
+ <dependencies >
+ <OpenOffice.org-minimal-version value="2.1" d:name="OpenOffice.org 2.1"/>
+ </dependencies>
+ <update-information>
+ <src xlink:href="http://update.services.openoffice.org/ProductUpdateService/check.Update?product=extension&amp;extensionid=org.openoffice.extensions.testarea.desktop.updateinfo&amp;refresh=true"/>
+ </update-information>
+</description>
diff --git a/desktop/test/deployment/update/updateinfocreation/build/makefile.mk b/desktop/test/deployment/update/updateinfocreation/build/makefile.mk
new file mode 100755
index 000000000000..6af3928279e0
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/makefile.mk
@@ -0,0 +1,88 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..$/..
+PRJNAME = updateinfo
+PACKAGE = com$/sun$/star$/comp$/smoketest
+TARGET = com_sun_star_comp_smoketest
+
+no_common_build_zip:=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES = ridl.jar jurt.jar unoil.jar juh.jar
+
+
+JARTARGET = TestExtension.jar
+JARCOMPRESS = TRUE
+CUSTOMMANIFESTFILE = MANIFEST.MF
+
+ZIP1TARGET=updateinfo
+ZIP1LIST=*
+ZIPFLAGS=-r
+ZIP1DIR=$(MISC)$/$(TARGET)
+ZIP1EXT=.oxt
+
+EXTUPDATEINFO_NAME=org.openoffice.extensions.testarea.desktop.updateinfo.update.xml
+EXTUPDATEINFO_SOURCE=description.xml
+EXTUPDATEINFO_URLS = http://extensions.openoffice.org/testarea/desktop/updateinfocreation/update/updateinfo.oxt
+# --- Files --------------------------------------------------------
+
+COPY_OXT_MANIFEST:= $(MISC)$/$(TARGET)$/META-INF$/manifest.xml
+JAVAFILES = TestExtension.java
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(JARTARGETN) : $(MISC)$/$(TARGET).javamaker.done
+
+$(JAVACLASSFILES) : $(MISC)$/$(TARGET).javamaker.done
+
+$(MISC)$/$(TARGET).javamaker.done: $(BIN)$/TestExtension.rdb
+ $(JAVAMAKER) -O$(CLASSDIR) -BUCR -nD -X$(SOLARBINDIR)/types.rdb $<
+ $(TOUCH) $@
+
+$(BIN)$/TestExtension.rdb: TestExtension.idl
+ $(IDLC) -O$(MISC) -I$(SOLARIDLDIR) -cid -we $<
+ +-$(RM) $@
+ $(REGMERGE) $@ /UCR $(MISC)$/TestExtension.urd
+
+$(MISC)$/$(ZIP1TARGET).createdir :
+ +$(MKDIRHIER) $(MISC)$/$(TARGET)$/META-INF >& $(NULLDEV) && $(TOUCH) $@
+
+$(MISC)$/$(TARGET)_resort : manifest.xml $(JARTARGETN) $(MISC)$/$(ZIP1TARGET).createdir $(BIN)$/TestExtension.rdb description.xml
+ $(GNUCOPY) -u manifest.xml $(MISC)$/$(TARGET)$/META-INF$/manifest.xml
+ $(GNUCOPY) -u $(JARTARGETN) $(MISC)$/$(TARGET)$/$(JARTARGET)
+ $(GNUCOPY) -u $(BIN)$/TestExtension.rdb $(MISC)$/$(TARGET)$/TestExtension.rdb
+ $(GNUCOPY) -u description.xml $(MISC)$/$(TARGET)$/description.xml
+ $(TOUCH) $@
+
+$(ZIP1TARGETN) : $(MISC)$/$(TARGET)_resort $(MISC)$/$(ZIP1TARGET).createdir
+
diff --git a/desktop/test/deployment/update/updateinfocreation/build/manifest.xml b/desktop/test/deployment/update/updateinfocreation/build/manifest.xml
new file mode 100755
index 000000000000..7e3e7947aa0f
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/build/manifest.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest:manifest>
+ <manifest:file-entry manifest:full-path="TestExtension.jar" manifest:media-type="application/vnd.sun.star.uno-component;type=Java"/>
+ <manifest:file-entry manifest:full-path="TestExtension.rdb" manifest:media-type="application/vnd.sun.star.uno-typelibrary;type=RDB"/>
+</manifest:manifest> \ No newline at end of file
diff --git a/desktop/test/deployment/update/updateinfocreation/readme.txt b/desktop/test/deployment/update/updateinfocreation/readme.txt
new file mode 100644
index 000000000000..c4fc059053e9
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/readme.txt
@@ -0,0 +1,38 @@
+The extension build in this test uses an update information which is obtained
+through a http get request. That is the URL does not reference an update
+information file. Instead it invokes code on a webserver which returns the
+update information. The URL used in this example is:
+
+http://update.services.openoffice.org/ProductUpdateService/check.Update?product=extension&amp;extensionid=org.openoffice.extensions.testarea.desktop.updateinfo&amp;refresh=true
+
+The updateinfo.oxt in this directory has the version 1.0 and in the sub-directory "update is the version 2 of this extension. Version 1.0 is also available here
+/extensions/www/testarea/desktop/updateinfocreation/updateinfo.oxt
+and version 2.0 here
+/extensions/www/testarea/desktop/updateinfocreation/update/updateinfo.oxt
+
+Therefore they can be accessed through
+
+http://extensions.openoffice.org/testarea/desktop/updateinfocreation/updateinfo.oxt
+and
+http://extensions.openoffice.org/testarea/desktop/updateinfocreation/update/updateinfo.oxt
+
+The latter location (version 2.0) will also be referenced by the update information
+which are returned by the webserver.
+
+The build sub-directory contains the code of the extension (version 2.0) and can
+be build by calling dmake in this directory. The makefile uses the special macros:
+
+EXTUPDATEINFO_NAME=org.openoffice.extensions.testarea.desktop.updateinfo.update.xml
+EXTUPDATEINFO_SOURCE=description.xml
+EXTUPDATEINFO_URLS = http://extensions.openoffice.org/testarea/desktop/updateinfocreation/update/updateinfo.oxt
+
+This causes the generation of the update information file. This file could be
+directly references by the URL in the <update-information> of the description.xml.
+See also the Wiki entry at:
+http://wiki.services.openoffice.org/wiki/Creating_update_information_for_extensions
+This generated update information file can then be used by the webserver, when it
+sends back the requested update information. The update information file will be
+generated in the misc diretory of the output directory.
+
+The update information file needs to be copied into common.pro/pus.mxyz directory.
+The project mwsfinish will process the files in the pus directory.
diff --git a/desktop/test/deployment/update/updateinfocreation/update/updateinfo.oxt b/desktop/test/deployment/update/updateinfocreation/update/updateinfo.oxt
new file mode 100644
index 000000000000..52ddd3158e31
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/update/updateinfo.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/updateinfocreation/updateinfo.oxt b/desktop/test/deployment/update/updateinfocreation/updateinfo.oxt
new file mode 100644
index 000000000000..43ac7003bc59
--- /dev/null
+++ b/desktop/test/deployment/update/updateinfocreation/updateinfo.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/readme.txt b/desktop/test/deployment/update/website_update/readme.txt
new file mode 100644
index 000000000000..4ae5ddd9182f
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/readme.txt
@@ -0,0 +1,133 @@
+The folder contains extensions which need to be updated through a web site.
+The "Updates dialog" of the Extension Manager will mark the updates for these
+extensions as "browser based update". The Extension Manager will open a browser
+for each of the extensions and navigate to the respective website.
+
+================================================================================
+web1.oxt - web5.oxt:
+================================================================================
+They contain <update-information>. That is they reference directly the respective
+webX.update.xml (for example, web1.update.xml) files which are available at
+http://extensions.openoffice.org/testarea/desktop/website_update/update/...
+For example:
+http://extensions.openoffice.org/testarea/desktop/website_update/update/web2.update.xml
+
+The update information contain multiple URLs to "localized" web sites. Each URL is
+assigned to a particular local. For example:
+
+<src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de"/>
+
+The Extension Manager will choose the URLs where the lang attribute matches most
+closely the locale of the office.
+
+The following table shows what localized web site is used, when the office uses the locale
+en-US. The web page will display the locale used. See update/web1_de.html, etc.
+
+
+Localization:
+
+Installed office en-US
+ | publisher | release notes
+=============================================
+web1.oxt | en-US | en-US
+---------------------------------------------
+web2.oxt | en-US-region1 | en-US-region1
+---------------------------------------------
+web3.oxt | en | en
+---------------------------------------------
+web4.oxt | en-GB | en-GB
+---------------------------------------------
+web5.oxt | de | de
+
+
+================================================================================
+web6.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop.
+
+web6.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+Test
+----
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. In our case this should be
+ http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+
+-Create a new release for the extension. Upload the description.xml of version 2.0
+(update/web6/description.xml). Provide a download URL for the web site (field
+ "Download from page / Open follow up page URL", which should be
+ http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+ Provide release notes.
+
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/website_update/web6.oxt
+
+-Run the update in the Extension Manager
+
+
+Result:
+The Update Dialog should show the publisher name as provided in "Provider URL" field
+of the extension edit page (not release).
+
+A release notes link is displayed with an URL to the release notes as provided in
+the "Provider Title" field of the extension release edit page.
+
+When running the update then the web browser should navigate to
+http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+
+
+================================================================================
+web7.oxt
+================================================================================
+Need not be committed in extensions/www/testarea/desktop
+
+web7.oxt is intended for tests with extensions.services.openoffice.org.
+It does not contain <update-information>. That is, the Extension Manager will obtain
+the update information from the repository as feed:
+
+http://updateext.services.openoffice.org/ProductUpdateService/check.Update
+
+The description.xml which will be uploaded contains URLs for release notes and publisher
+names/ URLs. That is, these information are not generated from the information of the
+repository web site.
+
+Test
+-----------
+Repository:
+
+-Create the new extension in the repository.
+-Provide a company name and a URL to the company website. In our case these should be different
+ to those provided in the description.xml. These should NOT go into the update feed.
+ Choose for example as "Provider Title": FOO and as "Provider URL" some valid URL but NOT
+ http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+
+-Create a new release for the extension. Upload the description.xml of version 2.0
+(update/web7/description.xml). Provide a download URL for the web site (field
+ "Download from page / Open follow up page URL", which should be
+ http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
+ Provide release notes.
+
+Office:
+-Install version 1.0 of the extension:
+ desktop/test/deployment/update/website_update/web7.oxt
+
+-Run the update in the Extension Manager
+
+Result:
+The Update Dialog should show the publisher name as provided in the description.xml.
+That is: My OpenOffice en-US and NOT "FOO".
+
+A release notes link is displayed with an URL to the release notes as provided in
+the description.xml. That is:
+http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_xxx.html
+
+When running the update then the web browser should navigate to
+http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html
diff --git a/desktop/test/deployment/update/website_update/update/web1.oxt b/desktop/test/deployment/update/website_update/update/web1.oxt
new file mode 100644
index 000000000000..157d5d952c60
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web1.update.xml b/desktop/test/deployment/update/website_update/update/web1.update.xml
new file mode 100644
index 000000000000..ad2379dd43ca
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1.update.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web1"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US.html" lang="en-US" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-region3.html" lang="en-region3" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_de-DE-altmark.html b/desktop/test/deployment/update/website_update/update/web1_de-DE-altmark.html
new file mode 100644
index 000000000000..ffed5a52e892
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_de-DE-altmark.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>de-DE-altmark</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_de-DE.html b/desktop/test/deployment/update/website_update/update/web1_de-DE.html
new file mode 100644
index 000000000000..33fb7f2ec8bc
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_de-DE.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>de-DE</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_de.html b/desktop/test/deployment/update/website_update/update/web1_de.html
new file mode 100644
index 000000000000..31a53b91dbe4
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_de.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>de</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-GB.html b/desktop/test/deployment/update/website_update/update/web1_en-GB.html
new file mode 100644
index 000000000000..c46328a82145
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-GB.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-GB</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-US-region1.html b/desktop/test/deployment/update/website_update/update/web1_en-US-region1.html
new file mode 100644
index 000000000000..80b41823b70f
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-US-region1.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-US-region1</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-US-region2.html b/desktop/test/deployment/update/website_update/update/web1_en-US-region2.html
new file mode 100644
index 000000000000..1a501f520d85
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-US-region2.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-US-region2</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-US.html b/desktop/test/deployment/update/website_update/update/web1_en-US.html
new file mode 100644
index 000000000000..f861b09c0162
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-US.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-US</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en-region3.html b/desktop/test/deployment/update/website_update/update/web1_en-region3.html
new file mode 100644
index 000000000000..f55bcbe38135
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en-region3.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en-region3</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web1_en.html b/desktop/test/deployment/update/website_update/update/web1_en.html
new file mode 100644
index 000000000000..a0b422ebf20e
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web1_en.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>
+<H1>Update Extensions</H1>
+<H1>en</H1>
+<p><a href="web1.oxt">web1.oxt</a></p>
+<p><a href="web2.oxt">web2.oxt</a></p>
+<p><a href="web3.oxt">web3.oxt</a></p>
+<p><a href="web4.oxt">web4.oxt</a></p>
+<p><a href="web5.oxt">web5.oxt</a></p>
+<p><a href="web6.oxt">web6.oxt</a></p>
+<p><a href="web7.oxt">web7.oxt</a></p>
+
+
+</BODY>
+</HTML>
+
diff --git a/desktop/test/deployment/update/website_update/update/web2.oxt b/desktop/test/deployment/update/website_update/update/web2.oxt
new file mode 100644
index 000000000000..3a13e8114314
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web2.update.xml b/desktop/test/deployment/update/website_update/update/web2.update.xml
new file mode 100644
index 000000000000..afdcdf078edf
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web2.update.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web2"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-region3.html" lang="en-region3" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web3.oxt b/desktop/test/deployment/update/website_update/update/web3.oxt
new file mode 100644
index 000000000000..b3214a4e693f
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web3.update.xml b/desktop/test/deployment/update/website_update/update/web3.update.xml
new file mode 100644
index 000000000000..ce6263656120
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web3.update.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web3"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-region3.html" lang="en-region3" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web4.oxt b/desktop/test/deployment/update/website_update/update/web4.oxt
new file mode 100644
index 000000000000..93766fd44faf
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web4.update.xml b/desktop/test/deployment/update/website_update/update/web4.update.xml
new file mode 100644
index 000000000000..d07f1dec149e
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web4.update.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web4"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_en-region3.html" lang="en-region3" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web5.oxt b/desktop/test/deployment/update/website_update/update/web5.oxt
new file mode 100644
index 000000000000..1ae8f01b19cb
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web5.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web5.update.xml b/desktop/test/deployment/update/website_update/update/web5.update.xml
new file mode 100644
index 000000000000..a392466c5785
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web5.update.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web5"/>
+
+ <update-website>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/website_update/update/web1_de-DE-altmark.html" lang="de-DE-altmark" />
+ </update-website>
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web6.oxt b/desktop/test/deployment/update/website_update/update/web6.oxt
new file mode 100644
index 000000000000..8bc16fb2c73a
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web6.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web6/description.xml b/desktop/test/deployment/update/website_update/update/web6/description.xml
new file mode 100644
index 000000000000..243c1d8ff962
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web6/description.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web6"/>
+ <display-name>
+ <name lang="en">web-based update test 1</name>
+ </display-name>
+
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web6/readme.txt b/desktop/test/deployment/update/website_update/update/web6/readme.txt
new file mode 100644
index 000000000000..7a1ba06efaa3
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web6/readme.txt
@@ -0,0 +1,5 @@
+This folder contains the description.xml from update/web6.oxt
+When creating the release 2.0 on the repository then this description.xml can be uploaded.
+
+
+This folder is not needed on extensions.openoffice.org/testarea/desktop/....
diff --git a/desktop/test/deployment/update/website_update/update/web7.oxt b/desktop/test/deployment/update/website_update/update/web7.oxt
new file mode 100644
index 000000000000..4d6220a48af2
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web7.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/update/web7/description.xml b/desktop/test/deployment/update/website_update/update/web7/description.xml
new file mode 100644
index 000000000000..5b03e12ad436
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web7/description.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/description/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="2.0" />
+ <identifier value="org.openoffice/framework/desktop/test/deployment/update/website_update/web7"/>
+ <display-name>
+ <name lang="en">web-based update test 1</name>
+ </display-name>
+
+ <publisher>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de.html" lang="de">My OpenOffice de</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en.html" lang="en">My OpenOffice en</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE.html" lang="de-DE">My OpenOffice de-DE</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_de-DE-altmark.html" lang="de-DE-altmark">My OpenOffice de-DE-altmark</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-GB.html" lang="en-GB">My OpenOffice en-GB</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US.html" lang="en-US">My OpenOffice en-US</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region1.html" lang="en-US-region1">My OpenOffice en-US-region1</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-US-region2.html" lang="en-US-region2">My OpenOffice en-US-region2</name>
+ <name xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/publisher_en-region3.html" lang="en-region3">My OpenOffice en-region3</name>
+ </publisher>
+
+ <release-notes>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de.html" lang="de" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en.html" lang="en" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE.html" lang="de-DE" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_de-DE-altmark.html" lang="de-DE-altmark" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-GB.html" lang="en-GB" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US.html" lang="en-US" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region1.html" lang="en-US-region1" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-US-region2.html" lang="en-US-region2" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/publisher/release-notes_en-region3.html" lang="en-region3" />
+ </release-notes>
+
+
+</description>
+
diff --git a/desktop/test/deployment/update/website_update/update/web7/readme.txt b/desktop/test/deployment/update/website_update/update/web7/readme.txt
new file mode 100644
index 000000000000..8a6721b8e85c
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/update/web7/readme.txt
@@ -0,0 +1,5 @@
+This folder contains the description.xml from update/web7.oxt
+When creating the release 2.0 on the repository then this description.xml can be uploaded.
+
+
+This folder is not needed on extensions.openoffice.org/testarea/desktop/....
diff --git a/desktop/test/deployment/update/website_update/web1.oxt b/desktop/test/deployment/update/website_update/web1.oxt
new file mode 100644
index 000000000000..7c17586e0454
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web2.oxt b/desktop/test/deployment/update/website_update/web2.oxt
new file mode 100644
index 000000000000..705e70a7533f
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web3.oxt b/desktop/test/deployment/update/website_update/web3.oxt
new file mode 100644
index 000000000000..4e63a75f0cbf
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web4.oxt b/desktop/test/deployment/update/website_update/web4.oxt
new file mode 100644
index 000000000000..e66513e68384
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web4.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web5.oxt b/desktop/test/deployment/update/website_update/web5.oxt
new file mode 100644
index 000000000000..65b02db9347d
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web5.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web6.oxt b/desktop/test/deployment/update/website_update/web6.oxt
new file mode 100644
index 000000000000..98416edfa583
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web6.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/website_update/web7.oxt b/desktop/test/deployment/update/website_update/web7.oxt
new file mode 100644
index 000000000000..31ba45f032d5
--- /dev/null
+++ b/desktop/test/deployment/update/website_update/web7.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/readme.txt b/desktop/test/deployment/update/wrong_url/readme.txt
new file mode 100644
index 000000000000..cc2459763ca9
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/readme.txt
@@ -0,0 +1,18 @@
+The extensions use either multiple urls to the update information file, or the update information file contains multiple urls. Some of those URLs point to locations which do not exist.
+
+url1.oxt: The corresponding url1.update.xml contains two download urls. The first Url points to a location that is not available. The second points to the new version.
+
+url2.oxt: Contains to URLs to update information files. The first URL in url2.oxt is wrong and the second is
+correct.
+
+url3.oxt: contains to URLs to update information files which point to locations which do not exist.
+
+wrongdownload1.oxt: The corresponding wrongdownload1.update.xml contains two download URLs which point to locations which are not available.
+
+wrongdownload2.oxt: same as wrongdownload1.oxt
+
+wrongdownload3.oxt: same as wrongdownload1.oxt
+
+
+Use the wrongdownload extensions to check the automatic scolling of the text area that contains the results.
+
diff --git a/desktop/test/deployment/update/wrong_url/update/url1.oxt b/desktop/test/deployment/update/wrong_url/update/url1.oxt
new file mode 100644
index 000000000000..479b546c84dd
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/url1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/update/url1.update.xml b/desktop/test/deployment/update/wrong_url/update/url1.update.xml
new file mode 100644
index 000000000000..5ff3bce7bb2f
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/url1.update.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.url1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/notavailable/url1.oxt" />
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/update/url1.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/update/url2.oxt b/desktop/test/deployment/update/wrong_url/update/url2.oxt
new file mode 100644
index 000000000000..ec2c5c6528cd
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/url2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/update/url2.update.xml b/desktop/test/deployment/update/wrong_url/update/url2.update.xml
new file mode 100644
index 000000000000..4bf79eb39425
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/url2.update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.url2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/update/url2.oxt" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/update/wrongdownload1.update.xml b/desktop/test/deployment/update/wrong_url/update/wrongdownload1.update.xml
new file mode 100644
index 000000000000..0fd5bee55346
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/wrongdownload1.update.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.wrongdownload1.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/notavailable/wrongdownload1.oxt" />
+ <src xlink:href="http://extensions.openoffice.org/notavailable/" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/update/wrongdownload2.update.xml b/desktop/test/deployment/update/wrong_url/update/wrongdownload2.update.xml
new file mode 100644
index 000000000000..124331215215
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/wrongdownload2.update.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.wrongdownload2.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/notavailable/wrongdownload2.oxt" />
+ <src xlink:href="http://extensions.openoffice.org/notavailable/" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/update/wrongdownload3.update.xml b/desktop/test/deployment/update/wrong_url/update/wrongdownload3.update.xml
new file mode 100644
index 000000000000..051d33ec4ba4
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/update/wrongdownload3.update.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description xmlns="http://openoffice.org/extensions/update/2006"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <identifier value="org.openoffice.legacy.wrongdownload3.oxt"/>
+ <version value="2.0" />
+ <update-download>
+ <src xlink:href="http://extensions.openoffice.org/testarea/desktop/wrong_url/notavailable/wrongdownload3.oxt" />
+ <src xlink:href="http://extensions.openoffice.org/notavailable/" />
+ </update-download>
+</description>
+
diff --git a/desktop/test/deployment/update/wrong_url/url1.oxt b/desktop/test/deployment/update/wrong_url/url1.oxt
new file mode 100644
index 000000000000..41d8522fbbce
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/url1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/url2.oxt b/desktop/test/deployment/update/wrong_url/url2.oxt
new file mode 100644
index 000000000000..d68e45e5e55f
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/url2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/url3.oxt b/desktop/test/deployment/update/wrong_url/url3.oxt
new file mode 100644
index 000000000000..80f93b74d11f
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/url3.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/wrongdownload1.oxt b/desktop/test/deployment/update/wrong_url/wrongdownload1.oxt
new file mode 100644
index 000000000000..535ae331a9af
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/wrongdownload1.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/wrongdownload2.oxt b/desktop/test/deployment/update/wrong_url/wrongdownload2.oxt
new file mode 100644
index 000000000000..aafe2c24672b
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/wrongdownload2.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/wrong_url/wrongdownload3.oxt b/desktop/test/deployment/update/wrong_url/wrongdownload3.oxt
new file mode 100644
index 000000000000..fbdac925a257
--- /dev/null
+++ b/desktop/test/deployment/update/wrong_url/wrongdownload3.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/readme.txt b/desktop/test/deployment/version/readme.txt
new file mode 100644
index 000000000000..c2ba28afd916
--- /dev/null
+++ b/desktop/test/deployment/version/readme.txt
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+There are three extensions in various versions:
+
+1 version_XXX/plain.oxt has no dependencies and no license.
+2a version_XXX/dependency.oxt has an unsatisfied dependency and no license.
+2b version_nodependencies_XXX/dependency.oxt is identical to 2a but without the
+ dependency.
+3 version_XXX/license.oxt has no dependencies and a license.
+
+The different versions are:
+
+A version_none contains no version element (treated as version "0").
+B version_badelement contains a bad <version val="1"/> (not allowed by the
+ specification, but treated by the current implementation as version "0").
+C version_badvalue contains a bad <version value="1.a"/> (not allowed by the
+ specification, but treated by the current implementation as version "1").
+D version_0.0 contains <version value="0.0"/> (same as version "0").
+E version_1.2.3 contains <version value="1.2.3"/>.
+F version_1.2.4.7 contains <version value="1.2.4.7"/>.
+G version_1.02.4.7.0 contains <version value="1.02.4.7.0"/> (same as version
+ "1.2.4.7").
+H version_1.2.15.3 contains <version value="1.2.15.3"/>.
+
+The total order among the various versions is thus
+
+ A = B = D < C < E < F = G < H.
+
+Things to watch for:
+
+- If version y of extension e is to be installed and version x < y of
+ extension e is already installed, then
+ unopkg add e
+ will replace x with y.
+
+- If version y of extension e is to be installed and version x >= y of
+ extension e is already installed, then
+ unopkg add e
+ will fail with an error message.
+
+- If version y of extension e is to be installed and any version x of
+ extension e is already installed, then
+ unopkg add -f e
+ will replace x with y.
+
+- If version y of extension e is to be installed and any version x of
+ extension e is already installed, then
+ unopkg gui "Add..."
+ and
+ soffice "Tools - Package Manager... - Add..."
+ will query with a dialog whether to replace x with y. The dialog will have
+ "OK" (replace) preselected if x < y, and "Cancel" otherwise.
+
+- If replacing an installed version x of an extension e with a version y fails
+ because y has unsatisfied dependencies, or because y has a license to wich the
+ user does not agree, version x is left installed afterwards.
+
+- Checking for already installed versions of an extension is only done within a
+ single layer (unopkg versus unopkg --shared; "My Packages" versus
+ "OpenOffice Packages" in unopkg gui/soffice), not across layers.
diff --git a/desktop/test/deployment/version/version_0.0/dependency.oxt b/desktop/test/deployment/version/version_0.0/dependency.oxt
new file mode 100644
index 000000000000..30c8432251a5
--- /dev/null
+++ b/desktop/test/deployment/version/version_0.0/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_0.0/license.oxt b/desktop/test/deployment/version/version_0.0/license.oxt
new file mode 100644
index 000000000000..b994ff71b732
--- /dev/null
+++ b/desktop/test/deployment/version/version_0.0/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_0.0/plain.oxt b/desktop/test/deployment/version/version_0.0/plain.oxt
new file mode 100644
index 000000000000..f156014eb8c3
--- /dev/null
+++ b/desktop/test/deployment/version/version_0.0/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.02.4.7.0/dependency.oxt b/desktop/test/deployment/version/version_1.02.4.7.0/dependency.oxt
new file mode 100644
index 000000000000..4d75f7076234
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.02.4.7.0/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.02.4.7.0/license.oxt b/desktop/test/deployment/version/version_1.02.4.7.0/license.oxt
new file mode 100644
index 000000000000..40938b7543db
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.02.4.7.0/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.02.4.7.0/plain.oxt b/desktop/test/deployment/version/version_1.02.4.7.0/plain.oxt
new file mode 100644
index 000000000000..521a2b6c77a8
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.02.4.7.0/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.15.3/dependency.oxt b/desktop/test/deployment/version/version_1.2.15.3/dependency.oxt
new file mode 100644
index 000000000000..6f2a301f3bb3
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.15.3/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.15.3/license.oxt b/desktop/test/deployment/version/version_1.2.15.3/license.oxt
new file mode 100644
index 000000000000..2e2a87575047
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.15.3/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.15.3/plain.oxt b/desktop/test/deployment/version/version_1.2.15.3/plain.oxt
new file mode 100644
index 000000000000..000f3a144fbd
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.15.3/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.3/dependency.oxt b/desktop/test/deployment/version/version_1.2.3/dependency.oxt
new file mode 100644
index 000000000000..c2966345872d
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.3/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.3/license.oxt b/desktop/test/deployment/version/version_1.2.3/license.oxt
new file mode 100644
index 000000000000..9cd80e9911b4
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.3/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.3/plain.oxt b/desktop/test/deployment/version/version_1.2.3/plain.oxt
new file mode 100644
index 000000000000..e34264591c58
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.3/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.4.7/dependency.oxt b/desktop/test/deployment/version/version_1.2.4.7/dependency.oxt
new file mode 100644
index 000000000000..53089e76b07e
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.4.7/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.4.7/license.oxt b/desktop/test/deployment/version/version_1.2.4.7/license.oxt
new file mode 100644
index 000000000000..e283508d3492
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.4.7/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_1.2.4.7/plain.oxt b/desktop/test/deployment/version/version_1.2.4.7/plain.oxt
new file mode 100644
index 000000000000..d63c79a734b6
--- /dev/null
+++ b/desktop/test/deployment/version/version_1.2.4.7/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badelement/dependency.oxt b/desktop/test/deployment/version/version_badelement/dependency.oxt
new file mode 100644
index 000000000000..3cb8faa2e7b6
--- /dev/null
+++ b/desktop/test/deployment/version/version_badelement/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badelement/license.oxt b/desktop/test/deployment/version/version_badelement/license.oxt
new file mode 100644
index 000000000000..7b2b7730eced
--- /dev/null
+++ b/desktop/test/deployment/version/version_badelement/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badelement/plain.oxt b/desktop/test/deployment/version/version_badelement/plain.oxt
new file mode 100644
index 000000000000..62267c212fdc
--- /dev/null
+++ b/desktop/test/deployment/version/version_badelement/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badvalue/dependency.oxt b/desktop/test/deployment/version/version_badvalue/dependency.oxt
new file mode 100644
index 000000000000..7d8103365452
--- /dev/null
+++ b/desktop/test/deployment/version/version_badvalue/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badvalue/license.oxt b/desktop/test/deployment/version/version_badvalue/license.oxt
new file mode 100644
index 000000000000..b97723ebb0bc
--- /dev/null
+++ b/desktop/test/deployment/version/version_badvalue/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_badvalue/plain.oxt b/desktop/test/deployment/version/version_badvalue/plain.oxt
new file mode 100644
index 000000000000..f9964ed8f070
--- /dev/null
+++ b/desktop/test/deployment/version/version_badvalue/plain.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_0.0/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_0.0/dependency.oxt
new file mode 100644
index 000000000000..f156014eb8c3
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_0.0/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_1.02.4.7.0/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_1.02.4.7.0/dependency.oxt
new file mode 100644
index 000000000000..521a2b6c77a8
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_1.02.4.7.0/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_1.2.15.3/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_1.2.15.3/dependency.oxt
new file mode 100644
index 000000000000..000f3a144fbd
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_1.2.15.3/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_1.2.3/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_1.2.3/dependency.oxt
new file mode 100644
index 000000000000..e34264591c58
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_1.2.3/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_1.2.4.7/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_1.2.4.7/dependency.oxt
new file mode 100644
index 000000000000..d63c79a734b6
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_1.2.4.7/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_badelement/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_badelement/dependency.oxt
new file mode 100644
index 000000000000..62267c212fdc
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_badelement/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_badvalue/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_badvalue/dependency.oxt
new file mode 100644
index 000000000000..f9964ed8f070
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_badvalue/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_nodependencies_none/dependency.oxt b/desktop/test/deployment/version/version_nodependencies_none/dependency.oxt
new file mode 100644
index 000000000000..fc227b099ec8
--- /dev/null
+++ b/desktop/test/deployment/version/version_nodependencies_none/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_none/dependency.oxt b/desktop/test/deployment/version/version_none/dependency.oxt
new file mode 100644
index 000000000000..36a1854bf59b
--- /dev/null
+++ b/desktop/test/deployment/version/version_none/dependency.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_none/license.oxt b/desktop/test/deployment/version/version_none/license.oxt
new file mode 100644
index 000000000000..1564c089b0a7
--- /dev/null
+++ b/desktop/test/deployment/version/version_none/license.oxt
Binary files differ
diff --git a/desktop/test/deployment/version/version_none/plain.oxt b/desktop/test/deployment/version/version_none/plain.oxt
new file mode 100644
index 000000000000..fc227b099ec8
--- /dev/null
+++ b/desktop/test/deployment/version/version_none/plain.oxt
Binary files differ
diff --git a/desktop/unx/source/officeloader/makefile.mk b/desktop/unx/source/officeloader/makefile.mk
new file mode 100644
index 000000000000..050da981e88d
--- /dev/null
+++ b/desktop/unx/source/officeloader/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET=officeloader
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/officeloader.obj
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/unx/source/officeloader/officeloader.cxx b/desktop/unx/source/officeloader/officeloader.cxx
new file mode 100755
index 000000000000..87621960c61a
--- /dev/null
+++ b/desktop/unx/source/officeloader/officeloader.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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/main.h>
+#include <osl/process.h>
+#include <rtl/ustring.hxx>
+
+#include "../../../source/inc/exithelper.hxx"
+
+using namespace rtl;
+using namespace desktop;
+
+SAL_IMPLEMENT_MAIN()
+{
+ oslProcess process;
+ oslProcessError error;
+
+ OUString sExecutableFile;
+ rtl_uString **pCommandArgs;
+ sal_uInt32 nCommandArgs;
+
+ osl_getExecutableFile( &sExecutableFile.pData );
+
+ sExecutableFile += OUString( RTL_CONSTASCII_USTRINGPARAM(".bin") );
+
+ nCommandArgs = osl_getCommandArgCount();
+ pCommandArgs = new rtl_uString *[nCommandArgs];
+
+ for ( sal_uInt32 i = 0; i < nCommandArgs; i++ )
+ {
+ pCommandArgs[i] = NULL;
+ osl_getCommandArg( i, &pCommandArgs[i] );
+ }
+
+ bool bRestart = false;
+ bool bFirstRun = true;
+ oslProcessExitCode exitcode = 255;
+
+ do {
+ error = osl_executeProcess(
+ sExecutableFile.pData,
+ bFirstRun ? pCommandArgs : NULL,
+ bFirstRun ? nCommandArgs : 0,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ &process
+ );
+
+ if ( osl_Process_E_None == error )
+ {
+ oslProcessInfo info;
+
+ info.Size = sizeof(info);
+
+ error = osl_joinProcess( process );
+ if ( osl_Process_E_None != error )
+ break;
+
+ error = osl_getProcessInfo( process, osl_Process_EXITCODE, &info );
+ if ( osl_Process_E_None != error )
+ break;
+
+ if ( info.Fields & osl_Process_EXITCODE )
+ {
+ exitcode = info.Code;
+ bRestart = (ExitHelper::E_CRASH_WITH_RESTART == exitcode || ExitHelper::E_NORMAL_RESTART == exitcode);
+ }
+ else
+ break;
+
+ osl_freeProcessHandle( process );
+
+ }
+
+ bFirstRun = false;
+
+ } while ( bRestart );
+
+ return exitcode;
+}
diff --git a/desktop/util/hidother.src b/desktop/util/hidother.src
new file mode 100644
index 000000000000..a7ca7c09874e
--- /dev/null
+++ b/desktop/util/hidother.src
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "../source/inc/helpid.hrc"
+
+hidspecial HID_PACKAGE_MANAGER { HelpID = HID_PACKAGE_MANAGER; };
+hidspecial HID_PACKAGE_MANAGER_MENU_ITEM { HelpID = HID_PACKAGE_MANAGER_MENU_ITEM; };
+hidspecial HID_PACKAGE_MANAGER_TREELISTBOX { HelpID = HID_PACKAGE_MANAGER_TREELISTBOX; };
+hidspecial HID_PACKAGE_MANAGER_PROGRESS { HelpID = HID_PACKAGE_MANAGER_PROGRESS; };
+hidspecial HID_PACKAGE_MANAGER_PROGRESS_CANCEL { HelpID = HID_PACKAGE_MANAGER_PROGRESS_CANCEL; };
+
+hidspecial HID_PACKAGE_MANAGER_UPD_REQ { HelpID = HID_PACKAGE_MANAGER_UPD_REQ; };
+
+hidspecial HID_FIRSTSTART_PREV { HelpId = HID_FIRSTSTART_PREV;};
+hidspecial HID_FIRSTSTART_NEXT { HelpId = HID_FIRSTSTART_NEXT;};
+hidspecial HID_FIRSTSTART_CANCEL { HelpId = HID_FIRSTSTART_CANCEL;};
+hidspecial HID_FIRSTSTART_FINISH { HelpId = HID_FIRSTSTART_FINISH;};
+hidspecial UID_FIRSTSTART_HELP { HelpId = UID_FIRSTSTART_HELP;};
+
+hidspecial UID_BTN_LICENSE_ACCEPT { HelpId = UID_BTN_LICENSE_ACCEPT;};
+
+hidspecial HID_DEPLOYMENT_GUI_UPDATE { HelpId = HID_DEPLOYMENT_GUI_UPDATE;};
+hidspecial HID_DEPLOYMENT_GUI_UPDATEINSTALL { HelpId = HID_DEPLOYMENT_GUI_UPDATEINSTALL;};
+
+hidspecial HID_EXTENSION_MANAGER_LISTBOX { HelpId = HID_EXTENSION_MANAGER_LISTBOX; };
+hidspecial HID_EXTENSION_MANAGER_LISTBOX_OPTIONS { HelpId = HID_EXTENSION_MANAGER_LISTBOX_OPTIONS; };
+hidspecial HID_EXTENSION_MANAGER_LISTBOX_ENABLE { HelpId = HID_EXTENSION_MANAGER_LISTBOX_ENABLE; };
+hidspecial HID_EXTENSION_MANAGER_LISTBOX_DISABLE { HelpId = HID_EXTENSION_MANAGER_LISTBOX_DISABLE; };
+hidspecial HID_EXTENSION_MANAGER_LISTBOX_REMOVE { HelpId = HID_EXTENSION_MANAGER_LISTBOX_REMOVE; };
+
diff --git a/desktop/util/makefile.mk b/desktop/util/makefile.mk
new file mode 100644
index 000000000000..8cf03f157254
--- /dev/null
+++ b/desktop/util/makefile.mk
@@ -0,0 +1,277 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=desktop
+TARGET=soffice
+TARGETTYPE=GUI
+LIBTARGET=NO
+GEN_HID=TRUE
+GEN_HID_OTHER=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+UWINAPILIB =
+
+VERINFONAME=verinfo
+
+# --- Resourcen ----------------------------------------------------
+
+.IF "$(GUI)" == "WNT"
+RCFILES=verinfo.rc
+.ENDIF
+.IF "$(GUI)" == "OS2"
+RCFILES=ooverinfo2.rc
+.ENDIF
+
+# --- Linken der Applikation ---------------------------------------
+
+.IF "$(OS)" == "MACOSX"
+LINKFLAGSAPPGUI!:= $(LINKFLAGSAPPGUI:s/-bind_at_load//)
+.ENDIF # MACOSX
+
+#.IF "$(OS)" == "LINUX" || "$(OS)" == "FREEBSD" || "$(OS)" == "NETBSD"
+## #74158# linux needs sal/vos/tools at end of link list, solaris needs it first,
+## winXX is handled like solaris for now
+#APP1_STDPRE=
+#APP1_STDPOST=$(CPPULIB) $(CPPUHELPERLIB) $(UNOLIB) $(TOOLSLIB) \
+# $(VOSLIB) $(SALLIB)
+#.ELSE
+#APP1_STDPRE=$(SALLIB) $(VOSLIB) $(TOOLSLIB) $(UNOLIB) $(CPPULIB) \
+# $(CPPUHELPERLIB)
+#APP1_STDPOST=
+#.ENDIF
+
+RESLIB1NAME= dkt
+RESLIB1IMAGES= $(PRJ)$/res
+RESLIB1SRSFILES= $(SRS)$/desktop.srs \
+ $(SRS)$/wizard.srs
+
+.IF "$(L10N_framework)"==""
+.IF "$(LINK_SO)"=="TRUE"
+.IF "$(GUI)" != "OS2"
+APP1TARGET=so$/$(TARGET)
+APP1NOSAL=TRUE
+APP1RPATH=BRAND
+APP1OBJS=$(OBJ)$/copyright_ascii_sun.obj $(OBJ)$/main.obj
+APP1STDLIBS = $(SALLIB) $(SOFFICELIB)
+APP1DEPN= $(APP1RES) verinfo.rc
+
+.IF "$(GUI)" == "WNT"
+APP1RES= $(RES)$/desktop.res
+APP1ICON=$(SOLARRESDIR)$/icons/so9_main_app.ico
+APP1VERINFO=verinfo.rc
+APP1LINKRES=$(MISC)$/$(TARGET)1.res
+APP1STACK=10000000
+
+# create a manifest file with the same name as the
+#office executable file soffice.exe.manifest
+#$(BIN)$/$(TARGET).exe.manifest: template.manifest
+#$(COPY) $< $@
+
+.ENDIF # WNT
+
+.ENDIF # "$(GUI)" != "OS2"
+
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+APP5TARGET=soffice
+APP5NOSAL=TRUE
+APP5RPATH=BRAND
+APP5OBJS=$(OBJ)$/copyright_ascii_ooo.obj $(OBJ)$/main.obj
+APP5STDLIBS = $(SALLIB) $(SOFFICELIB)
+.IF "$(OS)" == "LINUX"
+APP5STDLIBS+= -lXext -lX11
+#APP5STDLIBS+= -lXext -lSM -lICE
+.ENDIF # LINUX
+
+APP5DEPN= $(APP1TARGETN) $(APP5RES) ooverinfo.rc
+APP5DEF= $(MISCX)$/$(TARGET).def
+
+.IF "$(GUI)" == "WNT"
+APP5RES= $(RES)$/oodesktop.res
+APP5ICON=$(SOLARRESDIR)$/icons/ooo3_main_app.ico
+APP5VERINFO=ooverinfo.rc
+APP5LINKRES=$(MISC)$/ooffice5.res
+APP5STACK=10000000
+.ENDIF # WNT
+
+.IF "$(GUI)" == "OS2"
+APP5DEF= # automatic
+APP5RES= $(RES)$/oodesktop.res
+APP5ICON=$(SOLARRESDIR)$/icons/ooo-main-app.ico
+APP5VERINFO=ooverinfo2.rc
+APP5LINKRES=$(MISC)$/ooffice.res
+.ENDIF # OS2
+
+.IF "$(GUI)" == "WNT"
+.IF "$(LINK_SO)"=="TRUE"
+APP6TARGET=so$/officeloader
+APP6RES=$(RES)$/soloader.res
+APP6NOSAL=TRUE
+APP6DEPN= $(APP1TARGETN) $(APP6RES) verinfo.rc
+APP6VERINFO=verinfo.rc
+APP6LINKRES=$(MISC)$/soffice6.res
+APP6ICON=$(SOLARRESDIR)$/icons/so9_main_app.ico
+APP6OBJS = \
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/officeloader.obj \
+ $(SOLARLIBDIR)$/pathutils-obj.obj
+STDLIB6=$(ADVAPI32LIB) $(SHELL32LIB) $(SHLWAPILIB)
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+APP7TARGET=officeloader
+APP7RES=$(RES)$/ooloader.res
+APP7NOSAL=TRUE
+APP7DEPN= $(APP1TARGETN) $(APP7RES) ooverinfo.rc
+APP7VERINFO=ooverinfo.rc
+APP7LINKRES=$(MISC)$/ooffice7.res
+APP7ICON=$(SOLARRESDIR)$/icons/ooo3_main_app.ico
+APP7OBJS = \
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/officeloader.obj \
+ $(SOLARLIBDIR)$/pathutils-obj.obj
+STDLIB7=$(ADVAPI32LIB) $(SHELL32LIB) $(SHLWAPILIB)
+.ELIF "$(OS)" == "MACOSX"
+APP6TARGET=officeloader
+APP6NOSAL=TRUE
+APP6RPATH=BRAND
+APP6OBJS=$(OBJ)$/copyright_ascii_ooo.obj $(OBJ)$/officeloader.obj
+APP6STDLIBS = $(SALLIB)
+APP5DEPN= $(APP1TARGETN) $(APP5RES) ooverinfo.rc
+APP5DEF= $(MISCX)$/$(TARGET).def
+.ENDIF # WNT
+
+.ENDIF
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(L10N_framework)"==""
+
+.IF "$(APP1TARGETN)"!=""
+$(APP1TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP1TARGETN)"!=""
+
+.IF "$(APP5TARGETN)"!=""
+$(APP5TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP6TARGETN)"!=""
+
+.IF "$(APP6TARGETN)"!=""
+$(APP6TARGETN) : $(MISC)$/binso_created.flg
+.ENDIF # "$(APP6TARGETN)"!=""
+
+.IF "$(GUI)" == "WNT"
+ALLTAR: $(MISC)$/$(TARGET).exe.manifest
+ALLTAR: $(MISC)$/$(TARGET).bin.manifest
+ALLTAR: $(BIN)$/$(TARGET).bin
+.IF "$(LINK_SO)"=="TRUE"
+ALLTAR: $(BIN)$/so$/$(TARGET).bin
+.ENDIF # "$(LINK_SO)"=="TRUE"
+.ENDIF # WNT
+
+.IF "$(GUI)" == "OS2"
+ALLTAR: $(BIN)$/$(TARGET).bin
+.ENDIF # OS2
+
+$(BIN)$/soffice_oo$(EXECPOST) : $(APP5TARGETN)
+ $(COPY) $< $@
+
+.IF "$(GUI)" != "OS2"
+.IF "$(LINK_SO)"=="TRUE"
+$(BIN)$/so$/soffice_so$(EXECPOST) : $(APP1TARGETN)
+ $(COPY) $< $@
+
+ALLTAR : $(BIN)$/so$/soffice_so$(EXECPOST)
+.ENDIF # "$(LINK_SO)"=="TRUE"
+ALLTAR : $(BIN)$/soffice_oo$(EXECPOST)
+.ENDIF
+
+.IF "$(OS)" == "MACOSX"
+.IF "$(LINK_SO)"=="TRUE"
+$(BIN)$/so$/soffice_mac$(EXECPOST) : $(APP1TARGETN)
+ $(COPY) $< $@
+
+ALLTAR : $(BIN)$/so$/soffice_mac$(EXECPOST)
+.ENDIF # "$(LINK_SO)"=="TRUE"
+
+$(BIN)$/soffice_mac$(EXECPOST) : $(APP5TARGETN)
+ $(COPY) $< $@
+
+ALLTAR : $(BIN)$/soffice_mac$(EXECPOST)
+
+.ENDIF # "$(OS)" == "MACOSX"
+
+.IF "$(GUI)" == "WNT"
+
+# create a manifest file with the same name as the
+# office executable file soffice.exe.manifest
+.IF "$(CCNUMVER)" <= "001399999999"
+$(MISC)$/$(TARGET).exe.manifest: template.manifest
+ $(COPY) $< $@
+.ELSE
+$(MISC)$/$(TARGET).exe.template.manifest: template.manifest
+ $(COPY) $< $@
+
+$(MISC)$/$(TARGET).exe.linker.manifest: $(BIN)$/$(TARGET)$(EXECPOST)
+ mt.exe -inputresource:$(BIN)$/$(TARGET)$(EXECPOST) -out:$@
+
+$(MISC)$/$(TARGET).exe.manifest: $(MISC)$/$(TARGET).exe.template.manifest $(MISC)$/$(TARGET).exe.linker.manifest
+ mt.exe -manifest $(MISC)$/$(TARGET).exe.linker.manifest $(MISC)$/$(TARGET).exe.template.manifest -out:$@
+.ENDIF
+
+# create a manifest file with the same name as the
+# office executable file soffice.bin.manifest
+.IF "$(CCNUMVER)" <= "001399999999"
+$(MISC)$/$(TARGET).bin.manifest: template.manifest
+ $(COPY) $< $@
+.ELSE
+$(MISC)$/$(TARGET).bin.manifest: $(MISC)$/$(TARGET).exe.manifest
+ $(COPY) $(MISC)$/$(TARGET).exe.manifest $@
+.ENDIF
+
+$(BIN)$/$(TARGET).bin: $(BIN)$/$(TARGET)$(EXECPOST)
+ $(COPY) $< $@
+
+$(BIN)$/so$/$(TARGET).bin: $(BIN)$/so$/$(TARGET)$(EXECPOST)
+ $(COPY) $< $@
+
+.ENDIF # WNT
+
+.IF "$(GUI)" == "OS2"
+$(BIN)$/$(TARGET).bin: $(BIN)$/$(TARGET)$(EXECPOST)
+ $(COPY) $< $@
+.ENDIF # OS2
+
+$(MISC)$/binso_created.flg :
+ @@-$(MKDIRHIER) $(BIN)$/so && $(TOUCH) $@
+
+.ENDIF
diff --git a/desktop/util/ooverinfo.rc b/desktop/util/ooverinfo.rc
new file mode 100644
index 000000000000..6d92e2a99500
--- /dev/null
+++ b/desktop/util/ooverinfo.rc
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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(ENGLISH)
+#define LG_D // generate always german version
+#endif
+
+#define VER_FIRSTYEAR 2000
+
+#include <windows.h>
+#include "version.hrc"
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+#ifndef WIN32
+ fileos VOS_DOS_WINDOWS16
+#else
+ fileos VOS_NT_WINDOWS32
+#endif
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+#ifdef LG_D
+ block "040704E4"
+ {
+ // German StringTable
+ value "CompanyName", "OpenOffice.org\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", "SOFFICE.EXE\0"
+ value "InternalName", "SOFFICE\0"
+ value "LegalCopyright", S_CRIGHT " Oracle, Inc.\0"
+ }
+#else
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "OpenOffice.org\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", "SOFFICE.EXE\0"
+ value "InternalName", "SOFFICE\0"
+ value "LegalCopyright", S_CRIGHT " Oracle, Inc.\0"
+ }
+#endif
+ }
+
+ block "VarFileInfo"
+ {
+#ifdef LG_D
+ value "Translation", 0x0407, 1252
+#else
+ value "Translation", 0x0409, 1252
+#endif
+ }
+ }
+
+2 ICON "icons\\oasis-text.ico"
+3 ICON "icons\\oasis-text-template.ico"
+4 ICON "icons\\oasis-spreadsheet.ico"
+5 ICON "icons\\oasis-spreadsheet-template.ico"
+6 ICON "icons\\oasis-drawing.ico"
+7 ICON "icons\\oasis-drawing-template.ico"
+8 ICON "icons\\oasis-presentation.ico"
+9 ICON "icons\\oasis-presentation-template.ico"
+10 ICON "icons\\oasis-presentation-template.ico"
+11 ICON "icons\\oasis-master-document.ico"
+12 ICON "icons\\oasis-web-template.ico"
+13 ICON "icons\\oasis-empty-document.ico"
+14 ICON "icons\\oasis-database.ico"
+15 ICON "icons\\oasis-formula.ico"
+16 ICON "icons\\oasis-web-template.ico"
+17 ICON "icons\\empty-document.ico"
+18 ICON "icons\\ooo-configuration.ico"
+19 ICON "icons\\ooo3_open.ico"
+20 ICON "icons\\empty-document.ico"
+21 ICON "icons\\ooo3_writer_app.ico"
+22 ICON "icons\\ooo3_calc_app.ico"
+23 ICON "icons\\ooo3_draw_app.ico"
+24 ICON "icons\\ooo3_impress_app.ico"
+25 ICON "icons\\ooo3_math_app.ico"
+26 ICON "icons\\ooo3_base_app.ico"
+27 ICON "icons\\oasis-empty-document.ico"
+28 ICON "icons\\text.ico"
+29 ICON "icons\\text-template.ico"
+30 ICON "icons\\spreadsheet.ico"
+31 ICON "icons\\spreadsheet-template.ico"
+32 ICON "icons\\drawing.ico"
+33 ICON "icons\\drawing-template.ico"
+34 ICON "icons\\presentation.ico"
+35 ICON "icons\\presentation-template.ico"
+36 ICON "icons\\master-document.ico"
+37 ICON "icons\\empty-document.ico"
+38 ICON "icons\\database.ico"
+39 ICON "icons\\formula.ico"
+40 ICON "icons\\oxt-extension.ico"
+
diff --git a/desktop/util/ooverinfo2.rc b/desktop/util/ooverinfo2.rc
new file mode 100644
index 000000000000..f149ec6474e7
--- /dev/null
+++ b/desktop/util/ooverinfo2.rc
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ *************************************************************************/
+
+#define VERSION 3
+#define SUBVERSION 2
+//#define VERVARIANT 0
+// .0 + VER_CONCEPT
+// .100 + VER_ALPHA
+// .200 + VER_BETA
+// .300 + VER_GAMMA
+// .500 + VER_FINAL
+//#define VER_CONCEPT 0
+//#define VER_BETA 6
+#define VER_FINAL 0
+
+#define VER_DAY 1
+#define VER_MONTH 9
+#define VER_YEAR 2009
+
+// -----------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+// language/character set specification table
+// -----------------------------------------------------------------------
+
+
+ICON 2 "icons/oasis-text.ico"
+ICON 3 "icons/oasis-text-template.ico"
+ICON 4 "icons/oasis-spreadsheet.ico"
+ICON 5 "icons/oasis-spreadsheet-template.ico"
+ICON 6 "icons/oasis-drawing.ico"
+ICON 7 "icons/oasis-drawing-template.ico"
+ICON 8 "icons/oasis-presentation.ico"
+ICON 9 "icons/oasis-presentation-template.ico"
+ICON 10 "icons/oasis-presentation-template.ico"
+// ICON 11 "icons/oasis-master-document.ico"
+// ICON 12 "icons/oasis-web-template.ico"
+ICON 13 "icons/oasis-empty-document.ico"
+ICON 14 "icons/oasis-database.ico"
+ICON 15 "icons/oasis-formula.ico"
+ICON 16 "icons/oasis-web-template.ico"
+ICON 17 "icons/empty-document.ico"
+ICON 18 "icons/ooo-configuration.ico"
+ICON 19 "icons/ooo-open.ico"
+ICON 20 "icons/empty-document.ico"
+ICON 21 "icons/ooo-writer-app.ico"
+ICON 22 "icons/ooo-calc-app.ico"
+ICON 23 "icons/ooo-draw-app.ico"
+ICON 24 "icons/ooo-impress-app.ico"
+ICON 25 "icons/ooo-math-app.ico"
+ICON 26 "icons/ooo-base-app.ico"
+ICON 27 "icons/oasis-empty-document.ico"
+ICON 28 "icons/text.ico"
+ICON 29 "icons/text-template.ico"
+ICON 30 "icons/spreadsheet.ico"
+ICON 31 "icons/spreadsheet-template.ico"
+ICON 32 "icons/drawing.ico"
+ICON 33 "icons/drawing-template.ico"
+ICON 34 "icons/presentation.ico"
+ICON 35 "icons/presentation-template.ico"
+ICON 36 "icons/master-document.ico"
+ICON 37 "icons/empty-document.ico"
+ICON 38 "icons/database.ico"
+ICON 39 "icons/formula.ico"
+ICON 40 "icons/oxt-extension.ico"
+
diff --git a/desktop/util/soffice.ico b/desktop/util/soffice.ico
new file mode 100644
index 000000000000..88ccf5e5a6a0
--- /dev/null
+++ b/desktop/util/soffice.ico
Binary files differ
diff --git a/desktop/util/template.manifest b/desktop/util/template.manifest
new file mode 100644
index 000000000000..dbed81ce3f21
--- /dev/null
+++ b/desktop/util/template.manifest
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity version="1.0.0.0" processorArchitecture="x86" name="OpenOffice" type="win32" />
+<description>http://www.openoffice.org</description>
+<dependency>
+<dependentAssembly>
+<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="x86"/>
+</dependentAssembly>
+</dependency>
+</assembly>
diff --git a/desktop/util/verinfo.rc b/desktop/util/verinfo.rc
new file mode 100644
index 000000000000..038953f2aa79
--- /dev/null
+++ b/desktop/util/verinfo.rc
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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(ENGLISH)
+#define LG_D // generate always german version
+#endif
+
+#define VER_FIRSTYEAR 2007
+
+#include <windows.h>
+#include "version_so.hrc"
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+#ifndef SUBVERSION
+ fileversion VERSION, 0, VERVARIANT, VER_COUNT
+ productversion VERSION, 0, VERVARIANT, VER_COUNT
+#else
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+#endif
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+#ifndef WIN32
+ fileos VOS_DOS_WINDOWS16
+#else
+ fileos VOS_NT_WINDOWS32
+#endif
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+#ifdef LG_D
+ block "040704E4"
+ {
+ // German StringTable
+ value "CompanyName", "Oracle, Inc.\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", "SOFFICE.EXE\0"
+ value "InternalName", "SOFFICE\0"
+ value "LegalCopyright", S_CRIGHT " Oracle, Inc.\0"
+ }
+#else
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "Oracle, Inc.\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", "SOFFICE.EXE\0"
+ value "InternalName", "SOFFICE\0"
+ value "LegalCopyright", S_CRIGHT " Oracle, Inc.\0"
+ }
+#endif
+ }
+
+ block "VarFileInfo"
+ {
+#ifdef LG_D
+ value "Translation", 0x0407, 1252
+#else
+ value "Translation", 0x0409, 1252
+#endif
+ }
+ }
+
+2 ICON "icons\\oasis-text.ico"
+3 ICON "icons\\oasis-text-template.ico"
+4 ICON "icons\\oasis-spreadsheet.ico"
+5 ICON "icons\\oasis-spreadsheet-template.ico"
+6 ICON "icons\\oasis-drawing.ico"
+7 ICON "icons\\oasis-drawing-template.ico"
+8 ICON "icons\\oasis-presentation.ico"
+9 ICON "icons\\oasis-presentation-template.ico"
+10 ICON "icons\\oasis-presentation-template.ico"
+11 ICON "icons\\oasis-master-document.ico"
+12 ICON "icons\\oasis-web-template.ico"
+13 ICON "icons\\oasis-empty-document.ico"
+14 ICON "icons\\oasis-database.ico"
+15 ICON "icons\\oasis-formula.ico"
+16 ICON "icons\\oasis-web-template.ico"
+17 ICON "icons\\empty-document.ico"
+18 ICON "icons\\so8-configuration.ico"
+19 ICON "icons\\so9_open.ico"
+20 ICON "icons\\empty-document.ico"
+21 ICON "icons\\so9_writer_app.ico"
+22 ICON "icons\\so9_calc_app.ico"
+23 ICON "icons\\so9_draw_app.ico"
+24 ICON "icons\\so9_impress_app.ico"
+25 ICON "icons\\so9_math_app.ico"
+26 ICON "icons\\so9_base_app.ico"
+27 ICON "icons\\oasis-empty-document.ico"
+28 ICON "icons\\text.ico"
+29 ICON "icons\\text-template.ico"
+30 ICON "icons\\spreadsheet.ico"
+31 ICON "icons\\spreadsheet-template.ico"
+32 ICON "icons\\drawing.ico"
+33 ICON "icons\\drawing-template.ico"
+34 ICON "icons\\presentation.ico"
+35 ICON "icons\\presentation-template.ico"
+36 ICON "icons\\master-document.ico"
+37 ICON "icons\\empty-document.ico"
+38 ICON "icons\\database.ico"
+39 ICON "icons\\formula.ico"
+40 ICON "icons\\oxt-extension.ico"
diff --git a/desktop/util/writer.r b/desktop/util/writer.r
new file mode 100644
index 000000000000..2a0ec2722900
--- /dev/null
+++ b/desktop/util/writer.r
@@ -0,0 +1 @@
+//************************************************************************* //* //* $Workfile: writer.r $ //* //* Ersterstellung KH //* //* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 16:15:12 $ //* $Revision: 1.1.1.1 $ //* //* $Logfile: T:/desktop/util/writer.r_v $ //* //* Copyright (c) 1990 - 1995, STAR DIVISION //* //************************************************************************* #include "Types.r" //#ifndef MAINSHLBNAME // #define MAINSHLBNAME "Sw356MP Library" //#endif // //resource 'STR#' (2001, "MainShlbName", purgeable) { // { /* array StringArray: 2 elements */ // /* [1] */ // MAINSHLBNAME, // /* [2] */ // "Test" // } //}; resource 'SIZE' (-1) { reserved, acceptSuspendResumeEvents, reserved, canBackground, multiFinderAware, backgroundAndForeground, dontGetFrontClicks, ignoreChildDiedEvents, is32BitCompatible, isHighLevelEventAware, onlyLocalHLEvents, isStationeryAware, dontUseTextEditServices, true, reserved, reserved, 7096000, 3584000 }; resource 'SIZE' (0) { reserved, acceptSuspendResumeEvents, reserved, canBackground, multiFinderAware, backgroundAndForeground, dontGetFrontClicks, ignoreChildDiedEvents, is32BitCompatible, isHighLevelEventAware, onlyLocalHLEvents, isStationeryAware, dontUseTextEditServices, true, reserved, reserved, 7096000, 3584000 }; resource 'ics8' (128) { $"EFF0 EF00 0000 0000 F900 0000 0000 0000" $"F0EF F000 0000 00F9 D257 0000 0000 0000" $"EFF0 EF00 0000 7A00 00D2 F900 0000 0000" $"EFF0 F000 00FA 00F9 FA00 D256 0000 0000" $"F0EF F000 7B00 FA00 F9FF 00D2 F900 0000" $"EFEF EFFA 00F9 0000 00F9 FF00 D2F9 0000" $"F0F0 F900 FA00 0000 0000 FAF9 00D2 F900" $"EFF9 00FA 00FA F9FA F9FA F9FA FF00 D2F9" $"F0EF FAF9 FAE5 E6E6 05E5 D2D2 F9FA F900" $"EFF0 F900 00E6 E505 0505 E6E5 D2F9 0000" $"F0F9 0000 F7E5 E6E5 05E6 E5E6 E5D2 FF00" $"EF00 0000 E5E6 E5D2 D2E5 E6E5 E6D2 FF00" $"F900 FAE6 E5E6 D2E5 D2E5 E5E6 D2D2 F9FA" $"00FA 00E6 2BD2 E5E6 E5D2 E6E5 D2D2 C9F9" $"F9C9 2B2B F7D2 E6E5 E6D2 E5E6 F9D2 C2FA" $"FA00 C3D2 D2D2 E5E6 C2E5 C9F9 D2C3 FAF9" }; resource 'ics8' (129) { $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000" $"00FF F5F5 F5F5 F5F5 F5F5 FFFF 0000 0000" $"00FF F5EC ECEC F5F5 F5F5 FFF8 FF00 0000" $"00FF F5EC ECEC FFFF 00FF FFFF FFFF 0000" $"00FF F5EC ECEC 0000 0000 00F5 F5FF 0000" $"00FF F5EC ECF5 FFFF FF00 FFF5 F5FF 0000" $"00FF F5EC F5F5 0000 0000 00F5 F5FF 0000" $"00FF F5EC F5F5 FF00 FFFF FFF5 F5FF 0000" $"00FF F5EC F5F5 0000 0000 00F5 F5FF 0000" $"00FF F5EC ECF5 FFFF FF00 FFF5 F5FF 0000" $"00FF F5EC ECEC 0000 0000 00F5 F5FF 0000" $"00FF F5EC ECEC FF00 FFFF FFF5 F5FF 0000" $"00FF F5EC ECEC 0000 0000 00F5 F5FF 0000" $"00FF F5EC ECEC FFFF FF00 FFF5 F5FF 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"00FF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (130) { $"00FF FFFF FFFF FFFF FFFF FFFF 0000 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"00FF F5EC ECEC FFF5 FFFF F5FF FFFF 0000" $"00FF F5EC ECEC F5F5 F5F5 F5FF F5FF 0000" $"00FF F5EC ECEC FFFF F5FF F5FF F5FF 0000" $"00FF F5EC ECF5 F5F5 F5F5 F5FF F5FF 0000" $"00FF F5EC F5F5 FFF5 FFFF F5FF F5FF 0000" $"00FF F5EC F5F5 F5F5 F5F5 F5FF F5FF 0000" $"00FF F5EC ECF5 FFFF F5FF F5FF F5FF 0000" $"00FF F5EC ECEC F5F5 F5F5 F5FF F5FF 0000" $"00FF F5EC ECEC FFF5 FFFF FFFF F5FF 0000" $"00FF F5EC ECEC F5F5 FF2B FFF5 F5FF 0000" $"00FF F5F5 F5F5 F5F5 FFFF F5F5 F5FF 0000" $"00FF FFFF FFFF FFFF FFF5 F5FF F5FF 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 00FF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (131) { $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000" $"00FF F5F5 F5F5 F5F5 F5F5 FFFF 0000 0000" $"00FF F5EC ECEC F5F5 F5F5 FF2B FF00 0000" $"00FF F5EC ECEC F5F5 F5F5 FFFF FFFF 0000" $"00FF F5EC ECEC F5F5 F5F5 F5F5 F5FF 0000" $"00FF F5EC ECF5 F5F5 F5F5 F5F5 F5FF 0000" $"00FF F5EC FFF5 FFFF F5FF FFF5 F5FF 0000" $"00FF F5EC F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"00FF F5EC FFFF FFFF F5FF FFF5 F5FF 0000" $"00FF F5EC ECF5 F5F5 F5F5 F5F5 F5FF 0000" $"00FF F5EC FFFF F5FF FFF5 FFF5 F5FF 0000" $"00FF F5EC ECEC F5F5 F5F5 F5F5 F5FF 0000" $"00FF F5EC ECEC F5F5 F5F5 F5F5 F5FF 0000" $"00FF F5EC ECEC F5F5 F5F5 F5F5 F5FF 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"00FF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (132) { $"0000 FFFF FFFF FFFF FFFF FFFF 0000 0000" $"0000 FF00 0000 0000 0000 FF00 FF00 0000" $"0000 FF00 ECEC ECC0 4848 FF00 00FF 0000" $"0000 FF00 ECEC ECC0 0000 FFFF FFFF 0000" $"0000 FF00 ECEC ECFF 0000 0000 00FF 0000" $"0000 FF00 ECEC C000 FFFF 00FF FFFF 0000" $"0000 FF00 EC00 48FF 0000 FF00 00FF 0000" $"0000 FF00 EC00 C000 FFFF 00FF FFFF 0000" $"0000 FF00 EC00 48FF 0000 FF00 00FF 0000" $"0000 FF00 ECEC 48FF 0000 FF00 00FF 0000" $"0000 FF00 ECEC B000 FFFF 00FF FFFF 0000" $"0000 FF00 ECEC ECFF 0000 FF00 00FF 0000" $"0000 FF00 ECEC ECFF 0000 FF00 00FF 0000" $"0000 FF00 ECEC EC00 FFFF 00FF FFFF 0000" $"0000 FF00 0000 0000 0000 0000 00FF 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (133) { $"00FF FFFF FFFF FFFF FFFF FFFF 0000 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"00FF F5EC ECEC C048 48C0 48FF FFFF 0000" $"00FF F5EC ECEC 00FF FF00 FFFF 00FF 0000" $"00FF F5EC ECEC FFF5 F5FF 00FF 00FF 0000" $"00FF F5EC EC48 FFF5 F5FF 00FF FFFF 0000" $"00FF F5EC F5C0 00FF FF00 FFFF 00FF 0000" $"00FF F5EC F548 FFF5 F5FF F5FF 00FF 0000" $"00FF F5EC EC48 FFF5 F5FF F5FF FFFF 0000" $"00FF F5EC ECEC 00FF FF00 FFFF 00FF 0000" $"00FF F5EC ECEC FFF5 FFFF FFFF 00FF 0000" $"00FF F5EC ECEC FFF5 FF2B FF00 FFFF 0000" $"00FF F5F5 F5F5 F5F5 FFFF 0000 00FF 0000" $"00FF FFFF FFFF FFFF FF00 FF00 00FF 0000" $"0000 00FF 0000 0000 0000 0000 00FF 0000" $"0000 00FF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (134) { $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000" $"00FF F5F5 F5F5 F5F5 F5F5 FFFF 0000 0000" $"00FF F5EC ECEC FAFA FAFA FF00 FF00 0000" $"00FF F5EC ECEC FAFC FCFC FFFF FFFF 0000" $"00FF F5EC ECEC FAFC 05EC F5F5 F5FF 0000" $"00FF F5EC ECF5 FAFC D8E3 F5F5 FFFF 0000" $"00FF F5EC F5F5 FAFC F5F5 F5FF F5FF 0000" $"00FF F5EC F5F5 FAFC F5FF FFF5 F5FF 0000" $"00FF F5EC F5F5 FAFF FFF5 F5F5 F5FF 0000" $"00FF F5EC ECF5 FFF5 F5F5 2BF5 F5FF 0000" $"00FF F5EC ECEC F5FA FA2B 2B2B F5FF 0000" $"00FF F5EC ECEC F5FA FAF5 2BF5 F5FF 0000" $"00FF F5EC ECEC F5F5 F5F8 F5F5 F5FF 0000" $"00FF F5EC ECEC F5F5 F8F8 F8F5 F5FF 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"00FF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (135) { $"00FF FFFF FFFF FFFF FFFF FFFF FF00 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"00FF F5EC ECEC FAFA FAFA FAFA FFFF FF00" $"00FF F5EC ECEC FAFC FCFC FCFC FFF5 FF00" $"00FF F5EC ECF5 FAFC 05EC F5F5 FFF5 FF00" $"00FF F5EC F5F5 FAFC D8E3 F5F5 FFF5 FF00" $"00FF F5EC F5F5 FAFC 0000 FFFF FFF5 FF00" $"00FF F5EC F5F5 FAFC FFFF F5F5 FFF5 FF00" $"00FF F5EC ECF5 FFFF F5F5 F5F5 FFF5 FF00" $"00FF F5EC ECEC F5F5 F5F5 F5F5 FFF5 FF00" $"00FF F5EC ECEC FAFA F5FF FFFF FFF5 FF00" $"00FF F5EC ECEC FAFA F5FF 2BFF F5F5 FF00" $"00FF F5F5 F5F5 F5F5 F5FF FFF5 F5F5 FF00" $"00FF FFFF FFFF FFFF FFFF F5F5 F5F5 FF00" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 FF00" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'ics8' (136) { $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000" $"00FF F5F5 F5F5 F5F5 F5F5 FFFF 0000 0000" $"00FF F5EC ECEC FCF5 F5F5 FFF5 FF00 0000" $"00FF F5EC ECEC FAF5 F5F5 FFFF FFFF 0000" $"00FF F5EC ECEC FCF5 05EC ECF5 F5FF 0000" $"00FF F5EC ECF5 FA05 05EC ECEC F5FF 0000" $"00FF F5EC F5F5 FC05 0505 ECEC F5FF 0000" $"00FF F5EC F5F5 FA05 05D8 13D8 F5FF 0000" $"00FF F5EC F5F5 FCF5 D813 D8F5 F5FF 0000" $"00FF F5EC ECF5 FAF5 F5F5 F5F5 C0FF 0000" $"00FF F5EC ECEC FCF5 F5C0 F5C0 F5FF 0000" $"00FF F5EC ECEC FAF5 C0F5 C0F5 F5FF 0000" $"00FF F5EC ECEC FCF5 F5F5 F5F5 F5FF 0000" $"00FF F5EC ECEC FAFC FAFC FAFC F5FF 0000" $"00FF F5F5 F5F5 0000 0000 00F5 F5FF 0000" $"00FF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (137) { $"00FF FFFF FFFF FFFF FFFF FFFF FF00 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"00FF F5EC ECEC F505 ECEC F5F5 FFFF FF00" $"00FF F5EC ECC0 0505 ECEC ECF5 FFF5 FF00" $"00FF F5EC ECFB 0505 05EC ECF5 FFF5 FF00" $"00FF F5EC F5F9 0505 D813 D8F5 FFF5 FF00" $"00FF F5EC F5FB F5D8 13D8 F5F5 FFF5 FF00" $"00FF F5EC F5F9 F5F5 F5F5 F5C0 FFF5 FF00" $"00FF F5EC ECFB F5F5 C0F5 C000 FFF5 FF00" $"00FF F5EC ECC0 F5C0 F5C0 0000 FFF5 FF00" $"00FF F5EC ECEC F5F5 F5FF FFFF FFF5 FF00" $"00FF F5EC ECC0 FBF9 FBFF 2BFF F5F5 FF00" $"00FF F5F5 F5F5 F5F5 F5FF FFF5 F5F5 FF00" $"00FF FFFF FFFF FFFF FFFF F5F5 F5F5 FF00" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 FF00" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'ics8' (138) { $"0000 FFFF FFFF FFFF FFFF FF00 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 FFFF 0000 0000" $"0000 FFF5 ECEC ECFD D8F5 FF2B FF00 0000" $"0000 FFF5 ECEC ECFD D8D8 FFFF FFFF 0000" $"0000 FFF5 ECEC ECFD 0505 05FD F5FF 0000" $"0000 FFF5 ECEC F5FD 05E3 00FD F5FF 0000" $"0000 FFF5 ECF5 F5FD FDFD FDFD F5FF 0000" $"0000 FFF5 ECF5 F5FD E3E3 E3FD F5FF 0000" $"0000 FFF5 ECF5 F5FD E3E3 E3FD F5FF 0000" $"0000 FFF5 ECEC F5FD FDFD FDFD F5FF 0000" $"0000 FFF5 ECEC ECFD 2B2B 2BFD F5FF 0000" $"0000 FFF5 ECEC ECFD 2B00 00FD F5FF 0000" $"0000 FFF5 ECEC ECFD FDFD FDFD F5FF 0000" $"0000 FFF5 ECEC ECFD 05E3 E3FD F5FF 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (139) { $"00FF FFFF FFFF FFFF FFFF FFFF FF00 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"00FF F5EC ECEC F5FD ECEC FDF5 FFFF FF00" $"00FF F5EC ECEC F5FD FDFD FDF5 FFF5 FF00" $"00FF F5EC ECEC F5FD E3D8 FDF5 FFF5 FF00" $"00FF F5EC EC00 F5FD D8E3 FDF5 FFF5 FF00" $"00FF F5EC 0000 F5FD FDFD FDF5 FFF5 FF00" $"00FF F5EC 0000 F5FD E3E3 FDF5 FFF5 FF00" $"00FF F5EC EC00 F5FD E3E3 FDF5 FFF5 FF00" $"00FF F5EC ECEC F5FD FDFD FDF5 FFF5 FF00" $"00FF F5EC ECEC F5FD 05FF FFFF FFF5 FF00" $"00FF F5EC ECEC F5FD 05FF 2BFF F5F5 FF00" $"00FF F5F5 F5F5 F5F5 F5FF FFF5 FDF5 FF00" $"00FF FFFF FFFF FFFF FFFF F505 FDF5 FF00" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 FF00" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'ics8' (140) { $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000" $"00FF F5F5 F5F5 F5F5 F5F5 FFFF 0000 0000" $"00FF F5EC ECEC F5F5 F5F5 FF2B FF00 0000" $"00FF F5EC ECEC F5F5 F5F5 FFFF FFFF 0000" $"00FF F5EC ECB0 FFFF FFFF FFF5 F5FF 0000" $"00FF F5EC ECFF FFF5 F5F5 FFF5 F5FF 0000" $"00FF F5EC F500 FFFF F5F5 F5F5 F5FF 0000" $"00FF F5EC F505 F7FF FFF5 F5F5 F5FF 0000" $"00FF F5EC F5F7 0500 FFFF F5F5 F5FF 0000" $"00FF F5EC EC00 0000 FFFF F5F5 F5FF 0000" $"00FF F5EC ECEC 00FF FFF5 F5F5 F5FF 0000" $"00FF F5EC ECEC FFFF F5F5 F5F5 F5FF 0000" $"00FF F5EC ECB0 FFF5 F5F5 FFF5 F5FF 0000" $"00FF F5EC ECB0 FFFF FFFF FFF5 F5FF 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"00FF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'ics8' (141) { $"00FF FFFF FFFF FFFF FFFF FFFF FF00 0000" $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"00FF F5EC ECEC FFFF FFFF FFF5 FFFF FF00" $"00FF F5EC ECEC FFF5 F5F5 FFF5 FFF5 FF00" $"00FF F5EC ECF5 FFFF F5F5 F5F5 FFF5 FF00" $"00FF F5EC F5F5 F5FF FFF5 F5F5 FFF5 FF00" $"00FF F5EC F505 2BF5 FFFF F5F5 FFF5 FF00" $"00FF F5EC F52B 05F5 FFFF F5F5 FFF5 FF00" $"00FF F5EC ECF5 F5FF FFF5 F5F5 FFF5 FF00" $"00FF F5EC ECEC FFFF F5F5 F5F5 FFF5 FF00" $"00FF F5EC ECEC FFF5 F5FF FFFF FFF5 FF00" $"00FF F5EC ECEC FFFF FFFF 2BFF F5F5 FF00" $"00FF F5F5 F5F5 F5F5 F5FF FFF5 F5F5 FF00" $"00FF FFFF FFFF FFFF FFFF F5F5 F5F5 FF00" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 FF00" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'ics8' (142) { $"EFF0 EF00 0000 0000 F900 0000 0000 0000" $"F0EF F000 0000 00F9 D257 0000 0000 0000" $"EFF0 EF00 0000 7A00 00D2 F900 0000 0000" $"EFF0 F000 00FA 00F9 FA00 D256 0000 0000" $"F0EF F000 7B00 FA00 F9FF 00D2 F900 0000" $"EFEF EFFA 00F9 0000 00F9 FF00 D2F9 0000" $"F0F0 F900 FA00 0000 0000 FAF9 00D2 F900" $"EFF9 00FA 00FA F9FA F9FA F9FA FF00 D2F9" $"F0EF FAF9 FAE5 E6E6 05E5 D2D2 F9FA F900" $"EFF0 F900 00E6 E505 0505 E6E5 D2F9 0000" $"F0F9 0000 F7E5 E6E5 05E6 E5E6 E5D2 FF00" $"EF00 0000 E5E6 E5D2 D2E5 E6E5 E6D2 FF00" $"F900 FAE6 E5E6 D2E5 D2E5 E5E6 D2D2 F9FA" $"00FA 00E6 2BD2 E5E6 E5D2 E6E5 D2D2 C9F9" $"F9C9 2B2B F7D2 E6E5 E6D2 E5E6 F9D2 C2FA" $"FA00 C3D2 D2D2 E5E6 C2E5 C9F9 D2C3 FAF9" }; resource 'ics4' (128) { $"6660 0000 D000 0000 6660 000D 6D00 0000" $"6660 00D0 06D0 0000 6660 0D0D D06D 0000" $"6660 D0D0 DF06 D000 666D 0D00 0DF0 6D00" $"66D0 D000 00DD 06D0 6D0D 0DDD DDDD F06D" $"66DD D999 1966 DDD0 66D0 0991 1199 6D00" $"6D00 C999 1999 96F0 6000 9996 6999 96F0" $"D0D9 9969 6999 66DD 0D09 C699 9699 669D" $"D9CC C699 9699 D67D D086 6699 799D 68DD" }; resource 'ics4' (129) { $"0FFF FFFF FFF0 0000 0F00 0000 00FF 0000" $"0F06 6600 00FC F000 0F06 66FF 0FFF FF00" $"0F06 6600 0000 0F00 0F06 60FF F0F0 0F00" $"0F06 0000 0000 0F00 0F06 00F0 FFF0 0F00" $"0F06 0000 0000 0F00 0F06 60FF F0F0 0F00" $"0F06 6600 0000 0F00 0F06 66F0 FFF0 0F00" $"0F06 6600 0000 0F00 0F06 66FF F0F0 0F00" $"0F00 0000 0000 0F00 0FFF FFFF FFFF FF" }; resource 'ics4' (130) { $"0FFF FFFF FFFF 0000 0F00 0000 000F 0000" $"0F06 66F0 FF0F FF00 0F06 6600 000F 0F00" $"0F06 66FF 0F0F 0F00 0F06 6000 000F 0F00" $"0F06 00F0 FF0F 0F00 0F06 0000 000F 0F00" $"0F06 60FF 0F0F 0F00 0F06 6600 000F 0F00" $"0F06 66F0 FFFF 0F00 0F06 6600 FCF0 0F00" $"0F00 0000 FF00 0F00 0FFF FFFF F00F 0F00" $"000F 0000 0000 0F00 000F FFFF FFFF FF" }; resource 'ics4' (131) { $"0FFF FFFF FFF0 0000 0F00 0000 00FF 0000" $"0F06 6600 00FC F000 0F06 6600 00FF FF00" $"0F06 6600 0000 0F00 0F06 6000 0000 0F00" $"0F06 F0FF 0FF0 0F00 0F06 0000 0000 0F00" $"0F06 FFFF 0FF0 0F00 0F06 6000 0000 0F00" $"0F06 FF0F F0F0 0F00 0F06 6600 0000 0F00" $"0F06 6600 0000 0F00 0F06 6600 0000 0F00" $"0F00 0000 0000 0F00 0FFF FFFF FFFF FF" }; resource 'ics4' (132) { $"00FF FFFF FFFF 0000 00F0 0000 00F0 F000" $"00F0 6667 CCF0 0F00 00F0 6667 00FF FF00" $"00F0 666F 0000 0F00 00F0 6670 FF0F FF00" $"00F0 60CF 00F0 0F00 00F0 6070 FF0F FF00" $"00F0 60CF 00F0 0F00 00F0 66CF 00F0 0F00" $"00F0 6650 FF0F FF00 00F0 666F 00F0 0F00" $"00F0 666F 00F0 0F00 00F0 6660 FF0F FF00" $"00F0 0000 0000 0F00 00FF FFFF FFFF FF" }; resource 'ics4' (133) { $"0FFF FFFF FFFF 0000 0F00 0000 000F 0000" $"0F06 6670 070F FF00 0F06 660F F0FF 0F00" $"0F06 66F0 0F0F 0F00 0F06 60F0 0F0F FF00" $"0F06 070F F0FF 0F00 0F06 00F0 0F0F 0F00" $"0F06 60F0 0F0F FF00 0F06 660F F0FF 0F00" $"0F06 66F0 FFFF 0F00 0F06 66F0 FCF0 FF00" $"0F00 0000 FF00 0F00 0FFF FFFF F0F0 0F00" $"000F 0000 0000 0F00 000F FFFF FFFF FF" }; resource 'ics4' (134) { $"0FFF FFFF FFF0 0000 0F00 0000 00FF 0000" $"0F06 66DD DDF0 F000 0F06 66DE EEFF FF00" $"0F06 66DE 1600 0F00 0F06 60DE 3800 FF00" $"0F06 00DE 000F 0F00 0F06 00DE 0FF0 0F00" $"0F06 00DF F000 0F00 0F06 60F0 00C0 0F00" $"0F06 660D DCCC 0F00 0F06 660D D0C0 0F00" $"0F06 6600 0C00 0F00 0F06 6600 CCC0 0F00" $"0F00 0000 0000 0F00 0FFF FFFF FFFF FF" }; resource 'ics4' (135) { $"0FFF FFFF FFFF F000 0F00 0000 0000 F000" $"0F06 66DD DDDD FFF0 0F06 66DE EEEE F0F0" $"0F06 60DE 1600 F0F0 0F06 00DE 3800 F0F0" $"0F06 00DE 00FF F0F0 0F06 00DE FF00 F0F0" $"0F06 60FF 0000 F0F0 0F06 6600 0000 F0F0" $"0F06 66FF 0FFF F0F0 0F06 66FF 0F0F 00F0" $"0F00 0000 0FF0 00F0 0FFF FFFF FF00 00F0" $"000F 0000 0000 00F0 000F FFFF FFFF FFF0" }; resource 'ics4' (136) { $"0FFF FFFF FFF0 0000 0F00 0000 00FF 0000" $"0F06 66E0 00F0 F000 0F06 66D0 00FF FF00" $"0F06 66E0 1660 0F00 0F06 60D1 1666 0F00" $"0F06 00E1 1166 0F00 0F06 00D1 1343 0F00" $"0F06 00E0 3430 0F00 0F06 60D0 0000 7F00" $"0F06 66E0 0707 0F00 0F06 66D0 7070 0F00" $"0F06 66E0 0000 0F00 0F06 66DE DEDE 0F00" $"0F00 0000 0000 0F00 0FFF FFFF FFFF FF" }; resource 'ics4' (137) { $"0FFF FFFF FFFF F000 0F00 0000 0000 F000" $"0F06 6601 6600 FFF0 0F06 6711 6660 F0F0" $"0F06 6E11 1660 F0F0 0F06 0D11 3C30 F0F0" $"0F06 0E03 C300 F0F0 0F06 0D00 0007 F0F0" $"0F06 6E00 7070 F0F0 0F06 6707 0700 F0F0" $"0F06 6600 0FFF F0F0 0F06 67ED EF0F 00F0" $"0F00 0000 0FF0 00F0 0FFF FFFF FF00 00F0" $"000F 0000 0000 00F0 000F FFFF FFFF FFF0" }; resource 'ics4' (138) { $"00FF FFFF FFF0 0000 00F0 0000 00FF 0000" $"00F0 666E 30FC F000 00F0 666F 33FF FF00" $"00F0 666E 111E 0F00 00F0 660F 180F 0F00" $"00F0 600E FEFE 0F00 00F0 600F 888F 0F00" $"00F0 600E 888E 0F00 00F0 660F EFEF 0F00" $"00F0 666E CCCE 0F00 00F0 666F C00F 0F00" $"00F0 666E FEFE 0F00 00F0 666F 188F 0F00" $"00F0 0000 0000 0F00 00FF FFFF FFFF FF" }; resource 'ics4' (139) { $"0FFF FFFF FFFF F000 0F00 0000 0000 F000" $"0F06 660A 66A0 FFF0 0F06 660A AAA0 F0F0" $"0F06 660A 83A0 F0F0 0F06 600A 38A0 F0F0" $"0F06 000A AAA0 F0F0 0F06 000A 88A0 F0F0" $"0F06 600A 88A0 F0F0 0F06 660A AAA0 F0F0" $"0F06 660A 1FFF F0F0 0F06 660A 1FCF 00F0" $"0F00 0000 0FF0 A0F0 0FFF FFFF FF01 A0F0" $"000F 0000 0000 00F0 000F FFFF FFFF FFF0" }; resource 'ics4' (140) { $"0FFF FFFF FFF0 0000 0F00 0000 00FF 0000" $"0F06 6600 00FC F000 0F06 6600 00FF FF00" $"0F06 6FFF FFF0 0F00 0F06 6FF0 00F0 0F00" $"0F06 00FF 0000 0F00 0F06 01CF F000 0F00" $"0F06 0C10 FF00 0F00 0F06 6000 FF00 0F00" $"0F06 660F F000 0F00 0F06 66FF 0000 0F00" $"0F06 65F0 00F0 0F00 0F06 65FF FFF0 0F00" $"0F00 0000 0000 0F00 0FFF FFFF FFFF FF" }; resource 'ics4' (141) { $"0FFF FFFF FFFF F000 0F00 0000 0000 F000" $"0F06 66FF FFF0 FFF0 0F06 66F0 00F0 F0F0" $"0F06 60FF 0000 F0F0 0F06 000F F000 F0F0" $"0F06 01C0 FF00 F0F0 0F06 0C10 FF00 F0F0" $"0F06 600F F000 F0F0 0F06 66FF 0000 F0F0" $"0F06 66F0 0FFF F0F0 0F06 66FF FFCF 00F0" $"0F00 0000 0FF0 00F0 0FFF FFFF FF00 00F0" $"000F 0000 0000 00F0 000F FFFF FFFF FFF0" }; resource 'ics4' (142) { $"6660 0000 D000 0000 6660 000D 6D00 0000" $"6660 00D0 06D0 0000 6660 0D0D D06D 0000" $"6660 D0D0 DF06 D000 666D 0D00 0DF0 6D00" $"66D0 D000 00DD 06D0 6D0D 0DDD DDDD F06D" $"66DD D999 1966 DDD0 66D0 0991 1199 6D00" $"6D00 C999 1999 96F0 6000 9996 6999 96F0" $"D0D9 9969 6999 66DD 0D09 C699 9699 669D" $"D9CC C699 9699 D67D D086 6699 799D 68DD" }; resource 'ics#' (128) { { /* array: 2 elements */ /* [1] */ $"E000 E080 E040 E4A0 E250 F028 C824 955A" $"EF74 C638 8FFE 9776 3DDD 5F76 4BDF BDEA", /* [2] */ $"E000 E180 E3C0 E7E0 EFF0 FFF8 FFFC FFFE" $"FFFE FFFF FFFF FFFF FFFF FFFF FFFF FFFF" } }; resource 'ics#' (129) { { /* array: 2 elements */ /* [1] */ $"7FE0 4430 4428 477C 4404 4BA4 5004 52E4" $"5004 4BA4 4404 46E4 4404 47A4 4404 7FFC", /* [2] */ $"7FE0 7FF0 7FF8 7FFC 7FFC 7FFC 7FFC 7FFC" $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC" } }; resource 'ics#' (130) { { /* array: 2 elements */ /* [1] */ $"7FF0 4410 46DC 4414 4754 4814 52D4 5014" $"4B54 4414 46F4 44A4 44C4 7F94 1004 1FFC", /* [2] */ $"7FF0 7FF0 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC" $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 1FFC 1FFC" } }; resource 'ics#' (131) { { /* array: 2 elements */ /* [1] */ $"7FE0 4830 4828 483C 4804 5004 6B64 6004" $"6F64 5004 4DA4 4804 4804 4804 4804 7FFC", /* [2] */ $"7FE0 7FF0 7FF8 7FFC 7FFC 7FFC 7FFC 7FFC" $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC" } }; resource 'ics#' (132) { { /* array: 2 elements */ /* [1] */ $"3FF0 2228 2324 233C 2304 26DC 2924 2EDC" $"2924 2524 22DC 2324 2324 22DC 2204 3FFC", /* [2] */ $"3FF0 3FF8 3FFC 3FFC 3FFC 3FFC 3FFC 3FFC" $"3FFC 3FFC 3FFC 3FFC 3FFC 3FFC 3FFC 3FFC" } }; resource 'ics#' (133) { { /* array: 2 elements */ /* [1] */ $"7FF0 4410 465C 45B4 4654 4A5C 55B4 5254" $"4A5C 45B4 46F4 46AC 44C4 7FA4 1004 1FFC", /* [2] */ $"7FF0 7FF0 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC" $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 1FFC 1FFC" } }; resource 'ics#' (134) { { /* array: 2 elements */ /* [1] */ $"7FE0 4830 4BE8 4A3C 4AC4 52CC 6214 6264" $"6184 5224 4DD4 49A4 4844 48E4 4804 7FFC", /* [2] */ $"7FE0 7FF0 7FF8 7FFC 7FFC 7FFC 7FFC 7FFC" $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC" } }; resource 'ics#' (135) { { /* array: 2 elements */ /* [1] */ $"7FF8 4808 4BFE 4A0A 4ACA 52CA 623A 60CA" $"530A 4C0A 4B7A 4B52 4862 7FC2 1002 1FFE", /* [2] */ $"7FF8 7FF8 7FFE 7FFE 7FFE 7FFE 7FFE 7FFE" $"7FFE 7FFE 7FFE 7FFE 7FFE 7FFE 1FFE 1FFE" } }; resource 'ics#' (136) { { /* array: 2 elements */ /* [1] */ $"7FE0 4830 4A28 483C 4AE4 5174 6334 6154" $"62A4 500C 4A54 48A4 4A04 4954 4804 7FFC", /* [2] */ $"7FE0 7FF0 7FF8 7FFC 7FFC 7FFC 7FFC 7FFC" $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC" } }; resource 'ics#' (137) { { /* array: 2 elements */ /* [1] */ $"7FF8 4808 4DCE 4AEA 4E6A 52AA 654A 601A" $"52AA 494A 4C7A 4A52 4862 7FC2 1002 1FFE", /* [2] */ $"7FF8 7FF8 7FFE 7FFE 7FFE 7FFE 7FFE 7FFE" $"7FFE 7FFE 7FFE 7FFE 7FFE 7FFE 1FFE 1FFE" } }; resource 'ics#' (138) { { /* array: 2 elements */ /* [1] */ $"3FE0 2230 22A8 22FC 2294 2494 28F4 2894" $"2894 24F4 2294 2294 22F4 2294 2204 3FFC", /* [2] */ $"3FE0 3FF0 3FF8 3FFC 3FFC 3FFC 3FFC 3FFC" $"3FFC 3FFC 3FFC 3FFC 3FFC 3FFC 3FFC 3FFC" } }; resource 'ics#' (139) { { /* array: 2 elements */ /* [1] */ $"7FF8 4408 452E 45EA 452A 492A 51EA 512A" $"492A 45EA 457A 4552 446A 7FCA 1002 1FFE", /* [2] */ $"7FF8 7FF8 7FFE 7FFE 7FFE 7FFE 7FFE 7FFE" $"7FFE 7FFE 7FFE 7FFE 7FFE 7FFE 1FFE 1FFE" } }; resource 'ics#' (140) { { /* array: 2 elements */ /* [1] */ $"7FE0 4830 4828 483C 4FE4 5624 6304 6184" $"60C4 50C4 4984 4B04 4E24 4FE4 4804 7FFC", /* [2] */ $"7FE0 7FF0 7FF8 7FFC 7FFC 7FFC 7FFC 7FFC" $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC" } }; resource 'ics#' (141) { { /* array: 2 elements */ /* [1] */ $"7FF8 4808 4FEE 4E2A 4B0A 518A 60CA 60CA" $"518A 4B0A 4E7A 4FD2 4862 7FC2 1002 1FFE", /* [2] */ $"7FF8 7FF8 7FFE 7FFE 7FFE 7FFE 7FFE 7FFE" $"7FFE 7FFE 7FFE 7FFE 7FFE 7FFE 1FFE 1FFE" } }; resource 'ics#' (142) { { /* array: 2 elements */ /* [1] */ $"E000 E080 E040 E4A0 E250 F028 C824 955A" $"EF74 C638 8FFE 9776 3DDD 5F76 4BDF BDEA", /* [2] */ $"E000 E180 E3C0 E7E0 EFF0 FFF8 FFFC FFFE" $"FFFE FFFF FFFF FFFF FFFF FFFF FFFF FFFF" } }; resource 'ICN#' (128) { { /* array: 2 elements */ /* [1] */ $"0000 0000 F800 8000 F801 C000 F802 6000" $"F804 7000 F80C 9800 F818 4C00 F824 9600" $"F820 1700 F888 2180 F810 01C0 F920 0A60" $"F800 0130 F401 2258 C108 995C D205 5704" $"8450 5D87 E843 7760 C1AC 1CC6 F040 0774" $"FA5C 1DD8 FC57 7770 FA1D 5DDC F977 7774" $"F55D DDDC FA77 7774 F5DD DDDC FB77 7774" $"F5DD DDDC FB77 7774 F1DD DDD8 FF77 7770", /* [2] */ $"0000 0000 F800 8000 F801 C000 F803 E000" $"F807 F000 F80F F800 F81F FC00 F83F FE00" $"F83F FF00 F8FF FF80 F9FF FFC0 FBFF FFE0" $"FFFF FFF0 FFFF FFF8 FFFF FFFC FFFF FFFE" $"FFFF FFFE FFFF FFFE FFFF FFFE FFFF FFFE" $"FFFF FFFC FFFF FFFC FFFF FFFC FFFF FFFC" $"FFFF FFFC FFFF FFFC FFFF FFFC FFFF FFFC" $"FFFF FFFC FFFF FFFC FFFF FFFC FFFF FFFC" } }; resource 'ICN#' (129) { { /* array: 2 elements */ /* [1] */ $"1FFF FE00 1040 0300 1040 0280 1040 0240" $"1040 0220 104D 7E10 1040 03F8 105E 7688" $"1040 0008 10AD 6B48 1100 0008 115D D748" $"1200 0008 12D7 6DC8 1200 0008 12BE F6C8" $"1200 0008 12DD BB08 1100 0008 1176 AAC8" $"1080 0008 105B BD48 1040 0008 1056 F6C8" $"1040 0008 105C EE48 1040 0008 105D 7348" $"1040 0008 1040 0008 1040 0008 1FFF FFF8", /* [2] */ $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0" $"1FFF FFE0 1FFF FFF0 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" } }; resource 'ICN#' (130) { { /* array: 2 elements */ /* [1] */ $"3FFF FFF0 2080 0010 2080 0010 2080 001C" $"2080 0014 20DB DD14 2080 0014 209D 6D14" $"2100 0014 22B5 D694 2200 0014 25BD EE14" $"2400 0014 24B7 9B94 2400 0014 25DC DD94" $"2400 0014 22DF 3614 2200 0014 216E F594" $"2080 0014 20E7 7A94 2080 0014 20DE 6FE4" $"2080 0844 20CD A8A4 2080 0904 20B7 6AA4" $"2080 0C04 3FFF F804 0800 0004 0FFF FFFC", /* [2] */ $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 0FFF FFFC 0FFF FFFC" } }; resource 'ICN#' (131) { { /* array: 2 elements */ /* [1] */ $"3FFF FC00 2100 0600 2100 0500 2100 0480" $"2100 0440 2100 0420 2100 07F0 2100 0010" $"2100 0010 2200 0010 2400 0010 25DD DB10" $"2800 0010 2800 0010 29DE F710 2800 0010" $"2800 0010 29BF BB10 2400 0010 2400 0010" $"2200 0010 2100 0010 2100 0010 2100 0010" $"2100 0010 2100 0010 2100 0010 2100 0010" $"2100 0010 2100 0010 2100 0010 3FFF FFF0", /* [2] */ $"3FFF FC00 3FFF FE00 3FFF FF00 3FFF FF80" $"3FFF FFC0 3FFF FFE0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" } }; resource 'ICN#' (132) { { /* array: 2 elements */ /* [1] */ $"1FFF FE00 1040 0300 1075 EA80 1044 0A40" $"107B F620 1044 0A10 1044 0BF8 1044 0808" $"107B F7F8 1084 0808 1134 0808 1104 0808" $"12FB F7F8 1204 0808 1274 0808 1204 0808" $"12FB F7F8 1104 0808 1134 0808 1104 0808" $"10FB F7F8 1044 0808 1054 0808 1044 0808" $"107B F7F8 1044 0808 1054 0808 1044 0808" $"107B F7F8 1044 0808 1040 0008 1FFF FFF8", /* [2] */ $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0" $"1FFF FFE0 1FFF FFF0 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" } }; resource 'ICN#' (133) { { /* array: 2 elements */ /* [1] */ $"3FFF FFF0 2080 0010 2085 EBD0 2084 081C" $"20FB F7F4 2084 0814 2094 0814 2084 081C" $"21FB F7F4 2204 0814 2274 0814 2404 081C" $"25FB F7F4 2404 0814 24F4 0814 2404 081C" $"25FB F7F4 2204 0814 2274 0814 2104 081C" $"20FB F7F4 2084 0814 2094 0814 2084 0FEC" $"20FB F844 2084 0884 2094 0904 2084 0AFC" $"2080 0C04 3FFF FA04 0800 0004 0FFF FFFC", /* [2] */ $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 0FFF FFFC 0FFF FFFC" } }; resource 'ICN#' (134) { { /* array: 2 elements */ /* [1] */ $"3FFF FC00 2100 0600 217F FD00 2140 0480" $"2140 0440 214F FC20 2149 87F0 214A 4010" $"214C 2790 224C 2030 244A 4ED0 2449 8110" $"2848 0210 284B 6C10 284B 1010 284B 6010" $"2848 8790 284B 0850 2444 1030 244B F830" $"2233 F830 2143 F830 2103 F850 2103 FF90" $"2103 FC10 2103 F610 2100 6B10 2100 D590" $"2101 FFD0 2100 0010 2100 0010 3FFF FFF0", /* [2] */ $"3FFF FC00 3FFF FE00 3FFF FF00 3FFF FF80" $"3FFF FFC0 3FFF FFE0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFF0" } }; resource 'ICN#' (135) { { /* array: 2 elements */ /* [1] */ $"3FFF FFF0 2100 0010 217F FFD0 2140 001C" $"2140 0014 215F FFD4 2153 0014 2154 8014" $"2258 4F34 2458 4054 2454 9D94 2853 0214" $"2850 0414 2856 D814 2856 2014 2856 C014" $"2851 0F14 2456 1094 2448 2054 2217 F054" $"2167 F054 2187 F054 2107 F094 2107 FFF4" $"2107 E824 2107 D844 2100 A884 2101 F904" $"2100 0A04 3FFF FC04 0800 0004 0FFF FFFC", /* [2] */ $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 0FFF FFFC 0FFF FFFC" } }; resource 'ICN#' (136) { { /* array: 2 elements */ /* [1] */ $"1FFF FE00 1080 0300 1088 0280 1098 0240" $"1088 0220 1088 0210 109C 1FF8 1088 6788" $"1088 87C8 1118 87C8 1209 07E8 1209 07E8" $"141D 0FE8 1409 1AA8 1408 B548 1418 EAD8" $"1408 75A8 1408 1E28 121C 0048 1208 6048" $"1108 6088 1098 9088 1088 8908 1089 0708" $"109B 0308 108B 0008 1088 0408 108F FFE8" $"1081 2488 1080 0008 1080 0008 1FFF FFF8", /* [2] */ $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0" $"1FFF FFE0 1FFF FFF0 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" } }; resource 'ICN#' (137) { { /* array: 2 elements */ /* [1] */ $"3FFF FFF0 2100 0010 2100 0010 2170 781C" $"2121 9E14 2122 1F14 2162 1F14 2124 1F94" $"2224 1F94 2474 3F94 2424 6A94 2822 D514" $"2863 AB54 2821 D694 2820 7894 2870 0114" $"2821 8114 2421 8214 2462 4214 2222 2414" $"2124 1C14 216C 0C14 212C 0014 2120 0FE4" $"213F F844 2104 9884 2100 0904 2100 0A04" $"2100 0C04 3FFF F804 0800 0004 0FFF FFFC", /* [2] */ $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 0FFF FFFC 0FFF FFFC" } }; resource 'ICN#' (138) { { /* array: 2 elements */ /* [1] */ $"1FFF FE00 1040 0300 105E AA80 105C 4240" $"1056 2A20 1055 0210 105F FFF8 105F FFE8" $"105E AAE8 109C 81E8 1116 14A8 1114 16A8" $"121E 82E8 121C 25E8 121E 80E8 121F FFE8" $"1217 FFA8 1214 00A8 111C AAE8 111D 54E8" $"109C 2AE8 105D 44E8 1054 0AA8 1055 14A8" $"105F FFE8 105F FFE8 105C 20E8 105D 52E8" $"1054 09A8 1055 40A8 1040 0008 1FFF FFF8", /* [2] */ $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0" $"1FFF FFE0 1FFF FFF0 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" } }; resource 'ICN#' (139) { { /* array: 2 elements */ /* [1] */ $"3FFF FFF0 2080 0010 20AC 5550 20AA 2B5C" $"20BD 55D4 20BF FFD4 20BF FFD4 20BD 03D4" $"212C 2B54 222D 2D54 223D 05D4 243C 4BD4" $"243D ABD4 243F FFD4 242F FF54 2428 0154" $"2439 55D4 223A A9D4 2238 55D4 213A 89D4" $"20A8 1554 20AA 2954 20BF FFD4 20BF FFE4" $"20B8 4854 20BA A8B4 20A8 1974 20AA 8A74" $"2080 0DD4 3FFF F854 0800 0004 0FFF FFFC", /* [2] */ $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 0FFF FFFC 0FFF FFFC" } }; resource 'ICN#' (140) { { /* array: 2 elements */ /* [1] */ $"1FFF FE00 1080 0300 1080 0280 1080 0240" $"1080 0220 1080 6210 1080 0FF8 1080 0188" $"109F FE08 111F FF08 121E 0308 120E 0008" $"1407 0108 1403 8008 1411 C008 1448 E008" $"1440 F048 1400 70C8 1208 3048 1200 6008" $"1100 C008 1081 8008 1083 0088 1086 0088" $"108C 0188 109F FF08 109F FF08 1080 0008" $"1098 0008 1098 0008 1080 0008 1FFF FFF8", /* [2] */ $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0" $"1FFF FFE0 1FFF FFF0 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" $"1FFF FFF8 1FFF FFF8 1FFF FFF8 1FFF FFF8" } }; resource 'ICN#' (141) { { /* array: 2 elements */ /* [1] */ $"3FFF FFF0 2080 0010 2080 0010 2080 C01C" $"2080 1814 2080 0314 20BF FC14 20BF FE14" $"213C 0614 221C 0014 220E 0214 2407 0014" $"2407 8014 2421 C014 2481 E014 2480 E114" $"2400 6014 2210 C014 2201 8014 2103 0014" $"2086 0114 208C 0114 2098 0314 20BF FFE4" $"20BF F844 2080 0884 20B0 0904 20B0 0A04" $"2080 0C04 3FFF F804 0800 0004 0FFF FFFC", /* [2] */ $"3FFF FFF0 3FFF FFF0 3FFF FFF0 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 3FFF FFFC 3FFF FFFC" $"3FFF FFFC 3FFF FFFC 0FFF FFFC 0FFF FFFC" } }; resource 'ICN#' (142) { { /* array: 2 elements */ /* [1] */ $"0000 0000 F800 8000 F801 C000 F802 6000" $"F804 7000 F80C 9800 F818 4C00 F824 9600" $"F820 1700 F888 2180 F810 01C0 F920 0A60" $"F800 0130 F401 2258 C108 995C D205 5704" $"8450 5D87 E843 7760 C1AC 1CC6 F040 0774" $"FA5C 1DD8 FC57 7770 FA1D 5DDC F977 7774" $"F55D DDDC FA77 7774 F5DD DDDC FB77 7774" $"F5DD DDDC FB77 7774 F1DD DDD8 FF77 7770", /* [2] */ $"0000 0000 F800 8000 F801 C000 F803 E000" $"F807 F000 F80F F800 F81F FC00 F83F FE00" $"F83F FF00 F8FF FF80 F9FF FFC0 FBFF FFE0" $"FFFF FFF0 FFFF FFF8 FFFF FFFC FFFF FFFE" $"FFFF FFFE FFFF FFFE FFFF FFFE FFFF FFFE" $"FFFF FFFC FFFF FFFC FFFF FFFC FFFF FFFC" $"FFFF FFFC FFFF FFFC FFFF FFFC FFFF FFFC" $"FFFF FFFC FFFF FFFC FFFF FFFC FFFF FFFC" } }; resource 'icl8' (128) { $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"F0EF F0EF F000 0000 0000 0000 0000 0000" $"FA00 0000 0000 0000 0000 0000 0000 0000" $"F0EF F0EF F000 0000 0000 0000 0000 00FA" $"D2FA 0000 0000 0000 0000 0000 0000 0000" $"EFF0 EFF0 EF00 0000 0000 0000 0000 FA00" $"F9D2 FA00 0000 0000 0000 0000 0000 0000" $"F0EF F0EF F000 0000 0000 0000 00FA 0000" $"00FA D2FA 0000 0000 0000 0000 0000 0000" $"EFF0 EFF0 EF00 0000 0000 0000 FAFF 0000" $"FA00 57D2 FA00 0000 0000 0000 0000 0000" $"EFF0 EFF0 EF00 0000 0000 00FA FF00 F7F9" $"00FF 00F9 D2FA 0000 0000 0000 0000 0000" $"F0EF F0EF F000 0000 0000 FA00 00FA F900" $"FA00 00FA F9D2 FA00 0000 0000 0000 0000" $"EFF0 EFF0 EF00 0000 007B FF00 00F9 0000" $"00F9 00FF 00FA D2FA 0000 0000 0000 0000" $"F0EF F0EF F000 0000 FA00 002B FA00 0000" $"0000 FA00 0000 F9D2 FA00 0000 0000 0000" $"EFF0 EFF0 EF00 00F9 0000 00FA 0000 0000" $"0000 00F9 0000 00FA D2FA 0000 0000 0000" $"F0EF F0EF F000 F9FF 0000 FA00 0000 0000" $"0000 0000 FA00 FFF9 F9D2 FA00 0000 0000" $"EFF0 EFF0 EFF9 0000 F7F9 0000 0000 0000" $"0000 0000 00F9 00FF 00F9 D2FA 0000 0000" $"F0EF EFF0 F9FF 0000 F900 0000 0000 F9FA" $"00F9 FAF9 FA00 FA00 00FA F9D2 FA00 0000" $"EFF0 F0F9 0000 00FA 0000 0000 FAF9 00F9" $"FA00 F9FA FFF9 F9FA 00FF 00FA D2FA 0000" $"EFF0 F9FF 0000 FA00 0000 00F9 00FA 00C9" $"00D2 00D2 C2EF F0F0 F900 0000 F9D2 7B00" $"F0F9 0000 00FA 0000 00FA 00D2 0000 C200" $"05E6 E5E6 D2E5 EFEF F0F9 0000 00FA D2FA" $"EFEF FA00 FA00 0000 F9D2 0000 D2F9 E6E6" $"05E5 E6E5 E5E6 E6E5 EFF0 FA00 0000 F900" $"F0EF EFF9 0000 00FA FA00 C300 FAE6 E505" $"0505 E5D2 D2E5 E5F9 E6E5 EFF9 00FA 8C00" $"F0EF F0F0 FA00 F900 00D2 00F9 E505 0505" $"0505 0505 E5D2 E6E6 E5EF F0FF F98C 0000" $"EFF0 EFEF F0F9 FA00 F9D2 FAD2 C8E5 E505" $"0505 E6E5 E6E5 E6EF E6E5 E6FF FF00 0000" $"EFF0 EFF0 EFFA 0000 D2FA 00C2 E5E5 E6E6" $"05E6 D2E6 E5E6 E5E5 E5E6 FFE5 F000 0000" $"F0EF F0EF F0F9 FAF9 0000 E6E6 E5E6 E5E5" $"05E5 E6D2 E6E5 E6EF E5EF E5FF F0FF 0000" $"EFF0 EFF0 F900 00FA D2C2 C9C2 E6E5 D2E5" $"E6D2 D2D2 E5E5 E6E5 E6E5 FFEF E5FF 0000" $"F0EF F0EF 00FA 00D2 F9EB D2C9 E5D2 D2E6" $"D2D2 D2E5 E6E6 E5E6 EFE6 E5E6 EFFF 0000" $"EFF0 EFEF FAF9 D200 D2D2 D2D2 D2D2 D2D2" $"E5E6 E5E6 E5E5 E6E5 E6E5 F0EF F0FF 0000" $"F0EF F0F0 00D2 00D2 D2D2 D2E5 E5E6 E5E6" $"D2E5 D2E5 E6E5 E5E6 EFE5 EFE5 EFFF 0000" $"EFF0 EFF0 F900 D2D2 D2D2 E5E5 E6E5 E6E5" $"E5D2 E5E6 E5E6 E5E6 E5EF E5FF EFFF 0000" $"EFEF F0EF 00D2 00D2 D2E5 E6E6 E5E6 E5E6" $"E6D2 D2E5 E6E5 E6E5 EFF0 FFE5 FFFF 0000" $"F0F0 EFF0 FAF9 D2D2 D2E6 E5E5 E6E5 E6E5" $"E5D2 D2E5 E6E5 E6E5 F0E6 E5EF FFFF 0000" $"EFEF F0EF F000 F0D2 D2D2 E6E5 E6E5 E6E5" $"E6D2 D2D2 E5E6 EFE6 EFF0 EFFF FF00 0000" $"F0F0 EFF0 EFFA C2F0 EFD2 D2D2 E5E6 E5E6" $"D2D2 F0D2 D2EF F0EF F0EF FFFF FF" }; resource 'icl8' (129) { $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FF00 0000 0000 0000 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FFFF 0000 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FF2B FF00 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FF2B 2BFF 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FF2B 2B2B FF00 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFFF F5FF" $"F5FF FFFF FFFF FF2B 2B2B 2BFF 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFFF FFF5" $"F5FF FFFF F5FF FFF5 FFF5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECF5 FFF5 FFFF F5FF" $"F5FF FFF5 FFF5 FFFF F5FF F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5FF F5FF FFFF F5FF" $"FFFF F5FF F5FF FFFF F5FF F5F5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECF5 FFFF F5FF F5FF FFFF" $"F5FF FFF5 FFFF F5FF FFFF F5F5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECF5 FFF5 FFFF FFFF FFF5" $"FFFF FFFF F5FF FFF5 FFFF F5F5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECF5 FFFF F5FF FFFF F5FF" $"FFF5 FFFF FFF5 FFFF F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5FF FFFF F5FF FFF5" $"FFF5 FFF5 FFF5 FFF5 FFFF F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFF5 FFFF" $"FFF5 FFFF FFFF F5FF F5FF F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF F5FF FFF5" $"FFFF FFFF F5FF FFF5 FFFF F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFFF F5F5" $"FFFF FFF5 FFFF FFF5 F5FF F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFFF F5FF" $"F5FF FFFF F5F5 FFFF F5FF F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl8' (130) { $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF FFFF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF F5FF FFF5 FFFF" $"FFFF F5FF FFFF F5FF F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5FF FFFF F5FF" $"F5FF FFF5 FFFF F5FF F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 FFF5 FFFF F5FF F5FF" $"FFFF F5FF F5FF FFF5 FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5FF FFF5 FFFF FFFF F5FF" $"FFFF FFF5 FFFF FFF5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 FFF5 FFFF F5FF FFFF" $"FFF5 F5FF FFF5 FFFF FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5FF FFFF F5FF FFFF F5F5" $"FFFF F5FF FFFF F5FF FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 FFFF F5FF FFFF FFFF" $"F5F5 FFFF F5FF FFF5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC F5FF FFF5 FFFF FFF5" $"FFFF FFFF F5FF F5FF FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF FFF5 F5FF FFFF" $"F5FF FFFF FFF5 FFF5 FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF F5FF FFFF FFF5" $"F5FF FFF5 FFFF FFFF FFFF FFF5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FF2B 2B2B 2BFF F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF F5F5 FFFF F5FF" $"FFF5 FFF5 FF2B 2B2B FFF5 FFF5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FF2B 2BFF F5F5 F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFFF F5FF FFFF" $"F5FF FFF5 FF2B FFF5 FFF5 FFF5 F5FF 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FFFF F5F5 F5F5 F5F5 F5FF 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFF5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 0000 FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl8' (131) { $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF 0000 0000 0000 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5FF FF00 0000 0000 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5FF 2BFF 0000 0000 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5FF 2B2B FF00 0000 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5FF 2B2B 2BFF 0000 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5FF 2B2B 2B2B FF00 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5FF FFFF FFFF FFFF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECF5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECFF FFFF F5FF FFFF F5FF" $"FFFF F5FF FFF5 FFFF F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5FF FFFF F5FF FFFF FFF5" $"FFFF FFFF F5FF FFFF F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5FF FFF5 FFFF FFFF FFFF" $"FFF5 FFFF FFF5 FFFF F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECF5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECF5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl8' (132) { $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FF00 0000 0000 0000 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FFFF 0000 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC FFFF 48C0 48FF" $"FFFF FF48 C048 FF2B FF00 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC 4848 48C0 4848" $"4848 4848 C048 FF2B 2BFF 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC C0C0 C000 FFFF" $"FFFF FFFF 00FF FF2B 2B2B FF00 0000 0000" $"0000 00FF F5EC ECEC ECEC 4848 48FF F5F5" $"F5F5 F5F5 FFF5 FF2B 2B2B 2BFF 0000 0000" $"0000 00FF F5EC ECEC ECEC 4848 48FF F5F5" $"F5F5 F5F5 FFF5 FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC ECEC 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC EC48 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC 4848 FFFF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECF5 C0C0 C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECF5 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECF5 48FF FFFF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECF5 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECF5 C0C0 C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECF5 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC 4848 FFFF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECC0 C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC ECEC 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC 48FF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC ECEC 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC 48FF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC ECEC 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl8' (133) { $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC EC48 4848 48C0 48FF" $"FFFF FF48 C048 FFFF FFFF 48FF 0000 0000" $"0000 FFF5 ECEC ECEC EC48 4848 48C0 4848" $"4848 4848 C048 4848 4848 48FF FFFF 0000" $"0000 FFF5 ECEC ECEC ECC0 C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 48FF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF FFFF 0000" $"0000 FFF5 ECEC ECEC C0C0 C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF 00FF 0000" $"0000 FFF5 ECEC EC48 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC EC48 48FF FFFF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC F548 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF FFFF 0000" $"0000 FFF5 ECEC F5C0 C0C0 C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF 00FF 0000" $"0000 FFF5 ECEC F548 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC F548 FFFF FFFF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC F548 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF FFFF 0000" $"0000 FFF5 ECEC F5C0 C0C0 C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF 00FF 0000" $"0000 FFF5 ECEC EC48 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC EC48 48FF FFFF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC 4848 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF FFFF 0000" $"0000 FFF5 ECEC ECEC ECC0 C0C0 C000 FFFF" $"FFFF FFFF 00FF FFFF FFFF FFFF 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 4848 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 48FF 48FF F5F5" $"F5F5 F5F5 FFF5 F5F5 F5F5 F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 4848 48FF F5F5" $"F5F5 F5F5 FFFF FFFF FFFF FF00 FFFF 0000" $"0000 FFF5 ECEC ECEC ECC0 C0C0 C000 FFFF" $"FFFF FFFF FF2B 2B2B 2BFF 0000 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 4848 48FF F5F5" $"F5F5 F5F5 FF2B 2B2B FF00 0000 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 48FF 48FF F5F5" $"F5F5 F5F5 FF2B 2BFF 0000 0000 00FF 0000" $"0000 FFF5 ECEC ECEC EC48 4848 48FF F5F5" $"F5F5 F5F5 FF2B FF00 FFFF FFFF FFFF 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FFFF 0000 0000 0000 00FF 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FF00 FF00 0000 0000 00FF 0000" $"0000 0000 FF00 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 00FF 0000" $"0000 0000 FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl8' (134) { $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF 0000 0000 0000 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5FF FF00 0000 0000 0000 0000" $"0000 FFF5 ECEC ECEC ECFF FFFF FFFF FFFF" $"FFFF FFFF FFFF 2BFF 0000 0000 0000 0000" $"0000 FFF5 ECEC ECEC ECFF 2B2B 2B2B 2B2B" $"2B2B 2B2B 2BFF 2B2B FF00 0000 0000 0000" $"0000 FFF5 ECEC ECEC ECFF 2BF8 F8F8 F8F8" $"F8F8 F8F8 F8FF 2B2B 2BFF 0000 0000 0000" $"0000 FFF5 ECEC ECEC ECFF 2BF8 FFFF FFFF" $"FFFF FFFF FFFF 2B2B 2B2B FF00 0000 0000" $"0000 FFF5 ECEC ECEC ECFF 2BF8 FFF5 F505" $"ECF5 F5F5 F5FF FFFF FFFF FFFF 0000 0000" $"0000 FFF5 ECEC ECEC ECFF 2BF8 FFF5 0505" $"ECEC F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECFF 2BF8 FF05 0505" $"ECEC ECF5 F5FF FFFF FFF5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC F5FF 2BF8 FFD8 D8D8" $"E3E3 E3F5 F5F5 F5F5 F5F5 FFFF 0000 0000" $"0000 FFF5 ECEC ECF5 F5FF 2BF8 FFF5 D8D8" $"E3E3 F5F5 FFFF FFF5 FFFF F5FF 0000 0000" $"0000 FFF5 ECEC ECF5 F5FF 2BF8 FFF5 F5D8" $"E3F5 F5F5 F5F5 F5FF F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BF8 FFF5 F5F5" $"F5F5 F5F5 F5F5 FFF5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BF8 FFF5 FFFF" $"F5FF FFF5 FFFF F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BF8 FFF5 FFFF" $"F5F5 F5FF F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BF8 FFF5 FFFF" $"F5FF FFF5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BF8 FFF5 F5F5" $"FFF5 F5F5 F5FF FFFF FFF5 F5FF 0000 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BF8 FFF5 FFFF" $"F5F5 F5F5 FFF6 F6F6 F6FF F5FF 0000 0000" $"0000 FFF5 ECEC ECF5 F5FF 2BF8 F5FF F5F5" $"F5F5 F5FF F6F6 F6F6 F6F6 FFFF 0000 0000" $"0000 FFF5 ECEC ECF5 F5FF F5F5 FFF5 FFFF" $"FFFF FFFF FFF6 F6F6 F6F6 FFFF 0000 0000" $"0000 FFF5 ECEC ECEC F5F5 FFFF F5F5 FFFA" $"FAFA FAFA FFF6 F6F6 F6F6 FFFF 0000 0000" $"0000 FFF5 ECEC ECEC ECFF F5F5 F5F5 FFFA" $"FAFA FAFA FFF6 F6F6 F6F6 FFFF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 FFFA" $"FAFA FAFA FFF6 F6F6 F6FF F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 FFFA" $"FAFA FAFA FFFF FFFF FFF5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 FFFA" $"FAFA FAFF F8FF F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 FFFF" $"FFFF FFF8 F8F8 FFF5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5FF F8F8 F8F8 F8FF F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"FFF8 F8F8 F8F8 F8F8 FFF5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5FF" $"FFFF FFFF FFFF FFFF FFFF F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl8' (135) { $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECFF 2B2B 2B2B 2B2B" $"2B2B 2B2B 2B2B 2B2B 2B2B F5FF FFFF 0000" $"0000 FFF5 ECEC ECEC ECFF 2BF8 F8F8 F8F8" $"F8F8 F8F8 F8F8 F8F8 F8F8 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF 2BFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF 2BFF F5F5 05EC" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF 2BFF F505 05EC" $"ECF5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC F5FF 2BFF 0505 05EC" $"ECEC F5F5 FFFF FFFF F5F5 FFFF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5FF 2BFF D8D8 D8E3" $"E3E3 F5F5 F5F5 F5F5 F5FF F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5FF 2BFF F5D8 D8E3" $"E3F5 F5FF FFFF F5FF FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BFF F5F5 D8E3" $"F5F5 F5F5 F5F5 FFF5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BFF F5F5 F5F5" $"F5F5 F5F5 F5FF F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BFF F5FF FFF5" $"FFFF F5FF FFF5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BFF F5FF FFF5" $"F5F5 FFF5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BFF F5FF FFF5" $"FFFF F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5FF 2BFF F5F5 F5FF" $"F5F5 F5F5 FFFF FFFF F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5FF 2BFF F5FF FFF5" $"F5F5 F5FF F6F6 F6F6 FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5FF 2B00 FFF5 F5F5" $"F5F5 FFF6 F6F6 2BF6 F6FF F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC F5F5 F5FF F5FF FFFF" $"FFFF FFFF F6F6 F6F6 F6FF F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF FFF5 F5FF FAFA" $"FAFA FAFF F6F6 F6F6 F6FF F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5FF FAFA" $"FAFA FAFF F62B F6F6 F6FF F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5FF FAFA" $"FAFA FAFF F6F6 F6F6 FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5FF FAFA" $"FAFA FAFF FFFF FFFF FFFF FFFF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5FF FAFA" $"FAFA FFF8 FF2B 2B2B 2B2B FFF5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5FF FFFF" $"FFFF F8F8 FF2B 2B2B 2BFF F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"FFF8 F8F8 FF2B 2B2B FFF5 F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5FF" $"FFFF FFFF FF2B 2BFF F5F5 F5F5 F5FF 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FF2B FFF5 F5F5 F5F5 F5FF 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF F5F5 F5F5 F5F5 F5FF 0000" $"0000 0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 0000 FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl8' (136) { $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FF00 0000 0000 0000 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FFFF 0000 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 F5F5" $"F5F5 F5F5 F5F5 FF2B FF00 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFF5 F5F5" $"F5F5 F5F5 F5F5 FF2B 2BFF 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 F5F5" $"F5F5 F5F5 F5F5 FF2B 2B2B FF00 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 F5F5" $"F5F5 F5F5 F5F5 FF2B 2B2B 2BFF 0000 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFFF F5F5" $"F5F5 F5FF FFFF FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 F5F5" $"F5FF FF05 05FF ECFF FFF5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 F5F5" $"FF05 0505 05FF ECEC ECFF F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECF5 F5FF FFF5 F5F5" $"FF05 0505 05FF ECEC ECFF F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5F5 FFF5 F5FF" $"0505 0505 05FF ECEC ECEC FFF5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5F5 FFF5 F5FF" $"0505 0505 05FF ECEC ECEC FFF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5FF FFFF F5FF" $"0505 0505 FFFF FFFF FFFF FFF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5F5 FFF5 F5FF" $"0505 05FF D813 D813 D813 FFF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5F5 FFF5 F5F5" $"FF05 FFD8 13D8 13D8 13FF F5F5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5FF FFF5 F5F5" $"FFFF D813 D813 D813 D8FF F5C0 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5F5 FFF5 F5F5" $"F5FF FFD8 13D8 13FF FFF5 C0F5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5F5 FFF5 F5F5" $"F5F5 F5FF FFFF FFF5 F5F5 C0F5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5FF FFFF F5F5" $"F5F5 F5F5 F5F5 F5F5 F5C0 F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5F5 FFF5 F5F5" $"F5C0 C0F5 F5F5 F5F5 F5C0 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECF5 F5F5 FFF5 F5F5" $"F5C0 C0F5 F5F5 F5F5 C0F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFF5 F5F5" $"C0F5 F5C0 F5F5 F5F5 C0F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 F5F5" $"C0F5 F5F5 C0F5 F5C0 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 F5C0" $"F5F5 F5F5 F5C0 C0C0 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFF5 C0C0" $"F5F5 F5F5 F5F5 C0C0 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 C0C0" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFF5 F5F5" $"F5F5 F5F5 F5FF F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5FF" $"F5F5 FFF5 F5FF F5F5 FFF5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl8' (137) { $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECFF FFFF F5F5 F5F5" $"F5FF FFFF FFF5 F5F5 F5F5 F5FF FFFF 0000" $"0000 FFF5 ECEC ECEC EC00 FFF5 F5F5 F5FF" $"FF05 05FF ECFF FFF5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC EC00 FFF5 F5F5 FF05" $"0505 05FF ECEC ECFF F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF FFF5 F5F5 FF05" $"0505 05FF ECEC ECFF F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFF5 F5FF 0505" $"0505 05FF ECEC ECEC FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC F5F5 FFF5 F5FF 0505" $"0505 05FF ECEC ECEC FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5FF FFFF F5FF 0505" $"0505 FFFF FFFF FFFF FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 FFF5 F5FF 0505" $"05FF D813 D813 D813 FFF5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FFF5 F5F5 FF05" $"FFD8 13D8 13D8 13FF F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5FF FFF5 F5F5 FFFF" $"D813 D813 D813 D8FF F5C0 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FFF5 F5F5 F5FF" $"FFD8 13D8 13FF FFF5 C0F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FFF5 F5F5 F5F5" $"F5FF FFFF FFF5 F5F5 C0F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5FF FFFF F5F5 F5F5" $"F5F5 F5F5 F5F5 F5C0 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FFF5 F5F5 F5C0" $"C0F5 F5F5 F5F5 F5C0 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 FFF5 F5F5 F5C0" $"C0F5 F5F5 F5F5 C0F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5FF FFF5 F5F5 C0F5" $"F5C0 F5F5 F5F5 C0F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC F5F5 FFF5 F5F5 C0F5" $"F5F5 C0F5 F5C0 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFF5 F5C0 F5F5" $"F5F5 F5C0 C0C0 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECFF FFF5 C0C0 F5F5" $"F5F5 F5F5 C0C0 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFF5 C0C0 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFF5 F5F5 F5F5" $"F5F5 F5F5 FFFF FFFF FFFF FFF5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFFF FFFF FFFF" $"FFFF FFFF FF2B 2B2B 2BFF F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5FF F5F5" $"FFF5 F5FF FF2B 2B2B FFF5 F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FF2B 2BFF F5F5 F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FF2B FFF5 F5F5 F5F5 F5FF 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FFFF F5F5 F5F5 F5F5 F5FF 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFF5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 0000 FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl8' (138) { $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FF00 0000 0000 0000 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FFFF 0000 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD D8D8" $"D8D8 D8D8 D8D8 FF2B FF00 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD D8F9" $"F9D8 F9F9 D8D8 FF2B 2BFF 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5FD 00FD D8D8" $"F9F9 D8D8 D8F9 FF2B 2B2B FF00 0000 0000" $"0000 00FF F5EC ECEC ECEC F5FD 00FD F9D8" $"D8F9 F9D8 F9D8 FF2B 2B2B 2BFF 0000 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD FDFD" $"FDFD FDFD FDFD FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD E3E3" $"E3E3 E3E3 E3E3 E3E3 FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECF5 F5FD FDFD E3F9" $"E3F9 F9F9 F9F9 F9E3 FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5FD 00FD E3F9" $"F9F9 F9E3 F9E3 F9E3 FD00 FDF5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5FD 00FD E3F9" $"E3F9 F9E3 F9E3 E3F9 FD00 FDF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5FD FDFD E3F9" $"E3F9 F9F9 F9F9 E3F9 FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5FD FDFD E3F9" $"F9F9 E3F9 F9E3 F9E3 FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5FD FDFD E3F9" $"E3E3 F9E3 F9E3 F9E3 FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5FD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5FD 00FD FDFD" $"FDFD FDFD FDFD FDFD FD00 FDF5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F5FD 00FD 2B2B" $"2B2B 2B2B 2B2B 2B2B FD00 FDF5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5FD FDFD 2BF9" $"F92B F9F9 F9F9 F92B FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5FD FDFD 2BF9" $"F9F9 2BF9 F9F9 F92B FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECF5 F5FD FDFD 2BF9" $"2BF9 F92B F92B F92B FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD 2BF9" $"F9F9 F92B F9F9 F92B FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD 00FD 2BF9" $"2B2B 2BF9 F92B F92B FD00 FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD 00FD 2BF9" $"F92B 2BF9 F9F9 F92B FD00 FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD 0505" $"0505 FC05 0505 0505 FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD FDFD 05FC" $"FCFC FCFC 0505 FC05 FDFD FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD F5FD 05FC" $"05FC 05FC FC05 FCFC FDF5 FDF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FD F5FD 05FC" $"05FC 0505 0505 0505 FDF5 FDF5 FF00 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl8' (139) { $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 FDF5 FDD8 D8F9" $"F9D8 D8D8 F9D8 D8FD F5FD F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 FDF5 FDF9 D8D8" $"F9F9 D8F9 D8D8 D8FD F5FD F5FF FFFF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDFD FDE3 E3E3" $"E3E3 E3E3 E3E3 E3FD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDFD FDE3 F9E3" $"F9F9 F9F9 F9F9 E3FD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC F5F5 FD00 FDE3 F9F9" $"F9F9 E3F9 E3F9 E3FD 00FD F5FF 00FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 FD00 FDE3 F9E3" $"F9F9 E3F9 E3E3 F9FD 00FD F5FF 00FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 FDFD FDE3 F9E3" $"F9F9 F9F9 F9E3 F9FD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FDFD FDE3 F9F9" $"F9E3 F9F9 E3F9 E3FD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FDFD FDE3 F9E3" $"E3F9 E3F9 E3F9 E3FD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FD00 FDFD FDFD" $"FDFD FDFD FDFD FDFD 00FD F5FF 00FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FD00 FD2B 2B2B" $"2B2B 2B2B 2B2B 2BFD 00FD F5FF 00FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 FDFD FD2B F9F9" $"2BF9 F9F9 F9F9 2BFD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 FDFD FD2B F9F9" $"F92B F9F9 F9F9 2BFD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 FDFD FD2B F92B" $"F9F9 2BF9 2BF9 2BFD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC F5F5 FDFD FD2B F9F9" $"F9F9 2BF9 F9F9 2BFD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FD00 FD2B F92B" $"2B2B F9F9 2BF9 2BFD 00FD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FD00 FD2B F9F9" $"2B2B F9F9 F9F9 2BFD 00FD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD F5FF 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDFD FDFD FDFD" $"FDFD FDFD FFFF FFFF FFFF FFF5 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDFD FD05 0505" $"05F9 0505 FF2B 2B2B 2BFF F5FD 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDFD FD05 F9F9" $"F9F9 F905 FF2B 2B2B FFF5 FDFD 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDF5 FD05 F905" $"F905 F9F9 FF2B 2BFF F5FD FDFD 00FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FDF5 FD05 F905" $"F905 0505 FF2B FFF5 05FD FDFD 00FF 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FFFF F5FC FCFD F5FD 00FF 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFF5 0505 05FD F5FD 00FF 0000" $"0000 0000 FF00 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 00FF 0000" $"0000 0000 FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl8' (140) { $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FF00 0000 0000 0000 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FFFF 0000 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 FF2B FF00 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F9 F52B F5F5" $"2B2B F5F5 F5F5 FF2B 2BFF 0000 0000 0000" $"0000 00FF F5EC ECEC ECEC F52B F52B F5F9" $"F5F5 F5F5 F5F5 FF2B 2B2B FF00 0000 0000" $"0000 00FF F5EC ECEC ECEC F52B F52B F5F5" $"F5E3 E3F5 F5F5 FF2B 2B2B 2BFF 0000 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F52B" $"2BF5 F5F5 E3E3 FFFF FFFF FFFF FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F5F5 F5F5" $"F5F5 F52B 0000 2BE3 E3F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFFF FFFF" $"FFFF FFFF FFFF FFF5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECF5 F5FF FFFF FFFF" $"FFFF FFFF FFFF FFFF F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 F5FF FFFF FFF5" $"F5F5 F52B F5F5 FFFF F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5F9 F5F5 FFFF FFF9" $"F5F5 F5F9 F5F5 F52B F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECF5 F5F5 F52B 00FF FFFF" $"F5F5 F52B F5F5 F5FF F52B F5F5 FF00 0000" $"0000 00FF F5EC ECF5 0505 0505 0500 FFFF" $"FFF5 F5F5 2BF9 F52B F52B F5F5 FF00 0000" $"0000 00FF F5EC ECF5 05F9 F9FF F905 00FF" $"FFFF F5F5 F5F5 F5F5 F52B F5F5 FF00 0000" $"0000 00FF F5EC ECF5 05FF F905 E305 0500" $"FFFF FFF5 F5F5 F52B F5F5 2BF5 FF00 0000" $"0000 00FF F5EC ECF5 05FF 05F9 F9F9 052B" $"FFFF FFFF F52B F5F5 F5FF F5F5 FF00 0000" $"0000 00FF F5EC ECF5 F5F9 0505 F905 052B" $"00FF FFFF F5F5 F5F5 FFFF F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 0505 FF05 0500" $"0000 FFFF F5F5 2BF5 F5FF F5F5 FF00 0000" $"0000 00FF F5EC ECEC F5F5 0505 0505 0500" $"00FF FF2B F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECF5 F5F5 F5F5 F52B" $"FFFF F52B F5F5 2BF5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F9 F9F5 F5FF" $"FFF5 F5F5 F5F5 2BF5 F5F5 2BF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5F5 F52B FFFF" $"F5F5 F5F5 F5F5 F5F5 FFF5 2BF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F52B F5FF FF2B" $"F5F5 F5F5 F5F5 F5F5 FFF5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F52B FFFF F5F5" $"F52B F5F5 2BF5 2BFF FFF5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFFF FFFF" $"FFFF FFFF FFFF FFFF F9F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5FF FFFF FFFF" $"FFFF FFFF FFFF FFFF 2BF5 2BF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F52B 2BF5 F52B" $"F5F5 2BF5 F52B 2BF5 F5F5 F5F5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5D8 D8F9 F5F5" $"F5F5 F5F5 F5F5 F5F9 F9F5 2BF5 FF00 0000" $"0000 00FF F5EC ECEC ECEC F5D8 D8F9 F52B" $"F9F5 F52B F5F5 F5F9 2B2B F5F5 FF00 0000" $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F52B F5F5 F5F5 F5F5 F5F5 FF00 0000" $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl8' (141) { $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF 0000 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 2BF5 2BF5 F9F5" $"F52B F5F5 F52B F5F5 F5F5 F5FF 0000 0000" $"0000 FFF5 ECEC ECEC ECF5 2BF5 2BF5 F5F5" $"E3E3 F5F5 F52B 2BF5 F52B F5FF FFFF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 2B2B" $"F5F5 F5E3 E3F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F5F5 F5F5" $"F5F5 2B00 002B E3E3 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFFF FFFF FFFF" $"FFFF FFFF FFFF F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFFF FFFF FFFF" $"FFFF FFFF FFFF FFF5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC F5F5 FFFF FFFF F5F5" $"F5F5 2BF5 F5FF FFF5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 2BF5 F5FF FFFF F9F5" $"F5F5 F9F5 F5F5 2BF5 2BF5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 2BF5 2BF5 FFFF FFF5" $"F5F5 2BF5 F5F5 FFF5 2BF5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F5F5 F5F5 F5FF FFFF" $"F5F5 F52B F9F5 2BF5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F505 0505 0505 F5FF FFFF" $"FFF5 F5F5 F5F5 F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F505 F9F9 FFF9 0500 00FF" $"FFFF F5F5 F5F5 2BF5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC F505 FFF9 0505 0505 2BFF" $"FFFF FFF5 2BF5 F5F5 2BF5 F5FF F5FF 0000" $"0000 FFF5 ECEC F505 FF05 F9F9 F905 2B00" $"FFFF FFF5 F5F5 F5FF 2BF5 F5FF F5FF 0000" $"0000 FFF5 ECEC F5F5 F905 05F9 0505 0000" $"00FF FFF5 F52B F5F5 F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F505 05FF 0505 0000" $"FFFF 2BF5 F5F5 F5F5 F52B F5FF F5FF 0000" $"0000 FFF5 ECEC ECF5 F5F5 F5F5 F5F5 2BFF" $"FFF5 2BF5 F52B F5F5 F52B F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC F5F5 F5F5 F5F5 FFFF" $"F5F5 F5F5 F52B F5F5 F52B F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 2BFF FFF5" $"F5F5 2BF5 F5F5 F5FF F52B F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 2BF5 FFFF 2BF5" $"F5F5 F5F5 F5F5 F5FF F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 2BFF FFF5 F5F5" $"2BF5 F52B F52B FFFF F5F5 F5FF F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFF5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 FFFF FFFF FFFF" $"FFFF FFFF FF2B 2B2B 2BFF F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 F5F5 F500 F5F5" $"F5F5 F5F5 FF2B 2B2B FFF5 F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 D8D8 F52B 2BF5" $"F52B F5F5 FF2B 2BFF F5F5 F5F5 F5FF 0000" $"0000 FFF5 ECEC ECEC ECF5 D8D8 2BF5 2BF5" $"F5F5 F5F5 FF2B FFF5 F5F5 F5F5 F5FF 0000" $"0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FFFF F5F5 F5F5 F5F5 F5FF 0000" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFF5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 0000 FFF5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000" $"0000 0000 FFFF FFFF FFFF FFFF FFFF FFFF" $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl8' (142) { $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"F0EF F0EF F000 0000 0000 0000 0000 0000" $"FA00 0000 0000 0000 0000 0000 0000 0000" $"F0EF F0EF F000 0000 0000 0000 0000 00FA" $"D2FA 0000 0000 0000 0000 0000 0000 0000" $"EFF0 EFF0 EF00 0000 0000 0000 0000 FA00" $"F9D2 FA00 0000 0000 0000 0000 0000 0000" $"F0EF F0EF F000 0000 0000 0000 00FA 0000" $"00FA D2FA 0000 0000 0000 0000 0000 0000" $"EFF0 EFF0 EF00 0000 0000 0000 FAFF 0000" $"FA00 57D2 FA00 0000 0000 0000 0000 0000" $"EFF0 EFF0 EF00 0000 0000 00FA FF00 F7F9" $"00FF 00F9 D2FA 0000 0000 0000 0000 0000" $"F0EF F0EF F000 0000 0000 FA00 00FA F900" $"FA00 00FA F9D2 FA00 0000 0000 0000 0000" $"EFF0 EFF0 EF00 0000 007B FF00 00F9 0000" $"00F9 00FF 00FA D2FA 0000 0000 0000 0000" $"F0EF F0EF F000 0000 FA00 002B FA00 0000" $"0000 FA00 0000 F9D2 FA00 0000 0000 0000" $"EFF0 EFF0 EF00 00F9 0000 00FA 0000 0000" $"0000 00F9 0000 00FA D2FA 0000 0000 0000" $"F0EF F0EF F000 F9FF 0000 FA00 0000 0000" $"0000 0000 FA00 FFF9 F9D2 FA00 0000 0000" $"EFF0 EFF0 EFF9 0000 F7F9 0000 0000 0000" $"0000 0000 00F9 00FF 00F9 D2FA 0000 0000" $"F0EF EFF0 F9FF 0000 F900 0000 0000 F9FA" $"00F9 FAF9 FA00 FA00 00FA F9D2 FA00 0000" $"EFF0 F0F9 0000 00FA 0000 0000 FAF9 00F9" $"FA00 F9FA FFF9 F9FA 00FF 00FA D2FA 0000" $"EFF0 F9FF 0000 FA00 0000 00F9 00FA 00C9" $"00D2 00D2 C2EF F0F0 F900 0000 F9D2 7B00" $"F0F9 0000 00FA 0000 00FA 00D2 0000 C200" $"05E6 E5E6 D2E5 EFEF F0F9 0000 00FA D2FA" $"EFEF FA00 FA00 0000 F9D2 0000 D2F9 E6E6" $"05E5 E6E5 E5E6 E6E5 EFF0 FA00 0000 F900" $"F0EF EFF9 0000 00FA FA00 C300 FAE6 E505" $"0505 E5D2 D2E5 E5F9 E6E5 EFF9 00FA 8C00" $"F0EF F0F0 FA00 F900 00D2 00F9 E505 0505" $"0505 0505 E5D2 E6E6 E5EF F0FF F98C 0000" $"EFF0 EFEF F0F9 FA00 F9D2 FAD2 C8E5 E505" $"0505 E6E5 E6E5 E6EF E6E5 E6FF FF00 0000" $"EFF0 EFF0 EFFA 0000 D2FA 00C2 E5E5 E6E6" $"05E6 D2E6 E5E6 E5E5 E5E6 FFE5 F000 0000" $"F0EF F0EF F0F9 FAF9 0000 E6E6 E5E6 E5E5" $"05E5 E6D2 E6E5 E6EF E5EF E5FF F0FF 0000" $"EFF0 EFF0 F900 00FA D2C2 C9C2 E6E5 D2E5" $"E6D2 D2D2 E5E5 E6E5 E6E5 FFEF E5FF 0000" $"F0EF F0EF 00FA 00D2 F9EB D2C9 E5D2 D2E6" $"D2D2 D2E5 E6E6 E5E6 EFE6 E5E6 EFFF 0000" $"EFF0 EFEF FAF9 D200 D2D2 D2D2 D2D2 D2D2" $"E5E6 E5E6 E5E5 E6E5 E6E5 F0EF F0FF 0000" $"F0EF F0F0 00D2 00D2 D2D2 D2E5 E5E6 E5E6" $"D2E5 D2E5 E6E5 E5E6 EFE5 EFE5 EFFF 0000" $"EFF0 EFF0 F900 D2D2 D2D2 E5E5 E6E5 E6E5" $"E5D2 E5E6 E5E6 E5E6 E5EF E5FF EFFF 0000" $"EFEF F0EF 00D2 00D2 D2E5 E6E6 E5E6 E5E6" $"E6D2 D2E5 E6E5 E6E5 EFF0 FFE5 FFFF 0000" $"F0F0 EFF0 FAF9 D2D2 D2E6 E5E5 E6E5 E6E5" $"E5D2 D2E5 E6E5 E6E5 F0E6 E5EF FFFF 0000" $"EFEF F0EF F000 F0D2 D2D2 E6E5 E6E5 E6E5" $"E6D2 D2D2 E5E6 EFE6 EFF0 EFFF FF00 0000" $"F0F0 EFF0 EFFA C2F0 EFD2 D2D2 E5E6 E5E6" $"D2D2 F0D2 D2EF F0EF F0EF FFFF FF" }; resource 'icl4' (128) { $"0000 0000 0000 0000 0000 0000 0000 0000" $"6666 6000 0000 0000 D000 0000 0000 0000" $"6666 6000 0000 000D 6D00 0000 0000 0000" $"6666 6000 0000 00D0 D6D0 0000 0000 0000" $"6666 6000 0000 0D00 0D6D 0000 0000 0000" $"6666 6000 0000 DF00 D0D6 D000 0000 0000" $"6666 6000 000D F0CD 0F0D 6D00 0000 0000" $"6666 6000 00D0 0DD0 D00D D6D0 0000 0000" $"6666 6000 0DF0 0D00 0D0F 0D6D 0000 0000" $"6666 6000 D00C D000 00D0 00D6 D000 0000" $"6666 600D 000D 0000 000D 000D 6D00 0000" $"6666 60DF 00D0 0000 0000 D0FD D6D0 0000" $"6666 6D00 CD00 0000 0000 0D0F 0D6D 0000" $"6666 DF00 D000 00DD 0DDD D0D0 0DD6 D000" $"666D 000D 0000 DD0D D0DD FDDD 0F0D 6D00" $"66DF 00D0 000D 0D09 0606 7666 D000 D6D0" $"6D00 0D00 0D06 0070 1999 6966 6D00 0D6D" $"66D0 D000 D600 6D99 1999 9999 66D0 00D0" $"666D 000D D080 D991 1196 699D 996D 0D50" $"6666 D0D0 060D 9111 1111 9699 966F D500" $"6666 6DD0 D6D6 9991 1199 9996 999F F000" $"6666 6D00 6D07 9999 1969 9999 99F9 6000" $"6666 6DDD 0099 9999 1996 9996 969F 6F00" $"6666 D00D 6797 9969 9666 9999 99F6 9F00" $"6666 0D06 D669 9669 6669 9999 6999 6F00" $"6666 DD60 6666 6666 9999 9999 9966 6F00" $"6666 0606 6669 9999 6969 9999 6969 6F00" $"6666 D066 6699 9999 9699 9999 969F 6F00" $"6666 0606 6999 9999 9669 9999 66F9 FF00" $"6666 DD66 6999 9999 9669 9999 6996 FF00" $"6666 6066 6699 9999 9666 9969 666F F000" $"6666 6D76 6666 9999 6666 6666 66FF F0" }; resource 'icl4' (129) { $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000" $"000F 0000 0000 0000 0000 00FF 0000 0000" $"000F 0666 6600 0000 0000 00FC F000 0000" $"000F 0666 6600 0000 0000 00FC CF00 0000" $"000F 0666 6600 0000 0000 00FC CCF0 0000" $"000F 0666 6600 FF0F 0FFF FFFC CCCF 0000" $"000F 0666 6600 0000 0000 00FF FFFF F000" $"000F 0666 660F FFF0 0FFF 0FF0 F000 F000" $"000F 0666 6600 0000 0000 0000 0000 F000" $"000F 0666 60F0 FF0F 0FF0 F0FF 0F00 F000" $"000F 0666 0000 0000 0000 0000 0000 F000" $"000F 0666 0F0F FF0F FF0F 0FFF 0F00 F000" $"000F 0660 0000 0000 0000 0000 0000 F000" $"000F 0660 FF0F 0FFF 0FF0 FF0F FF00 F000" $"000F 0660 0000 0000 0000 0000 0000 F000" $"000F 0660 F0FF FFF0 FFFF 0FF0 FF00 F000" $"000F 0660 0000 0000 0000 0000 0000 F000" $"000F 0660 FF0F FF0F F0FF F0FF 0000 F000" $"000F 0666 0000 0000 0000 0000 0000 F000" $"000F 0666 0FFF 0FF0 F0F0 F0F0 FF00 F000" $"000F 0666 6000 0000 0000 0000 0000 F000" $"000F 0666 660F F0FF F0FF FF0F 0F00 F000" $"000F 0666 6600 0000 0000 0000 0000 F000" $"000F 0666 660F 0FF0 FFFF 0FF0 FF00 F000" $"000F 0666 6600 0000 0000 0000 0000 F000" $"000F 0666 660F FF00 FFF0 FFF0 0F00 F000" $"000F 0666 6600 0000 0000 0000 0000 F000" $"000F 0666 660F FF0F 0FFF 00FF 0F00 F000" $"000F 0666 6600 0000 0000 0000 0000 F000" $"000F 0666 6600 0000 0000 0000 0000 F000" $"000F 0000 0000 0000 0000 0000 0000 F000" $"000F FFFF FFFF FFFF FFFF FFFF FFFF F0" }; resource 'icl4' (130) { $"00FF FFFF FFFF FFFF FFFF FFFF FFFF 0000" $"00F0 0000 0000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F FF00" $"00F0 6666 6000 0000 0000 0000 000F 0F00" $"00F0 6666 6F0F F0FF FF0F FF0F 000F 0F00" $"00F0 6666 6000 0000 0000 0000 000F 0F00" $"00F0 6666 600F FF0F 0FF0 FF0F 000F 0F00" $"00F0 6666 0000 0000 0000 0000 000F 0F00" $"00F0 6660 F0FF 0F0F FF0F 0FF0 F00F 0F00" $"00F0 6660 0000 0000 0000 0000 000F 0F00" $"00F0 660F F0FF FF0F FFF0 FFF0 000F 0F00" $"00F0 6600 0000 0000 0000 0000 000F 0F00" $"00F0 6600 F0FF 0FFF F00F F0FF F00F 0F00" $"00F0 6600 0000 0000 0000 0000 000F 0F00" $"00F0 660F FF0F FF00 FF0F FF0F F00F 0F00" $"00F0 6600 0000 0000 0000 0000 000F 0F00" $"00F0 6660 FF0F FFFF 00FF 0FF0 000F 0F00" $"00F0 6660 0000 0000 0000 0000 000F 0F00" $"00F0 6666 0FF0 FFF0 FFFF 0F0F F00F 0F00" $"00F0 6666 6000 0000 0000 0000 000F 0F00" $"00F0 6666 6FF0 0FFF 0FFF F0F0 F00F 0F00" $"00F0 6666 6000 0000 0000 0000 000F 0F00" $"00F0 6666 6F0F FFF0 0FF0 FFFF FFF0 0F00" $"00F0 6666 6000 0000 0000 FCCC CF00 0F00" $"00F0 6666 6F00 FF0F F0F0 FCCC F0F0 0F00" $"00F0 6666 6000 0000 0000 FCCF 0000 0F00" $"00F0 6666 60FF 0FFF 0FF0 FCF0 F0F0 0F00" $"00F0 0000 0000 0000 0000 FF00 0000 0F00" $"00FF FFFF FFFF FFFF FFFF F000 0000 0F00" $"0000 F000 0000 0000 0000 0000 0000 0F00" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl4' (131) { $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000" $"00F0 0000 0000 0000 0000 0FF0 0000 0000" $"00F0 6666 6000 0000 0000 0FCF 0000 0000" $"00F0 6666 6000 0000 0000 0FCC F000 0000" $"00F0 6666 6000 0000 0000 0FCC CF00 0000" $"00F0 6666 6000 0000 0000 0FCC CCF0 0000" $"00F0 6666 6000 0000 0000 0FFF FFFF 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 0000 0000 0000 0000 000F 0000" $"00F0 6660 0000 0000 0000 0000 000F 0000" $"00F0 666F FF0F FF0F FF0F F0FF 000F 0000" $"00F0 6600 0000 0000 0000 0000 000F 0000" $"00F0 6600 0000 0000 0000 0000 000F 0000" $"00F0 660F FF0F FFF0 FFFF 0FFF 000F 0000" $"00F0 6600 0000 0000 0000 0000 000F 0000" $"00F0 6600 0000 0000 0000 0000 000F 0000" $"00F0 660F F0FF FFFF F0FF F0FF 000F 0000" $"00F0 6660 0000 0000 0000 0000 000F 0000" $"00F0 6660 0000 0000 0000 0000 000F 0000" $"00F0 6666 0000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 0000 0000 0000 0000 0000 000F 0000" $"00FF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl4' (132) { $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000" $"000F 0000 0000 0000 0000 00FF 0000 0000" $"000F 0666 66FF 070F FFF0 70FC F000 0000" $"000F 0666 6600 0700 0000 70FC CF00 0000" $"000F 0666 6677 70FF FFFF 0FFC CCF0 0000" $"000F 0666 6600 0F00 0000 F0FC CCCF 0000" $"000F 0666 6600 0F00 0000 F0FF FFFF F000" $"000F 0666 6600 0F00 0000 F000 0000 F000" $"000F 0666 6677 70FF FFFF 0FFF FFFF F000" $"000F 0666 6000 0F00 0000 F000 0000 F000" $"000F 0666 00FF 0F00 0000 F000 0000 F000" $"000F 0666 0000 0F00 0000 F000 0000 F000" $"000F 0660 7777 70FF FFFF 0FFF FFFF F000" $"000F 0660 0000 0F00 0000 F000 0000 F000" $"000F 0660 0FFF 0F00 0000 F000 0000 F000" $"000F 0660 0000 0F00 0000 F000 0000 F000" $"000F 0660 7777 70FF FFFF 0FFF FFFF F000" $"000F 0660 0000 0F00 0000 F000 0000 F000" $"000F 0666 00FF 0F00 0000 F000 0000 F000" $"000F 0666 0000 0F00 0000 F000 0000 F000" $"000F 0666 6777 70FF FFFF 0FFF FFFF F000" $"000F 0666 6600 0F00 0000 F000 0000 F000" $"000F 0666 660F 0F00 0000 F000 0000 F000" $"000F 0666 6600 0F00 0000 F000 0000 F000" $"000F 0666 6677 70FF FFFF 0FFF FFFF F000" $"000F 0666 6600 0F00 0000 F000 0000 F000" $"000F 0666 660F 0F00 0000 F000 0000 F000" $"000F 0666 6600 0F00 0000 F000 0000 F000" $"000F 0666 6677 70FF FFFF 0FFF FFFF F000" $"000F 0666 6600 0F00 0000 F000 0000 F000" $"000F 0000 0000 0000 0000 0000 0000 F000" $"000F FFFF FFFF FFFF FFFF FFFF FFFF F0" }; resource 'icl4' (133) { $"00FF FFFF FFFF FFFF FFFF FFFF FFFF 0000" $"00F0 0000 0000 0000 0000 0000 000F 0000" $"00F0 6666 6000 070F FFF0 70FF FF0F 0000" $"00F0 6666 6000 0700 0000 7000 000F FF00" $"00F0 6666 6777 70FF FFFF 0FFF FFFF 0F00" $"00F0 6666 6000 0F00 0000 F000 000F 0F00" $"00F0 6666 600F 0F00 0000 F000 000F 0F00" $"00F0 6666 6000 0F00 0000 F000 000F FF00" $"00F0 6666 7777 70FF FFFF 0FFF FFFF 0F00" $"00F0 6660 0000 0F00 0000 F000 000F 0F00" $"00F0 6660 0FFF 0F00 0000 F000 000F 0F00" $"00F0 6600 0000 0F00 0000 F000 000F FF00" $"00F0 6607 7777 70FF FFFF 0FFF FFFF 0F00" $"00F0 6600 0000 0F00 0000 F000 000F 0F00" $"00F0 6600 FFFF 0F00 0000 F000 000F 0F00" $"00F0 6600 0000 0F00 0000 F000 000F FF00" $"00F0 6607 7777 70FF FFFF 0FFF FFFF 0F00" $"00F0 6660 0000 0F00 0000 F000 000F 0F00" $"00F0 6660 0FFF 0F00 0000 F000 000F 0F00" $"00F0 6666 0000 0F00 0000 F000 000F FF00" $"00F0 6666 6777 70FF FFFF 0FFF FFFF 0F00" $"00F0 6666 6000 0F00 0000 F000 000F 0F00" $"00F0 6666 600F 0F00 0000 F000 000F 0F00" $"00F0 6666 6000 0F00 0000 FFFF FFF0 FF00" $"00F0 6666 6777 70FF FFFF F000 0F00 0F00" $"00F0 6666 6000 0F00 0000 F000 F000 0F00" $"00F0 6666 600F 0F00 0000 F00F 0000 0F00" $"00F0 6666 6000 0F00 0000 F0F0 FFFF FF00" $"00F0 0000 0000 0000 0000 FF00 0000 0F00" $"00FF FFFF FFFF FFFF FFFF F0F0 0000 0F00" $"0000 F000 0000 0000 0000 0000 0000 0F00" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl4' (134) { $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000" $"00F0 0000 0000 0000 0000 0FF0 0000 0000" $"00F0 6666 6FFF FFFF FFFF FF0F 0000 0000" $"00F0 6666 6FCC CCCC CCCC CF00 F000 0000" $"00F0 6666 6FCD DDDD DDDD DF00 0F00 0000" $"00F0 6666 6FCD FFFF FFFF FF00 00F0 0000" $"00F0 6666 6FCD F001 6000 0FFF FFFF 0000" $"00F0 6666 6FCD F011 6600 0000 000F 0000" $"00F0 6666 6FCD F111 6660 0FFF F00F 0000" $"00F0 6666 0FCD F333 8880 0000 00FF 0000" $"00F0 6660 0FCD F033 8800 FFF0 FF0F 0000" $"00F0 6660 0FCD F003 8000 000F 000F 0000" $"00F0 6600 0FCD F000 0000 00F0 000F 0000" $"00F0 6600 0FCD F0FF 0FF0 FF00 000F 0000" $"00F0 6600 0FCD F0FF 000F 0000 000F 0000" $"00F0 6600 0FCD F0FF 0FF0 0000 000F 0000" $"00F0 6600 0FCD F000 F000 0FFF F00F 0000" $"00F0 6600 0FCD F0FF 0000 F0C0 CF0F 0000" $"00F0 6660 0FCD 0F00 000F 0C0C 0CFF 0000" $"00F0 6660 0F00 F0FF FFFF F0C0 C0FF 0000" $"00F0 6666 00FF 00FD DDDD FC0C 0CFF 0000" $"00F0 6666 6F00 00FD DDDD F0C0 C0FF 0000" $"00F0 6666 6000 00FD DDDD FC0C 0F0F 0000" $"00F0 6666 6000 00FD DDDD FFFF F00F 0000" $"00F0 6666 6000 00FD DDDF CF00 000F 0000" $"00F0 6666 6000 00FF FFFC DCF0 000F 0000" $"00F0 6666 6000 0000 0FCD CDCF 000F 0000" $"00F0 6666 6000 0000 FCDC DCDC F00F 0000" $"00F0 6666 6000 000F FFFF FFFF FF0F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 0000 0000 0000 0000 0000 000F 0000" $"00FF FFFF FFFF FFFF FFFF FFFF FFFF" }; resource 'icl4' (135) { $"00FF FFFF FFFF FFFF FFFF FFFF FFFF 0000" $"00F0 0000 0000 0000 0000 0000 000F 0000" $"00F0 6666 6FFF FFFF FFFF FFFF FF0F 0000" $"00F0 6666 6FCC CCCC CCCC CCCC CC0F FF00" $"00F0 6666 6FCC CCCC CCCC CCCC CC0F 0F00" $"00F0 6666 6FCF FFFF FFFF FFFF FF0F 0F00" $"00F0 6666 6FCF 0016 0000 0000 000F 0F00" $"00F0 6666 6FCF 0116 6000 0000 000F 0F00" $"00F0 6666 0FCF 1116 6600 FFFF 00FF 0F00" $"00F0 6660 0FCF 3338 8800 0000 0F0F 0F00" $"00F0 6660 0FCF 0338 800F FF0F F00F 0F00" $"00F0 6600 0FCF 0038 0000 00F0 000F 0F00" $"00F0 6600 0FCF 0000 0000 0F00 000F 0F00" $"00F0 6600 0FCF 0FF0 FF0F F000 000F 0F00" $"00F0 6600 0FCF 0FF0 00F0 0000 000F 0F00" $"00F0 6600 0FCF 0FF0 FF00 0000 000F 0F00" $"00F0 6600 0FCF 000F 0000 FFFF 000F 0F00" $"00F0 6660 0FCF 0FF0 000F 0C0C F00F 0F00" $"00F0 6660 0FC0 F000 00F0 C0C0 CF0F 0F00" $"00F0 6666 000F 0FFF FFFF 0C0C 0F0F 0F00" $"00F0 6666 6FF0 0FDD DDDF C0C0 CF0F 0F00" $"00F0 6666 6000 0FDD DDDF 0C0C 0F0F 0F00" $"00F0 6666 6000 0FDD DDDF C0C0 F00F 0F00" $"00F0 6666 6000 0FDD DDDF FFFF FFFF 0F00" $"00F0 6666 6000 0FDD DDFC F000 00F0 0F00" $"00F0 6666 6000 0FFF FFCD F000 0F00 0F00" $"00F0 6666 6000 0000 FCDC F000 F000 0F00" $"00F0 6666 6000 000F FFFF F00F 0000 0F00" $"00F0 0000 0000 0000 0000 F0F0 0000 0F00" $"00FF FFFF FFFF FFFF FFFF FF00 0000 0F00" $"0000 F000 0000 0000 0000 0000 0000 0F00" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl4' (136) { $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000" $"000F 0000 0000 0000 0000 00FF 0000 0000" $"000F 0666 6600 F000 0000 00FC F000 0000" $"000F 0666 660F F000 0000 00FC CF00 0000" $"000F 0666 6600 F000 0000 00FC CCF0 0000" $"000F 0666 6600 F000 0000 00FC CCCF 0000" $"000F 0666 660F FF00 000F FFFF FFFF F000" $"000F 0666 6600 F000 0FF1 1F6F F000 F000" $"000F 0666 6600 F000 F111 1F66 6F00 F000" $"000F 0666 600F F000 F111 1F66 6F00 F000" $"000F 0666 0000 F00F 1111 1F66 66F0 F000" $"000F 0666 0000 F00F 1111 1F66 66F0 F000" $"000F 0660 000F FF0F 1111 FFFF FFF0 F000" $"000F 0660 0000 F00F 111F 3C3C 3CF0 F000" $"000F 0660 0000 F000 F1F3 C3C3 CF00 F000" $"000F 0660 000F F000 FF3C 3C3C 3F07 F000" $"000F 0660 0000 F000 0FF3 C3CF F070 F000" $"000F 0660 0000 F000 000F FFF0 0070 F000" $"000F 0666 000F FF00 0000 0000 0700 F000" $"000F 0666 0000 F000 0770 0000 0700 F000" $"000F 0666 6000 F000 0770 0000 7000 F000" $"000F 0666 660F F000 7007 0000 7000 F000" $"000F 0666 6600 F000 7000 7007 0000 F000" $"000F 0666 6600 F007 0000 0777 0000 F000" $"000F 0666 660F F077 0000 0077 0000 F000" $"000F 0666 6600 F077 0000 0000 0000 F000" $"000F 0666 6600 F000 0000 0F00 0000 F000" $"000F 0666 6600 FFFF FFFF FFFF FFF0 F000" $"000F 0666 6600 000F 00F0 0F00 F000 F000" $"000F 0666 6600 0000 0000 0000 0000 F000" $"000F 0000 0000 0000 0000 0000 0000 F000" $"000F FFFF FFFF FFFF FFFF FFFF FFFF F0" }; resource 'icl4' (137) { $"00FF FFFF FFFF FFFF FFFF FFFF FFFF 0000" $"00F0 0000 0000 0000 0000 0000 000F 0000" $"00F0 6666 6000 0000 0000 0000 000F 0000" $"00F0 6666 6FFF 0000 0FFF F000 000F FF00" $"00F0 6666 60F0 000F F11F 6FF0 000F 0F00" $"00F0 6666 60F0 00F1 111F 666F 000F 0F00" $"00F0 6666 6FF0 00F1 111F 666F 000F 0F00" $"00F0 6666 60F0 0F11 111F 6666 F00F 0F00" $"00F0 6666 00F0 0F11 111F 6666 F00F 0F00" $"00F0 6660 0FFF 0F11 11FF FFFF F00F 0F00" $"00F0 6660 00F0 0F11 1F3C 3C3C F00F 0F00" $"00F0 6600 00F0 00F1 F3C3 C3CF 000F 0F00" $"00F0 6600 0FF0 00FF 3C3C 3C3F 070F 0F00" $"00F0 6600 00F0 000F F3C3 CFF0 700F 0F00" $"00F0 6600 00F0 0000 0FFF F000 700F 0F00" $"00F0 6600 0FFF 0000 0000 0007 000F 0F00" $"00F0 6600 00F0 0007 7000 0007 000F 0F00" $"00F0 6660 00F0 0007 7000 0070 000F 0F00" $"00F0 6660 0FF0 0070 0700 0070 000F 0F00" $"00F0 6666 00F0 0070 0070 0700 000F 0F00" $"00F0 6666 60F0 0700 0007 7700 000F 0F00" $"00F0 6666 6FF0 7700 0000 7700 000F 0F00" $"00F0 6666 60F0 7700 0000 0000 000F 0F00" $"00F0 6666 60F0 0000 0000 FFFF FFF0 0F00" $"00F0 6666 60FF FFFF FFFF FCCC CF00 0F00" $"00F0 6666 6000 0F00 F00F FCCC F000 0F00" $"00F0 6666 6000 0000 0000 FCCF 0000 0F00" $"00F0 6666 6000 0000 0000 FCF0 0000 0F00" $"00F0 0000 0000 0000 0000 FF00 0000 0F00" $"00FF FFFF FFFF FFFF FFFF F000 0000 0F00" $"0000 F000 0000 0000 0000 0000 0000 0F00" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl4' (138) { $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000" $"000F 0000 0000 0000 0000 00FF 0000 0000" $"000F 0666 660E FE33 3333 33FC F000 0000" $"000F 0666 660F EF3D D3DD 33FC CF00 0000" $"000F 0666 660E 0E33 DD33 3DFC CCF0 0000" $"000F 0666 660F 0FD3 3DD3 D3FC CCCF 0000" $"000F 0666 660E FEFE FEFE FEFF FFFF F000" $"000F 0666 660F EFEF EFEF EFEF EFE0 F000" $"000F 0666 660E FE88 8888 8888 FEF0 F000" $"000F 0666 600F EF8D 8DDD DDD8 EFE0 F000" $"000F 0666 000E 0E8D DDD8 D8D8 F0F0 F000" $"000F 0666 000F 0F8D 8DD8 D88D E0E0 F000" $"000F 0660 000E FE8D 8DDD DD8D FEF0 F000" $"000F 0660 000F EF8D DD8D D8D8 EFE0 F000" $"000F 0660 000E FE8D 88D8 D8D8 FEF0 F000" $"000F 0660 000F EFEF EFEF EFEF EFE0 F000" $"000F 0660 000E 0EFE FEFE FEFE F0F0 F000" $"000F 0660 000F 0FCC CCCC CCCC E0E0 F000" $"000F 0666 000E FECD DCDD DDDC FEF0 F000" $"000F 0666 000F EFCD DDCD DDDC EFE0 F000" $"000F 0666 600E FECD CDDC DCDC FEF0 F000" $"000F 0666 660F EFCD DDDC DDDC EFE0 F000" $"000F 0666 660E 0ECD CCCD DCDC F0F0 F000" $"000F 0666 660F 0FCD DCCD DDDC E0E0 F000" $"000F 0666 660E FEFE FEFE FEFE FEF0 F000" $"000F 0666 660F EFEF EFEF EFEF EFE0 F000" $"000F 0666 660E FE11 11F1 1111 FEF0 F000" $"000F 0666 660F EF1F EFEF 11E1 EFE0 F000" $"000F 0666 660E 0E1E 1E1E F1FE F0F0 F000" $"000F 0666 660F 0F1F 1F11 1111 E0E0 F000" $"000F 0000 0000 0000 0000 0000 0000 F000" $"000F FFFF FFFF FFFF FFFF FFFF FFFF F0" }; resource 'icl4' (139) { $"00FF FFFF FFFF FFFF FFFF FFFF FFFF 0000" $"00F0 0000 0000 0000 0000 0000 000F 0000" $"00F0 6666 60F0 F33D D333 D33E 0E0F 0000" $"00F0 6666 60E0 ED33 DD3D 333F 0F0F FF00" $"00F0 6666 60FE FEFE FEFE FEFE FE0F 0F00" $"00F0 6666 60EF EFEF EFEF EFEF EF0F 0F00" $"00F0 6666 60FE F888 8888 888E FE0F 0F00" $"00F0 6666 60EF E8D8 DDDD DD8F EF0F 0F00" $"00F0 6666 00F0 F8DD DD8D 8D8E 0E0F 0F00" $"00F0 6660 00E0 E8D8 DD8D 88DF 0F0F 0F00" $"00F0 6660 00FE F8D8 DDDD D8DE FE0F 0F00" $"00F0 6600 00EF E8DD D8DD 8D8F EF0F 0F00" $"00F0 6600 00FE F8D8 8D8D 8D8E FE0F 0F00" $"00F0 6600 00EF EFEF EFEF EFEF EF0F 0F00" $"00F0 6600 00F0 FEFE FEFE FEFE 0E0F 0F00" $"00F0 6600 00E0 ECCC CCCC CCCF 0F0F 0F00" $"00F0 6600 00FE FCDD CDDD DDCE FE0F 0F00" $"00F0 6660 00EF ECDD DCDD DDCF EF0F 0F00" $"00F0 6660 00FE FCDC DDCD CDCE FE0F 0F00" $"00F0 6666 00EF ECDD DDCD DDCF EF0F 0F00" $"00F0 6666 60F0 FCDC CCDD CDCE 0E0F 0F00" $"00F0 6666 60E0 ECDD CCDD DDCF 0F0F 0F00" $"00F0 6666 60FE FEFE FEFE FEFE FE0F 0F00" $"00F0 6666 60EF EFEF EFEF FFFF FFF0 0F00" $"00F0 6666 60FE F111 1D11 FCCC CF0E 0F00" $"00F0 6666 60EF E1DD DDD1 FCCC F0EF 0F00" $"00F0 6666 60F0 F1D1 D1DD FCCF 0EFE 0F00" $"00F0 6666 60E0 E1D1 D111 FCF0 1FEF 0F00" $"00F0 0000 0000 0000 0000 FF0E EE0E 0F00" $"00FF FFFF FFFF FFFF FFFF F011 1F0F 0F00" $"0000 F000 0000 0000 0000 0000 0000 0F00" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl4' (140) { $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000" $"000F 0000 0000 0000 0000 00FF 0000 0000" $"000F 0666 6600 0000 0000 00FC F000 0000" $"000F 0666 660D 0C00 CC00 00FC CF00 0000" $"000F 0666 660C 0C0D 0000 00FC CCF0 0000" $"000F 0666 660C 0C00 0880 00FC CCCF 0000" $"000F 0666 6600 000C C000 88FF FFFF F000" $"000F 0666 6600 0000 000C 00C8 8000 F000" $"000F 0666 660F FFFF FFFF FFF0 0000 F000" $"000F 0666 600F FFFF FFFF FFFF 0000 F000" $"000F 0666 000F FFF0 000C 00FF 0000 F000" $"000F 0666 0D00 FFFD 000D 000C 0000 F000" $"000F 0660 000C 0FFF 000C 000F 0C00 F000" $"000F 0660 1111 10FF F000 CD0C 0C00 F000" $"000F 0660 1DDF D10F FF00 0000 0C00 F000" $"000F 0660 1FD1 8110 FFF0 000C 00C0 F000" $"000F 0660 1F1D DD1C FFFF 0C00 0F00 F000" $"000F 0660 0D11 D11C 0FFF 0000 FF00 F000" $"000F 0666 0011 F110 00FF 00C0 0F00 F000" $"000F 0666 0011 1110 0FFC 0000 0000 F000" $"000F 0666 6000 000C FF0C 00C0 0000 F000" $"000F 0666 660D D00F F000 00C0 00C0 F000" $"000F 0666 6600 0CFF 0000 0000 F0C0 F000" $"000F 0666 660C 0FFC 0000 0000 F000 F000" $"000F 0666 660C FF00 0C00 C0CF F000 F000" $"000F 0666 660F FFFF FFFF FFFF D000 F000" $"000F 0666 660F FFFF FFFF FFFF C0C0 F000" $"000F 0666 660C C00C 00C0 0CC0 0000 F000" $"000F 0666 6603 3D00 0000 000D D0C0 F000" $"000F 0666 6603 3D0C D00C 000D CC00 F000" $"000F 0000 0000 0000 000C 0000 0000 F000" $"000F FFFF FFFF FFFF FFFF FFFF FFFF F0" }; resource 'icl4' (141) { $"00FF FFFF FFFF FFFF FFFF FFFF FFFF 0000" $"00F0 0000 0000 0000 0000 0000 000F 0000" $"00F0 6666 60C0 C0D0 0C00 0C00 000F 0000" $"00F0 6666 60C0 C000 8800 0CC0 0C0F FF00" $"00F0 6666 6000 00CC 0008 8000 000F 0F00" $"00F0 6666 6000 0000 00C0 0C88 000F 0F00" $"00F0 6666 60FF FFFF FFFF FF00 000F 0F00" $"00F0 6666 60FF FFFF FFFF FFF0 000F 0F00" $"00F0 6666 00FF FF00 00C0 0FF0 000F 0F00" $"00F0 6660 C00F FFD0 00D0 00C0 C00F 0F00" $"00F0 6660 C0C0 FFF0 00C0 00F0 C00F 0F00" $"00F0 6600 0000 0FFF 000C D0C0 000F 0F00" $"00F0 6601 1111 0FFF F000 0000 000F 0F00" $"00F0 6601 DDFD 100F FF00 00C0 000F 0F00" $"00F0 6601 FD11 11CF FFF0 C000 C00F 0F00" $"00F0 6601 F1DD D1C0 FFF0 000F C00F 0F00" $"00F0 6600 D11D 1100 0FF0 0C00 000F 0F00" $"00F0 6660 011F 1100 FFC0 0000 0C0F 0F00" $"00F0 6660 0000 00CF F0C0 0C00 0C0F 0F00" $"00F0 6666 0000 00FF 0000 0C00 0C0F 0F00" $"00F0 6666 6000 CFF0 00C0 000F 0C0F 0F00" $"00F0 6666 60C0 FFC0 0000 000F 000F 0F00" $"00F0 6666 60CF F000 C00C 0CFF 000F 0F00" $"00F0 6666 60FF FFFF FFFF FFFF FFF0 0F00" $"00F0 6666 60FF FFFF FFFF F000 0F00 0F00" $"00F0 6666 6000 0000 0000 F000 F000 0F00" $"00F0 6666 6033 0CC0 0C00 F00F 0000 0F00" $"00F0 6666 6033 C0C0 0000 F0F0 0000 0F00" $"00F0 0000 0000 0000 0000 FF00 0000 0F00" $"00FF FFFF FFFF FFFF FFFF F000 0000 0F00" $"0000 F000 0000 0000 0000 0000 0000 0F00" $"0000 FFFF FFFF FFFF FFFF FFFF FFFF FF" }; resource 'icl4' (142) { $"0000 0000 0000 0000 0000 0000 0000 0000" $"6666 6000 0000 0000 D000 0000 0000 0000" $"6666 6000 0000 000D 6D00 0000 0000 0000" $"6666 6000 0000 00D0 D6D0 0000 0000 0000" $"6666 6000 0000 0D00 0D6D 0000 0000 0000" $"6666 6000 0000 DF00 D0D6 D000 0000 0000" $"6666 6000 000D F0CD 0F0D 6D00 0000 0000" $"6666 6000 00D0 0DD0 D00D D6D0 0000 0000" $"6666 6000 0DF0 0D00 0D0F 0D6D 0000 0000" $"6666 6000 D00C D000 00D0 00D6 D000 0000" $"6666 600D 000D 0000 000D 000D 6D00 0000" $"6666 60DF 00D0 0000 0000 D0FD D6D0 0000" $"6666 6D00 CD00 0000 0000 0D0F 0D6D 0000" $"6666 DF00 D000 00DD 0DDD D0D0 0DD6 D000" $"666D 000D 0000 DD0D D0DD FDDD 0F0D 6D00" $"66DF 00D0 000D 0D09 0606 7666 D000 D6D0" $"6D00 0D00 0D06 0070 1999 6966 6D00 0D6D" $"66D0 D000 D600 6D99 1999 9999 66D0 00D0" $"666D 000D D080 D991 1196 699D 996D 0D50" $"6666 D0D0 060D 9111 1111 9699 966F D500" $"6666 6DD0 D6D6 9991 1199 9996 999F F000" $"6666 6D00 6D07 9999 1969 9999 99F9 6000" $"6666 6DDD 0099 9999 1996 9996 969F 6F00" $"6666 D00D 6797 9969 9666 9999 99F6 9F00" $"6666 0D06 D669 9669 6669 9999 6999 6F00" $"6666 DD60 6666 6666 9999 9999 9966 6F00" $"6666 0606 6669 9999 6969 9999 6969 6F00" $"6666 D066 6699 9999 9699 9999 969F 6F00" $"6666 0606 6999 9999 9669 9999 66F9 FF00" $"6666 DD66 6999 9999 9669 9999 6996 FF00" $"6666 6066 6699 9999 9666 9969 666F F000" $"6666 6D76 6666 9999 6666 6666 66FF F0" }; resource 'FREF' (128) { 'APPL', 0, "" }; resource 'FREF' (129) { 'SW/©', 1, "" }; resource 'FREF' (130) { 'TEXT', 2, "" }; resource 'FREF' (131) { 'sW/©', 3, "" }; // Writer 2.0 resource 'FREF' (132) { 'SDwr', 4, "" }; // Writer 2.0 Vorlage resource 'FREF' (133) { 'SWwv', 5, "" }; // Excel resource 'FREF' (134) { 'XLS ', 6, "" }; resource 'FREF' (135) { 'RTF ', 7, "" }; // Word 6 resource 'FREF' (136) { 'W6BN', 8, "" }; resource 'FREF' (137) { 'SVsc', 9, "" }; resource 'FREF' (138) { 'sVsc', 10, "" }; resource 'FREF' (139) { 'SVsd', 11, "" }; resource 'FREF' (140) { 'sVsd', 12, "" }; resource 'FREF' (141) { 'SVsh', 13, "" }; resource 'FREF' (142) { 'sVsh', 14, "" }; resource 'FREF' (143) { 'SVsi', 15, "" }; resource 'FREF' (144) { 'sVsi', 16, "" }; resource 'FREF' (145) { 'SVsm', 17, "" }; resource 'FREF' (146) { 'sVsm', 18, "" }; resource 'FREF' (147) { 'SVfs', 19, "" }; resource 'BNDL' (128) { 'SVdt', 0, { /* array TypeArray: 2 elements */ /* [1] */ 'FREF', { /* array IDArray: 20 elements */ /* [1] */ 0, 128, /* [2] */ 1, 129, /* [3] */ 2, 130, /* [4] */ 3, 131, /* [5] */ 4, 132, /* [6] */ 5, 133, /* [7] */ 6, 134, /* [8] */ 7, 135, /* [9] */ 8, 136, /* [10] */ 9, 137, /* [11] */ 10, 138, /* [12] */ 11, 139, /* [13] */ 12, 140, /* [14] */ 13, 141, /* [15] */ 14, 142, /* [16] */ 15, 143, /* [17] */ 16, 144, /* [18] */ 17, 145, /* [19] */ 18, 146, /* [20] */ 19, 147 }, /* [2] */ 'ICN#', { /* array IDArray: 20 elements */ /* [1] */ 0, 128, /* [2] */ 1, 129, /* [3] */ 2, 131, /* [4] */ 3, 130, /* [5] */ 4, 0, /* [6] */ 5, 0, /* [7] */ 6, 0, /* [8] */ 7, 0, /* [9] */ 8, 0, /* [10] */ 9, 132, /* [11] */ 10, 133, /* [12] */ 11, 134, /* [13] */ 12, 135, /* [14] */ 13, 136, /* [15] */ 14, 137, /* [16] */ 15, 138, /* [17] */ 16, 139, /* [18] */ 17, 140, /* [19] */ 18, 141, /* [20] */ 19, 142 } } }; data 'cicn' (2001, "mrj bar") { $"0000 0000 8010 0000 0000 0020 0020 0000" $"0000 0000 0000 0048 0000 0048 0000 0000" $"0004 0001 0004 0000 0000 0000 0000 0000" $"0000 0000 0000 0004 0000 0000 0020 0020" $"0000 0000 0004 0000 0000 0020 0020 0000" $"0000 FC00 0000 FC00 0000 FC00 0000 FC00" $"0000 FC00 0000 FC00 0000 FC00 0000 FC00" $"0000 FC00 0000 FC00 0000 FC00 0000 FC00" $"0000 FC00 0000 FC00 0000 FC00 0000 FC00" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 FC00 0000 8400 0000 C400 0000 E400" $"0000 F400 0000 FC00 0000 9C00 0000 8C00" $"0000 C400 0000 E400 0000 F400 0000 FC00" $"0000 9C00 0000 8C00 0000 C400 0000 E400" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0007 0000 FFFF FFFF" $"FFFF 0001 FFFF FFFF 3333 0002 FFFF CCCC" $"0000 0003 3333 3333 3333 0004 4444 4444" $"4444 0005 2222 2222 2222 0006 1111 1111" $"1111 000F 0000 0000 0000 FFFF FF00 0000" $"0000 0000 0000 0000 0000 F122 4300 0000" $"0000 0000 0000 0000 0000 F422 2600 0000" $"0000 0000 0000 0000 0000 F5F2 2F00 0000" $"0000 0000 0000 0000 0000 F5FF FF00 0000" $"0000 0000 0000 0000 0000 F1FF FF00 0000" $"0000 0000 0000 0000 0000 F22F FF00 0000" $"0000 0000 0000 0000 0000 F222 FF00 0000" $"0000 0000 0000 0000 0000 F422 2F00 0000" $"0000 0000 0000 0000 0000 F5F2 2F00 0000" $"0000 0000 0000 0000 0000 F5FF FF00 0000" $"0000 0000 0000 0000 0000 F1FF FF00 0000" $"0000 0000 0000 0000 0000 F22F FF00 0000" $"0000 0000 0000 0000 0000 F222 FF00 0000" $"0000 0000 0000 0000 0000 F422 2F00 0000" $"0000 0000 0000 0000 0000 F5F2 2F00 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000" };
diff --git a/desktop/win32/source/applauncher/launcher.cxx b/desktop/win32/source/applauncher/launcher.cxx
new file mode 100644
index 000000000000..386fb7500655
--- /dev/null
+++ b/desktop/win32/source/applauncher/launcher.cxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+
+#ifndef _WINDOWS_
+# define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+# include <windows.h>
+# include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+
+#include <stdlib.h>
+#include <malloc.h>
+
+
+#ifdef __MINGW32__
+extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
+#else
+extern "C" int APIENTRY _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
+#endif
+{
+ // Retreive startup info
+
+ STARTUPINFO aStartupInfo;
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof( aStartupInfo );
+ GetStartupInfo( &aStartupInfo );
+
+ // Retrieve command line
+
+ LPTSTR lpCommandLine = GetCommandLine();
+
+ LPTSTR *ppArguments = NULL;
+ int nArguments = 0;
+
+ ppArguments = GetArgv( &nArguments );
+
+ // if ( 1 == nArguments )
+ {
+ lpCommandLine = (LPTSTR)_alloca( sizeof(_TCHAR) * (_tcslen(lpCommandLine) + _tcslen(APPLICATION_SWITCH) + 2) );
+
+ _tcscpy( lpCommandLine, GetCommandLine() );
+ _tcscat( lpCommandLine, _T(" ") );
+ _tcscat( lpCommandLine, APPLICATION_SWITCH );
+ }
+
+
+ // Calculate application name
+
+ TCHAR szApplicationName[MAX_PATH];
+ TCHAR szDrive[MAX_PATH];
+ TCHAR szDir[MAX_PATH];
+ TCHAR szFileName[MAX_PATH];
+ TCHAR szExt[MAX_PATH];
+
+ GetModuleFileName( NULL, szApplicationName, MAX_PATH );
+ _tsplitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
+ _tmakepath( szApplicationName, szDrive, szDir, OFFICE_IMAGE_NAME, _T(".exe") );
+
+ PROCESS_INFORMATION aProcessInfo;
+
+ BOOL fSuccess = CreateProcess(
+ szApplicationName,
+ lpCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ if ( fSuccess )
+ {
+ // Wait for soffice process to be terminated to allow other applications
+ // to wait for termination of started process
+
+ WaitForSingleObject( aProcessInfo.hProcess, INFINITE );
+
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+
+ return 0;
+ }
+
+ DWORD dwError = GetLastError();
+
+ LPVOID lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dwError,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ // Display the string.
+ MessageBox( NULL, (LPCTSTR)lpMsgBuf, NULL, MB_OK | MB_ICONERROR );
+
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+
+ return GetLastError();
+}
+
diff --git a/desktop/win32/source/applauncher/launcher.hxx b/desktop/win32/source/applauncher/launcher.hxx
new file mode 100644
index 000000000000..561b94a8f882
--- /dev/null
+++ b/desktop/win32/source/applauncher/launcher.hxx
@@ -0,0 +1,21 @@
+#pragma once
+#ifndef __cplusplus
+#error Need C++ to compile
+#endif
+
+#ifndef _INC_TCHAR
+# ifdef UNICODE
+# define _UNICODE
+# endif
+# include <tchar.h>
+#endif
+
+#ifdef UNICODE
+# define GetArgv( pArgc ) CommandLineToArgvW( GetCommandLine(), pArgc )
+#else
+# define GetArgv( pArgc ) (*pArgc = __argc, __argv)
+#endif
+
+#define OFFICE_IMAGE_NAME _T("soffice")
+
+extern _TCHAR APPLICATION_SWITCH[];
diff --git a/desktop/win32/source/applauncher/makefile.mk b/desktop/win32/source/applauncher/makefile.mk
new file mode 100644
index 000000000000..f0f5743f38a1
--- /dev/null
+++ b/desktop/win32/source/applauncher/makefile.mk
@@ -0,0 +1,148 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET=applauncher
+LIBTARGET=NO
+TARGETTYPE=GUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+CDEFS+=-DUNICODE
+
+
+OBJFILES= \
+ $(OBJ)$/launcher.obj \
+ $(OBJ)$/swriter.obj \
+ $(OBJ)$/scalc.obj \
+ $(OBJ)$/sdraw.obj \
+ $(OBJ)$/simpress.obj \
+ $(OBJ)$/sbase.obj \
+ $(OBJ)$/smath.obj \
+ $(OBJ)$/sweb.obj
+
+# SO launcher
+.IF "$(BUILD_SPECIAL)"!=""
+APP1DEPN= $(APP1RES) verinfo.rc
+APP1TARGET=so$/swriter
+APP1NOSAL=TRUE
+APP1LINKRES=$(MISC)$/$(TARGET)1.res
+APP1ICON=$(SOLARRESDIR)$/icons/so9_writer_app.ico
+APP1OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/swriter.obj
+APP1STDLIBS = $(SHELL32LIB)
+APP1VERINFO=verinfo.rc
+APP1PRODUCTDEF+=-DRES_APP_NAME=swriter
+
+APP2TARGET=so$/scalc
+APP2NOSAL=TRUE
+APP2LINKRES=$(MISC)$/$(TARGET)2.res
+APP2ICON=$(SOLARRESDIR)$/icons/so9_calc_app.ico
+APP2OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/scalc.obj
+APP2STDLIBS = $(SHELL32LIB)
+APP2DEPN=verinfo.rc
+APP2VERINFO=verinfo.rc
+APP2PRODUCTDEF+=-DRES_APP_NAME=scalc
+
+APP3TARGET=so$/sdraw
+APP3NOSAL=TRUE
+APP3LINKRES=$(MISC)$/$(TARGET)3.res
+APP3ICON=$(SOLARRESDIR)$/icons/so9_draw_app.ico
+APP3OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sdraw.obj
+APP3STDLIBS = $(SHELL32LIB)
+APP3DEPN=verinfo.rc
+APP3VERINFO=verinfo.rc
+APP3PRODUCTDEF+=-DRES_APP_NAME=sdraw
+
+APP4TARGET=so$/simpress
+APP4NOSAL=TRUE
+APP4LINKRES=$(MISC)$/$(TARGET)4.res
+APP4ICON=$(SOLARRESDIR)$/icons/so9_impress_app.ico
+APP4OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/simpress.obj
+APP4STDLIBS = $(SHELL32LIB)
+APP4DEPN=verinfo.rc
+APP4VERINFO=verinfo.rc
+APP4PRODUCTDEF+=-DRES_APP_NAME=simpress
+
+APP5TARGET=so$/sbase
+APP5NOSAL=TRUE
+APP5LINKRES=$(MISC)$/$(TARGET)5.res
+APP5ICON=$(SOLARRESDIR)$/icons/so9_base_app.ico
+APP5OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sbase.obj
+APP5STDLIBS = $(SHELL32LIB)
+APP5DEPN=verinfo.rc
+APP5VERINFO=verinfo.rc
+APP5PRODUCTDEF+=-DRES_APP_NAME=sbase
+
+APP6TARGET=so$/smath
+APP6NOSAL=TRUE
+APP6LINKRES=$(MISC)$/$(TARGET)6.res
+APP6ICON=$(SOLARRESDIR)$/icons/so9_math_app.ico
+APP6OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/smath.obj
+APP6STDLIBS = $(SHELL32LIB)
+APP6DEPN=verinfo.rc
+APP6VERINFO=verinfo.rc
+APP6PRODUCTDEF+=-DRES_APP_NAME=smath
+
+APP7TARGET=so$/sweb
+APP7NOSAL=TRUE
+APP7LINKRES=$(MISC)$/$(TARGET)7.res
+APP7ICON=$(SOLARRESDIR)$/icons/so9_writer_app.ico
+APP7OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sweb.obj
+APP7STDLIBS = $(SHELL32LIB)
+APP7DEPN=verinfo.rc
+APP7VERINFO=verinfo.rc
+APP7PRODUCTDEF+=-DRES_APP_NAME=sweb
+
+
+.ENDIF # "$(BUILD_SPECIAL)"!=""
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/applauncher/ooo/makefile.mk b/desktop/win32/source/applauncher/ooo/makefile.mk
new file mode 100644
index 000000000000..02f240cce9e0
--- /dev/null
+++ b/desktop/win32/source/applauncher/ooo/makefile.mk
@@ -0,0 +1,130 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+
+PRJNAME=desktop
+TARGET=applauncher
+LIBTARGET=NO
+TARGETTYPE=GUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+APP1TARGET=swriter
+APP1DEPN=verinfo.rc
+APP1VERINFO=verinfo.rc
+APP1NOSAL=TRUE
+APP1LINKRES=$(MISC)$/$(TARGET)1.res
+APP1ICON=$(SOLARRESDIR)$/icons/ooo3_writer_app.ico
+APP1OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/swriter.obj
+APP1STDLIBS = $(SHELL32LIB)
+APP1PRODUCTDEF+=-DRES_APP_NAME=$(APP1TARGET)
+
+APP2TARGET=scalc
+APP2DEPN=verinfo.rc
+APP2VERINFO=verinfo.rc
+APP2NOSAL=TRUE
+APP2LINKRES=$(MISC)$/$(TARGET)2.res
+APP2ICON=$(SOLARRESDIR)$/icons/ooo3_calc_app.ico
+APP2OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/scalc.obj
+APP2STDLIBS = $(SHELL32LIB)
+APP2PRODUCTDEF+=-DRES_APP_NAME=$(APP2TARGET)
+
+APP3TARGET=sdraw
+APP3DEPN=verinfo.rc
+APP3VERINFO=verinfo.rc
+APP3NOSAL=TRUE
+APP3LINKRES=$(MISC)$/$(TARGET)3.res
+APP3ICON=$(SOLARRESDIR)$/icons/ooo3_draw_app.ico
+APP3OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sdraw.obj
+APP3STDLIBS = $(SHELL32LIB)
+APP3PRODUCTDEF+=-DRES_APP_NAME=$(APP3TARGET)
+
+APP4TARGET=simpress
+APP4DEPN=verinfo.rc
+APP4VERINFO=verinfo.rc
+APP4NOSAL=TRUE
+APP4LINKRES=$(MISC)$/$(TARGET)4.res
+APP4ICON=$(SOLARRESDIR)$/icons/ooo3_impress_app.ico
+APP4OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/simpress.obj
+APP4STDLIBS = $(SHELL32LIB)
+APP4PRODUCTDEF+=-DRES_APP_NAME=$(APP4TARGET)
+
+APP5TARGET=smath
+APP5DEPN=verinfo.rc
+APP5VERINFO=verinfo.rc
+APP5NOSAL=TRUE
+APP5LINKRES=$(MISC)$/$(TARGET)5.res
+APP5ICON=$(SOLARRESDIR)$/icons/ooo3_math_app.ico
+APP5OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/smath.obj
+APP5STDLIBS = $(SHELL32LIB)
+APP5PRODUCTDEF+=-DRES_APP_NAME=$(APP5TARGET)
+
+APP6TARGET=sbase
+APP6DEPN=verinfo.rc
+APP6VERINFO=verinfo.rc
+APP6NOSAL=TRUE
+APP6LINKRES=$(MISC)$/$(TARGET)6.res
+APP6ICON=$(SOLARRESDIR)$/icons/ooo3_base_app.ico
+APP6OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sbase.obj
+APP6STDLIBS = $(SHELL32LIB)
+APP6PRODUCTDEF+=-DRES_APP_NAME=$(APP6TARGET)
+
+APP7TARGET=sweb
+APP7DEPN=verinfo.rc
+APP7VERINFO=verinfo.rc
+APP7NOSAL=TRUE
+APP7LINKRES=$(MISC)$/$(TARGET)7.res
+APP7ICON=$(SOLARRESDIR)$/icons/ooo3_writer_app.ico
+APP7OBJS = \
+ $(OBJ)$/launcher.obj\
+ $(OBJ)$/sweb.obj
+APP7STDLIBS = $(SHELL32LIB)
+APP7PRODUCTDEF+=-DRES_APP_NAME=$(APP7TARGET)
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/applauncher/ooo/verinfo.rc b/desktop/win32/source/applauncher/ooo/verinfo.rc
new file mode 100644
index 000000000000..ce698ba80333
--- /dev/null
+++ b/desktop/win32/source/applauncher/ooo/verinfo.rc
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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(ENGLISH)
+#define LG_D // generate always german version
+#endif
+
+#define VER_FIRSTYEAR 2009
+
+#include <windows.h>
+#include "version.hrc"
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+#ifndef WIN32
+ fileos VOS_DOS_WINDOWS16
+#else
+ fileos VOS_NT_WINDOWS32
+#endif
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+#ifdef LG_D
+ block "040704E4"
+ {
+ // German StringTable
+ value "CompanyName", "OpenOffice.org\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", PPS(RES_APP_NAME) ".exe\0"
+ value "InternalName", PPS(RES_APP_NAME) "\0"
+ value "LegalCopyright", S_CRIGHT " Sun Microsystems, Inc.\0"
+ }
+#else
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "OpenOffice.org\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", PPS(RES_APP_NAME) ".exe\0"
+ value "InternalName", PPS(RES_APP_NAME) "\0"
+ value "LegalCopyright", S_CRIGHT " Sun Microsystems, Inc.\0"
+ }
+#endif
+ }
+
+ block "VarFileInfo"
+ {
+#ifdef LG_D
+ value "Translation", 0x0407, 1252
+#else
+ value "Translation", 0x0409, 1252
+#endif
+ }
+ }
diff --git a/desktop/win32/source/applauncher/sbase.cxx b/desktop/win32/source/applauncher/sbase.cxx
new file mode 100644
index 000000000000..8f50963ca3ff
--- /dev/null
+++ b/desktop/win32/source/applauncher/sbase.cxx
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-base" );
diff --git a/desktop/win32/source/applauncher/scalc.cxx b/desktop/win32/source/applauncher/scalc.cxx
new file mode 100644
index 000000000000..5795cb91d491
--- /dev/null
+++ b/desktop/win32/source/applauncher/scalc.cxx
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-calc" );
diff --git a/desktop/win32/source/applauncher/sdraw.cxx b/desktop/win32/source/applauncher/sdraw.cxx
new file mode 100644
index 000000000000..63061aa4994b
--- /dev/null
+++ b/desktop/win32/source/applauncher/sdraw.cxx
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-draw" );
diff --git a/desktop/win32/source/applauncher/simpress.cxx b/desktop/win32/source/applauncher/simpress.cxx
new file mode 100644
index 000000000000..c3ff3f697225
--- /dev/null
+++ b/desktop/win32/source/applauncher/simpress.cxx
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-impress" );
diff --git a/desktop/win32/source/applauncher/smath.cxx b/desktop/win32/source/applauncher/smath.cxx
new file mode 100644
index 000000000000..c5574cdb26be
--- /dev/null
+++ b/desktop/win32/source/applauncher/smath.cxx
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-math" );
diff --git a/desktop/win32/source/applauncher/sweb.cxx b/desktop/win32/source/applauncher/sweb.cxx
new file mode 100644
index 000000000000..a8728f0a1f72
--- /dev/null
+++ b/desktop/win32/source/applauncher/sweb.cxx
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-web" );
diff --git a/desktop/win32/source/applauncher/swriter.cxx b/desktop/win32/source/applauncher/swriter.cxx
new file mode 100644
index 000000000000..21919e0f3bca
--- /dev/null
+++ b/desktop/win32/source/applauncher/swriter.cxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "launcher.hxx"
+
+_TCHAR APPLICATION_SWITCH[] = _T( "-writer" );
diff --git a/desktop/win32/source/applauncher/verinfo.rc b/desktop/win32/source/applauncher/verinfo.rc
new file mode 100644
index 000000000000..0db55c58c4b2
--- /dev/null
+++ b/desktop/win32/source/applauncher/verinfo.rc
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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(ENGLISH)
+#define LG_D // generate always german version
+#endif
+
+#define VER_FIRSTYEAR 2009
+
+#include <windows.h>
+#include "version_so.hrc"
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+#ifndef SUBVERSION
+ fileversion VERSION, 0, VERVARIANT, VER_COUNT
+ productversion VERSION, 0, VERVARIANT, VER_COUNT
+#else
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+#endif
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+#ifndef WIN32
+ fileos VOS_DOS_WINDOWS16
+#else
+ fileos VOS_NT_WINDOWS32
+#endif
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+#ifdef LG_D
+ block "040704E4"
+ {
+ // German StringTable
+ value "CompanyName", "Sun Microsystems, Inc.\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", PPS(RES_APP_NAME) ".exe\0"
+ value "InternalName", PPS(RES_APP_NAME) "\0"
+ value "LegalCopyright", S_CRIGHT " Sun Microsystems, Inc.\0"
+ }
+#else
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "Sun Microsystems, Inc.\0"
+ value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", PPS(RES_APP_NAME) ".exe\0"
+ value "InternalName", PPS(RES_APP_NAME) "\0"
+ value "LegalCopyright", S_CRIGHT " Sun Microsystems, Inc.\0"
+ }
+#endif
+ }
+
+ block "VarFileInfo"
+ {
+#ifdef LG_D
+ value "Translation", 0x0407, 1252
+#else
+ value "Translation", 0x0409, 1252
+#endif
+ }
+ }
diff --git a/desktop/win32/source/extendloaderenvironment.cxx b/desktop/win32/source/extendloaderenvironment.cxx
new file mode 100644
index 000000000000..0092f04549f9
--- /dev/null
+++ b/desktop/win32/source/extendloaderenvironment.cxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "precompiled_desktop.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shlwapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include "tools/pathutils.hxx"
+
+#include "extendloaderenvironment.hxx"
+
+namespace {
+
+void fail() {
+ LPWSTR buf = NULL;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL);
+ MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR);
+ LocalFree(buf);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+bool contains(WCHAR const * paths, WCHAR const * path, WCHAR const * pathEnd) {
+ WCHAR const * q = path;
+ for (WCHAR const * p = paths;; ++p) {
+ WCHAR c = *p;
+ switch (c) {
+ case L'\0':
+ return q == pathEnd;
+ case L';':
+ if (q == pathEnd) {
+ return true;
+ }
+ q = path;
+ break;
+ default:
+ if (q != NULL) {
+ if (q != pathEnd && *q == c) {
+ ++q;
+ } else {
+ q = NULL;
+ }
+ }
+ break;
+ }
+ }
+}
+
+}
+
+namespace desktop_win32 {
+
+void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory) {
+ if (!GetModuleFileNameW(NULL, iniDirectory, MAX_PATH)) {
+ fail();
+ }
+ WCHAR * iniDirEnd = tools::filename(iniDirectory);
+ WCHAR name[MAX_PATH + MY_LENGTH(L".bin")];
+ // hopefully std::size_t is large enough to not overflow
+ WCHAR * nameEnd = name;
+ for (WCHAR * p = iniDirEnd; *p != L'\0'; ++p) {
+ *nameEnd++ = *p;
+ }
+ if (!(nameEnd - name >= 4 && nameEnd[-4] == L'.' &&
+ (nameEnd[-3] == L'E' || nameEnd[-3] == L'e') &&
+ (nameEnd[-2] == L'X' || nameEnd[-2] == L'x') &&
+ (nameEnd[-1] == L'E' || nameEnd[-1] == L'e')))
+ {
+ *nameEnd = L'.';
+ nameEnd += 4;
+ }
+ nameEnd[-3] = 'b';
+ nameEnd[-2] = 'i';
+ nameEnd[-1] = 'n';
+ tools::buildPath(binPath, iniDirectory, iniDirEnd, name, nameEnd - name);
+ *iniDirEnd = L'\0';
+ WCHAR path[MAX_PATH];
+ WCHAR * pathEnd = tools::buildPath(
+ path, iniDirectory, iniDirEnd, MY_STRING(L"..\\basis-link"));
+ if (pathEnd == NULL) {
+ fail();
+ }
+ std::size_t const maxEnv = 32767;
+ WCHAR pad[2 * MAX_PATH + maxEnv];
+ // hopefully std::size_t is large enough to not overflow
+ WCHAR * padEnd = NULL;
+ WCHAR env[maxEnv];
+ DWORD n = GetEnvironmentVariableW(L"PATH", env, maxEnv);
+ if (n >= maxEnv || n == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
+ fail();
+ }
+ env[n] = L'\0';
+ bool exclude1;
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ fail();
+ }
+ // This path is only taken by testtool.exe in basis program directory;
+ // its PATH needs to include the brand program directory:
+ pathEnd = tools::buildPath(
+ path, iniDirectory, iniDirEnd, MY_STRING(L".."));
+ if (pathEnd == NULL) {
+ fail();
+ }
+ padEnd = tools::buildPath(
+ pad, path, pathEnd, MY_STRING(L"\\..\\program"));
+ if (padEnd == NULL) {
+ fail();
+ }
+ exclude1 = contains(env, pad, padEnd);
+ } else {
+ exclude1 = true;
+ }
+ WCHAR * pad2 = exclude1 ? pad : padEnd + 1;
+ pathEnd = tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link"));
+ if (pathEnd == NULL) {
+ fail();
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ fail();
+ }
+ padEnd = tools::buildPath(pad2, path, pathEnd, MY_STRING(L"\\bin"));
+ if (padEnd == NULL) {
+ fail();
+ }
+ bool exclude2 = contains(env, pad2, padEnd);
+ if (!(exclude1 && exclude2)) {
+ if (!(exclude1 || exclude2)) {
+ pad2[-1] = L';';
+ }
+ WCHAR * p = exclude2 ? pad2 - 1 : padEnd;
+ if (n != 0) {
+ *p++ = L';';
+ }
+ for (DWORD i = 0; i <= n; ++i) {
+ *p++ = env[i];
+ }
+ if (!SetEnvironmentVariableW(L"PATH", pad)) {
+ fail();
+ }
+ }
+}
+
+}
diff --git a/desktop/win32/source/extendloaderenvironment.hxx b/desktop/win32/source/extendloaderenvironment.hxx
new file mode 100644
index 000000000000..ba90a1b7bd7e
--- /dev/null
+++ b/desktop/win32/source/extendloaderenvironment.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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_WIN32_SOURCE_EXTENDLOADERENVIRONMENT_HXX
+#define INCLUDED_DESKTOP_WIN32_SOURCE_EXTENDLOADERENVIRONMENT_HXX
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include <tchar.h>
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+
+namespace desktop_win32 {
+
+inline WCHAR * commandLineAppend(
+ WCHAR * buffer, WCHAR const * text, std::size_t length)
+{
+ wcsncpy(buffer, text, length + 1); // trailing null
+ return buffer + length;
+}
+
+inline WCHAR * commandLineAppend(WCHAR * buffer, WCHAR const * text) {
+ return commandLineAppend(buffer, text, wcslen(text));
+}
+
+inline WCHAR * commandLineAppendEncoded(WCHAR * buffer, WCHAR const * text) {
+ std::size_t n = 0;
+ for (;;) {
+ WCHAR c = *text++;
+ if (c == L'\0') {
+ break;
+ } else if (c == L'$') {
+ buffer = commandLineAppend(buffer, MY_STRING(L"\\$"));
+ n = 0;
+ } else if (c == L'\\') {
+ buffer = commandLineAppend(buffer, MY_STRING(L"\\\\"));
+ n += 2;
+ } else {
+ *buffer++ = c;
+ n = 0;
+ }
+ }
+ // The command line will continue with a double quote, so double any
+ // preceding backslashes as required by Windows:
+ for (std::size_t i = 0; i < n; ++i) {
+ *buffer++ = L'\\';
+ }
+ *buffer = L'\0';
+ return buffer;
+}
+
+// Set the PATH environment variable in the current (loader) process, so that a
+// following CreateProcess has the necessary environment:
+//
+// @param binPath
+// Must point to an array of size at least MAX_PATH. Is filled with the null
+// terminated full path to the "bin" file corresponding to the current
+// executable.
+//
+// @param iniDirectory
+// Must point to an array of size at least MAX_PATH. Is filled with the null
+// terminated full directory path (ending in "\") to the "ini" file
+// corresponding to the current executable.
+void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory);
+
+}
+
+#endif
diff --git a/desktop/win32/source/guiloader/genericloader.cxx b/desktop/win32/source/guiloader/genericloader.cxx
new file mode 100644
index 000000000000..1322c196d8a0
--- /dev/null
+++ b/desktop/win32/source/guiloader/genericloader.cxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+#define UNICODE
+#define _UNICODE
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <tchar.h>
+
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <systools/win32/uwinapi.h>
+
+#include "tools/pathutils.hxx"
+#include "../extendloaderenvironment.hxx"
+
+//---------------------------------------------------------------------------
+
+static int GenericMain()
+{
+ TCHAR szTargetFileName[MAX_PATH];
+ TCHAR szIniDirectory[MAX_PATH];
+ STARTUPINFO aStartupInfo;
+
+ desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof(aStartupInfo);
+
+ GetStartupInfo( &aStartupInfo );
+
+ DWORD dwExitCode = (DWORD)-1;
+
+ PROCESS_INFORMATION aProcessInfo;
+
+ size_t iniDirLen = wcslen(szIniDirectory);
+ WCHAR cwd[MAX_PATH];
+ DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd);
+ if (cwdLen >= MAX_PATH) {
+ cwdLen = 0;
+ }
+ WCHAR redirect[MAX_PATH];
+ DWORD dummy;
+ bool hasRedirect =
+ tools::buildPath(
+ redirect, szIniDirectory, szIniDirectory + iniDirLen,
+ MY_STRING(L"redirect.ini")) != NULL &&
+ (GetBinaryType(redirect, &dummy) || // cheaper check for file existence?
+ GetLastError() != ERROR_FILE_NOT_FOUND);
+ LPTSTR cl1 = GetCommandLine();
+ WCHAR * cl2 = new WCHAR[
+ wcslen(cl1) +
+ (hasRedirect
+ ? (MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") +
+ iniDirLen + MY_LENGTH(L"redirect.ini\""))
+ : 0) +
+ MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + MY_LENGTH(L"\"") + 1];
+ // 4 * cwdLen: each char preceded by backslash, each trailing backslash
+ // doubled
+ WCHAR * p = desktop_win32::commandLineAppend(cl2, cl1);
+ if (hasRedirect) {
+ p = desktop_win32::commandLineAppend(
+ p, MY_STRING(L" \"-env:INIFILENAME=vnd.sun.star.pathname:"));
+ p = desktop_win32::commandLineAppend(p, szIniDirectory);
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"redirect.ini\""));
+ }
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L" \"-env:OOO_CWD="));
+ if (cwdLen == 0) {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"0"));
+ } else {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"2"));
+ p = desktop_win32::commandLineAppendEncoded(p, cwd);
+ }
+ desktop_win32::commandLineAppend(p, MY_STRING(L"\""));
+
+ BOOL fSuccess = CreateProcess(
+ szTargetFileName,
+ cl2,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ szIniDirectory,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ delete[] cl2;
+
+ if ( fSuccess )
+ {
+ DWORD dwWaitResult;
+
+ do
+ {
+ // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so
+ // as if we where processing any messages
+
+ dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS );
+
+ if ( WAIT_OBJECT_0 + 1 == dwWaitResult )
+ {
+ MSG msg;
+
+ PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
+ }
+ } while ( WAIT_OBJECT_0 + 1 == dwWaitResult );
+
+ dwExitCode = 0;
+ GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
+
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+ }
+
+ return dwExitCode;
+}
+
+//---------------------------------------------------------------------------
+
+#ifdef __MINGW32__
+int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
+#else
+int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
+#endif
+{
+ return GenericMain();
+}
+
+//---------------------------------------------------------------------------
+
+#ifdef __MINGW32__
+int __cdecl main()
+#else
+int __cdecl _tmain()
+#endif
+{
+ return GenericMain();
+}
+
diff --git a/desktop/win32/source/guiloader/makefile.mk b/desktop/win32/source/guiloader/makefile.mk
new file mode 100644
index 000000000000..5bb1c523ff19
--- /dev/null
+++ b/desktop/win32/source/guiloader/makefile.mk
@@ -0,0 +1,64 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET=guiloader
+LIBTARGET=NO
+TARGETTYPE=GUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+APP1TARGET=guiloader
+APP1NOSAL=TRUE
+APP1ICON=$(SOLARRESDIR)$/icons/ooo-main-app.ico
+APP1OBJS=\
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/genericloader.obj \
+ $(SOLARLIBDIR)$/pathutils-obj.obj
+STDLIB1=$(SHLWAPILIB)
+
+APP2TARGET=so$/guiloader
+APP2NOSAL=TRUE
+APP2ICON=$(SOLARRESDIR)$/icons/so8-main-app.ico
+APP2OBJS=\
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/genericloader.obj \
+ $(SOLARLIBDIR)$/pathutils-obj.obj
+STDLIB2=$(SHLWAPILIB)
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/guistdio/guistdio.cxx b/desktop/win32/source/guistdio/guistdio.cxx
new file mode 100644
index 000000000000..4a0518a75736
--- /dev/null
+++ b/desktop/win32/source/guistdio/guistdio.cxx
@@ -0,0 +1,30 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "precompiled_desktop.hxx"
+
+#include "guistdio.inc"
diff --git a/desktop/win32/source/guistdio/guistdio.inc b/desktop/win32/source/guistdio/guistdio.inc
new file mode 100644
index 000000000000..7f2bbe9002d8
--- /dev/null
+++ b/desktop/win32/source/guistdio/guistdio.inc
@@ -0,0 +1,453 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#define UNICODE
+#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
+
+#define _UNICODE
+#include <tchar.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <systools/win32/uwinapi.h>
+
+#include <stdio.h>
+
+#ifdef UNOPKG
+
+DWORD passOutputToConsole(HANDLE readPipe, HANDLE console)
+{
+ BYTE aBuffer[1024];
+ DWORD dwRead = 0;
+ HANDLE hReadPipe = readPipe;
+ BOOL fSuccess;
+ DWORD dwWritten;
+
+ //Indicates that we read an odd number of bytes. That is, we only read half of the last
+ //wchar_t
+ bool bIncompleteWchar = false;
+ //fprintf, fwprintf will both send char data without the terminating zero.
+ //fwprintf converts the unicode string first.
+ //We expect here to receive unicode without the terminating zero.
+ //unopkg and the extension manager code MUST
+ //use dp_misc::writeConsole instead of using fprintf, etc.
+
+ DWORD dwToRead = sizeof(aBuffer);
+ BYTE * pBuffer = aBuffer;
+ while ( ReadFile( hReadPipe, pBuffer, dwToRead, &dwRead, NULL ) )
+ {
+ //If the previous ReadFile call read an odd number of bytes, then the last one was
+ //put at the front of the buffer. We increase the number of read bytes by one to reflect
+ //that one byte.
+ if (bIncompleteWchar)
+ dwRead++;
+ //We must make sure that only complete wchar_t|s are written. WriteConsolse takes
+ //the number of wchar_t|s as argument. ReadFile, however, reads bytes.
+ bIncompleteWchar = dwRead % 2 ? true : false;
+ if (bIncompleteWchar)
+ {
+ //To test this case, give aBuffer a small odd size, e.g. aBuffer[3]
+ //The last byte, which is the incomplete wchar_t (half of it), will not be written.
+ fSuccess = WriteConsoleW( console, aBuffer,
+ (dwRead - 1) / 2, &dwWritten, NULL );
+
+ //Move the last byte to the front of the buffer, so that it is the start of the
+ //next string
+ aBuffer[0] = aBuffer[dwRead - 1];
+
+ //Make sure that ReadFile does not overwrite the first byte the next time
+ dwToRead = sizeof(aBuffer) - 1;
+ pBuffer = aBuffer + 1;
+
+ }
+ else
+ { //We have read an even number of bytes. Therefore, we do not put the last incomplete
+ //wchar_t at the front of the buffer. We will use the complete buffer the next time
+ //when ReadFile is called.
+ dwToRead = sizeof(aBuffer);
+ pBuffer = aBuffer;
+ fSuccess = WriteConsoleW( console,
+ aBuffer, dwRead / 2, &dwWritten, NULL );
+ }
+ }
+
+ return 0;
+}
+
+#endif
+
+#ifdef UNOPKG
+DWORD WINAPI OutputThread( LPVOID pParam )
+{
+ return passOutputToConsole((HANDLE)pParam, GetStdHandle( STD_OUTPUT_HANDLE ));
+}
+
+#else
+DWORD WINAPI OutputThread( LPVOID pParam )
+{
+ BYTE aBuffer[256];
+ DWORD dwRead = 0;
+ HANDLE hReadPipe = (HANDLE)pParam;
+ while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
+ {
+ BOOL fSuccess;
+ DWORD dwWritten;
+
+ fSuccess = WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), aBuffer, dwRead, &dwWritten, NULL );
+ }
+
+ return 0;
+}
+#endif
+//---------------------------------------------------------------------------
+// Thread that reads from child process standard error pipe
+//---------------------------------------------------------------------------
+
+#ifdef UNOPKG
+DWORD WINAPI ErrorThread( LPVOID pParam )
+{
+ return passOutputToConsole((HANDLE)pParam, GetStdHandle( STD_ERROR_HANDLE ));
+}
+
+#else
+DWORD WINAPI ErrorThread( LPVOID pParam )
+{
+ BYTE aBuffer[256];
+ DWORD dwRead = 0;
+ HANDLE hReadPipe = (HANDLE)pParam;
+
+ while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
+ {
+ BOOL fSuccess;
+ DWORD dwWritten;
+
+ fSuccess = WriteFile( GetStdHandle( STD_ERROR_HANDLE ), aBuffer, dwRead, &dwWritten, NULL );
+ }
+
+ return 0;
+}
+#endif
+//---------------------------------------------------------------------------
+// Thread that writes to child process standard input pipe
+//---------------------------------------------------------------------------
+#ifdef UNOPKG
+
+DWORD WINAPI InputThread( LPVOID pParam )
+{
+ DWORD dwRead = 0;
+ HANDLE hWritePipe = (HANDLE)pParam;
+
+ //We need to read in the complete input until we encounter a new line before
+ //converting to Unicode. This is necessary because the input string can use
+ //characters of one, two, and more bytes. If the last character is not
+ //complete, then it will not be converted properly.
+
+ //Find out how a new line (0xd 0xa) looks like with the used code page.
+ //Characters may have one or multiple bytes and different byte ordering
+ //can be used (little and big endian);
+ int cNewLine = WideCharToMultiByte(
+ GetConsoleCP(), 0, L"\r\n", 2, NULL, 0, NULL, NULL);
+ char * mbBuff = new char[cNewLine];
+ WideCharToMultiByte(
+ GetConsoleCP(), 0, L"\r\n", 2, mbBuff, cNewLine, NULL, NULL);
+
+ const size_t dwBufferSize = 256;
+ char* readBuf = (char*) malloc(dwBufferSize);
+ int readAll = 0;
+ size_t curBufSize = dwBufferSize;
+
+ while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ),
+ readBuf + readAll,
+ curBufSize - readAll, &dwRead, NULL ) )
+ {
+ readAll += dwRead;
+ int lastBufSize = curBufSize;
+ //Grow the buffer if necessary
+ if (readAll > curBufSize * 0.7)
+ {
+ curBufSize *= 2;
+ readBuf = (char *) realloc(readBuf, curBufSize);
+ }
+
+ //If the buffer was filled completely then
+ //there could be more input coming. But if we read from the console
+ //and the console input fits exactly in the buffer, then the next
+ //ReadFile would block until the users presses return, etc.
+ //Therefor we check if last character is a new line.
+ //To test this, set dwBufferSize to 4 and enter "no". This should produce
+ //4 bytes with most code pages.
+ if ( readAll == lastBufSize
+ && memcmp(readBuf + lastBufSize - cNewLine, mbBuff, cNewLine) != 0)
+ {
+ //The buffer was completely filled and the last byte(s) are no
+ //new line, so there is more to come.
+ continue;
+ }
+ //Obtain the size of the buffer for the converted string.
+ int sizeWBuf = MultiByteToWideChar(
+ GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, NULL, 0);
+
+ wchar_t * wideBuf = new wchar_t[sizeWBuf];
+
+ //Do the conversion.
+ MultiByteToWideChar(
+ GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, wideBuf, sizeWBuf);
+
+ BOOL fSuccess;
+ DWORD dwWritten;
+ fSuccess = WriteFile( hWritePipe, wideBuf, sizeWBuf * 2, &dwWritten, NULL );
+ delete[] wideBuf;
+ readAll = 0;
+ }
+ delete[] mbBuff;
+ free(readBuf);
+ return 0;
+}
+#else
+DWORD WINAPI InputThread( LPVOID pParam )
+{
+ BYTE aBuffer[256];
+ DWORD dwRead = 0;
+ HANDLE hWritePipe = (HANDLE)pParam;
+
+ while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ), &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
+ {
+ BOOL fSuccess;
+ DWORD dwWritten;
+
+ fSuccess = WriteFile( hWritePipe, aBuffer, dwRead, &dwWritten, NULL );
+ }
+
+ return 0;
+}
+#endif
+
+//---------------------------------------------------------------------------
+// Thread that waits until child process reached input idle
+//---------------------------------------------------------------------------
+
+DWORD WINAPI WaitForUIThread( LPVOID pParam )
+{
+ HANDLE hProcess = (HANDLE)pParam;
+
+#ifndef UNOPKG
+ if ( !_tgetenv( TEXT("UNOPKG") ) )
+ WaitForInputIdle( hProcess, INFINITE );
+#endif
+
+ return 0;
+}
+
+
+//---------------------------------------------------------------------------
+// Ctrl-Break handler that terminates the child process if Ctrl-C was pressed
+//---------------------------------------------------------------------------
+
+HANDLE hTargetProcess = INVALID_HANDLE_VALUE;
+
+BOOL WINAPI CtrlBreakHandler(
+ DWORD // control signal type
+)
+{
+ TerminateProcess( hTargetProcess, 255 );
+ return TRUE;
+}
+
+
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+
+#ifdef __MINGW32__
+int main( int, char ** )
+#else
+int _tmain( int, _TCHAR ** )
+#endif
+{
+ TCHAR szTargetFileName[MAX_PATH] = TEXT("");
+ STARTUPINFO aStartupInfo;
+ PROCESS_INFORMATION aProcessInfo;
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof(aStartupInfo);
+ aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
+
+ // Create an output pipe where the write end is inheritable
+
+ HANDLE hOutputRead, hOutputWrite;
+
+ if ( CreatePipe( &hOutputRead, &hOutputWrite, NULL, 0 ) )
+ {
+ HANDLE hTemp;
+
+ DuplicateHandle( GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ CloseHandle( hOutputWrite );
+ hOutputWrite = hTemp;
+
+ aStartupInfo.hStdOutput = hOutputWrite;
+ }
+
+ // Create an error pipe where the write end is inheritable
+
+ HANDLE hErrorRead, hErrorWrite;
+
+ if ( CreatePipe( &hErrorRead, &hErrorWrite, NULL, 0 ) )
+ {
+ HANDLE hTemp;
+
+ DuplicateHandle( GetCurrentProcess(), hErrorWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ CloseHandle( hErrorWrite );
+ hErrorWrite = hTemp;
+
+ aStartupInfo.hStdError = hErrorWrite;
+ }
+
+ // Create an input pipe where the read end is inheritable
+
+ HANDLE hInputRead, hInputWrite;
+
+ if ( CreatePipe( &hInputRead, &hInputWrite, NULL, 0 ) )
+ {
+ HANDLE hTemp;
+
+ DuplicateHandle( GetCurrentProcess(), hInputRead, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
+ CloseHandle( hInputRead );
+ hInputRead = hTemp;
+
+ aStartupInfo.hStdInput = hInputRead;
+ }
+
+ // Get image path with same name but with .exe extension
+
+ TCHAR szModuleFileName[MAX_PATH];
+
+ GetModuleFileName( NULL, szModuleFileName, MAX_PATH );
+ _TCHAR *lpLastDot = _tcsrchr( szModuleFileName, '.' );
+ if ( lpLastDot && 0 == _tcsicmp( lpLastDot, _T(".COM") ) )
+ {
+ size_t len = lpLastDot - szModuleFileName;
+ _tcsncpy( szTargetFileName, szModuleFileName, len );
+ _tcsncpy( szTargetFileName + len, _T(".EXE"), sizeof(szTargetFileName)/sizeof(szTargetFileName[0]) - len );
+ }
+
+ // Create process with same command line, environment and stdio handles which
+ // are directed to the created pipes
+
+ BOOL fSuccess = CreateProcess(
+ szTargetFileName,
+ GetCommandLine(),
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ if ( fSuccess )
+ {
+ // These pipe ends are inherited by the child process and no longer used
+ CloseHandle( hOutputWrite );
+ CloseHandle( hErrorWrite );
+ CloseHandle( hInputRead );
+
+ // Set the Ctrl-Break handler
+ hTargetProcess = aProcessInfo.hProcess;
+ SetConsoleCtrlHandler( CtrlBreakHandler, TRUE );
+
+ // Create threads that redirect remote pipe io to current process's console stdio
+
+ DWORD dwOutputThreadId, dwErrorThreadId, dwInputThreadId;
+
+ HANDLE hOutputThread = CreateThread( NULL, 0, OutputThread, (LPVOID)hOutputRead, 0, &dwOutputThreadId );
+ HANDLE hErrorThread = CreateThread( NULL, 0, OutputThread, (LPVOID)hErrorRead, 0, &dwErrorThreadId );
+ HANDLE hInputThread = CreateThread( NULL, 0, InputThread, (LPVOID)hInputWrite, 0, &dwInputThreadId );
+
+ // Create thread that wait until child process entered input idle
+
+ DWORD dwWaitForUIThreadId;
+ HANDLE hWaitForUIThread = CreateThread( NULL, 0, WaitForUIThread, (LPVOID)aProcessInfo.hProcess, 0, &dwWaitForUIThreadId );
+
+ DWORD dwWaitResult;
+ HANDLE hObjects[] =
+ {
+ hTargetProcess,
+ hWaitForUIThread,
+ hOutputThread,
+ hErrorThread
+ };
+
+ #ifdef UNOPKG
+ dwWaitResult = WaitForMultipleObjects( elementsof(hObjects), hObjects, TRUE, INFINITE );
+ #else
+ bool bDetach = false;
+ int nOpenPipes = 2;
+ do
+ {
+ dwWaitResult = WaitForMultipleObjects( elementsof(hObjects), hObjects, FALSE, INFINITE );
+
+ switch ( dwWaitResult )
+ {
+ case WAIT_OBJECT_0: // The child process has terminated
+ case WAIT_OBJECT_0 + 1: // The child process entered input idle
+ bDetach = true;
+ break;
+ case WAIT_OBJECT_0 + 2: // The remote end of stdout pipe was closed
+ case WAIT_OBJECT_0 + 3: // The remote end of stderr pipe was closed
+ bDetach = --nOpenPipes <= 0;
+ break;
+ default: // Something went wrong
+ bDetach = true;
+ break;
+ }
+ } while( !bDetach );
+
+#endif
+
+ CloseHandle( hOutputThread );
+ CloseHandle( hErrorThread );
+ CloseHandle( hInputThread );
+ CloseHandle( hWaitForUIThread );
+
+ DWORD dwExitCode = 0;
+ GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+
+ return dwExitCode;
+ }
+
+ return -1;
+}
diff --git a/desktop/win32/source/guistdio/makefile.mk b/desktop/win32/source/guistdio/makefile.mk
new file mode 100644
index 000000000000..660a48bcdca9
--- /dev/null
+++ b/desktop/win32/source/guistdio/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET=guistdio
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+TARGETTYPE=CUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+CFLAGS+= $(LFS_CFLAGS)
+CXXFLAGS+= $(LFS_CFLAGS)
+
+# --- Files --------------------------------------------------------
+
+OBJFILES=$(APP1OBJS) $(APP2OBJS)
+
+APP1NOSAL=TRUE
+APP1OBJS=$(OBJ)$/guistdio.obj
+APP1TARGET=$(TARGET)
+
+APP2NOSAL=TRUE
+APP2OBJS=$(OBJ)$/unopkgio.obj
+APP2TARGET=unopkgio
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/desktop/win32/source/guistdio/unopkgio.cxx b/desktop/win32/source/guistdio/unopkgio.cxx
new file mode 100644
index 000000000000..59701d08e1ff
--- /dev/null
+++ b/desktop/win32/source/guistdio/unopkgio.cxx
@@ -0,0 +1,31 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "precompiled_desktop.hxx"
+
+#define UNOPKG
+#include "guistdio.inc"
diff --git a/desktop/win32/source/lwrapa.cxx b/desktop/win32/source/lwrapa.cxx
new file mode 100644
index 000000000000..0d1931aafb75
--- /dev/null
+++ b/desktop/win32/source/lwrapa.cxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+#define LOCAL
+#include "wrapper.h"
diff --git a/desktop/win32/source/lwrapw.cxx b/desktop/win32/source/lwrapw.cxx
new file mode 100644
index 000000000000..734ae4497a39
--- /dev/null
+++ b/desktop/win32/source/lwrapw.cxx
@@ -0,0 +1,33 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+#define LOCAL
+#define UNICODE
+#include "wrapper.h"
diff --git a/desktop/win32/source/main.h b/desktop/win32/source/main.h
new file mode 100644
index 000000000000..01a32ace68bb
--- /dev/null
+++ b/desktop/win32/source/main.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int MainA();
+int MainW();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
diff --git a/desktop/win32/source/makefile.mk b/desktop/win32/source/makefile.mk
new file mode 100644
index 000000000000..564ba319eb56
--- /dev/null
+++ b/desktop/win32/source/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=sowrap
+LIBTARGET=NO
+AUTOSEG=true
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+UWINAPILIB =
+
+# --- Files --------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/wrappera.obj \
+ $(OBJ)$/wrapperw.obj \
+ $(OBJ)$/lwrapa.obj \
+ $(OBJ)$/lwrapw.obj \
+ $(OBJ)$/rwrapa.obj \
+ $(OBJ)$/rwrapw.obj \
+ $(OBJ)$/sowrapper.obj \
+ $(OBJ)$/extendloaderenvironment.obj \
+ $(OBJ)$/unoinfo.obj
+
+APP1TARGET = unoinfo
+APP1OBJS = $(OBJ)$/unoinfo.obj $(SOLARLIBDIR)$/pathutils-obj.obj
+APP1STDLIBS =
+APP1RPATH = BRAND
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/officeloader/makefile.mk b/desktop/win32/source/officeloader/makefile.mk
new file mode 100644
index 000000000000..10758727b743
--- /dev/null
+++ b/desktop/win32/source/officeloader/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET=officeloader
+LIBTARGET=NO
+#TARGETTYPE=GUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/officeloader.obj
+
+#APP1TARGET=so$/officeloader
+#APP1NOSAL=TRUE
+#APP1LINKRES=$(MISC)$/$(TARGET).res
+#APP1ICON=$(SOLARRESDIR)$/icons/001_star_main.ico
+#APP1OBJS = \
+# $(OBJ)$/officeloader.obj
+
+#APP2TARGET=officeloader
+#APP2NOSAL=TRUE
+#APP2LINKRES=$(MISC)$/$(TARGET).res
+#APP2ICON=$(SOLARRESDIR)$/icons/ooo_gulls.ico
+#APP2OBJS = \
+# $(OBJ)$/officeloader.obj
+
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/desktop/win32/source/officeloader/officeloader.cxx b/desktop/win32/source/officeloader/officeloader.cxx
new file mode 100644
index 000000000000..7c2dafc79bbb
--- /dev/null
+++ b/desktop/win32/source/officeloader/officeloader.cxx
@@ -0,0 +1,424 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+#define UNICODE
+#define _UNICODE
+
+#include <cstddef>
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <tchar.h>
+
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <systools/win32/uwinapi.h>
+
+#include "rtl/string.h"
+
+#include "../../../source/inc/exithelper.hxx"
+#include "../extendloaderenvironment.hxx"
+
+#define PIPE_PREFIX TEXT("\\\\.\\pipe\\OSL_PIPE_")
+#define PIPE_POSTFIX TEXT("_SingleOfficeIPC_")
+#define PIPE_TERMINATION_SEQUENCE "InternalIPC::ProcessingDone"
+
+BOOL WINAPI ConvertSidToStringSid( PSID pSid, LPTSTR* StringSid )
+{
+ PSID_IDENTIFIER_AUTHORITY psia;
+ DWORD dwSubAuthorities;
+ DWORD dwSidRev=SID_REVISION;
+ DWORD dwCounter;
+ DWORD dwSidSize;
+
+ // Validate the binary SID.
+
+ if(!IsValidSid(pSid)) return FALSE;
+
+ // Get the identifier authority value from the SID.
+
+ psia = GetSidIdentifierAuthority(pSid);
+
+ // Get the number of subauthorities in the SID.
+
+ dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
+
+ // Compute the buffer length.
+ // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
+
+ dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
+
+ *StringSid = (LPTSTR)LocalAlloc( LMEM_FIXED, dwSidSize );
+
+ // Add 'S' prefix and revision number to the string.
+
+ dwSidSize=wsprintf(*StringSid, TEXT("S-%lu-"), dwSidRev );
+
+ // Add a SID identifier authority to the string.
+
+ if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
+ {
+ dwSidSize+=wsprintf(*StringSid + lstrlen(*StringSid),
+ TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
+ (USHORT)psia->Value[0],
+ (USHORT)psia->Value[1],
+ (USHORT)psia->Value[2],
+ (USHORT)psia->Value[3],
+ (USHORT)psia->Value[4],
+ (USHORT)psia->Value[5]);
+ }
+ else
+ {
+ dwSidSize+=wsprintf(*StringSid + lstrlen(*StringSid),
+ TEXT("%lu"),
+ (ULONG)(psia->Value[5] ) +
+ (ULONG)(psia->Value[4] << 8) +
+ (ULONG)(psia->Value[3] << 16) +
+ (ULONG)(psia->Value[2] << 24) );
+ }
+
+ // Add SID subauthorities to the string.
+ //
+ for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
+ {
+ dwSidSize+=wsprintf(*StringSid + dwSidSize, TEXT("-%lu"),
+ *GetSidSubAuthority(pSid, dwCounter) );
+ }
+
+ return TRUE;
+}
+
+
+//---------------------------------------------------------------------------
+
+static LPTSTR *GetCommandArgs( int *pArgc )
+{
+#ifdef UNICODE
+ return CommandLineToArgvW( GetCommandLineW(), pArgc );
+#else
+ *pArgc = __argc;
+ return __argv;
+#endif
+}
+
+//---------------------------------------------------------------------------
+
+namespace {
+
+bool writeArgument(HANDLE pipe, char prefix, WCHAR const * argument) {
+ CHAR szBuffer[4096];
+ int n = WideCharToMultiByte(
+ CP_UTF8, 0, argument, -1, szBuffer, sizeof (szBuffer), NULL, NULL);
+ char b[1 + 2 * ((sizeof szBuffer) - 1)]; // hopefully does not overflow
+ b[0] = prefix;
+ char * p = b + 1;
+ for (int i = 0; i < n - 1; ++i) { // cannot underflow (n >= 0)
+ char c = szBuffer[i];
+ switch (c) {
+ case '\0':
+ *p++ = '\\';
+ *p++ = '0';
+ break;
+ case ',':
+ *p++ = '\\';
+ *p++ = ',';
+ break;
+ case '\\':
+ *p++ = '\\';
+ *p++ = '\\';
+ break;
+ default:
+ *p++ = c;
+ break;
+ }
+ }
+ DWORD w;
+ return WriteFile(pipe, b, p - b, &w, NULL);
+}
+
+}
+
+#ifdef __MINGW32__
+int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int )
+#else
+int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
+#endif
+{
+ TCHAR szTargetFileName[MAX_PATH] = TEXT("");
+ TCHAR szIniDirectory[MAX_PATH];
+ TCHAR szPerfTuneIniFile[MAX_PATH] = TEXT("");
+ STARTUPINFO aStartupInfo;
+
+ desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof(aStartupInfo);
+
+ GetStartupInfo( &aStartupInfo );
+ // Get image path with same name but with .bin extension
+
+ TCHAR szModuleFileName[MAX_PATH];
+
+ GetModuleFileName( NULL, szModuleFileName, MAX_PATH );
+ _TCHAR *lpLastSlash = _tcsrchr( szModuleFileName, '\\' );
+ if ( lpLastSlash )
+ {
+ size_t len = lpLastSlash - szModuleFileName + 1;
+ _tcsncpy( szPerfTuneIniFile, szModuleFileName, len );
+ _tcsncpy( szPerfTuneIniFile + len, _T("perftune.ini"), sizeof(szPerfTuneIniFile)/sizeof(szPerfTuneIniFile[0]) - len );
+ }
+
+ // Create process with same command line, environment and stdio handles which
+ // are directed to the created pipes
+
+ DWORD dwExitCode = (DWORD)-1;
+
+ BOOL fSuccess = FALSE;
+ LPTSTR lpCommandLine = NULL;
+ int argc = 0;
+ LPTSTR * argv = NULL;
+ bool bFirst = true;
+ WCHAR cwd[MAX_PATH];
+ DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd);
+ if (cwdLen >= MAX_PATH) {
+ cwdLen = 0;
+ }
+
+ do
+ {
+ TCHAR szKey[32];
+
+ GetPrivateProfileString(
+ TEXT("PerformanceTuning"),
+ TEXT("FastPipeCommunication"),
+ TEXT("0"),
+ szKey,
+ elementsof(szKey),
+ szPerfTuneIniFile
+ );
+
+ if ( 0 == _tcscmp( szKey, TEXT("1") ) )
+ {
+ HANDLE hProcessToken;
+
+ if ( OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hProcessToken ) )
+ {
+ TCHAR szPipeName[4096];
+
+
+ DWORD dwTokenLength = 0;
+
+
+ fSuccess = GetTokenInformation( hProcessToken, TokenUser, NULL, dwTokenLength, &dwTokenLength );
+
+ PVOID pTokenInfo = _alloca(dwTokenLength);
+ fSuccess = GetTokenInformation( hProcessToken, TokenUser, pTokenInfo, dwTokenLength, &dwTokenLength );
+ CloseHandle( hProcessToken );
+
+ PSID pSid = ((PTOKEN_USER)pTokenInfo)->User.Sid;
+ LPTSTR szUserIdent = NULL;
+ TCHAR szSUPD[11] = TEXT("0");
+
+ fSuccess = ConvertSidToStringSid( pSid, &szUserIdent );
+
+ _tcsncpy( szPipeName, PIPE_PREFIX, elementsof(szPipeName) );
+ _tcsncat( szPipeName, szUserIdent, elementsof(szPipeName) - _tcslen(szPipeName) - 1 );
+ _tcsncat( szPipeName, PIPE_POSTFIX, elementsof(szPipeName) - _tcslen(szPipeName) - 1 );
+ _tcsncat( szPipeName, _ultot( SUPD, szSUPD, 10), elementsof(szPipeName) - _tcslen(szPipeName) - 1 );
+
+ LocalFree( szUserIdent );
+
+ HANDLE hPipe = CreateFile(
+ szPipeName,
+ GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if ( INVALID_HANDLE_VALUE != hPipe )
+ {
+ DWORD dwBytesWritten;
+ int argc = 0;
+ LPWSTR *argv = CommandLineToArgvW( GetCommandLine(), &argc );
+
+ fSuccess = WriteFile( hPipe, RTL_CONSTASCII_STRINGPARAM("InternalIPC::Arguments"), &dwBytesWritten, NULL );
+ if (fSuccess) {
+ if (cwdLen > 0) {
+ fSuccess = writeArgument(hPipe, '2', cwd);
+ } else {
+ fSuccess = WriteFile(
+ hPipe, RTL_CONSTASCII_STRINGPARAM("0"),
+ &dwBytesWritten, NULL);
+ }
+ }
+ for ( int argn = 1; fSuccess && argn < argc; argn++ )
+ {
+ fSuccess = writeArgument(hPipe, ',', argv[argn]);
+ }
+
+ if ( fSuccess )
+ {
+ fSuccess = WriteFile( hPipe, "", 1, &dwBytesWritten, NULL );
+ if ( fSuccess )
+ {
+ DWORD dwBytesRead = 0;
+ char *pBuffer = (char *)_alloca( sizeof(PIPE_TERMINATION_SEQUENCE) );
+ fSuccess = ReadFile( hPipe, pBuffer, sizeof(PIPE_TERMINATION_SEQUENCE) - 1, &dwBytesRead, NULL );
+ if ( fSuccess )
+ {
+ pBuffer[dwBytesRead] = 0;
+ if ( 0 != strcmp( PIPE_TERMINATION_SEQUENCE, pBuffer ) )
+ fSuccess = FALSE;
+ }
+ }
+ }
+
+ CloseHandle( hPipe );
+
+ return fSuccess ? 0 : -1;
+ }
+
+ }
+ }
+
+ if ( bFirst ) {
+ argv = GetCommandArgs(&argc);
+ std::size_t n = wcslen(argv[0]) + 2;
+ for (int i = 1; i < argc; ++i) {
+ n += wcslen(argv[i]) + 3;
+ }
+ n += MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen +
+ MY_LENGTH(L"\"") + 1;
+ // 4 * cwdLen: each char preceded by backslash, each trailing
+ // backslash doubled
+ lpCommandLine = new WCHAR[n];
+ }
+ WCHAR * p = desktop_win32::commandLineAppend(
+ lpCommandLine, MY_STRING(L"\""));
+ p = desktop_win32::commandLineAppend(p, argv[0]);
+ for (int i = 1; i < argc; ++i) {
+ if (bFirst || ::desktop::ExitHelper::E_NORMAL_RESTART == dwExitCode || wcsncmp(argv[i], MY_STRING(L"-env:")) == 0) {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"\" \""));
+ p = desktop_win32::commandLineAppend(p, argv[i]);
+ }
+ }
+ p = desktop_win32::commandLineAppend(
+ p, MY_STRING(L"\" \"-env:OOO_CWD="));
+ if (cwdLen == 0) {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"0"));
+ } else {
+ p = desktop_win32::commandLineAppend(p, MY_STRING(L"2"));
+ p = desktop_win32::commandLineAppendEncoded(p, cwd);
+ }
+ desktop_win32::commandLineAppend(p, MY_STRING(L"\""));
+ bFirst = false;
+
+ TCHAR szParentProcessId[64]; // This is more than large enough for a 128 bit decimal value
+ BOOL bHeadlessMode( FALSE );
+
+ {
+ // Check command line arguments for "-headless" parameter. We only
+ // set the environment variable "ATTACHED_PARENT_PROCESSID" for the headless
+ // mode as self-destruction of the soffice.bin process can lead to
+ // certain side-effects (log-off can result in data-loss, ".lock" is not deleted.
+ // See 138244 for more information.
+ int argc;
+ LPTSTR *argv = GetCommandArgs( &argc );
+
+ if ( argc > 1 )
+ {
+ int n;
+
+ for ( n = 1; n < argc; n++ )
+ {
+ if ( 0 == _tcsnicmp( argv[n], _T("-headless"), 9 ) )
+ bHeadlessMode = TRUE;
+ }
+ }
+ }
+
+ if ( _ltot( (long)GetCurrentProcessId(),szParentProcessId, 10 ) && bHeadlessMode )
+ SetEnvironmentVariable( TEXT("ATTACHED_PARENT_PROCESSID"), szParentProcessId );
+
+ PROCESS_INFORMATION aProcessInfo;
+
+ fSuccess = CreateProcess(
+ szTargetFileName,
+ lpCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ szIniDirectory,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ if ( fSuccess )
+ {
+ DWORD dwWaitResult;
+
+ do
+ {
+ // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so
+ // as if we where processing any messages
+
+ dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS );
+
+ if ( WAIT_OBJECT_0 + 1 == dwWaitResult )
+ {
+ MSG msg;
+
+ PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
+ }
+ } while ( WAIT_OBJECT_0 + 1 == dwWaitResult );
+
+ dwExitCode = 0;
+ GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
+
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+ }
+ } while ( fSuccess
+ && ( ::desktop::ExitHelper::E_CRASH_WITH_RESTART == dwExitCode || ::desktop::ExitHelper::E_NORMAL_RESTART == dwExitCode ));
+ delete[] lpCommandLine;
+
+ return fSuccess ? dwExitCode : -1;
+}
diff --git a/desktop/win32/source/rebase/Resource.h b/desktop/win32/source/rebase/Resource.h
new file mode 100644
index 000000000000..b8ad7b0f824a
--- /dev/null
+++ b/desktop/win32/source/rebase/Resource.h
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _RESOURCE_H
+#define _RESOURCE_H
+
+#define IDS_APP_TITLE 10
+#define IDS_MSG_OPTIMIZED_FOR_CLIENT 11
+#define IDS_MSG_OPTIMIZED_FOR_SERVER 12
+#define IDS_MSG_NO_INSTALLATION_FOUND 13
+
+#define IDI_REBASEGUI 99
+
+#endif
diff --git a/desktop/win32/source/rebase/makefile.mk b/desktop/win32/source/rebase/makefile.mk
new file mode 100644
index 000000000000..724ea0edf465
--- /dev/null
+++ b/desktop/win32/source/rebase/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=desktop
+TARGET=rebasegui
+LIBTARGET=NO
+TARGETTYPE=GUI
+UWINAPILIB=
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES = \
+ $(OBJ)$/rebase.obj \
+ $(OBJ)$/rebasegui.obj
+
+ULFFILES= rebasegui.ulf
+
+.IF "$(WITH_LANG)"!=""
+ULFDIR:=$(COMMONMISC)$/$(TARGET)
+.ELSE # "$(WITH_LANG)"!=""
+ULFDIR:=.
+.ENDIF # "$(WITH_LANG)"!=""
+
+RCFILES= $(RES)$/$(TARGET).rc
+
+# --- Targets ------------------------------------------------------
+
+APP1NOSAL= TRUE
+APP1TARGET= rebaseoo
+
+APP1STDLIBS= $(SHELL32LIB) $(SOLARLIBDIR)$/pathutils-obj.obj
+.IF "$(COM)"=="GCC"
+ APP1STDLIBS+=$(PSDK_HOME)$/lib$/imagehlp.lib
+.ELSE
+ APP1STDLIBS+=imagehlp.lib
+.ENDIF
+
+APP1OBJS= $(OBJ)$/rebase.obj
+
+APP1RPATH= BRAND
+
+APP2NOSAL= TRUE
+APP2TARGET= rebasegui
+APP2STDLIBS= $(SHELL32LIB) $(SOLARLIBDIR)$/pathutils-obj.obj
+
+APP2OBJS= $(OBJ)$/rebasegui.obj
+
+APP2DEF= $(MISC)$/$(TARGET).def
+APP2RPATH= BRAND
+
+APP2RES= $(RES)$/$(TARGET).res
+APP2NOSVRES= $(RES)$/$(TARGET).res
+
+# --- setup --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(RCFILES) : $(ULFDIR)$/rebasegui.ulf makefile.mk rcfooter.txt rcheader.txt rctmpl.txt
+ $(LNGCONVEX) -ulf $(ULFDIR)$/rebasegui.ulf -rc $(RCFILES) -rct rctmpl.txt -rch rcheader.txt -rcf rcfooter.txt
diff --git a/desktop/win32/source/rebase/rcfooter.txt b/desktop/win32/source/rebase/rcfooter.txt
new file mode 100644
index 000000000000..3237729437f5
--- /dev/null
+++ b/desktop/win32/source/rebase/rcfooter.txt
@@ -0,0 +1,2 @@
+
+// The end
diff --git a/desktop/win32/source/rebase/rcheader.txt b/desktop/win32/source/rebase/rcheader.txt
new file mode 100644
index 000000000000..56afc5377920
--- /dev/null
+++ b/desktop/win32/source/rebase/rcheader.txt
@@ -0,0 +1,39 @@
+#if defined(_MSC_VER) && (_MSC_VER < 1500)
+#include <winres.h>
+#else
+#define WINVER 0x0500
+#include <winresrc.h>
+#define IDC_STATIC (-1)
+#endif
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,1,0
+ PRODUCTVERSION 1,1,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x9L
+#else
+ FILEFLAGS 0x8L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
diff --git a/desktop/win32/source/rebase/rctmpl.txt b/desktop/win32/source/rebase/rctmpl.txt
new file mode 100644
index 000000000000..97a2775e9b02
--- /dev/null
+++ b/desktop/win32/source/rebase/rctmpl.txt
@@ -0,0 +1,9 @@
+// String Table
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_APP_TITLE %APP_TITLE%
+ IDS_MSG_OPTIMIZED_FOR_CLIENT %MSG_OPTIMIZED_FOR_CLIENT%
+ IDS_MSG_OPTIMIZED_FOR_SERVER %MSG_OPTIMIZED_FOR_SERVER%
+ IDS_MSG_NO_INSTALLATION_FOUND %MSG_NO_INSTALLATION_FOUND%
+END
diff --git a/desktop/win32/source/rebase/rebase.cxx b/desktop/win32/source/rebase/rebase.cxx
new file mode 100644
index 000000000000..98d31a337d4f
--- /dev/null
+++ b/desktop/win32/source/rebase/rebase.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "precompiled_desktop.hxx"
+#define UNICODE
+#define _UNICODE
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <shellapi.h>
+#include <imagehlp.h>
+#include <wchar.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <time.h>
+#include "sal/config.h"
+#include "tools/pathutils.hxx"
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+
+const int FORMAT_MESSAGE_SIZE = 4096;
+const DWORD PE_Signature = 0x00004550;
+const DWORD BASEVIRTUALADDRESS = 0x10000000;
+
+namespace
+{
+
+bool IsValidHandle( HANDLE handle )
+{
+ return ((NULL != handle) && (INVALID_HANDLE_VALUE != handle));
+}
+
+void fail()
+{
+ LPWSTR buf = NULL;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL);
+ MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR);
+ LocalFree(buf);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+bool rebaseImage( wchar_t* pszFilePath, ULONG nNewImageBase)
+{
+ ULONG ulOldImageSize;
+ ULONG_PTR lpOldImageBase;
+ ULONG ulNewImageSize;
+ ULONG_PTR lpNewImageBase = nNewImageBase;
+ ULONG ulDateTimeStamp = 0;
+ bool bResult(false);
+
+ char cszFilePath[_MAX_PATH+1] = {0};
+ int nResult = WideCharToMultiByte(CP_ACP, 0, pszFilePath, -1, cszFilePath, _MAX_PATH, NULL, NULL);
+
+ if (nResult != 0)
+ {
+ BOOL bResult = ReBaseImage(
+ cszFilePath,
+ "",
+ TRUE,
+ FALSE,
+ FALSE,
+ 0,
+ &ulOldImageSize,
+ &lpOldImageBase,
+ &ulNewImageSize,
+ &lpNewImageBase,
+ ulDateTimeStamp );
+ }
+
+ return bResult;
+}
+
+wchar_t* getBrandPath(wchar_t * path)
+{
+ DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH);
+ if (n == 0 || n >= MAX_PATH) {
+ exit(EXIT_FAILURE);
+ }
+ return tools::filename(path);
+}
+
+void rebaseImagesInFolder( wchar_t* pszFolder, DWORD nNewImageBase )
+{
+ wchar_t szPattern[MAX_PATH];
+ wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' );
+ if ( lpLastSlash )
+ {
+ size_t len = lpLastSlash - pszFolder + 1;
+ wcsncpy( szPattern, pszFolder, len );
+ wcsncpy( szPattern + len, TEXT("*.dll"), sizeof(szPattern)/sizeof(szPattern[0]) - len );
+ }
+
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( szPattern, &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ BOOL fSuccess = false;
+
+ do
+ {
+ wchar_t szLibFilePath[MAX_PATH];
+ wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' );
+ if ( lpLastSlash )
+ {
+ size_t len = lpLastSlash - pszFolder + 1;
+ wcsncpy( szLibFilePath, pszFolder, len );
+ wcsncpy( szLibFilePath + len, aFindFileData.cFileName, sizeof(szLibFilePath)/sizeof(szLibFilePath[0]) - len );
+ }
+
+ rebaseImage( szLibFilePath, nNewImageBase );
+ fSuccess = FindNextFile( hFind, &aFindFileData );
+ }
+ while ( fSuccess );
+
+ FindClose( hFind );
+ }
+}
+
+}
+
+extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
+{
+ wchar_t path[MAX_PATH];
+
+ wchar_t * pathEnd = getBrandPath(path);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"")) == NULL)
+ fail();
+ rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL)
+ fail();
+ pathEnd = tools::resolveLink(path);
+
+ if ( pathEnd == NULL )
+ return 0;
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\")) == NULL)
+ fail();
+ rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL)
+ fail();
+ pathEnd = tools::resolveLink(path);
+
+ if ( pathEnd == NULL )
+ return 0;
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\")) == NULL)
+ fail();
+ rebaseImagesInFolder(path, BASEVIRTUALADDRESS);
+
+ return 0;
+}
diff --git a/desktop/win32/source/rebase/rebasegui.cxx b/desktop/win32/source/rebase/rebasegui.cxx
new file mode 100644
index 000000000000..99585c105b64
--- /dev/null
+++ b/desktop/win32/source/rebase/rebasegui.cxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "precompiled_desktop.hxx"
+
+#define UNICODE 1
+#define _UNICODE 1
+
+#ifndef _WINDOWS_
+# define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+# include <windows.h>
+# include <shellapi.h>
+# include <wchar.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+#include "Resource.h"
+#include <time.h>
+#include "sal/config.h"
+#include "tools/pathutils.hxx"
+
+const DWORD PE_Signature = 0x00004550;
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+#define MAX_STR_CAPTION 256
+#define MAX_TEXT_LENGTH 1024
+
+static void failPath(wchar_t* pszAppTitle, wchar_t* pszMsg)
+{
+ MessageBoxW(NULL, pszMsg, pszAppTitle, MB_OK | MB_ICONERROR);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+static void fail()
+{
+ LPWSTR buf = NULL;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL);
+ MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR);
+ LocalFree(buf);
+ TerminateProcess(GetCurrentProcess(), 255);
+}
+
+static LPVOID getVirtualBaseAddress( wchar_t* pszFilePath )
+{
+ HANDLE hFile;
+ HANDLE hFileMapping;
+ LPVOID lpFileBase = 0;
+ PIMAGE_DOS_HEADER lpDosHeader;
+ PIMAGE_NT_HEADERS lpNTHeader;
+
+ hFile = CreateFile(pszFilePath,
+ GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
+ 0);
+
+ if ( hFile == INVALID_HANDLE_VALUE )
+ {
+ return NULL;
+ }
+
+ hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if ( hFileMapping == 0 )
+ {
+ CloseHandle(hFile);
+ return NULL;
+ }
+
+ lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+ if ( lpFileBase == 0 )
+ {
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ return NULL;
+ }
+
+ lpDosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+ if ( lpDosHeader->e_magic == IMAGE_DOS_SIGNATURE )
+ {
+ lpNTHeader = (PIMAGE_NT_HEADERS)((char*)lpDosHeader + lpDosHeader->e_lfanew);
+ if (lpNTHeader->Signature == PE_Signature )
+ lpFileBase = reinterpret_cast<LPVOID>( lpNTHeader->OptionalHeader.ImageBase );
+ }
+
+ UnmapViewOfFile(lpFileBase);
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+
+ return lpFileBase;
+}
+
+static bool checkImageVirtualBaseAddress(wchar_t* pszFilePath, LPVOID lpVBA)
+{
+ LPVOID lpImageVBA = getVirtualBaseAddress(pszFilePath);
+ if ( lpImageVBA == lpVBA )
+ return true;
+ else
+ return false;
+}
+
+static wchar_t* getBrandPath(wchar_t * pszPath)
+{
+ DWORD n = GetModuleFileNameW(NULL, pszPath, MAX_PATH);
+ if (n == 0 || n >= MAX_PATH) {
+ exit(EXIT_FAILURE);
+ }
+ return tools::filename(pszPath);
+}
+
+extern "C" int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
+{
+ wchar_t* pAppTitle = new wchar_t[ MAX_STR_CAPTION ];
+ pAppTitle[0] = '\0';
+ LoadString( hInst, IDS_APP_TITLE, pAppTitle, MAX_STR_CAPTION );
+
+ wchar_t* pTextServer = new wchar_t[ MAX_TEXT_LENGTH ];
+ pTextServer[0] = '\0';
+ LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_SERVER, pTextServer, MAX_TEXT_LENGTH );
+
+ wchar_t* pTextClient = new wchar_t[ MAX_TEXT_LENGTH ];
+ pTextClient[0] = '\0';
+ LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_CLIENT, pTextClient, MAX_TEXT_LENGTH );
+
+ wchar_t* pTextNoInstallation = new wchar_t[ MAX_TEXT_LENGTH ];
+ pTextNoInstallation[0] = '\0';
+ LoadString( hInst, IDS_MSG_NO_INSTALLATION_FOUND, pTextNoInstallation, MAX_TEXT_LENGTH );
+
+ LPVOID VBA = (void*)0x10000000;
+ wchar_t path[MAX_PATH];
+
+ wchar_t * pathEnd = getBrandPath(path);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"libxml2.dll")) == NULL)
+ fail();
+ bool bFast = checkImageVirtualBaseAddress(path, VBA);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL)
+ fail();
+ pathEnd = tools::resolveLink(path);
+
+ if (pathEnd == NULL)
+ failPath(pAppTitle, pTextNoInstallation);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\vclmi.dll")) == NULL)
+ fail();
+ bFast &= checkImageVirtualBaseAddress(path, VBA);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL)
+ fail();
+ pathEnd = tools::resolveLink(path);
+
+ if (pathEnd == NULL)
+ failPath(pAppTitle, pTextNoInstallation);
+
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\sal3.dll")) == NULL)
+ fail();
+ bFast &= checkImageVirtualBaseAddress(path, VBA);
+
+ const wchar_t* pOutput = pTextClient;
+ if (!bFast)
+ pOutput = pTextServer;
+
+ MessageBoxW( NULL, pOutput, pAppTitle, MB_OK );
+
+ return 0;
+}
diff --git a/desktop/win32/source/rebase/rebasegui.ulf b/desktop/win32/source/rebase/rebasegui.ulf
new file mode 100644
index 000000000000..ee6b6e828ac1
--- /dev/null
+++ b/desktop/win32/source/rebase/rebasegui.ulf
@@ -0,0 +1,11 @@
+[%APP_TITLE%]
+en-US = "Installation Status"
+
+[%MSG_OPTIMIZED_FOR_CLIENT%]
+en-US = "Installation is optimized for clients."
+
+[%MSG_OPTIMIZED_FOR_SERVER%]
+en-US = "Installation is optimized for servers."
+
+[%MSG_NO_INSTALLATION_FOUND%]
+en-US = "Cannot find Office installation."
diff --git a/desktop/win32/source/rwrapa.cxx b/desktop/win32/source/rwrapa.cxx
new file mode 100644
index 000000000000..de57b2b3f2dc
--- /dev/null
+++ b/desktop/win32/source/rwrapa.cxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+#define REMOTE
+#include "wrapper.h"
diff --git a/desktop/win32/source/rwrapw.cxx b/desktop/win32/source/rwrapw.cxx
new file mode 100644
index 000000000000..712d2f954efc
--- /dev/null
+++ b/desktop/win32/source/rwrapw.cxx
@@ -0,0 +1,33 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+#define REMOTE
+#define UNICODE
+#include "wrapper.h"
diff --git a/desktop/win32/source/setup/Resource.h b/desktop/win32/source/setup/Resource.h
new file mode 100644
index 000000000000..a40d72994429
--- /dev/null
+++ b/desktop/win32/source/setup/Resource.h
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 _RESOURCE_H
+#define _RESOURCE_H
+
+#define IDS_APP_TITLE 10
+#define IDS_APP_PROD_TITLE 11
+#define IDS_OUTOFMEM 12
+#define IDS_NOMSI 13
+#define IDS_USER_CANCELLED 14
+#define IDS_REQUIRES_ADMIN_PRIV 15
+#define IDS_FILE_NOT_FOUND 16
+#define IDS_INVALID_PARAM 17
+#define IDS_ALLOW_MSI_UPDATE 18
+#define IDS_USAGE 19
+#define IDS_ALREADY_RUNNING 20
+#define IDS_UNKNOWN_ERROR 21
+#define IDS_INVALID_PROFILE 22
+#define IDS_UNKNOWN_LANG 23
+#define IDS_SETUP_TO_OLD 24
+#define IDS_SETUP_NOT_FOUND 25
+#define IDS_LANGUAGE_ENGLISH 50
+#define IDS_LANGUAGE_SPAIN 51
+#define IDS_LANGUAGE_GERMAN 52
+#define IDS_LANGUAGE_ZH_TW 53
+#define IDS_LANGUAGE_CS 54
+#define IDS_LANGUAGE_DA 55
+#define IDS_LANGUAGE_DE_DE 56
+#define IDS_LANGUAGE_EL 57
+#define IDS_LANGUAGE_EN_US 58
+#define IDS_LANGUAGE_ES 59
+#define IDS_LANGUAGE_FI 60
+#define IDS_LANGUAGE_FR_FR 61
+#define IDS_LANGUAGE_HE 62
+#define IDS_LANGUAGE_HU 63
+#define IDS_LANGUAGE_IT_IT 64
+#define IDS_LANGUAGE_JA 65
+#define IDS_LANGUAGE_KO 66
+#define IDS_LANGUAGE_NL_NL 67
+#define IDS_LANGUAGE_NO_NO 68
+#define IDS_LANGUAGE_PL 69
+#define IDS_LANGUAGE_PT_BR 70
+#define IDS_LANGUAGE_RU 71
+#define IDS_LANGUAGE_SK 72
+#define IDS_LANGUAGE_SV_SE 73
+#define IDS_LANGUAGE_TH 74
+#define IDS_LANGUAGE_TR 75
+#define IDS_LANGUAGE_ET 76
+#define IDS_LANGUAGE_ZH_CN 77
+#define IDS_LANGUAGE_PT_PT 78
+
+#define IDI_INSTALLER 99
+
+#endif
diff --git a/desktop/win32/source/setup/makefile.mk b/desktop/win32/source/setup/makefile.mk
new file mode 100644
index 000000000000..d9105724035c
--- /dev/null
+++ b/desktop/win32/source/setup/makefile.mk
@@ -0,0 +1,91 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME = desktop
+TARGET = loader2
+LIBTARGET = NO
+DYNAMIC_CRT =
+TARGETTYPE = GUI
+
+ENABLE_EXCEPTIONS = TRUE
+
+# --- Settings ------------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Allgemein -----------------------------------------------------------
+
+INCPRE+=$(MFC_INCLUDE)
+
+.IF "$(USE_STLP_DEBUG)"!=""
+CDEFS+=-D_DEBUG
+.ENDIF # "$(USE_STLP_DEBUG)"!=""
+
+RCFILES= $(RES)$/$(TARGET).rc
+
+ULFFILES= setup.ulf
+
+.IF "$(WITH_LANG)"!=""
+ULFDIR:=$(COMMONMISC)$/$(TARGET)
+.ELSE # "$(WITH_LANG)"!=""
+ULFDIR:=.
+.ENDIF # "$(WITH_LANG)"!=""
+
+OBJFILES= $(OBJ)$/setup_main.obj \
+ $(OBJ)$/setup_a.obj \
+ $(OBJ)$/setup_w.obj
+
+# --- Targets ------------------------------------------------------
+# Generate the native Windows resource file
+# using lngconvex.exe
+
+UWINAPILIB= $(0)
+LIBSALCPPRT= $(0)
+
+APP1NOSAL= TRUE
+APP1TARGET= loader2
+
+APP1STDLIBS= $(GDI32LIB) $(ADVAPI32LIB) $(SHELL32LIB) $(MSILIB)
+.IF "$(COM)"!="GCC"
+APP1STDLIBS+= libcmt.lib
+.ENDIF
+APP1OBJS= $(OBJFILES)
+
+APP1DEF= $(MISC)$/$(TARGET).def
+
+APP1RES= $(RES)$/$(TARGET).res
+APP1NOSVRES= $(RES)$/$(TARGET).res
+
+# --- setup --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(RCFILES) : $(ULFDIR)$/setup.ulf makefile.mk rcfooter.txt rcheader.txt rctmpl.txt
+ $(LNGCONVEX) -ulf $(ULFDIR)$/setup.ulf -rc $(RCFILES) -rct rctmpl.txt -rch rcheader.txt -rcf rcfooter.txt
+
diff --git a/desktop/win32/source/setup/rcfooter.txt b/desktop/win32/source/setup/rcfooter.txt
new file mode 100644
index 000000000000..3237729437f5
--- /dev/null
+++ b/desktop/win32/source/setup/rcfooter.txt
@@ -0,0 +1,2 @@
+
+// The end
diff --git a/desktop/win32/source/setup/rcheader.txt b/desktop/win32/source/setup/rcheader.txt
new file mode 100644
index 000000000000..9a59ad7f6477
--- /dev/null
+++ b/desktop/win32/source/setup/rcheader.txt
@@ -0,0 +1,43 @@
+#if defined(_MSC_VER) && (_MSC_VER < 1500)
+#include <winres.h>
+#else
+#define WINVER 0x0500
+#include <winresrc.h>
+#define LB_ADDSTRING (WM_USER+1)
+#define CB_ADDSTRING (WM_USER+3)
+#define IDC_STATIC (-1)
+#endif
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,1,0
+ PRODUCTVERSION 1,1,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x9L
+#else
+ FILEFLAGS 0x8L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+IDI_INSTALLER ICON "setup.ico"
+
diff --git a/desktop/win32/source/setup/rctmpl.txt b/desktop/win32/source/setup/rctmpl.txt
new file mode 100644
index 000000000000..59f454f70c16
--- /dev/null
+++ b/desktop/win32/source/setup/rctmpl.txt
@@ -0,0 +1,49 @@
+// String Table
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_APP_TITLE %APP_TITLE%
+ IDS_APP_PROD_TITLE %APP_PROD_TITLE%
+ IDS_OUTOFMEM %OUTOFMEM%
+ IDS_NOMSI %NOMSI%
+ IDS_USER_CANCELLED %USER_CANCELLED%
+ IDS_REQUIRES_ADMIN_PRIV %REQUIRES_ADMIN_PRIV%
+ IDS_FILE_NOT_FOUND %FILE_NOT_FOUND%
+ IDS_INVALID_PARAM %INVALID_PARAM%
+ IDS_SETUP_TO_OLD %SETUP_TO_OLD%
+ IDS_SETUP_NOT_FOUND %SETUP_NOT_FOUND%
+ IDS_USAGE %USAGE%
+ IDS_ALREADY_RUNNING %ALREADY_RUNNING%
+ IDS_UNKNOWN_ERROR %UNKNOWN_ERROR%
+ IDS_INVALID_PROFILE %INVALID_PROFILE%
+ IDS_UNKNOWN_LANG %UNKNOWN_LANG%
+ IDS_LANGUAGE_ENGLISH %LANGUAGE_ENGLISH%
+ IDS_LANGUAGE_SPAIN %LANGUAGE_SPAIN%
+ IDS_LANGUAGE_GERMAN %LANGUAGE_GERMAN%
+ IDS_LANGUAGE_ZH_TW %LANGUAGE_ZH_TW%
+ IDS_LANGUAGE_CS %LANGUAGE_CS%
+ IDS_LANGUAGE_DA %LANGUAGE_DA%
+ IDS_LANGUAGE_DE_DE %LANGUAGE_DE_DE%
+ IDS_LANGUAGE_EL %LANGUAGE_EL%
+ IDS_LANGUAGE_EN_US %LANGUAGE_EN_US%
+ IDS_LANGUAGE_ES %LANGUAGE_ES%
+ IDS_LANGUAGE_FI %LANGUAGE_FI%
+ IDS_LANGUAGE_FR_FR %LANGUAGE_FR_FR%
+ IDS_LANGUAGE_HE %LANGUAGE_HE%
+ IDS_LANGUAGE_HU %LANGUAGE_HU%
+ IDS_LANGUAGE_IT_IT %LANGUAGE_IT_IT%
+ IDS_LANGUAGE_JA %LANGUAGE_JA%
+ IDS_LANGUAGE_KO %LANGUAGE_KO%
+ IDS_LANGUAGE_NL_NL %LANGUAGE_NL_NL%
+ IDS_LANGUAGE_NO_NO %LANGUAGE_NO_NO%
+ IDS_LANGUAGE_PL %LANGUAGE_PL%
+ IDS_LANGUAGE_PT_BR %LANGUAGE_PT_BR%
+ IDS_LANGUAGE_RU %LANGUAGE_RU%
+ IDS_LANGUAGE_SK %LANGUAGE_SK%
+ IDS_LANGUAGE_SV_SE %LANGUAGE_SV_SE%
+ IDS_LANGUAGE_TH %LANGUAGE_TH%
+ IDS_LANGUAGE_TR %LANGUAGE_TR%
+ IDS_LANGUAGE_ET %LANGUAGE_ET%
+ IDS_LANGUAGE_ZH_CN %LANGUAGE_ZH_CN%
+ IDS_LANGUAGE_PT_PT %LANGUAGE_PT_PT%
+END
diff --git a/desktop/win32/source/setup/setup.cpp b/desktop/win32/source/setup/setup.cpp
new file mode 100755
index 000000000000..edc27751b110
--- /dev/null
+++ b/desktop/win32/source/setup/setup.cpp
@@ -0,0 +1,2066 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#define WIN // scope W32 API
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <tchar.h>
+#include <assert.h>
+#include <shlwapi.h>
+#include <new>
+#include <time.h>
+#include <mbctype.h>
+#include <locale.h>
+#include <Msiquery.h>
+#include <MsiDefs.h>
+#include "strsafe.h"
+
+#include "setup.hxx"
+
+#include "resource.h"
+
+//--------------------------------------------------------------------------
+
+#define MAX_STR_LENGTH 32000
+#define MAX_TEXT_LENGTH 1024
+#define MAX_LANGUAGE_LEN 80
+#define MAX_STR_CAPTION 256
+#define VERSION_SIZE 80
+#define SECTION_SETUP TEXT( "Setup" )
+#define SECTION_LANGUAGE TEXT( "Languages" )
+#define PRODUCT_NAME_VAR TEXT( "%PRODUCTNAME" )
+#define PRODUCT_VERSION TEXT( "ProductVersion" )
+#define ERROR_SHOW_USAGE -2
+#define ERROR_SETUP_TO_OLD -3
+#define ERROR_SETUP_NOT_FOUND -4
+
+#define PARAM_SETUP_USED TEXT( " SETUP_USED=1 " )
+#define PARAM_PACKAGE TEXT( "/I " )
+#define PARAM_MINOR_UPGRADE TEXT( "/FVOMUS " )
+#define PARAM_ADMIN TEXT( "/A " )
+#define PARAM_TRANSFORM TEXT( " TRANSFORMS=" )
+#define PARAM_REBOOT TEXT( " REBOOT=Force" )
+#define PARAM_PATCH TEXT( " /update " )
+#define PARAM_REG_ALL_MSO_TYPES TEXT( "REGISTER_ALL_MSO_TYPES=1 " )
+#define PARAM_REG_NO_MSO_TYPES TEXT( "REGISTER_NO_MSO_TYPES=1 " )
+#define PARAM_SILENTINSTALL TEXT( " /QB" )
+
+#define PARAM_RUNNING TEXT( "ignore_running" )
+#define CMDLN_REG_ALL_MSO_TYPES TEXT( "msoreg=1" )
+#define CMDLN_REG_NO_MSO_TYPES TEXT( "msoreg=0" )
+
+#define MSI_DLL TEXT( "msi.dll" )
+#define ADVAPI32_DLL TEXT( "advapi32.dll" )
+#define PROFILE_NAME TEXT( "setup.ini" )
+
+#define RUNTIME_X64_NAME TEXT( "redist\\vcredist_x64.exe" )
+#define RUNTIME_X86_NAME TEXT( "redist\\vcredist_x86.exe" )
+#define PRODUCTCODE_X86 TEXT( "{E503B4BF-F7BB-3D5F-8BC8-F694B1CFF942}" )
+#define PRODUCTCODE_X64 TEXT( "{350AA351-21FA-3270-8B7A-835434E766AD}" )
+
+#define MSIAPI_DllGetVersion "DllGetVersion"
+#define ADVAPI32API_CheckTokenMembership "CheckTokenMembership"
+
+typedef HRESULT (CALLBACK* PFnDllGetVersion)( DLLVERSIONINFO *pdvi);
+typedef BOOL (WINAPI* PFnCheckTokenMembership)(HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember);
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+//--------------------------------------------------------------------------
+
+const TCHAR sInstKey[] = TEXT( "Software\\Microsoft\\Windows\\CurrentVersion\\Installer" );
+const TCHAR sInstLocValue[] = TEXT( "InstallerLocation" );
+const TCHAR sMsiDll[] = TEXT( "\\msi.dll" );
+const TCHAR sMsiExe[] = TEXT( "\\msiexec.exe" );
+const TCHAR sDelayReboot[] = TEXT( " /c:\"msiinst /delayreboot\"" );
+const TCHAR sMsiQuiet[] = TEXT( " /q" );
+const TCHAR sMemMapName[] = TEXT( "Global\\MsiErrorObject" );
+
+//--------------------------------------------------------------------------
+SetupAppX::SetupAppX()
+{
+ m_hInst = NULL;
+ m_hMapFile = NULL;
+ m_pAppTitle = NULL;
+ m_pCmdLine = NULL;
+
+ m_pDatabase = NULL;
+ m_pReqVersion = NULL;
+ m_pProductName = NULL;
+ m_pAdvertise = NULL;
+ m_pTmpName = NULL;
+ m_pLogFile = NULL;
+ m_pModuleFile = NULL;
+ m_pPatchFiles = NULL;
+ m_pMSIErrorCode = NULL;
+ m_pUpgradeKey = NULL;
+ m_pProductVersion = NULL;
+
+ m_pErrorText = new TCHAR[ MAX_TEXT_LENGTH ];
+ m_pErrorText[0] = '\0';
+
+ m_nLanguageID = 0;
+ m_nLanguageCount = 0;
+ m_ppLanguageList = NULL;
+
+ m_bQuiet = false;
+ m_bRegNoMsoTypes = false;
+ m_bRegAllMsoTypes = false;
+ m_bIsMinorUpgrade = false;
+ m_bSupportsPatch = false;
+
+ m_bIgnoreAlreadyRunning = false;
+}
+
+//--------------------------------------------------------------------------
+SetupAppX::~SetupAppX()
+{
+ if ( m_ppLanguageList )
+ {
+ for ( int i = 0; i < m_nLanguageCount; i++ )
+ if ( m_ppLanguageList[i] )
+ delete m_ppLanguageList[ i ];
+ delete [] m_ppLanguageList;
+ }
+
+ time_t aTime;
+ time( &aTime );
+ tm *pTime = localtime( &aTime ); // Convert time to struct tm form
+
+ Log( TEXT( "End: %s\n\r\n\r\n" ), _tasctime( pTime ) );
+
+ if ( m_pLogFile ) fclose( m_pLogFile );
+
+ if ( m_pTmpName )
+ {
+ _tremove( m_pTmpName );
+ free( m_pTmpName );
+ }
+
+ if ( m_pMSIErrorCode ) UnmapViewOfFile( m_pMSIErrorCode );
+ if ( m_hMapFile ) CloseHandle( m_hMapFile );
+
+ if ( m_pAppTitle ) delete [] m_pAppTitle;
+ if ( m_pDatabase ) delete [] m_pDatabase;
+ if ( m_pReqVersion ) delete [] m_pReqVersion;
+ if ( m_pProductName ) delete [] m_pProductName;
+ if ( m_pAdvertise ) delete [] m_pAdvertise;
+ if ( m_pLogFile ) delete [] m_pLogFile;
+ if ( m_pErrorText ) delete [] m_pErrorText;
+ if ( m_pModuleFile ) delete [] m_pModuleFile;
+ if ( m_pPatchFiles ) delete [] m_pPatchFiles;
+ if ( m_pUpgradeKey ) delete [] m_pUpgradeKey;
+ if ( m_pProductVersion ) delete [] m_pProductVersion;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::Initialize( HINSTANCE hInst )
+{
+ m_pCmdLine = WIN::GetCommandLine();
+ m_hInst = hInst;
+
+ // Load our AppTitle (caption)
+ m_pAppTitle = new TCHAR[ MAX_STR_CAPTION ];
+ m_pAppTitle[0] = '\0';
+ WIN::LoadString( hInst, IDS_APP_TITLE, m_pAppTitle, MAX_STR_CAPTION );
+
+ // Obtain path we are running from
+ m_pModuleFile = new TCHAR[ MAX_PATH ];
+ m_pModuleFile[ 0 ] = '\0';
+
+ if ( 0 == WIN::GetModuleFileName( hInst, m_pModuleFile, MAX_PATH ) )
+ {
+ SetError( WIN::GetLastError() );
+ return false;
+ }
+
+ if ( ! GetCmdLineParameters( &m_pCmdLine ) )
+ return false;
+
+ m_hMapFile = CreateFileMapping(
+ INVALID_HANDLE_VALUE, // use paging file
+ NULL, // default security
+ PAGE_READWRITE, // read/write access
+ 0, // max. object size
+ sizeof( int ), // buffer size
+ sMemMapName );
+ if ( m_hMapFile )
+ {
+ m_pMSIErrorCode = (int*) MapViewOfFile( m_hMapFile, // handle to map object
+ FILE_MAP_ALL_ACCESS, // read/write permission
+ 0,
+ 0,
+ sizeof( int ) );
+ if ( m_pMSIErrorCode )
+ *m_pMSIErrorCode = 0;
+ else
+ OutputDebugStringFormat( TEXT("Could not map view of file (%d).\n"), GetLastError() );
+ }
+ else
+ OutputDebugStringFormat( TEXT("Could not create file mapping object (%d).\n"), GetLastError() );
+
+ Log( TEXT("Starting: %s\r\n"), m_pModuleFile );
+ Log( TEXT(" CommandLine=<%s>\r\n"), m_pCmdLine );
+
+ if ( m_bQuiet )
+ Log( TEXT(" Using quiet install mode\r\n") );
+
+ time_t aTime;
+ time( &aTime );
+ tm* pTime = localtime( &aTime );
+ Log( TEXT(" Begin: %s\n"), _tasctime( pTime ) );
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::GetProfileSection( LPCTSTR pFileName, LPCTSTR pSection,
+ DWORD& rSize, LPTSTR *pRetBuf )
+{
+ if ( !rSize || !*pRetBuf )
+ {
+ rSize = 512;
+ *pRetBuf = new TCHAR[ rSize ];
+ }
+
+ DWORD nRet = GetPrivateProfileSection( pSection, *pRetBuf, rSize, pFileName );
+
+ if ( nRet && ( nRet + 2 > rSize ) ) // buffer was too small, retry with bigger one
+ {
+ if ( nRet < 32767 - 2 )
+ {
+ delete [] (*pRetBuf);
+ rSize = nRet + 2;
+ *pRetBuf = new TCHAR[ rSize ];
+
+ nRet = GetPrivateProfileSection( pSection, *pRetBuf, rSize, pFileName );
+ }
+ }
+
+ if ( !nRet )
+ {
+ SetError( WIN::GetLastError() );
+
+ TCHAR sBuf[80];
+ StringCchPrintf( sBuf, 80, TEXT("ERROR: GetPrivateProfileSection(): GetLastError returned %u\r\n"), GetError() );
+ Log( sBuf );
+ return false;
+ }
+ else if ( nRet + 2 > rSize )
+ {
+ SetError( ERROR_OUTOFMEMORY );
+ Log( TEXT( "ERROR: GetPrivateProfileSection() out of memory\r\n" ) );
+ return false;
+ }
+
+ Log( TEXT( " GetProfileSection read %s\r\n" ), pSection );
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::ReadProfile()
+{
+ boolean bRet = false;
+ TCHAR *sProfilePath = 0;
+
+ if ( GetPathToFile( PROFILE_NAME, &sProfilePath ) )
+ {
+ DWORD nSize = 0;
+ LPTSTR pRetBuf = NULL;
+
+ Log( TEXT( " Open ini file: <%s>\r\n" ), sProfilePath );
+
+ bRet = GetProfileSection( sProfilePath, SECTION_SETUP, nSize, &pRetBuf );
+
+ if ( !bRet )
+ {
+ LPTSTR pTmpFile = CopyIniFile( sProfilePath );
+ delete [] sProfilePath;
+ sProfilePath = pTmpFile;
+
+ if ( sProfilePath )
+ {
+ SetError( ERROR_SUCCESS );
+
+ Log( TEXT( " Could not open inifile, copied ini file to: <%s>\r\n" ), sProfilePath );
+ bRet = GetProfileSection( sProfilePath, SECTION_SETUP, nSize, &pRetBuf );
+ }
+ }
+
+ if ( bRet )
+ {
+ LPTSTR pCurLine = pRetBuf;
+ while ( *pCurLine )
+ {
+ LPTSTR pName = 0;
+ LPTSTR pValue = 0;
+
+ pCurLine += GetNameValue( pCurLine, &pName, &pValue );
+
+ if ( lstrcmpi( TEXT( "database" ), pName ) == 0 )
+ {
+ m_pDatabase = pValue;
+ Log( TEXT( " Database = %s\r\n" ), pValue );
+ }
+ else if ( lstrcmpi( TEXT( "msiversion" ), pName ) == 0 )
+ {
+ m_pReqVersion = pValue;
+ Log( TEXT( " msiversion = %s\r\n" ), pValue );
+ }
+ else if ( lstrcmpi( TEXT( "productname" ), pName ) == 0 )
+ {
+ m_pProductName = pValue;
+ Log( TEXT( " productname = %s\r\n" ), pValue );
+ m_pAppTitle = SetProdToAppTitle( m_pProductName );
+ }
+ else if ( lstrcmpi( TEXT( "upgradekey" ), pName ) == 0 )
+ {
+ m_pUpgradeKey = pValue;
+ Log( TEXT( " upgradekey = %s\r\n" ), pValue );
+ }
+ else if ( lstrcmpi( TEXT( "productversion" ), pName ) == 0 )
+ {
+ m_pProductVersion = pValue;
+ Log( TEXT( " productversion = %s\r\n" ), pValue );
+ }
+ else if ( lstrcmpi( TEXT( "productcode" ), pName ) == 0 )
+ {
+ delete [] pValue;
+ }
+ else
+ {
+ Log( TEXT( "Warning: unknown entry in profile <%s>\r\n" ), pName );
+ delete [] pValue;
+ }
+ }
+ }
+
+ if ( bRet && ( !m_pDatabase || !m_pReqVersion || !m_pProductName ) )
+ {
+ Log( TEXT( "ERROR: incomplete 'Setup' section in profile\r\n" ) );
+ SetError( ERROR_INVALID_DATA );
+ bRet = false;
+ }
+
+ if ( bRet )
+ bRet = GetProfileSection( sProfilePath, SECTION_LANGUAGE, nSize, &pRetBuf );
+
+ if ( bRet )
+ {
+ LPTSTR pName = 0;
+ LPTSTR pValue = 0;
+ LPTSTR pCurLine = pRetBuf;
+ LPTSTR pLastChar;
+ int nNext = 0;
+
+ // first line in this section should be the language count
+ nNext = GetNameValue( pCurLine, &pName, &pValue );
+ if ( lstrcmpi( TEXT( "count" ), pName ) == 0 )
+ {
+ Log( TEXT( " Languages = %s\r\n" ), pValue );
+ m_nLanguageCount = _tcstol( pValue, &pLastChar, 10 );
+ pCurLine += nNext;
+ delete [] pValue;
+ }
+
+ m_ppLanguageList = new LanguageDataX*[ m_nLanguageCount ];
+
+ for ( int i=0; i < m_nLanguageCount; i++ )
+ {
+ if ( !*pCurLine )
+ {
+ m_nLanguageCount = i;
+ break;
+ }
+
+ pCurLine += GetNameValue( pCurLine, &pName, &pValue );
+ m_ppLanguageList[ i ] = new LanguageDataX( pValue );
+ Log( TEXT( " Language = %s\r\n" ), pValue );
+
+ if ( m_ppLanguageList[ i ]->m_pTransform )
+ Log( TEXT( " Transform = %s\r\n" ), m_ppLanguageList[ i ]->m_pTransform );
+
+ delete [] pValue;
+ }
+ }
+
+ if ( pRetBuf )
+ delete [] pRetBuf;
+ }
+
+ if ( sProfilePath && ! m_pTmpName )
+ delete [] sProfilePath;
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::AddFileToPatchList( TCHAR* pPath, TCHAR* pFile )
+{
+ if ( m_pPatchFiles == NULL )
+ {
+ m_pPatchFiles = new TCHAR[ MAX_STR_LENGTH ];
+ StringCchCopy( m_pPatchFiles, MAX_STR_LENGTH, TEXT("\"") );
+ }
+ else
+ StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, TEXT(";") );
+
+ StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, pPath );
+ StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, pFile );
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::GetPatches()
+{
+ boolean bRet = true;
+
+ int nPatternLen = lstrlen( m_pModuleFile ) + 7; // 1 for null terminator, 1 for back slash, 5 for extensions
+ TCHAR* pPattern = new TCHAR[ nPatternLen ];
+ TCHAR* pBaseDir = new TCHAR[ nPatternLen ];
+
+ // find 'setup.exe' in the path so we can remove it
+ TCHAR *pFilePart = 0;
+ if ( 0 == GetFullPathName( m_pModuleFile, nPatternLen, pPattern, &pFilePart ) )
+ {
+ SetError( WIN::GetLastError() );
+ bRet = false;
+ }
+ else
+ {
+ if ( pFilePart )
+ *pFilePart = '\0';
+ StringCchCopy( pBaseDir, nPatternLen, pPattern );
+ StringCchCat( pPattern, nPatternLen, TEXT("*.msp") );
+
+ WIN32_FIND_DATA aFindFileData;
+
+ HANDLE hFindPatches = FindFirstFile( pPattern, &aFindFileData );
+
+ if ( hFindPatches != INVALID_HANDLE_VALUE )
+ {
+ if ( ! IsPatchInstalled( pBaseDir, aFindFileData.cFileName ) )
+ AddFileToPatchList( pBaseDir, aFindFileData.cFileName );
+
+ while ( FindNextFile( hFindPatches, &aFindFileData ) )
+ {
+ if ( ! IsPatchInstalled( pBaseDir, aFindFileData.cFileName ) )
+ AddFileToPatchList( pBaseDir, aFindFileData.cFileName );
+ }
+
+ if ( m_pPatchFiles != NULL )
+ StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, TEXT("\"") );
+
+ FindClose( hFindPatches );
+ }
+ }
+
+ delete [] pPattern;
+ delete [] pBaseDir;
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::GetPathToFile( TCHAR* pFileName, TCHAR** pPath )
+{
+ // generate the path to the file = szModuleFile + FileName
+ // note: FileName is a relative path
+
+ boolean bRet = true;
+
+ int nTempPath = lstrlen( m_pModuleFile ) + lstrlen( pFileName ) + 2; // 1 for null terminator, 1 for back slash
+ TCHAR* pTempPath = new TCHAR[ nTempPath ];
+
+ // find 'setup.exe' in the path so we can remove it
+ TCHAR *pFilePart = 0;
+ if ( 0 == GetFullPathName( m_pModuleFile, nTempPath, pTempPath, &pFilePart ) )
+ {
+ SetError( WIN::GetLastError() );
+ bRet = false;
+ }
+ else
+ {
+ if ( pFilePart )
+ *pFilePart = '\0';
+
+ StringCchCat( pTempPath, nTempPath, pFileName );
+
+ int nPath = 2 * nTempPath;
+ *pPath = new TCHAR[ nPath ];
+
+ // normalize the path
+ int nReturn = GetFullPathName( pTempPath, nPath, *pPath, &pFilePart );
+
+ if ( nReturn > nPath )
+ {
+ // try again, with larger buffer
+ delete [] (*pPath);
+ nPath = nReturn;
+ *pPath = new TCHAR[ nPath ];
+
+ nReturn = GetFullPathName( pTempPath, nPath, *pPath, &pFilePart );
+ }
+
+ if ( 0 == nReturn )
+ {
+ // error -- invalid path
+ SetError( WIN::GetLastError() );
+ bRet = false;
+ }
+ }
+
+ if ( bRet ) // check for the file's existence
+ {
+ DWORD dwFileAttrib = GetFileAttributes( *pPath );
+
+ if (0xFFFFFFFF == dwFileAttrib)
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pFileName );
+ SetError( ERROR_FILE_NOT_FOUND );
+ bRet = false;
+ }
+ }
+
+ delete [] pTempPath;
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+int SetupAppX::GetNameValue( TCHAR* pLine, TCHAR** pName, TCHAR** pValue )
+{
+ int nRet = lstrlen( pLine ) + 1;
+ *pValue = 0;
+
+ if ( nRet == 1 )
+ return nRet;
+
+ LPTSTR pChar = pLine;
+ LPTSTR pLast = NULL;
+
+ // Skip leading spaces.
+ while (' ' == *pChar || '\t' == *pChar)
+ pChar = CharNext( pChar );
+
+ *pName = pChar;
+
+ // look for the end of the name
+ while( *pChar && (' ' != *pChar) &&
+ ( '\t' != *pChar ) && ( '=' != *pChar ) )
+ pChar = CharNext( pChar );
+
+ if ( ! *pChar )
+ return nRet;
+
+ pLast = pChar;
+ pChar = CharNext( pChar );
+ *pLast = '\0';
+
+ // look for the start of the value
+ while( ( ' ' == *pChar ) || ( '\t' == *pChar ) ||
+ ( '=' == *pChar ) )
+ pChar = CharNext( pChar );
+
+ int nValueLen = lstrlen( pChar ) + 1;
+ *pValue = new TCHAR[ nValueLen ];
+
+ if ( *pValue )
+ StringCchCopy( *pValue, nValueLen, pChar );
+
+ return nRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::ChooseLanguage( long& rLanguage )
+{
+ rLanguage = 0;
+
+ if ( m_bQuiet )
+ return true;
+
+ // When there are none or only one language, there is nothing
+ // to do here
+ if ( m_nLanguageCount > 1 )
+ {
+ TCHAR *sString = new TCHAR[ MAX_LANGUAGE_LEN ];
+
+ LANGID nUserDefLang = GetUserDefaultLangID();
+ LANGID nSysDefLang = GetSystemDefaultLangID();
+
+ int nUserPrimary = PRIMARYLANGID( nUserDefLang );
+ int nSysPrimary = PRIMARYLANGID( nSysDefLang );
+
+ long nUserIndex = -1;
+ long nUserPrimIndex = -1;
+ long nSystemIndex = -1;
+ long nSystemPrimIndex = -1;
+ long nParamIndex = -1;
+
+ for ( long i=0; i<GetLanguageCount(); i++ )
+ {
+ long nLanguage = GetLanguageID( i );
+ int nPrimary = PRIMARYLANGID( nLanguage );
+ GetLanguageName( nLanguage, sString );
+ Log( TEXT( " Info: found Language: %s\r\n" ), sString );
+
+ if ( nLanguage == nUserDefLang )
+ nUserIndex = i;
+ if ( nPrimary == nUserPrimary )
+ nUserPrimIndex = i;
+ if ( nLanguage == nSysDefLang )
+ nSystemIndex = i;
+ if ( nPrimary == nSysPrimary )
+ nSystemPrimIndex = i;
+ if ( m_nLanguageID && ( nLanguage == m_nLanguageID ) )
+ nParamIndex = i;
+ }
+
+ if ( m_nLanguageID && ( nParamIndex == -1 ) )
+ {
+ Log( TEXT( "Warning: Language chosen with parameter -lang not found.\r\n" ) );
+ }
+
+ if ( nParamIndex != -1 )
+ {
+ Log( TEXT( "Info: Found language chosen with parameter -lang.\r\n" ) );
+ rLanguage = GetLanguageID( nParamIndex );
+ }
+ else if ( nUserIndex != -1 )
+ {
+ Log( TEXT( "Info: Found user default language.\r\n" ) );
+ rLanguage = GetLanguageID( nUserIndex );
+ }
+ else if ( nUserPrimIndex != -1 )
+ {
+ Log( TEXT( "Info: Found user default primary language.\r\n" ) );
+ rLanguage = GetLanguageID( nUserPrimIndex );
+ }
+ else if ( nSystemIndex != -1 )
+ {
+ Log( TEXT( "Info: Found system default language.\r\n" ) );
+ rLanguage = GetLanguageID( nSystemIndex );
+ }
+ else if ( nSystemPrimIndex != -1 )
+ {
+ Log( TEXT( "Info: Found system default primary language.\r\n" ) );
+ rLanguage = GetLanguageID( nSystemPrimIndex );
+ }
+ else
+ {
+ Log( TEXT( "Info: Use default language from ini file.\r\n" ) );
+ rLanguage = GetLanguageID( 0 );
+ }
+ delete [] sString;
+ }
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+HMODULE SetupAppX::LoadMsiLibrary()
+{
+ HMODULE hMsi = NULL;
+ HKEY hInstKey = NULL;
+
+ // find registered location of Msi.dll
+ if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sInstKey, 0, KEY_READ, &hInstKey ) )
+ {
+ long nRet = ERROR_SUCCESS;
+ TCHAR *sMsiFolder = new TCHAR[ MAX_PATH + 1 ];
+ DWORD dwMsiFolderSize = MAX_PATH + 1;
+ DWORD dwType = 0;
+
+ if ( ERROR_MORE_DATA == ( nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL,
+ &dwType, (BYTE*)sMsiFolder, &dwMsiFolderSize ) ) )
+ {
+ // try again with larger buffer
+ delete [] sMsiFolder;
+ sMsiFolder = new TCHAR[ dwMsiFolderSize ];
+
+ nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL, &dwType,
+ (BYTE*)sMsiFolder, &dwMsiFolderSize );
+ }
+
+ if ( ERROR_SUCCESS == nRet && dwType == REG_SZ && dwMsiFolderSize > 0 )
+ {
+ // load Msi.dll from registered location
+ int nLength = lstrlen( sMsiDll ) + dwMsiFolderSize + 1; // use StringCchLength ?
+ TCHAR *pMsiLocation = new TCHAR[ nLength ];
+
+ if ( SUCCEEDED( StringCchCopy( pMsiLocation, nLength, sMsiFolder ) ) &&
+ SUCCEEDED( StringCchCat( pMsiLocation, nLength, sMsiDll ) ) )
+ {
+ hMsi = LoadLibrary( pMsiLocation );
+ }
+ }
+ }
+
+ if ( !hMsi ) // use the default location
+ {
+ hMsi = LoadLibrary( sMsiDll );
+ }
+
+ return hMsi;
+}
+
+//--------------------------------------------------------------------------
+LPCTSTR SetupAppX::GetPathToMSI()
+{
+ LPTSTR sMsiPath = NULL;
+ HKEY hInstKey = NULL;
+ TCHAR *sMsiFolder = new TCHAR[ MAX_PATH + 1 ];
+ DWORD nMsiFolderSize = MAX_PATH + 1;
+
+ sMsiFolder[0] = '\0';
+
+ // find registered location of Msi.dll
+ if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sInstKey, 0, KEY_READ, &hInstKey ) )
+ {
+ LONG nRet = ERROR_SUCCESS;
+ DWORD dwType = 0;
+
+ if ( ERROR_MORE_DATA == ( nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL,
+ &dwType, (BYTE*)sMsiFolder, &nMsiFolderSize ) ) )
+ {
+ // try again with larger buffer
+ delete [] sMsiFolder;
+ sMsiFolder = new TCHAR[ nMsiFolderSize ];
+
+ nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL, &dwType,
+ (BYTE*)sMsiFolder, &nMsiFolderSize );
+ }
+
+ if ( ERROR_SUCCESS != nRet || dwType != REG_SZ || nMsiFolderSize == 0 )
+ sMsiFolder[0] = '\0';
+ }
+
+ if ( sMsiFolder[0] == '\0' ) // use the default location
+ {
+ Log( TEXT( " Could not find path to msiexec.exe in registry" ) );
+
+ DWORD nRet = WIN::GetSystemDirectory( sMsiFolder, nMsiFolderSize );
+ if ( nRet > nMsiFolderSize )
+ {
+ delete [] sMsiFolder;
+ sMsiFolder = new TCHAR[ nRet ];
+ nMsiFolderSize = nRet;
+
+ nRet = WIN::GetSystemDirectory( sMsiFolder, nMsiFolderSize );
+ }
+ if ( 0 == nRet )
+ {
+ sMsiFolder[0] = '\0';
+ SetError( WIN::GetLastError() );
+ }
+ nMsiFolderSize = nRet;
+ }
+
+ if ( sMsiFolder[0] != '\0' )
+ {
+ int nLength = lstrlen( sMsiExe ) + lstrlen( sMsiFolder ) + 1;
+ sMsiPath = new TCHAR[ nLength ];
+
+ if ( FAILED( StringCchCopy( sMsiPath, nLength, sMsiFolder ) ) ||
+ FAILED( StringCchCat( sMsiPath, nLength, sMsiExe ) ) )
+ {
+ delete [] sMsiPath;
+ sMsiPath = NULL;
+ }
+ }
+
+ if ( ! sMsiPath )
+ Log( TEXT( "ERROR: Can't build path to msiexec.exe!" ) );
+
+ return sMsiPath;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::LaunchInstaller( LPCTSTR pParam )
+{
+ LPCTSTR sMsiPath = GetPathToMSI();
+
+ if ( !sMsiPath )
+ {
+ Log( TEXT( "ERROR: msiexec not found!" ) );
+ SetError( ERROR_FILE_NOT_FOUND );
+ return false;
+ }
+
+ STARTUPINFO aSUI;
+ PROCESS_INFORMATION aPI;
+
+ Log( TEXT( " Will install using <%s>\r\n" ), sMsiPath );
+ Log( TEXT( " Prameters are: %s\r\n" ), pParam );
+
+ OutputDebugStringFormat( TEXT( " Will install using <%s>\r\n" ), sMsiPath );
+ OutputDebugStringFormat( TEXT( " Prameters are: %s\r\n" ), pParam );
+
+ ZeroMemory( (void*)&aPI, sizeof( PROCESS_INFORMATION ) );
+ ZeroMemory( (void*)&aSUI, sizeof( STARTUPINFO ) );
+
+ aSUI.cb = sizeof(STARTUPINFO);
+ aSUI.dwFlags = STARTF_USESHOWWINDOW;
+ aSUI.wShowWindow = SW_SHOW;
+
+ DWORD nCmdLineLength = lstrlen( sMsiPath ) + lstrlen( pParam ) + 2;
+ TCHAR *sCmdLine = new TCHAR[ nCmdLineLength ];
+
+ if ( FAILED( StringCchCopy( sCmdLine, nCmdLineLength, sMsiPath ) ) ||
+ FAILED( StringCchCat( sCmdLine, nCmdLineLength, TEXT( " " ) ) ) ||
+ FAILED( StringCchCat( sCmdLine, nCmdLineLength, pParam ) ) )
+ {
+ delete [] sCmdLine;
+ SetError( ERROR_INSTALL_FAILURE );
+ return false;
+ }
+
+ if ( !WIN::CreateProcess( NULL, sCmdLine, NULL, NULL, FALSE,
+ CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
+ &aSUI, &aPI ) )
+ {
+ Log( TEXT( "ERROR: Could not create process %s.\r\n" ), sCmdLine );
+ SetError( WIN::GetLastError() );
+ delete [] sCmdLine;
+ return false;
+ }
+
+ DWORD nResult = WaitForProcess( aPI.hProcess );
+ bool bRet = true;
+
+ if( ERROR_SUCCESS != nResult )
+ {
+ Log( TEXT( "ERROR: While waiting for %s.\r\n" ), sCmdLine );
+ SetError( nResult );
+ bRet = false;
+ }
+ else
+ {
+ GetExitCodeProcess( aPI.hProcess, &nResult );
+ SetError( nResult );
+
+ if ( nResult != ERROR_SUCCESS )
+ {
+ TCHAR sBuf[80];
+ StringCchPrintf( sBuf, 80, TEXT("Warning: msiexec returned %u.\r\n"), nResult );
+ Log( sBuf );
+ }
+ else
+ Log( TEXT( " Installation completed successfully.\r\n" ) );
+ }
+
+ CloseHandle( aPI.hProcess );
+
+ delete [] sCmdLine;
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::Install( long nLanguage )
+{
+ LPTSTR pTransform = NULL;
+
+ if ( nLanguage ) // look for transformation
+ {
+ for ( int i = 0; i < m_nLanguageCount; i++ )
+ {
+ if ( m_ppLanguageList[i]->m_nLanguageID == nLanguage )
+ {
+ if ( m_ppLanguageList[i]->m_pTransform )
+ {
+ if ( !GetPathToFile( m_ppLanguageList[i]->m_pTransform,
+ &pTransform ) )
+ {
+ Log( TEXT( "ERROR: Could not find transform <%s\r\n" ), m_ppLanguageList[i]->m_pTransform );
+ return false;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ TCHAR *pDataBasePath = NULL;
+
+ if ( ! GetPathToFile( m_pDatabase, &pDataBasePath ) )
+ {
+ Log( TEXT( "ERROR: Could not find database <%s\r\n" ), m_pDatabase );
+ SetError( ERROR_INSTALL_SOURCE_ABSENT );
+ return false;
+ }
+
+ // we will always use the parameter setup used
+ int nParLen = lstrlen( PARAM_SETUP_USED );
+
+ if ( m_bRegNoMsoTypes )
+ nParLen += lstrlen( PARAM_REG_NO_MSO_TYPES );
+ else if ( m_bRegAllMsoTypes )
+ nParLen += lstrlen( PARAM_REG_ALL_MSO_TYPES );
+
+ if ( m_pAdvertise )
+ nParLen += lstrlen( m_pAdvertise ) + 1; // one for the space
+ else if ( m_bIsMinorUpgrade )
+ nParLen += lstrlen( PARAM_MINOR_UPGRADE );
+ else
+ nParLen += lstrlen( PARAM_PACKAGE );
+
+ nParLen += lstrlen( pDataBasePath ) + 3; // two quotes, one null
+
+ if ( NeedReboot() )
+ nParLen += lstrlen( PARAM_REBOOT );
+
+ if ( m_pPatchFiles )
+ {
+ nParLen += lstrlen( PARAM_PATCH );
+ nParLen += lstrlen( m_pPatchFiles );
+ }
+
+ if ( pTransform )
+ {
+ nParLen += lstrlen( PARAM_TRANSFORM );
+ nParLen += lstrlen( pTransform ) + 2; // two quotes
+ }
+
+ if ( m_pCmdLine )
+ nParLen += lstrlen( m_pCmdLine ) + 1; // one for the space;
+
+ TCHAR *pParams = new TCHAR[ nParLen ];
+
+ StringCchCopy( pParams, nParLen, PARAM_SETUP_USED );
+
+ if ( m_bRegNoMsoTypes )
+ StringCchCat( pParams, nParLen, PARAM_REG_NO_MSO_TYPES );
+ else if ( m_bRegAllMsoTypes )
+ StringCchCat( pParams, nParLen, PARAM_REG_ALL_MSO_TYPES );
+
+ if ( m_pAdvertise )
+ StringCchCat( pParams, nParLen, m_pAdvertise );
+ else if ( IsAdminInstall() )
+ StringCchCat( pParams, nParLen, PARAM_ADMIN );
+ else if ( m_bIsMinorUpgrade )
+ StringCchCat( pParams, nParLen, PARAM_MINOR_UPGRADE );
+ else
+ StringCchCat( pParams, nParLen, PARAM_PACKAGE );
+
+ StringCchCat( pParams, nParLen, TEXT( "\"" ) );
+ StringCchCat( pParams, nParLen, pDataBasePath );
+ StringCchCat( pParams, nParLen, TEXT( "\"" ) );
+
+ if ( NeedReboot() )
+ StringCchCat( pParams, nParLen, PARAM_REBOOT );
+
+ if ( m_pPatchFiles )
+ {
+ StringCchCat( pParams, nParLen, PARAM_PATCH );
+ StringCchCat( pParams, nParLen, m_pPatchFiles );
+ }
+
+ if ( pTransform )
+ {
+ StringCchCat( pParams, nParLen, PARAM_TRANSFORM );
+ StringCchCat( pParams, nParLen, TEXT( "\"" ) );
+ StringCchCat( pParams, nParLen, pTransform );
+ StringCchCat( pParams, nParLen, TEXT( "\"" ) );
+ }
+
+ if ( m_pCmdLine )
+ {
+ StringCchCat( pParams, nParLen, TEXT( " " ) );
+ StringCchCat( pParams, nParLen, m_pCmdLine );
+ }
+
+ return LaunchInstaller( pParams );
+}
+
+//--------------------------------------------------------------------------
+UINT SetupAppX::GetError() const
+{
+ UINT nErr = 0;
+
+ if ( m_pMSIErrorCode )
+ nErr = (UINT) *m_pMSIErrorCode;
+
+ if ( nErr == 0 )
+ nErr = m_uiRet;
+
+ if ( nErr != 0 )
+ OutputDebugStringFormat( TEXT("Setup will return error (%d).\n"), nErr );
+ return nErr;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::DisplayError( UINT nErr ) const
+{
+ TCHAR sError[ MAX_TEXT_LENGTH ] = {0};
+ TCHAR sTmp[ MAX_TEXT_LENGTH ] = {0};
+
+ UINT nMsgType = MB_OK | MB_ICONERROR;
+
+ switch ( nErr )
+ {
+ case ERROR_SUCCESS: break; // 0
+
+ case ERROR_FILE_NOT_FOUND: // 2
+ WIN::LoadString( m_hInst, IDS_FILE_NOT_FOUND, sTmp, MAX_TEXT_LENGTH );
+ StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pErrorText );
+ break;
+ case ERROR_INVALID_DATA: // 13
+ WIN::LoadString( m_hInst, IDS_INVALID_PROFILE, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_OUTOFMEMORY: WIN::LoadString( m_hInst, IDS_OUTOFMEM, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_INSTALL_USEREXIT:
+ WIN::LoadString( m_hInst, IDS_USER_CANCELLED, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_INSTALL_ALREADY_RUNNING: // 1618
+ WIN::LoadString( m_hInst, IDS_ALREADY_RUNNING, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_INSTALL_SOURCE_ABSENT:
+ WIN::LoadString( m_hInst, IDS_NOMSI, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_DS_INSUFF_ACCESS_RIGHTS: // 8344
+ WIN::LoadString( m_hInst, IDS_REQUIRES_ADMIN_PRIV, sError, MAX_TEXT_LENGTH );
+ break;
+ case E_ABORT: WIN::LoadString( m_hInst, IDS_UNKNOWN_ERROR, sError, MAX_TEXT_LENGTH );
+ break;
+ case ERROR_INVALID_PARAMETER: // 87
+ WIN::LoadString( m_hInst, IDS_INVALID_PARAM, sTmp, MAX_TEXT_LENGTH );
+ StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pErrorText );
+ break;
+
+ case ERROR_SETUP_TO_OLD: // - 3
+ WIN::LoadString( m_hInst, IDS_SETUP_TO_OLD, sTmp, MAX_TEXT_LENGTH );
+ StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pReqVersion, m_pErrorText );
+ break;
+ case ERROR_SETUP_NOT_FOUND: // - 4
+ WIN::LoadString( m_hInst, IDS_SETUP_NOT_FOUND, sTmp, MAX_TEXT_LENGTH );
+ StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pReqVersion );
+ break;
+ case ERROR_SHOW_USAGE: // - 2
+ nMsgType = MB_OK | MB_ICONINFORMATION;
+ WIN::LoadString( m_hInst, IDS_USAGE, sError, MAX_TEXT_LENGTH );
+ break;
+
+ default: WIN::LoadString( m_hInst, IDS_UNKNOWN_ERROR, sError, MAX_TEXT_LENGTH );
+ break;
+ }
+
+ if ( sError[0] )
+ {
+ if ( !m_bQuiet )
+ {
+ ConvertNewline( sError );
+ WIN::MessageBox( NULL, sError, m_pAppTitle, nMsgType );
+ }
+
+ Log( TEXT( "ERROR: %s\r\n" ), sError );
+ }
+}
+
+//--------------------------------------------------------------------------
+long SetupAppX::GetLanguageID( long nIndex ) const
+{
+ if ( nIndex >=0 && nIndex < m_nLanguageCount )
+ return m_ppLanguageList[ nIndex ]->m_nLanguageID;
+ else
+ return 0;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::GetLanguageName( long nLanguage, LPTSTR sName ) const
+{
+ switch ( nLanguage )
+ {
+ case 1028: WIN::LoadString( m_hInst, IDS_LANGUAGE_ZH_TW, sName, MAX_LANGUAGE_LEN ); break;
+ case 1029: WIN::LoadString( m_hInst, IDS_LANGUAGE_CS, sName, MAX_LANGUAGE_LEN ); break;
+ case 1030: WIN::LoadString( m_hInst, IDS_LANGUAGE_DA, sName, MAX_LANGUAGE_LEN ); break;
+ case 1031: WIN::LoadString( m_hInst, IDS_LANGUAGE_DE_DE, sName, MAX_LANGUAGE_LEN ); break;
+ case 1032: WIN::LoadString( m_hInst, IDS_LANGUAGE_EL, sName, MAX_LANGUAGE_LEN ); break;
+ case 1033: WIN::LoadString( m_hInst, IDS_LANGUAGE_EN_US, sName, MAX_LANGUAGE_LEN ); break;
+ case 1034: WIN::LoadString( m_hInst, IDS_LANGUAGE_ES, sName, MAX_LANGUAGE_LEN ); break;
+ case 1035: WIN::LoadString( m_hInst, IDS_LANGUAGE_FI, sName, MAX_LANGUAGE_LEN ); break;
+ case 1036: WIN::LoadString( m_hInst, IDS_LANGUAGE_FR_FR, sName, MAX_LANGUAGE_LEN ); break;
+ case 1037: WIN::LoadString( m_hInst, IDS_LANGUAGE_HE, sName, MAX_LANGUAGE_LEN ); break;
+ case 1038: WIN::LoadString( m_hInst, IDS_LANGUAGE_HU, sName, MAX_LANGUAGE_LEN ); break;
+ case 1040: WIN::LoadString( m_hInst, IDS_LANGUAGE_IT_IT, sName, MAX_LANGUAGE_LEN ); break;
+ case 1041: WIN::LoadString( m_hInst, IDS_LANGUAGE_JA, sName, MAX_LANGUAGE_LEN ); break;
+ case 1042: WIN::LoadString( m_hInst, IDS_LANGUAGE_KO, sName, MAX_LANGUAGE_LEN ); break;
+ case 1043: WIN::LoadString( m_hInst, IDS_LANGUAGE_NL_NL, sName, MAX_LANGUAGE_LEN ); break;
+ case 1044: WIN::LoadString( m_hInst, IDS_LANGUAGE_NO_NO, sName, MAX_LANGUAGE_LEN ); break;
+ case 1045: WIN::LoadString( m_hInst, IDS_LANGUAGE_PL, sName, MAX_LANGUAGE_LEN ); break;
+ case 1046: WIN::LoadString( m_hInst, IDS_LANGUAGE_PT_BR, sName, MAX_LANGUAGE_LEN ); break;
+ case 1049: WIN::LoadString( m_hInst, IDS_LANGUAGE_RU, sName, MAX_LANGUAGE_LEN ); break;
+ case 1051: WIN::LoadString( m_hInst, IDS_LANGUAGE_SK, sName, MAX_LANGUAGE_LEN ); break;
+ case 1053: WIN::LoadString( m_hInst, IDS_LANGUAGE_SV_SE, sName, MAX_LANGUAGE_LEN ); break;
+ case 1054: WIN::LoadString( m_hInst, IDS_LANGUAGE_TH, sName, MAX_LANGUAGE_LEN ); break;
+ case 1055: WIN::LoadString( m_hInst, IDS_LANGUAGE_TR, sName, MAX_LANGUAGE_LEN ); break;
+ case 1061: WIN::LoadString( m_hInst, IDS_LANGUAGE_ET, sName, MAX_LANGUAGE_LEN ); break;
+ case 2052: WIN::LoadString( m_hInst, IDS_LANGUAGE_ZH_CN, sName, MAX_LANGUAGE_LEN ); break;
+ case 2070: WIN::LoadString( m_hInst, IDS_LANGUAGE_PT_PT, sName, MAX_LANGUAGE_LEN ); break;
+
+ default:
+ {
+ TCHAR sTmp[ MAX_LANGUAGE_LEN ] = {0};
+
+ WIN::LoadString( m_hInst, IDS_UNKNOWN_LANG, sTmp, MAX_LANGUAGE_LEN );
+ StringCchPrintf( sName, MAX_LANGUAGE_LEN, sTmp, nLanguage );
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::CheckVersion()
+{
+ boolean bRet = false;
+ HMODULE hMsi = LoadMsiLibrary();
+
+ Log( TEXT( " Looking for installed MSI with version >= %s\r\n" ), m_pReqVersion );
+
+ if ( !hMsi )
+ {
+ Log( TEXT( "Error: No MSI found!\r\n" ) );
+ SetError( (UINT) ERROR_SETUP_NOT_FOUND );
+ }
+ else
+ {
+ PFnDllGetVersion pDllGetVersion = (PFnDllGetVersion) GetProcAddress( hMsi, MSIAPI_DllGetVersion );
+
+ if ( pDllGetVersion )
+ {
+ DLLVERSIONINFO aInfo;
+
+ aInfo.cbSize = sizeof( DLLVERSIONINFO );
+ if ( NOERROR == pDllGetVersion( &aInfo ) )
+ {
+ TCHAR pMsiVersion[ VERSION_SIZE ];
+ StringCchPrintf( pMsiVersion, VERSION_SIZE, TEXT("%d.%d.%4d"),
+ aInfo.dwMajorVersion,
+ aInfo.dwMinorVersion,
+ aInfo.dwBuildNumber );
+ if ( _tcsncmp( pMsiVersion, m_pReqVersion, _tcslen( pMsiVersion ) ) < 0 )
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pMsiVersion );
+ SetError( (UINT) ERROR_SETUP_TO_OLD );
+ Log( TEXT( "Warning: Old MSI version found <%s>, update needed!\r\n" ), pMsiVersion );
+ }
+ else
+ {
+ Log( TEXT( " Found MSI version <%s>, no update needed\r\n" ), pMsiVersion );
+ bRet = true;
+ }
+ if ( aInfo.dwMajorVersion >= 3 )
+ m_bSupportsPatch = true;
+ else
+ Log( TEXT("Warning: Patching not supported! MSI-Version <%s>\r\n"), pMsiVersion );
+ }
+ }
+
+ FreeLibrary( hMsi );
+ }
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::CheckForUpgrade()
+{
+ // When we have patch files we will never try an Minor upgrade
+ if ( m_pPatchFiles ) return true;
+
+ if ( !m_pUpgradeKey || ( _tcslen( m_pUpgradeKey ) == 0 ) )
+ {
+ Log( TEXT( " No Upgrade Key Found -> continue with standard installation!\r\n" ) );
+ return true;
+ }
+
+ HKEY hInstKey = NULL;
+
+ if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, m_pUpgradeKey, 0, KEY_READ, &hInstKey ) )
+ {
+ Log( TEXT( " Found Upgrade Key in Registry (HKLM) -> will try minor upgrade!\r\n" ) );
+ m_bIsMinorUpgrade = true;
+ }
+ else if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER, m_pUpgradeKey, 0, KEY_READ, &hInstKey ) )
+ {
+ Log( TEXT( " Found Upgrade Key in Registry (HKCU) -> will try minor upgrade!\r\n" ) );
+ m_bIsMinorUpgrade = true;
+ }
+ else
+ {
+ Log( TEXT( " Didn't Find Upgrade Key in Registry -> continue with standard installation!\r\n" ) );
+ return true;
+ }
+
+ if ( m_pProductVersion && ( _tcslen( m_pProductVersion ) > 0 ) )
+ {
+ TCHAR *sProductVersion = new TCHAR[ MAX_PATH + 1 ];
+ DWORD nSize = MAX_PATH + 1;
+
+ sProductVersion[0] = '\0';
+
+ // get product version
+ if ( ERROR_SUCCESS == RegQueryValueEx( hInstKey, PRODUCT_VERSION, NULL, NULL, (LPBYTE)sProductVersion, &nSize ) )
+ {
+ if ( lstrcmpi( sProductVersion, m_pProductVersion ) == 0 )
+ {
+ Log( TEXT( " Same Product Version already installed, no minor upgrade!\r\n" ) );
+ m_bIsMinorUpgrade = false;
+ }
+ }
+
+ delete [] sProductVersion;
+ }
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::IsTerminalServerInstalled() const
+{
+ boolean bIsTerminalServer = false;
+
+ const TCHAR sSearchStr[] = TEXT("Terminal Server");
+ const TCHAR sKey[] = TEXT("System\\CurrentControlSet\\Control\\ProductOptions");
+ const TCHAR sValue[] = TEXT("ProductSuite");
+
+ DWORD dwSize = 0;
+ HKEY hKey = 0;
+ DWORD dwType = 0;
+
+ if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sKey, 0, KEY_READ, &hKey ) &&
+ ERROR_SUCCESS == RegQueryValueEx( hKey, sValue, NULL, &dwType, NULL, &dwSize ) &&
+ dwSize > 0 &&
+ REG_MULTI_SZ == dwType )
+ {
+ TCHAR* sSuiteList = new TCHAR[ (dwSize*sizeof(byte)/sizeof(TCHAR)) + 1 ];
+
+ ZeroMemory(sSuiteList, dwSize);
+
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, sValue, NULL, &dwType, (LPBYTE)sSuiteList, &dwSize) )
+ {
+ DWORD nMulti = 0;
+ DWORD nSrch = lstrlen( sSearchStr );
+ const TCHAR *sSubString = sSuiteList;
+
+ while (*sSubString)
+ {
+ nMulti = lstrlen( sSubString );
+ if ( nMulti == nSrch && 0 == lstrcmp( sSearchStr, sSubString ) )
+ {
+ bIsTerminalServer = true;
+ break;
+ }
+
+ sSubString += (nMulti + 1);
+ }
+ }
+ delete [] sSuiteList;
+ }
+
+ if ( hKey )
+ RegCloseKey( hKey );
+
+ return bIsTerminalServer;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::AlreadyRunning() const
+{
+ if ( m_bIgnoreAlreadyRunning )
+ {
+ Log( TEXT("Ignoring already running MSI instance!\r\n") );
+ return false;
+ }
+
+ const TCHAR *sMutexName = NULL;
+ const TCHAR sGUniqueName[] = TEXT( "Global\\_MSISETUP_{EA8130C1-8D3D-4338-9309-1A52D530D846}" );
+ const TCHAR sUniqueName[] = TEXT( "_MSISETUP_{EA8130C1-8D3D-4338-9309-1A52D530D846}" );
+
+ if ( IsWin9x() )
+ sMutexName = sUniqueName;
+ else if ( ( GetOSVersion() < 5 ) && ! IsTerminalServerInstalled() )
+ sMutexName = sUniqueName;
+ else
+ sMutexName = sGUniqueName;
+
+ HANDLE hMutex = 0;
+
+ hMutex = WIN::CreateMutex( NULL, FALSE, sMutexName );
+
+ if ( !hMutex || ERROR_ALREADY_EXISTS == WIN::GetLastError() )
+ {
+ if ( !hMutex )
+ Log( TEXT( "ERROR: AlreadyRunning() could not create mutex!\r\n" ) );
+ else
+ Log( TEXT( "ERROR: There's already a setup running!\r\n" ) );
+
+ return true;
+ }
+ Log( TEXT( " No running Setup found\r\n" ) );
+
+ return false;
+}
+
+//--------------------------------------------------------------------------
+DWORD SetupAppX::WaitForProcess( HANDLE hHandle )
+{
+ DWORD nResult = NOERROR;
+ boolean bLoop = true;
+
+ MSG aMsg;
+ ZeroMemory( (void*) &aMsg, sizeof(MSG) );
+
+ while ( bLoop )
+ {
+ switch ( WIN::MsgWaitForMultipleObjects( 1, &hHandle, false,
+ INFINITE, QS_ALLINPUT ) )
+ {
+ case WAIT_OBJECT_0: bLoop = false;
+ break;
+
+ case (WAIT_OBJECT_0 + 1):
+ {
+ if ( WIN::PeekMessage( &aMsg, NULL, NULL, NULL, PM_REMOVE ) )
+ {
+ WIN::TranslateMessage( &aMsg );
+ WIN::DispatchMessage( &aMsg );
+ }
+ break;
+ }
+
+ default:
+ {
+ nResult = WIN::GetLastError();
+ bLoop = false;
+ }
+ }
+ }
+
+ return nResult;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::Log( LPCTSTR pMessage, LPCTSTR pText ) const
+{
+ if ( m_pLogFile )
+ {
+ static boolean bInit = false;
+
+ if ( !bInit )
+ {
+ bInit = true;
+ if ( ! IsWin9x() )
+ _ftprintf( m_pLogFile, TEXT("%c"), 0xfeff );
+
+ _tsetlocale( LC_ALL, TEXT("") );
+ _ftprintf( m_pLogFile, TEXT("\nCodepage=%s\nMultiByte Codepage=[%d]\n"),
+ _tsetlocale( LC_ALL, NULL ), _getmbcp() );
+ }
+ if ( pText )
+ {
+ _ftprintf( m_pLogFile, pMessage, pText );
+ OutputDebugStringFormat( pMessage, pText );
+ }
+ else
+ {
+ _ftprintf( m_pLogFile, pMessage );
+ OutputDebugStringFormat( pMessage );
+ }
+
+ fflush( m_pLogFile );
+ }
+}
+
+//--------------------------------------------------------------------------
+DWORD SetupAppX::GetNextArgument( LPCTSTR pStr, LPTSTR *pArg, LPTSTR *pNext,
+ boolean bStripQuotes )
+{
+ boolean bInQuotes = false;
+ boolean bFoundArgEnd = false;
+ LPCTSTR pChar = pStr;
+ LPCTSTR pFirst = NULL;
+
+ if ( NULL == pChar )
+ return ERROR_NO_MORE_ITEMS;
+
+ while ( ' ' == (*pChar) || '\t' == (*pChar) )
+ pChar = CharNext( pChar );
+
+ if ( '\0' == (*pChar) )
+ return ERROR_NO_MORE_ITEMS;
+
+ int nCount = 1;
+ pFirst = pChar;
+
+ while ( ! bFoundArgEnd )
+ {
+ if ( '\0' == (*pChar) )
+ bFoundArgEnd = true;
+ else if ( !bInQuotes && ' ' == (*pChar) )
+ bFoundArgEnd = true;
+ else if ( !bInQuotes && '\t' == (*pChar) )
+ bFoundArgEnd = true;
+ else
+ {
+ if ( '\"' == (*pChar) )
+ {
+ bInQuotes = !bInQuotes;
+ if ( bStripQuotes )
+ {
+ if ( pChar == pFirst )
+ pFirst = CharNext( pFirst );
+ nCount -= 1;
+ }
+ }
+
+ pChar = CharNext( pChar );
+ nCount += 1;
+ }
+ }
+
+ if ( pArg )
+ {
+ *pArg = new TCHAR[ nCount ];
+ StringCchCopyN ( *pArg, nCount, pFirst, nCount-1 );
+ }
+
+ if ( pNext )
+ *pNext = CharNext( pChar );
+
+ return ERROR_SUCCESS;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::GetCmdLineParameters( LPTSTR *pCmdLine )
+{
+ int nRet = ERROR_SUCCESS;
+ LPTSTR pStart = NULL;
+ LPTSTR pNext = NULL;
+
+ if ( GetNextArgument( *pCmdLine, NULL, &pNext ) != ERROR_SUCCESS )
+ {
+ SetError( ERROR_NO_MORE_ITEMS );
+ return false;
+ }
+
+ int nSize = lstrlen( *pCmdLine ) + 2;
+ TCHAR *pNewCmdLine = new TCHAR[ nSize ];
+ pNewCmdLine[0] = '\0';
+
+ while ( GetNextArgument( pNext, &pStart, &pNext ) == ERROR_SUCCESS )
+ {
+ boolean bDeleteStart = true;
+
+ if ( (*pStart) == '/' || (*pStart) == '-' )
+ {
+ LPTSTR pSub = CharNext( pStart );
+ if ( (*pSub) == 'l' || (*pSub) == 'L' )
+ {
+ pSub = CharNext( pSub );
+ if ( (*pSub) == 'a' || (*pSub) == 'A' )
+ { // --- handle the lang parameter ---
+ LPTSTR pLanguage = NULL;
+ LPTSTR pLastChar;
+ if ( GetNextArgument( pNext, &pLanguage, &pNext, true ) != ERROR_SUCCESS )
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart );
+ nRet = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ m_nLanguageID = _tcstol( pLanguage, &pLastChar, 10 );
+ delete [] pLanguage;
+ }
+ else
+ { // --- handle the l(og) parameter ---
+ boolean bAppend = false;
+ LPTSTR pFileName = NULL;
+
+ while ( *pSub )
+ {
+ if ( *pSub == '+' )
+ {
+ bAppend = true;
+ break;
+ }
+ pSub = CharNext( pSub );
+ }
+
+ if ( GetNextArgument( pNext, &pFileName, &pNext, true ) != ERROR_SUCCESS )
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart );
+ nRet = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ // we need to append a '+' otherwise msiexec would overwrite our log file
+ if ( !bAppend && FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( "+" ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " \"" ) ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, pFileName ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( "\" " ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+
+ if ( bAppend )
+ m_pLogFile = _tfopen( pFileName, TEXT( "ab" ) );
+ else
+ m_pLogFile = _tfopen( pFileName, TEXT( "wb" ) );
+
+ delete [] pFileName;
+ }
+ }
+ else if ( (*pSub) == 'q' || (*pSub) == 'Q' )
+ { // --- Handle quiet file parameter ---
+ pSub = CharNext( pSub );
+ if ( ! (*pSub) || (*pSub) == 'n' || (*pSub) == 'N' )
+ m_bQuiet = true;
+
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ }
+ else if ( _tcsnicmp( pSub, PARAM_RUNNING, _tcslen( PARAM_RUNNING ) ) == 0 )
+ {
+ m_bIgnoreAlreadyRunning = true;
+ }
+ else if ( _tcsnicmp( pSub, CMDLN_REG_ALL_MSO_TYPES, _tcslen( CMDLN_REG_ALL_MSO_TYPES ) ) == 0 )
+ {
+ m_bRegAllMsoTypes = true;
+ }
+ else if ( _tcsnicmp( pSub, CMDLN_REG_NO_MSO_TYPES, _tcslen( CMDLN_REG_NO_MSO_TYPES ) ) == 0 )
+ {
+ m_bRegNoMsoTypes = true;
+ }
+ else if ( (*pSub) == 'i' || (*pSub) == 'I' || (*pSub) == 'f' || (*pSub) == 'F' ||
+ (*pSub) == 'p' || (*pSub) == 'P' || (*pSub) == 'x' || (*pSub) == 'X' ||
+ (*pSub) == 'y' || (*pSub) == 'Y' || (*pSub) == 'z' || (*pSub) == 'Z' )
+ {
+ StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart );
+ nRet = ERROR_INVALID_PARAMETER;
+ break;
+ }
+ else if ( (*pSub) == 'a' || (*pSub) == 'A' )
+ { // --- Handle Adminstrative Installation ---
+ SetAdminInstall( true );
+ }
+ else if ( (*pSub) == 'j' || (*pSub) == 'J' )
+ { // --- Handle Adminstrative Installation ---
+ m_pAdvertise = pStart;
+ m_bQuiet = true;
+ bDeleteStart = false;
+ }
+ else if ( (*pSub) == '?' || (*pSub) == 'h' || (*pSub) == 'H' )
+ { // --- Handle Show Usage ---
+ nRet = ERROR_SHOW_USAGE;
+ break;
+ }
+ else
+ {
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) ||
+ FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) )
+ {
+ nRet = ERROR_OUTOFMEMORY;
+ break;
+ }
+ }
+
+ if ( bDeleteStart ) delete [] pStart;
+ pStart = NULL;
+ }
+
+ if ( pStart ) delete [] pStart;
+
+ *pCmdLine = pNewCmdLine;
+
+ if ( nRet != ERROR_SUCCESS )
+ {
+ SetError( nRet );
+ return false;
+ }
+ else
+ return true;;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::IsAdmin()
+{
+ if ( IsWin9x() )
+ return true;
+
+ PSID aPsidAdmin;
+ SID_IDENTIFIER_AUTHORITY aAuthority = SECURITY_NT_AUTHORITY;
+
+ if ( !AllocateAndInitializeSid( &aAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
+ &aPsidAdmin ) )
+ return false;
+
+ BOOL bIsAdmin = FALSE;
+
+ if ( GetOSVersion() >= 5 )
+ {
+ HMODULE hAdvapi32 = LoadLibrary( ADVAPI32_DLL );
+
+ if ( !hAdvapi32 )
+ bIsAdmin = FALSE;
+ else
+ {
+ PFnCheckTokenMembership pfnCheckTokenMembership = (PFnCheckTokenMembership) GetProcAddress( hAdvapi32, ADVAPI32API_CheckTokenMembership);
+ if ( !pfnCheckTokenMembership || !pfnCheckTokenMembership( NULL, aPsidAdmin, &bIsAdmin ) )
+ bIsAdmin = FALSE;
+ }
+ FreeLibrary( hAdvapi32 );
+ }
+ else
+ {
+ // NT4, check groups of user
+ HANDLE hAccessToken = 0;
+ UCHAR *szInfoBuffer = new UCHAR[ 1024 ]; // may need to resize if TokenInfo too big
+ DWORD dwInfoBufferSize = 1024;
+ DWORD dwRetInfoBufferSize = 0;
+ UINT i=0;
+
+ if ( WIN::OpenProcessToken( WIN::GetCurrentProcess(), TOKEN_READ, &hAccessToken ) )
+ {
+ bool bSuccess = false;
+ bSuccess = WIN::GetTokenInformation( hAccessToken, TokenGroups,
+ szInfoBuffer, dwInfoBufferSize,
+ &dwRetInfoBufferSize ) == TRUE;
+
+ if( dwRetInfoBufferSize > dwInfoBufferSize )
+ {
+ delete [] szInfoBuffer;
+ szInfoBuffer = new UCHAR[ dwRetInfoBufferSize ];
+ dwInfoBufferSize = dwRetInfoBufferSize;
+ bSuccess = WIN::GetTokenInformation( hAccessToken, TokenGroups,
+ szInfoBuffer, dwInfoBufferSize,
+ &dwRetInfoBufferSize ) == TRUE;
+ }
+
+ WIN::CloseHandle( hAccessToken );
+
+ if ( bSuccess )
+ {
+ PTOKEN_GROUPS pGroups = (PTOKEN_GROUPS)(UCHAR*) szInfoBuffer;
+ for( i=0; i<pGroups->GroupCount; i++ )
+ {
+ if( WIN::EqualSid( aPsidAdmin, pGroups->Groups[i].Sid ) )
+ {
+ bIsAdmin = TRUE;
+ break;
+ }
+ }
+ }
+
+ delete [] szInfoBuffer;
+ }
+ }
+
+ WIN::FreeSid( aPsidAdmin );
+
+ return bIsAdmin ? true : false;
+}
+
+//--------------------------------------------------------------------------
+LPTSTR SetupAppX::CopyIniFile( LPCTSTR pIniFile )
+{
+ m_pTmpName = _ttempnam( TEXT( "C:\\" ), TEXT( "Setup" ) );
+
+ if ( !m_pTmpName )
+ {
+ Log( TEXT( "ERROR: Could not create temp file\n" ) );
+ return NULL;
+ }
+
+ FILE *pOut = _tfopen( m_pTmpName, TEXT( "wb" ) );
+ FILE *pIn = _tfopen( pIniFile, TEXT( "rb" ) );
+
+ if ( pOut && pIn )
+ {
+ size_t nRead, nWritten;
+ BYTE pBuf[1024];
+
+ nRead = fread( pBuf, sizeof( BYTE ), 1024, pIn );
+ while ( nRead && !ferror( pIn ) )
+ {
+ nWritten = fwrite( pBuf, sizeof( BYTE ), nRead, pOut );
+ if ( nWritten != nRead )
+ {
+ Log( TEXT( "ERROR: Could not write all bytes to temp file\n" ) );
+ break;
+ }
+ nRead = fread( pBuf, sizeof( BYTE ), 1024, pIn );
+ }
+ }
+
+ if ( pOut ) fclose( pOut );
+ if ( pIn ) fclose( pIn );
+
+ return m_pTmpName;
+}
+
+//--------------------------------------------------------------------------
+void SetupAppX::ConvertNewline( LPTSTR pText ) const
+{
+ int i=0;
+
+ while ( pText[i] != 0 )
+ {
+ if ( ( pText[i] == '\\' ) && ( pText[i+1] == 'n' ) )
+ {
+ pText[i] = 0x0d;
+ pText[i+1] = 0x0a;
+ i+=2;
+ }
+ else
+ i+=1;
+ }
+}
+
+//--------------------------------------------------------------------------
+LPTSTR SetupAppX::SetProdToAppTitle( LPCTSTR pProdName )
+{
+ if ( !pProdName ) return m_pAppTitle;
+
+ LPTSTR pAppProdTitle = new TCHAR[ MAX_STR_CAPTION ];
+ pAppProdTitle[0] = '\0';
+
+ WIN::LoadString( m_hInst, IDS_APP_PROD_TITLE, pAppProdTitle, MAX_STR_CAPTION );
+
+ int nAppLen = lstrlen( pAppProdTitle );
+ int nProdLen = lstrlen( pProdName );
+
+ if ( ( nAppLen == 0 ) || ( nProdLen == 0 ) )
+ {
+ delete [] pAppProdTitle;
+ return m_pAppTitle;
+ }
+
+ int nLen = nAppLen + nProdLen + 3;
+
+ if ( nLen > STRSAFE_MAX_CCH ) return m_pAppTitle;
+
+ LPTSTR pIndex = _tcsstr( pAppProdTitle, PRODUCT_NAME_VAR );
+
+ if ( pIndex )
+ {
+ int nOffset = pIndex - pAppProdTitle;
+ int nVarLen = lstrlen( PRODUCT_NAME_VAR );
+
+ LPTSTR pNewTitle = new TCHAR[ nLen ];
+ pNewTitle[0] = '\0';
+
+ if ( nOffset > 0 )
+ {
+ StringCchCopyN( pNewTitle, nLen, pAppProdTitle, nOffset );
+ }
+
+ StringCchCat( pNewTitle, nLen, pProdName );
+
+ if ( nOffset + nVarLen < nAppLen )
+ {
+ StringCchCat( pNewTitle, nLen, pIndex + nVarLen );
+ }
+
+ delete [] m_pAppTitle;
+ m_pAppTitle = pNewTitle;
+ }
+
+ delete [] pAppProdTitle;
+
+ return m_pAppTitle;
+}
+
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::IsPatchInstalled( TCHAR* pBaseDir, TCHAR* pFileName )
+{
+ if ( !m_bSupportsPatch )
+ return false;
+
+ PMSIHANDLE hSummaryInfo;
+ int nLen = lstrlen( pBaseDir ) + lstrlen( pFileName ) + 1;
+ TCHAR *szDatabasePath = new TCHAR [ nLen ];
+ TCHAR sBuf[80];
+
+ StringCchCopy( szDatabasePath, nLen, pBaseDir );
+ StringCchCat( szDatabasePath, nLen, pFileName );
+
+ UINT nRet = MsiGetSummaryInformation( NULL, szDatabasePath, 0, &hSummaryInfo );
+
+ if ( nRet != ERROR_SUCCESS )
+ {
+ StringCchPrintf( sBuf, 80, TEXT("ERROR: IsPatchInstalled: MsiGetSummaryInformation returned %u.\r\n"), nRet );
+ Log( sBuf );
+ return false;
+ }
+
+ UINT uiDataType;
+ LPTSTR szPatchID = new TCHAR[ 64 ];
+ DWORD cchValueBuf = 64;
+ nRet = MsiSummaryInfoGetProperty( hSummaryInfo, PID_REVNUMBER, &uiDataType, NULL, NULL, szPatchID, &cchValueBuf );
+
+ if ( nRet != ERROR_SUCCESS )
+ {
+ StringCchPrintf( sBuf, 80, TEXT("ERROR: IsPatchInstalled: MsiSummaryInfoGetProperty returned %u.\r\n"), nRet );
+ Log( sBuf );
+ return false;
+ }
+
+ nRet = MsiGetPatchInfo( szPatchID, INSTALLPROPERTY_LOCALPACKAGE, NULL, NULL );
+
+ StringCchPrintf( sBuf, 80, TEXT(" GetPatchInfo for (%s) returned (%u)\r\n"), szPatchID, nRet );
+ Log( sBuf );
+
+ delete []szPatchID;
+
+ if ( nRet == ERROR_BAD_CONFIGURATION )
+ return false;
+ else if ( nRet == ERROR_INVALID_PARAMETER )
+ return false;
+ else if ( nRet == ERROR_MORE_DATA )
+ return true;
+ else if ( nRet == ERROR_SUCCESS )
+ return true;
+ else if ( nRet == ERROR_UNKNOWN_PRODUCT )
+ return false;
+ else if ( nRet == ERROR_UNKNOWN_PROPERTY )
+ return false;
+ else return false;
+
+ return false;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::InstallRuntimes( TCHAR *sProductCode, TCHAR *sRuntimePath )
+{
+ INSTALLSTATE nRet = MsiQueryProductState( sProductCode );
+ OutputDebugStringFormat( TEXT( "MsiQueryProductState returned <%d>\r\n" ), nRet );
+ if ( nRet == INSTALLSTATE_DEFAULT )
+ return true;
+
+ Log( TEXT( " Will install runtime <%s>\r\n" ), sRuntimePath );
+ OutputDebugStringFormat( TEXT( " Will install runtime <%s>\r\n" ), sRuntimePath );
+
+ STARTUPINFO aSUI;
+ PROCESS_INFORMATION aPI;
+
+ ZeroMemory( (void*)&aPI, sizeof( PROCESS_INFORMATION ) );
+ ZeroMemory( (void*)&aSUI, sizeof( STARTUPINFO ) );
+
+ aSUI.cb = sizeof(STARTUPINFO);
+ aSUI.dwFlags = STARTF_USESHOWWINDOW;
+ aSUI.wShowWindow = SW_SHOW;
+
+ DWORD nCmdLineLength = lstrlen( sRuntimePath ) + lstrlen( PARAM_SILENTINSTALL ) + 2;
+ TCHAR *sCmdLine = new TCHAR[ nCmdLineLength ];
+
+ if ( FAILED( StringCchCopy( sCmdLine, nCmdLineLength, sRuntimePath ) ) ||
+ FAILED( StringCchCat( sCmdLine, nCmdLineLength, PARAM_SILENTINSTALL ) ) )
+ {
+ delete [] sCmdLine;
+ SetError( ERROR_INSTALL_FAILURE );
+ return false;
+ }
+
+ if ( !WIN::CreateProcess( NULL, sCmdLine, NULL, NULL, FALSE,
+ CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
+ &aSUI, &aPI ) )
+ {
+ Log( TEXT( "ERROR: Could not create process %s.\r\n" ), sCmdLine );
+ SetError( WIN::GetLastError() );
+ delete [] sCmdLine;
+ return false;
+ }
+
+ DWORD nResult = WaitForProcess( aPI.hProcess );
+ bool bRet = true;
+
+ if( ERROR_SUCCESS != nResult )
+ {
+ Log( TEXT( "ERROR: While waiting for %s.\r\n" ), sCmdLine );
+ SetError( nResult );
+ bRet = false;
+ }
+ else
+ {
+ GetExitCodeProcess( aPI.hProcess, &nResult );
+ SetError( nResult );
+
+ if ( nResult != ERROR_SUCCESS )
+ {
+ TCHAR sBuf[80];
+ StringCchPrintf( sBuf, 80, TEXT("Warning: install runtime returned %u.\r\n"), nResult );
+ Log( sBuf );
+ }
+ else
+ Log( TEXT( " Installation of runtime completed successfully.\r\n" ) );
+ }
+
+ CloseHandle( aPI.hProcess );
+
+ delete [] sCmdLine;
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------------
+boolean SetupAppX::InstallRuntimes()
+{
+ TCHAR *sRuntimePath = 0;
+ SYSTEM_INFO siSysInfo;
+
+ HMODULE hKernel32 = ::LoadLibrary(_T("Kernel32.dll"));
+ if ( hKernel32 != NULL )
+ {
+ typedef void (CALLBACK* pfnGetNativeSystemInfo_t)(LPSYSTEM_INFO);
+ pfnGetNativeSystemInfo_t pfnGetNativeSystemInfo;
+ pfnGetNativeSystemInfo = (pfnGetNativeSystemInfo_t)::GetProcAddress(hKernel32, "GetNativeSystemInfo");
+ if ( pfnGetNativeSystemInfo != NULL )
+ {
+ pfnGetNativeSystemInfo(&siSysInfo);
+ }
+ else
+ {
+ // GetNativeSystemInfo does not exist. Maybe the code is running under Windows 2000.
+ // Use GetSystemInfo instead.
+ GetSystemInfo(&siSysInfo);
+ }
+ FreeLibrary(hKernel32);
+ }
+ else
+ {
+ // Failed to check Kernel32.dll. There may be something wrong.
+ // Use GetSystemInfo instead anyway.
+ GetSystemInfo(&siSysInfo);
+ }
+
+ OutputDebugStringFormat( TEXT( "found architecture<%d>\r\n" ), siSysInfo.wProcessorArchitecture );
+
+ if ( siSysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
+ {
+ if ( GetPathToFile( RUNTIME_X64_NAME, &sRuntimePath ) )
+ InstallRuntimes( PRODUCTCODE_X64, sRuntimePath );
+ else
+ Log( TEXT( "ERROR: no installer for x64 runtime libraries found!" ) );
+
+ if ( sRuntimePath )
+ {
+ delete [] sRuntimePath;
+ sRuntimePath = 0;
+ }
+ }
+
+ if ( GetPathToFile( RUNTIME_X86_NAME, &sRuntimePath ) )
+ InstallRuntimes( PRODUCTCODE_X86, sRuntimePath );
+ else
+ Log( TEXT( "ERROR: no installer for x86 runtime libraries found!" ) );
+
+ if ( sRuntimePath )
+ delete [] sRuntimePath;
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+LanguageDataX::LanguageDataX( LPTSTR pData )
+{
+ m_nLanguageID = 0;
+ m_pTransform = NULL;
+
+ LPTSTR pLastChar;
+
+ m_nLanguageID = _tcstol( pData, &pLastChar, 10 );
+
+ if ( *pLastChar == ',' )
+ {
+ pLastChar += 1;
+ int nLen = lstrlen( pLastChar ) + 1;
+ m_pTransform = new TCHAR [ nLen ];
+ StringCchCopy( m_pTransform, nLen, pLastChar );
+ }
+}
+
+//--------------------------------------------------------------------------
+LanguageDataX::~LanguageDataX()
+{
+ if ( m_pTransform ) delete [] m_pTransform;
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+SetupApp* Create_SetupAppX()
+{
+ return new SetupAppX;
+}
+
+//--------------------------------------------------------------------------
diff --git a/desktop/win32/source/setup/setup.hxx b/desktop/win32/source/setup/setup.hxx
new file mode 100644
index 000000000000..1744b1aa427a
--- /dev/null
+++ b/desktop/win32/source/setup/setup.hxx
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "setup_main.hxx"
+
+//--------------------------------------------------------------------------
+
+#ifdef SetupAppX
+ #undef SetupAppX
+#endif
+
+#ifdef Create_SetupAppX
+ #undef Create_SetupAppX
+#endif
+
+#ifdef LanguageDataX
+ #undef LanguageDataX
+#endif
+
+
+#ifdef UNICODE
+ #define SetupAppX SetupAppW
+ #define Create_SetupAppX Create_SetupAppW
+ #define LanguageDataX LanguageDataW
+#else
+ #define SetupAppX SetupAppA
+ #define Create_SetupAppX Create_SetupAppA
+ #define LanguageDataX LanguageDataA
+#endif
+
+//--------------------------------------------------------------------------
+
+struct LanguageDataX
+{
+ long m_nLanguageID;
+ LPTSTR m_pTransform;
+
+ LanguageDataX( LPTSTR pData );
+ ~LanguageDataX();
+};
+
+//--------------------------------------------------------------------------
+
+class SetupAppX : public SetupApp
+{
+ HINSTANCE m_hInst;
+ HANDLE m_hMapFile;
+ LPTSTR m_pAppTitle;
+ LPTSTR m_pCmdLine;
+ LPTSTR m_pDatabase;
+ LPTSTR m_pReqVersion;
+ LPTSTR m_pProductName;
+ LPTSTR m_pAdvertise;
+ LPTSTR m_pTmpName;
+ LPTSTR m_pErrorText;
+ LPTSTR m_pModuleFile;
+ LPTSTR m_pPatchFiles;
+ LPCTSTR m_pUpgradeKey;
+ LPCTSTR m_pProductVersion;
+ int *m_pMSIErrorCode;
+
+ boolean m_bQuiet : 1;
+ boolean m_bIgnoreAlreadyRunning : 1;
+ boolean m_bRegNoMsoTypes :1;
+ boolean m_bRegAllMsoTypes :1;
+ boolean m_bIsMinorUpgrade :1;
+ boolean m_bSupportsPatch :1;
+
+ FILE *m_pLogFile;
+
+ long m_nLanguageID;
+ long m_nLanguageCount;
+ LanguageDataX** m_ppLanguageList;
+
+private:
+
+ boolean GetPathToFile( TCHAR* pFileName, TCHAR **pPath );
+ LPCTSTR GetPathToMSI();
+
+ int GetNameValue( TCHAR* pLine, TCHAR **pName, TCHAR **pValue );
+ boolean GetProfileSection( LPCTSTR pFileName, LPCTSTR pSection,
+ DWORD& rSize, LPTSTR *pRetBuf );
+ LPTSTR CopyIniFile( LPCTSTR pIniFile );
+ void ConvertNewline( LPTSTR pText ) const;
+
+ boolean LaunchInstaller( LPCTSTR pParam );
+ HMODULE LoadMsiLibrary();
+ DWORD WaitForProcess( HANDLE hHandle );
+
+ boolean GetCmdLineParameters( LPTSTR *pCmdLine );
+ DWORD GetNextArgument( LPCTSTR pStr, LPTSTR *pArg,
+ LPTSTR *pNext, boolean bStripQuotes = false );
+ boolean IsAdmin();
+
+ boolean GetCommandLine();
+
+ boolean IsTerminalServerInstalled() const;
+ void AddFileToPatchList( TCHAR* pPath, TCHAR* pFile );
+ boolean IsPatchInstalled( TCHAR* pBaseDir, TCHAR* pFileName );
+ boolean InstallRuntimes( TCHAR* pProductCode, TCHAR* pFileName );
+
+public:
+ SetupAppX();
+ ~SetupAppX();
+
+ virtual boolean Initialize( HINSTANCE hInst );
+ virtual boolean AlreadyRunning() const;
+ virtual boolean ReadProfile();
+ virtual boolean GetPatches();
+ virtual boolean ChooseLanguage( long& rLanguage );
+ virtual boolean CheckVersion();
+ virtual boolean CheckForUpgrade();
+ virtual boolean InstallRuntimes();
+ virtual boolean Install( long nLanguage );
+
+ virtual UINT GetError() const;
+ virtual void DisplayError( UINT nErr ) const;
+
+ void Log( LPCTSTR pMessage, LPCTSTR pText = NULL ) const;
+
+ long GetLanguageCount() const { return m_nLanguageCount; }
+ long GetLanguageID( long nIndex ) const;
+ void GetLanguageName( long nLanguage, LPTSTR sName ) const;
+
+ LPCTSTR GetAppTitle() const { return m_pAppTitle; }
+ LPTSTR SetProdToAppTitle( LPCTSTR pProdName );
+ HINSTANCE GetHInst() const { return m_hInst; }
+};
+
+//--------------------------------------------------------------------------
diff --git a/desktop/win32/source/setup/setup.ico b/desktop/win32/source/setup/setup.ico
new file mode 100644
index 000000000000..2a7ebda53a25
--- /dev/null
+++ b/desktop/win32/source/setup/setup.ico
Binary files differ
diff --git a/desktop/win32/source/setup/setup.ulf b/desktop/win32/source/setup/setup.ulf
new file mode 100644
index 000000000000..d0e867d49f3f
--- /dev/null
+++ b/desktop/win32/source/setup/setup.ulf
@@ -0,0 +1,162 @@
+[%APP_TITLE%]
+en-US = "Setup"
+
+
+[%APP_PROD_TITLE%]
+en-US = "The %PRODUCTNAME Setup"
+
+
+[%OUTOFMEM%]
+en-US = "Out of Memory"
+
+
+[%NOMSI%]
+en-US = "Setup was unable to find the msi package."
+
+
+[%USER_CANCELLED%]
+en-US = "Setup was cancelled"
+
+
+[%REQUIRES_ADMIN_PRIV%]
+en-US = "Administrator privileges are required for upgrading the Windows Installer."
+
+
+[%FILE_NOT_FOUND%]
+en-US = "Setup was unable to find the file '%s'."
+
+
+[%INVALID_PARAM%]
+en-US = "Invalid command line option '%s'. Please use '/?' for help."
+
+
+[%SETUP_TO_OLD%]
+en-US = "This package requires at least the version '%s' of the Windows Installer. \nYou have Windows Installer '%s' on your system!"
+
+[%SETUP_NOT_FOUND%]
+en-US = "This package requires the Windows Installer. \nYou need at least Windows Installer '%s' on your system!"
+
+
+[%USAGE%]
+en-US = "Usage:\n /? : Shows this dialog.\n /a : Performs an administrative installation.\n /j[u|m] : Performs an advertising installation.\n /q[n] : Do not show any user interface (silent mode).\n"
+
+
+[%ALREADY_RUNNING%]
+en-US = "There is already a setup process running."
+
+
+[%UNKNOWN_ERROR%]
+en-US = "An Unknown Error occured!"
+
+
+[%INVALID_PROFILE%]
+en-US = "Invalid or incomplete profile."
+
+
+[%UNKNOWN_LANG%]
+en-US = "Unknown Language: %d"
+
+
+[%LANGUAGE_ZH_TW%]
+en-US = "Chinese (traditional)"
+
+
+[%LANGUAGE_CS%]
+en-US = "Czech"
+
+
+[%LANGUAGE_DA%]
+en-US = "Danish"
+
+
+[%LANGUAGE_DE_DE%]
+en-US = "German (Germany)"
+
+
+[%LANGUAGE_EL%]
+en-US = "Greek"
+
+
+[%LANGUAGE_EN_US%]
+en-US = "English (USA)"
+
+
+[%LANGUAGE_ES%]
+en-US = "Spanish (Spain)"
+
+
+[%LANGUAGE_FI%]
+en-US = "Finnish"
+
+
+[%LANGUAGE_FR_FR%]
+en-US = "French (France)"
+
+
+[%LANGUAGE_HE%]
+en-US = "Hebrew"
+
+
+[%LANGUAGE_HU%]
+en-US = "Hungarian"
+
+
+[%LANGUAGE_IT_IT%]
+en-US = "Italian (Italy)"
+
+
+[%LANGUAGE_JA%]
+en-US = "Japanese"
+
+
+[%LANGUAGE_KO%]
+en-US = "Korean"
+
+
+[%LANGUAGE_NL_NL%]
+en-US = "Dutch (Netherlands)"
+
+
+[%LANGUAGE_NO_NO%]
+en-US = "Norwegian (Bokmål)"
+
+
+[%LANGUAGE_PL%]
+en-US = "Polish"
+
+
+[%LANGUAGE_PT_BR%]
+en-US = "Portuguese (Brazil)"
+
+
+[%LANGUAGE_RU%]
+en-US = "Russian"
+
+
+[%LANGUAGE_SK%]
+en-US = "Slovakian"
+
+
+[%LANGUAGE_SV_SE%]
+en-US = "Swedish (Sweden)"
+
+
+[%LANGUAGE_TH%]
+en-US = "Thai"
+
+
+[%LANGUAGE_TR%]
+en-US = "Turkish"
+
+
+[%LANGUAGE_ET%]
+en-US = "Estonian"
+
+
+[%LANGUAGE_ZH_CN%]
+en-US = "Chinese (Simplified)"
+
+
+[%LANGUAGE_PT_PT%]
+en-US = "Portuguese (Portugal)"
+
diff --git a/desktop/win32/source/setup/setup_a.cxx b/desktop/win32/source/setup/setup_a.cxx
new file mode 100644
index 000000000000..2264e96dd919
--- /dev/null
+++ b/desktop/win32/source/setup/setup_a.cxx
@@ -0,0 +1,31 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "setup.cpp"
diff --git a/desktop/win32/source/setup/setup_help.hxx b/desktop/win32/source/setup/setup_help.hxx
new file mode 100644
index 000000000000..2a638ead0811
--- /dev/null
+++ b/desktop/win32/source/setup/setup_help.hxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 SETUP_HELP_HXX
+#define SETUP_HELP_HXX
+
+//--------------------------------------------------------------------------
+
+
+#ifdef UNICODE
+#else
+ #define LanguageDataX LanguageDataA
+#endif
+
+//--------------------------------------------------------------------------
+
+class SetupHelperX
+{
+};
+
+//--------------------------------------------------------------------------
+
+#endif \ No newline at end of file
diff --git a/desktop/win32/source/setup/setup_main.cxx b/desktop/win32/source/setup/setup_main.cxx
new file mode 100644
index 000000000000..2750c87ae08a
--- /dev/null
+++ b/desktop/win32/source/setup/setup_main.cxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <new>
+
+#include "setup_main.hxx"
+
+//--------------------------------------------------------------------------
+
+void __cdecl newhandler()
+{
+ throw std::bad_alloc();
+ return;
+}
+
+//--------------------------------------------------------------------------
+
+SetupApp::SetupApp()
+{
+ m_uiRet = ERROR_SUCCESS;
+
+ // Get OS version
+ OSVERSIONINFO sInfoOS;
+
+ ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) );
+ sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+
+ GetVersionEx( &sInfoOS );
+
+ m_nOSVersion = sInfoOS.dwMajorVersion;
+ m_nMinorVersion = sInfoOS.dwMinorVersion;
+ m_bIsWin9x = ( VER_PLATFORM_WIN32_NT != sInfoOS.dwPlatformId );
+ m_bNeedReboot = false;
+ m_bAdministrative = false;
+}
+
+//--------------------------------------------------------------------------
+
+SetupApp::~SetupApp()
+{
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+extern "C" int __stdcall WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
+{
+ // Get OS version
+ OSVERSIONINFO sInfoOS;
+
+ ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) );
+ sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+
+ GetVersionEx( &sInfoOS );
+
+ boolean bIsWin9x = ( VER_PLATFORM_WIN32_NT != sInfoOS.dwPlatformId );
+
+ SetupApp *pSetup;
+
+ if ( bIsWin9x )
+ pSetup = Create_SetupAppA();
+ else
+ pSetup = Create_SetupAppW();
+
+ try
+ {
+ if ( ! pSetup->Initialize( hInst ) )
+ throw pSetup->GetError();
+
+ if ( pSetup->AlreadyRunning() )
+ throw (UINT) ERROR_INSTALL_ALREADY_RUNNING;
+
+ if ( ! pSetup->ReadProfile() )
+ throw pSetup->GetError();
+
+ if ( ! pSetup->CheckVersion() )
+ throw pSetup->GetError();
+
+ if ( ! pSetup->IsAdminInstall() )
+ if ( ! pSetup->GetPatches() )
+ throw pSetup->GetError();
+
+ // CheckForUpgrade() has to be called after calling GetPatches()!
+ if ( ! pSetup->CheckForUpgrade() )
+ throw pSetup->GetError();
+
+ long nLanguage;
+
+ if ( ! pSetup->ChooseLanguage( nLanguage ) )
+ throw pSetup->GetError();
+
+ if ( ! pSetup->InstallRuntimes() )
+ throw pSetup->GetError();
+
+ if ( ! pSetup->Install( nLanguage ) )
+ throw pSetup->GetError();
+ }
+ catch ( std::bad_alloc )
+ {
+ pSetup->DisplayError( ERROR_OUTOFMEMORY );
+ }
+ catch ( UINT nErr )
+ {
+ pSetup->DisplayError( nErr );
+ }
+
+ int nRet = pSetup->GetError();
+
+ delete pSetup;
+
+ return nRet;
+}
diff --git a/desktop/win32/source/setup/setup_main.hxx b/desktop/win32/source/setup/setup_main.hxx
new file mode 100644
index 000000000000..525d5579a256
--- /dev/null
+++ b/desktop/win32/source/setup/setup_main.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 SETUP_MAIN_HXX
+#define SETUP_MAIN_HXX
+
+class SetupApp
+{
+ DWORD m_nOSVersion;
+ DWORD m_nMinorVersion;
+ boolean m_bIsWin9x : 1;
+ boolean m_bNeedReboot : 1;
+ boolean m_bAdministrative : 1;
+
+public:
+ UINT m_uiRet;
+
+ SetupApp();
+ virtual ~SetupApp();
+
+ virtual boolean Initialize( HINSTANCE hInst ) = 0;
+ virtual boolean AlreadyRunning() const = 0;
+ virtual boolean ReadProfile() = 0;
+ virtual boolean GetPatches() = 0;
+ virtual boolean ChooseLanguage( long& rLanguage ) = 0;
+ virtual boolean CheckVersion() = 0;
+ virtual boolean CheckForUpgrade() = 0;
+ virtual boolean InstallRuntimes() = 0;
+ virtual boolean Install( long nLanguage ) = 0;
+
+ virtual UINT GetError() const = 0;
+ virtual void DisplayError( UINT nErr ) const = 0;
+
+ void SetError( UINT nErr ) { m_uiRet = nErr; }
+ boolean IsWin9x() const { return m_bIsWin9x; }
+ DWORD GetOSVersion() const { return m_nOSVersion; }
+ DWORD GetMinorVersion() const { return m_nMinorVersion; }
+
+ boolean IsAdminInstall() { return m_bAdministrative; }
+ void SetAdminInstall( boolean bValue ) { m_bAdministrative = bValue; }
+
+ void SetRebootNeeded( boolean bNeedReboot ) { m_bNeedReboot = bNeedReboot; }
+ boolean NeedReboot() const { return m_bNeedReboot; }
+};
+
+SetupApp* Create_SetupAppA();
+SetupApp* Create_SetupAppW();
+
+#endif
diff --git a/desktop/win32/source/setup/setup_w.cxx b/desktop/win32/source/setup/setup_w.cxx
new file mode 100644
index 000000000000..a21dbd685f46
--- /dev/null
+++ b/desktop/win32/source/setup/setup_w.cxx
@@ -0,0 +1,35 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+
+#define UNICODE 1
+#define _UNICODE 1
+
+#include "setup.cpp"
+
diff --git a/desktop/win32/source/sowrapper.cxx b/desktop/win32/source/sowrapper.cxx
new file mode 100644
index 000000000000..4b0292be41a6
--- /dev/null
+++ b/desktop/win32/source/sowrapper.cxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include "main.h"
+
+int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
+{
+ if ( (LONG)GetVersion() < 0 )
+ return MainA();
+ else
+ return MainW();
+}
diff --git a/desktop/win32/source/unoinfo.cxx b/desktop/win32/source/unoinfo.cxx
new file mode 100644
index 000000000000..c2a98802ccd3
--- /dev/null
+++ b/desktop/win32/source/unoinfo.cxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 <cstddef>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include "tools/pathutils.hxx"
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+
+namespace {
+
+wchar_t * getBrandPath(wchar_t * path) {
+ DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH);
+ if (n == 0 || n >= MAX_PATH) {
+ exit(EXIT_FAILURE);
+ }
+ return tools::filename(path);
+}
+
+void writeNull() {
+ if (fwrite("\0\0", 1, 2, stdout) != 2) {
+ exit(EXIT_FAILURE);
+ }
+}
+
+void writePath(
+ wchar_t const * frontBegin, wchar_t const * frontEnd,
+ wchar_t const * backBegin, std::size_t backLength)
+{
+ wchar_t path[MAX_PATH];
+ wchar_t * end = tools::buildPath(
+ path, frontBegin, frontEnd, backBegin, backLength);
+ if (end == NULL) {
+ exit(EXIT_FAILURE);
+ }
+ std::size_t n = (end - path) * sizeof (wchar_t);
+ if (fwrite(path, 1, n, stdout) != n) {
+ exit(EXIT_FAILURE);
+ }
+}
+
+}
+
+#ifdef __MINGW32__
+int main(int argc, char ** argv, char **) {
+ if (argc == 2 && strcmp(argv[1], "c++") == 0) {
+#else
+int wmain(int argc, wchar_t ** argv, wchar_t **) {
+ if (argc == 2 && wcscmp(argv[1], L"c++") == 0) {
+#endif
+ wchar_t path[MAX_PATH];
+ wchar_t * pathEnd = getBrandPath(path);
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link"))
+ == NULL)
+ {
+ exit(EXIT_FAILURE);
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL ||
+ (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) ==
+ NULL))
+ {
+ exit(EXIT_FAILURE);
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ exit(EXIT_FAILURE);
+ }
+ writePath(path, pathEnd, MY_STRING(L"\\bin"));
+#ifdef __MINGW32__
+ } else if (argc == 2 && strcmp(argv[1], "java") == 0) {
+#else
+ } else if (argc == 2 && wcscmp(argv[1], L"java") == 0) {
+#endif
+ if (fwrite("1", 1, 1, stdout) != 1) {
+ exit(EXIT_FAILURE);
+ }
+ wchar_t path[MAX_PATH];
+ wchar_t * pathEnd = getBrandPath(path);
+ writePath(path, pathEnd, MY_STRING(L""));
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link"))
+ == NULL)
+ {
+ exit(EXIT_FAILURE);
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ exit(EXIT_FAILURE);
+ }
+ writeNull();
+ writePath(path, pathEnd, MY_STRING(L"\\program\\classes\\unoil.jar"));
+ if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) ==
+ NULL)
+ {
+ exit(EXIT_FAILURE);
+ }
+ pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ exit(EXIT_FAILURE);
+ }
+ writeNull();
+ writePath(path, pathEnd, MY_STRING(L"\\java\\ridl.jar"));
+ writeNull();
+ writePath(path, pathEnd, MY_STRING(L"\\java\\jurt.jar"));
+ writeNull();
+ writePath(path, pathEnd, MY_STRING(L"\\java\\juh.jar"));
+ } else {
+ exit(EXIT_FAILURE);
+ }
+ exit(EXIT_SUCCESS);
+}
diff --git a/desktop/win32/source/wrapper.h b/desktop/win32/source/wrapper.h
new file mode 100644
index 000000000000..ebb46aa96a1b
--- /dev/null
+++ b/desktop/win32/source/wrapper.h
@@ -0,0 +1,173 @@
+#pragma once
+#ifndef __cplusplus
+#error Need C++ to compile
+#endif
+
+#include "main.h"
+
+#ifndef _WINDOWS_
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+# include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+
+#ifndef _INC_TCHAR
+# ifdef UNICODE
+# define _UNICODE
+# endif
+# include <tchar.h>
+#endif
+
+#ifdef UNICODE
+# define Main MainW
+# define GetArgv( pArgc ) CommandLineToArgvW( GetCommandLine(), pArgc )
+# define PROCESS_CREATIONFLAGS CREATE_UNICODE_ENVIRONMENT
+#else
+# define GetArgv( pArgc ) (*pArgc = __argc, __argv)
+# define PROCESS_CREATIONFLAGS 0
+# define Main MainA
+#endif
+
+#define BIN_EXT_STR TEXT(".bin")
+#define PARAM_LIBPATH_STR TEXT("-libpath=")
+#define PARAM_LOCAL_STR TEXT("-local")
+#define PARAM_REMOTE_STR TEXT("-remote")
+
+#if defined( REMOTE )
+#define DEFAULT_LIBPATH TEXT("remote;")
+#elif defined( LOCAL )
+#define DEFAULT_LIBPATH TEXT("local;")
+#endif
+
+extern "C" int Main()
+{
+ // Retreive startup info
+
+ STARTUPINFO aStartupInfo;
+
+ ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
+ aStartupInfo.cb = sizeof( aStartupInfo );
+ GetStartupInfo( &aStartupInfo );
+
+ // Retrieve command line
+
+ LPTSTR lpCommandLine = GetCommandLine();
+
+ LPTSTR *ppArguments = NULL;
+ int nArguments = 0;
+
+ ppArguments = GetArgv( &nArguments );
+
+ // Calculate application name
+
+
+ TCHAR szApplicationName[MAX_PATH];
+ TCHAR szDrive[MAX_PATH];
+ TCHAR szDir[MAX_PATH];
+ TCHAR szFileName[MAX_PATH];
+ TCHAR szExt[MAX_PATH];
+
+ GetModuleFileName( NULL, szApplicationName, MAX_PATH );
+ _tsplitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
+ _tmakepath( szApplicationName, szDrive, szDir, szFileName, BIN_EXT_STR );
+
+ // Retreive actual environment
+
+ TCHAR szBuffer[1024];
+ TCHAR szPathValue[1024] = TEXT("");
+
+#ifdef DEFAULT_LIBPATH
+ _tmakepath( szPathValue, szDrive, szDir, DEFAULT_LIBPATH, TEXT("") );
+#endif
+
+ for ( int argn = 1; argn < nArguments; argn++ )
+ {
+ if ( 0 == _tcscmp( ppArguments[argn], PARAM_REMOTE_STR ) )
+ {
+ _tmakepath( szPathValue, szDrive, szDir, TEXT("remote;"), TEXT("") );
+ break;
+ }
+ else if ( 0 == _tcscmp( ppArguments[argn], PARAM_LOCAL_STR ) )
+ {
+ _tmakepath( szPathValue, szDrive, szDir, TEXT("local;"), TEXT("") );
+ break;
+ }
+ else if ( 0 == _tcsncmp( ppArguments[argn], PARAM_LIBPATH_STR, _tcslen(PARAM_LIBPATH_STR) ) )
+ {
+ LPTSTR pFileSpec = NULL;
+
+ GetFullPathName( ppArguments[argn] + _tcslen(PARAM_LIBPATH_STR), sizeof(szPathValue) / sizeof(TCHAR), szPathValue, &pFileSpec );
+ _tcscat( szPathValue, TEXT(";") );
+ break;
+ }
+ }
+
+ GetEnvironmentVariable( TEXT("PATH"), szBuffer, sizeof(szBuffer) );
+ _tcscat( szPathValue, szBuffer );
+ SetEnvironmentVariable( TEXT("PATH"), szPathValue);
+
+ LPVOID lpEnvironment = GetEnvironmentStrings();
+
+
+ // Retrieve current directory
+
+ TCHAR szCurrentDirectory[MAX_PATH];
+ GetCurrentDirectory( MAX_PATH, szCurrentDirectory );
+
+ // Set the Flags
+
+ DWORD dwCreationFlags = PROCESS_CREATIONFLAGS;
+
+ PROCESS_INFORMATION aProcessInfo;
+
+ BOOL fSuccess = CreateProcess(
+ szApplicationName,
+ lpCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ dwCreationFlags,
+ lpEnvironment,
+ szCurrentDirectory,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ if ( fSuccess )
+ {
+ DWORD dwExitCode;
+
+ WaitForSingleObject( aProcessInfo.hProcess, INFINITE );
+ fSuccess = GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
+
+ return dwExitCode;
+ }
+
+ DWORD dwError = GetLastError();
+
+ LPVOID lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dwError,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ // Display the string.
+ MessageBox( NULL, (LPCTSTR)lpMsgBuf, NULL, MB_OK | MB_ICONERROR );
+
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+
+ return GetLastError();
+}
+
diff --git a/desktop/win32/source/wrappera.cxx b/desktop/win32/source/wrappera.cxx
new file mode 100644
index 000000000000..e121ce12172a
--- /dev/null
+++ b/desktop/win32/source/wrappera.cxx
@@ -0,0 +1,31 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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 "wrapper.h"
diff --git a/desktop/win32/source/wrapperw.cxx b/desktop/win32/source/wrapperw.cxx
new file mode 100644
index 000000000000..700f79f60355
--- /dev/null
+++ b/desktop/win32/source/wrapperw.cxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * 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"
+#define UNICODE
+#include "wrapper.h"
diff --git a/desktop/zipintro/delzip b/desktop/zipintro/delzip
new file mode 100644
index 000000000000..8b137891791f
--- /dev/null
+++ b/desktop/zipintro/delzip
@@ -0,0 +1 @@
+
diff --git a/desktop/zipintro/makefile.mk b/desktop/zipintro/makefile.mk
new file mode 100644
index 000000000000..fef106d1e09d
--- /dev/null
+++ b/desktop/zipintro/makefile.mk
@@ -0,0 +1,134 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=desktop
+TARGET=zipintro
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+DEFAULT_FLAVOURS=dev dev_nologo nologo broffice dev_broffice nologo_broffice nologo_dev_broffice intro
+
+ZIP1LIST= \
+ $(null,$(INTRO_BITMAPS) $(MISC)$/ooo_custom_images$/dev$/introabout$/intro.png $(INTRO_BITMAPS)) \
+ $(null,$(ABOUT_BITMAPS) $(MISC)$/$(RSCDEFIMG)$/introabout$/about.png $(ABOUT_BITMAPS))
+ZIP2LIST= \
+ $(null,$(INTRO_BITMAPS) $(MISC)$/ooo_custom_images$/dev_nologo$/introabout$/intro.png $(INTRO_BITMAPS)) \
+ $(null,$(ABOUT_BITMAPS) $(MISC)$/$(RSCDEFIMG)$/introabout$/about.png $(ABOUT_BITMAPS))
+ZIP3LIST= \
+ $(null,$(INTRO_BITMAPS) $(MISC)$/ooo_custom_images$/nologo$/introabout$/intro.png $(INTRO_BITMAPS)) \
+ $(null,$(ABOUT_BITMAPS) $(MISC)$/$(RSCDEFIMG)$/introabout$/about.png $(ABOUT_BITMAPS))
+ZIP4LIST= \
+ $(null,$(INTRO_BITMAPS) $(MISC)$/$(RSCDEFIMG)$/introabout$/intro.png $(INTRO_BITMAPS)) \
+ $(null,$(ABOUT_BITMAPS) $(MISC)$/$(RSCDEFIMG)$/introabout$/about.png $(ABOUT_BITMAPS))
+ZIP5LIST= \
+ $(null,$(INTRO_BITMAPS) $(MISC)$/ooo_custom_images$/dev_broffice$/introabout$/intro.png $(INTRO_BITMAPS)) \
+ $(null,$(ABOUT_BITMAPS) $(MISC)$/ooo_custom_images$/broffice$/introabout$/about.png $(ABOUT_BITMAPS))
+ZIP6LIST= \
+ $(null,$(INTRO_BITMAPS) $(MISC)$/ooo_custom_images$/broffice$/introabout$/intro.png $(INTRO_BITMAPS)) \
+ $(null,$(ABOUT_BITMAPS) $(MISC)$/ooo_custom_images$/broffice$/introabout$/about.png $(ABOUT_BITMAPS))
+ZIP7LIST= \
+ $(null,$(INTRO_BITMAPS) $(MISC)$/ooo_custom_images$/nologo_broffice$/introabout$/intro.png $(INTRO_BITMAPS)) \
+ $(null,$(ABOUT_BITMAPS) $(MISC)$/ooo_custom_images$/broffice$/introabout$/about.png $(ABOUT_BITMAPS))
+ZIP8LIST= \
+ $(null,$(INTRO_BITMAPS) $(MISC)$/ooo_custom_images$/dev_nologo_broffice$/introabout$/intro.png $(INTRO_BITMAPS)) \
+ $(null,$(ABOUT_BITMAPS) $(MISC)$/ooo_custom_images$/broffice$/introabout$/about.png $(ABOUT_BITMAPS))
+
+ZIP1TARGET=dev_intro
+ZIP1DEPS=$(ZIP1LIST)
+
+ZIP2TARGET=dev_nologo_intro
+ZIP2DEPS=$(ZIP2LIST)
+
+ZIP3TARGET=nologo_intro
+ZIP3DEPS=$(ZIP3LIST)
+
+ZIP4TARGET=intro_intro
+ZIP4DEPS=$(ZIP4LIST)
+
+ZIP5TARGET=dev_broffice_intro
+ZIP5DEPS=$(ZIP5LIST)
+
+ZIP6TARGET=broffice_intro
+ZIP6DEPS=$(ZIP6LIST)
+
+ZIP7TARGET=nologo_broffice_intro
+ZIP7DEPS=$(ZIP7LIST)
+
+ZIP8TARGET=nologo_dev_broffice_intro
+ZIP8DEPS=$(ZIP8LIST)
+
+.INCLUDE : target.mk
+
+ALLTAR : $(foreach,i,$(DEFAULT_FLAVOURS) $(COMMONBIN)$/$i$/intro.zip)
+
+# now duplicate for deliver...
+# Because of issue 78837 we cannot use a % rule here (Commented out below)
+# but have to write individual rules.
+#$(COMMONBIN)$/%$/intro.zip : $(COMMONBIN)$/%_intro.zip
+
+$(COMMONBIN)$/dev$/intro.zip : $(COMMONBIN)$/dev_intro.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/dev_nologo$/intro.zip : $(COMMONBIN)$/dev_nologo_intro.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/nologo$/intro.zip : $(COMMONBIN)$/nologo_intro.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/broffice$/intro.zip : $(COMMONBIN)$/broffice_intro.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/dev_broffice$/intro.zip : $(COMMONBIN)$/dev_broffice_intro.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/nologo_broffice$/intro.zip : $(COMMONBIN)$/nologo_broffice_intro.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/nologo_dev_broffice$/intro.zip : $(COMMONBIN)$/nologo_dev_broffice_intro.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(COMMONBIN)$/intro$/intro.zip : $(COMMONBIN)$/intro_intro.zip
+ @@-$(MKDIR) $(@:d)
+ @$(COPY) $< $@
+
+$(MISC)$/%.bmp : $(SOLARSRC)$/%.bmp
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
+
+$(MISC)$/%.png : $(SOLARSRC)$/%.png
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@