diff options
Diffstat (limited to 'comphelper')
232 files changed, 50624 insertions, 0 deletions
diff --git a/comphelper/CppunitTest_comphelper_test.mk b/comphelper/CppunitTest_comphelper_test.mk new file mode 100644 index 000000000000..92c32fe11997 --- /dev/null +++ b/comphelper/CppunitTest_comphelper_test.mk @@ -0,0 +1,56 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# Version: MPL 1.1 / GPLv3+ / LGPLv3+ +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License or as specified alternatively below. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Initial Developer of the Original Code is +# Caolán McNamara, Red Hat, Inc. <caolanm@redhat.com> +# Portions created by the Initial Developer are Copyright (C) 2011 the +# Initial Developer. All Rights Reserved. +# +# Major Contributor(s): +# +# For minor contributions see the git repository. +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 3 or later (the "GPLv3+"), or +# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), +# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable +# instead of those above. +#************************************************************************* + +$(eval $(call gb_CppunitTest_CppunitTest,comphelper_test)) + +$(eval $(call gb_CppunitTest_add_exception_objects,comphelper_test, \ + comphelper/qa/string/test_string \ +)) + +$(eval $(call gb_CppunitTest_add_api,comphelper_test, \ + udkapi \ + offapi \ +)) + +$(eval $(call gb_CppunitTest_add_linked_libs,comphelper_test, \ + comphelper \ + cppuhelper \ + cppu \ + sal \ + $(gb_STDLIBS) \ +)) + +$(eval $(call gb_CppunitTest_set_include,comphelper_test,\ + -I$(realpath $(SRCDIR)/comphelper/inc/pch) \ + -I$(realpath $(SRCDIR)/comphelper/inc) \ + $$(INCLUDE) \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/comphelper/JunitTest_comphelper_complex.mk b/comphelper/JunitTest_comphelper_complex.mk new file mode 100644 index 000000000000..adf616b220d0 --- /dev/null +++ b/comphelper/JunitTest_comphelper_complex.mk @@ -0,0 +1,49 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2011 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +$(eval $(call gb_JunitTest_JunitTest,comphelper_complex,SRCDIR)) + +$(eval $(call gb_JunitTest_add_sourcefiles,comphelper_complex,\ + comphelper/qa/complex/comphelper/Map \ + comphelper/qa/complex/comphelper/SequenceOutputStreamUnitTest \ +)) + +$(eval $(call gb_JunitTest_add_jars,comphelper_complex,\ + $(OUTDIR)/bin/OOoRunner.jar \ + $(OUTDIR)/bin/ridl.jar \ + $(OUTDIR)/bin/test.jar \ + $(OUTDIR)/bin/unoil.jar \ + $(OUTDIR)/bin/jurt.jar \ +)) + +$(eval $(call gb_JunitTest_add_classes,comphelper_complex,\ + complex.comphelper.SequenceOutputStreamUnitTest \ + complex.comphelper.Map \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/comphelper/Library_comphelp.mk b/comphelper/Library_comphelp.mk new file mode 100644 index 000000000000..80e233d1640f --- /dev/null +++ b/comphelper/Library_comphelp.mk @@ -0,0 +1,159 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2009 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +$(eval $(call gb_Library_Library,comphelper)) + +$(eval $(call gb_Library_add_package_headers,comphelper,comphelper_inc)) + +$(eval $(call gb_Library_add_precompiled_header,comphelper,$(SRCDIR)/comphelper/inc/pch/precompiled_comphelper)) + +$(eval $(call gb_Library_set_componentfile,comphelper,comphelper/util/comphelp)) + +$(eval $(call gb_Library_set_include,comphelper,\ + -I$(realpath $(SRCDIR)/comphelper/inc/pch) \ + -I$(realpath $(SRCDIR)/comphelper/source/inc) \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_Library_add_defs,comphelper,\ + -DCOMPHELPER_DLLIMPLEMENTATION \ +)) + +$(eval $(call gb_Library_add_linked_libs,comphelper,\ + sal \ + cppuhelper \ + cppu \ + ucbhelper \ + $(gb_STDLIBS) \ +)) + +$(eval $(call gb_Library_add_api,comphelper,\ + udkapi \ + offapi \ +)) + +$(eval $(call gb_Library_add_exception_objects,comphelper,\ + comphelper/source/compare/AnyCompareFactory \ + comphelper/source/container/IndexedPropertyValuesContainer \ + comphelper/source/container/NamedPropertyValuesContainer \ + comphelper/source/container/container \ + comphelper/source/container/containermultiplexer \ + comphelper/source/container/embeddedobjectcontainer \ + comphelper/source/container/enumerablemap \ + comphelper/source/container/enumhelper \ + comphelper/source/container/namecontainer \ + comphelper/source/eventattachermgr/eventattachermgr \ + comphelper/source/misc/accessiblecomponenthelper \ + comphelper/source/misc/accessiblecontexthelper \ + comphelper/source/misc/accessibleeventbuffer \ + comphelper/source/misc/accessibleeventnotifier \ + comphelper/source/misc/accessiblekeybindinghelper \ + comphelper/source/misc/accessibleselectionhelper \ + comphelper/source/misc/accessibletexthelper \ + comphelper/source/misc/accessiblewrapper \ + comphelper/source/misc/accimplaccess \ + comphelper/source/misc/anytostring \ + comphelper/source/misc/asyncnotification \ + comphelper/source/misc/comphelper_module \ + comphelper/source/misc/comphelper_services \ + comphelper/source/misc/componentbase \ + comphelper/source/misc/componentcontext \ + comphelper/source/misc/componentmodule \ + comphelper/source/misc/configurationhelper \ + comphelper/source/misc/docpasswordhelper \ + comphelper/source/misc/docpasswordrequest \ + comphelper/source/misc/documentinfo \ + comphelper/source/misc/documentiologring \ + comphelper/source/misc/evtlistenerhlp \ + comphelper/source/misc/evtmethodhelper \ + comphelper/source/misc/ihwrapnofilter \ + comphelper/source/misc/instancelocker \ + comphelper/source/misc/interaction \ + comphelper/source/misc/listenernotification \ + comphelper/source/misc/locale \ + comphelper/source/misc/logging \ + comphelper/source/misc/mediadescriptor \ + comphelper/source/misc/mimeconfighelper \ + comphelper/source/misc/namedvaluecollection \ + comphelper/source/misc/numberedcollection \ + comphelper/source/misc/numbers \ + comphelper/source/misc/officeresourcebundle \ + comphelper/source/misc/officerestartmanager \ + comphelper/source/misc/proxyaggregation \ + comphelper/source/misc/regpathhelper \ + comphelper/source/misc/scopeguard \ + comphelper/source/misc/SelectionMultiplex \ + comphelper/source/misc/sequenceashashmap \ + comphelper/source/misc/sequence \ + comphelper/source/misc/servicedecl \ + comphelper/source/misc/serviceinfohelper \ + comphelper/source/misc/sharedmutex \ + comphelper/source/misc/stillreadwriteinteraction \ + comphelper/source/misc/anycompare \ + comphelper/source/misc/storagehelper \ + comphelper/source/misc/string \ + comphelper/source/misc/synchronousdispatch \ + comphelper/source/misc/types \ + comphelper/source/misc/uieventslogger \ + comphelper/source/misc/weak \ + comphelper/source/misc/weakeventlistener \ + comphelper/source/officeinstdir/officeinstallationdirectories \ + comphelper/source/processfactory/componentfactory \ + comphelper/source/processfactory/processfactory \ + comphelper/source/property/ChainablePropertySet \ + comphelper/source/property/ChainablePropertySetInfo \ + comphelper/source/property/composedprops \ + comphelper/source/property/genericpropertyset \ + comphelper/source/property/MasterPropertySet \ + comphelper/source/property/MasterPropertySetInfo \ + comphelper/source/property/opropertybag \ + comphelper/source/property/propagg \ + comphelper/source/property/propertybag \ + comphelper/source/property/propertycontainer \ + comphelper/source/property/propertycontainerhelper \ + comphelper/source/property/property \ + comphelper/source/property/propertysethelper \ + comphelper/source/property/propertysetinfo \ + comphelper/source/property/propertystatecontainer \ + comphelper/source/property/propmultiplex \ + comphelper/source/property/propstate \ + comphelper/source/property/TypeGeneration \ + comphelper/source/streaming/basicio \ + comphelper/source/streaming/memorystream \ + comphelper/source/streaming/oslfile2streamwrap \ + comphelper/source/streaming/otransactedfilestream \ + comphelper/source/streaming/seekableinput \ + comphelper/source/streaming/seqinputstreamserv \ + comphelper/source/streaming/seqoutputstreamserv \ + comphelper/source/streaming/seqstream \ + comphelper/source/streaming/streamsection \ + comphelper/source/xml/attributelist \ + comphelper/source/xml/ofopxmlhelper \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/comphelper/Makefile b/comphelper/Makefile new file mode 100644 index 000000000000..8d71119918b6 --- /dev/null +++ b/comphelper/Makefile @@ -0,0 +1,39 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +ifeq ($(strip $(SOLARENV)),) +$(error No environment set!) +endif + +gb_PARTIALBUILD := T +GBUILDDIR := $(SOLARENV)/gbuild +include $(GBUILDDIR)/gbuild.mk + +$(eval $(call gb_Module_make_global_targets,$(shell ls $(dir $(realpath $(firstword $(MAKEFILE_LIST))))/Module*.mk))) + +# vim: set noet sw=4 ts=4: diff --git a/comphelper/Module_comphelper.mk b/comphelper/Module_comphelper.mk new file mode 100644 index 000000000000..08e3f17c92e4 --- /dev/null +++ b/comphelper/Module_comphelper.mk @@ -0,0 +1,44 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2009 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +$(eval $(call gb_Module_Module,comphelper)) + +$(eval $(call gb_Module_add_targets,comphelper,\ + Package_inc \ + Library_comphelp \ +)) + +$(eval $(call gb_Module_add_subsequentcheck_targets,comphelper,\ + JunitTest_comphelper_complex \ +)) + +$(eval $(call gb_Module_add_check_targets,comphelper,\ + CppunitTest_comphelper_test \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/comphelper/Package_inc.mk b/comphelper/Package_inc.mk new file mode 100644 index 000000000000..25c6f4b8e538 --- /dev/null +++ b/comphelper/Package_inc.mk @@ -0,0 +1,140 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2009 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +$(eval $(call gb_Package_Package,comphelper_inc,$(SRCDIR)/comphelper/inc)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/flagguard.hxx,comphelper/flagguard.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/stlunosequence.hxx,comphelper/stlunosequence.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/documentconstants.hxx,comphelper/documentconstants.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/evtmethodhelper.hxx,comphelper/evtmethodhelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/weakbag.hxx,comphelper/weakbag.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/basicio.hxx,comphelper/basicio.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/classids.hxx,comphelper/classids.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/MasterPropertySet.hxx,comphelper/MasterPropertySet.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/stillreadwriteinteraction.hxx,comphelper/stillreadwriteinteraction.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/anycompare.hxx,comphelper/anycompare.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propagg.hxx,comphelper/propagg.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/scopeguard.hxx,comphelper/scopeguard.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/scoped_disposing_ptr.hxx,comphelper/scoped_disposing_ptr.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/asyncnotification.hxx,comphelper/asyncnotification.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/namedvaluecollection.hxx,comphelper/namedvaluecollection.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/composedprops.hxx,comphelper/composedprops.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/mediadescriptor.hxx,comphelper/mediadescriptor.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/synchronousdispatch.hxx,comphelper/synchronousdispatch.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accessiblecomponenthelper.hxx,comphelper/accessiblecomponenthelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/otransactedfilestream.hxx,comphelper/otransactedfilestream.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propmultiplex.hxx,comphelper/propmultiplex.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/servicehelper.hxx,comphelper/servicehelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/servicedecl.hxx,comphelper/servicedecl.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/mimeconfighelper.hxx,comphelper/mimeconfighelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/implbase_var.hxx,comphelper/implbase_var.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/TypeGeneration.hxx,comphelper/TypeGeneration.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/MasterPropertySetInfo.hxx,comphelper/MasterPropertySetInfo.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accessiblewrapper.hxx,comphelper/accessiblewrapper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/sequence.hxx,comphelper/sequence.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/uieventslogger.hxx,comphelper/uieventslogger.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/docpasswordhelper.hxx,comphelper/docpasswordhelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propertystatecontainer.hxx,comphelper/propertystatecontainer.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propertysetinfo.hxx,comphelper/propertysetinfo.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accimplaccess.hxx,comphelper/accimplaccess.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/docpasswordrequest.hxx,comphelper/docpasswordrequest.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accessibleeventbuffer.hxx,comphelper/accessibleeventbuffer.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/regpathhelper.hxx,comphelper/regpathhelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/extract.hxx,comphelper/extract.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/interaction.hxx,comphelper/interaction.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/uno3.hxx,comphelper/uno3.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/unwrapargs.hxx,comphelper/unwrapargs.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propertycontainer.hxx,comphelper/propertycontainer.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/guarding.hxx,comphelper/guarding.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/fileformat.h,comphelper/fileformat.h)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/ChainablePropertySetInfo.hxx,comphelper/ChainablePropertySetInfo.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/enumhelper.hxx,comphelper/enumhelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/property.hxx,comphelper/property.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propertysethelper.hxx,comphelper/propertysethelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accessiblekeybindinghelper.hxx,comphelper/accessiblekeybindinghelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propertycontainerhelper.hxx,comphelper/propertycontainerhelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/make_shared_from_uno.hxx,comphelper/make_shared_from_uno.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/comphelperdllapi.h,comphelper/comphelperdllapi.h)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/listenernotification.hxx,comphelper/listenernotification.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/attributelist.hxx,comphelper/attributelist.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/streamsection.hxx,comphelper/streamsection.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accessibletexthelper.hxx,comphelper/accessibletexthelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accessibleselectionhelper.hxx,comphelper/accessibleselectionhelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/serviceinfohelper.hxx,comphelper/serviceinfohelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/locale.hxx,comphelper/locale.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/numberedcollection.hxx,comphelper/numberedcollection.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/ChainablePropertySet.hxx,comphelper/ChainablePropertySet.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/stl_types.hxx,comphelper/stl_types.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/eventattachermgr.hxx,comphelper/eventattachermgr.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/componentcontext.hxx,comphelper/componentcontext.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accessibleeventnotifier.hxx,comphelper/accessibleeventnotifier.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/ihwrapnofilter.hxx,comphelper/ihwrapnofilter.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/sequenceasvector.hxx,comphelper/sequenceasvector.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/officeresourcebundle.hxx,comphelper/officeresourcebundle.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/types.hxx,comphelper/types.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/seekableinput.hxx,comphelper/seekableinput.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/IdPropArrayHelper.hxx,comphelper/IdPropArrayHelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/accessiblecontexthelper.hxx,comphelper/accessiblecontexthelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/SelectionMultiplex.hxx,comphelper/SelectionMultiplex.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/storagehelper.hxx,comphelper/storagehelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/logging.hxx,comphelper/logging.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/sharedmutex.hxx,comphelper/sharedmutex.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/documentinfo.hxx,comphelper/documentinfo.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/weakeventlistener.hxx,comphelper/weakeventlistener.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/componentfactory.hxx,comphelper/componentfactory.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/containermultiplexer.hxx,comphelper/containermultiplexer.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/broadcasthelper.hxx,comphelper/broadcasthelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/numbers.hxx,comphelper/numbers.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/evtlistenerhlp.hxx,comphelper/evtlistenerhlp.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/optional.hxx,comphelper/optional.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/componentbase.hxx,comphelper/componentbase.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/componentguard.hxx,comphelper/componentguard.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/InlineContainer.hxx,comphelper/InlineContainer.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propertybag.hxx,comphelper/propertybag.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/embeddedobjectcontainer.hxx,comphelper/embeddedobjectcontainer.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/anytostring.hxx,comphelper/anytostring.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/implementationreference.hxx,comphelper/implementationreference.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/proparrhlp.hxx,comphelper/proparrhlp.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/PropertyInfoHash.hxx,comphelper/PropertyInfoHash.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/propstate.hxx,comphelper/propstate.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/proxyaggregation.hxx,comphelper/proxyaggregation.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/oslfile2streamwrap.hxx,comphelper/oslfile2streamwrap.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/genericpropertyset.hxx,comphelper/genericpropertyset.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/makesequence.hxx,comphelper/makesequence.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/ofopxmlhelper.hxx,comphelper/ofopxmlhelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/SettingsHelper.hxx,comphelper/SettingsHelper.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/string.hxx,comphelper/string.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/weak.hxx,comphelper/weak.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/componentmodule.hxx,comphelper/componentmodule.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/container.hxx,comphelper/container.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/seqstream.hxx,comphelper/seqstream.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/namecontainer.hxx,comphelper/namecontainer.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/processfactory.hxx,comphelper/processfactory.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/sequenceashashmap.hxx,comphelper/sequenceashashmap.hxx)) +$(eval $(call gb_Package_add_file,comphelper_inc,inc/comphelper/configurationhelper.hxx,comphelper/configurationhelper.hxx)) + +# vim: set noet sw=4 ts=4: diff --git a/comphelper/inc/comphelper/ChainablePropertySet.hxx b/comphelper/inc/comphelper/ChainablePropertySet.hxx new file mode 100644 index 000000000000..1b11005a42c2 --- /dev/null +++ b/comphelper/inc/comphelper/ChainablePropertySet.hxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_CHAINABLEPROPERTYSET_HXX_ +#define _COMPHELPER_CHAINABLEPROPERTYSET_HXX_ + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <comphelper/PropertyInfoHash.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + class ChainablePropertySetInfo; +} + +/* + * A ChainablePropertySet has the following features: + * + * 1. It implements both the PropertySet and MultiPropertySet interfaces. + * 2. It can be 'included' in a MasterPropertySet to seamlessly appear as if + * if it's properties were in the master. + * + * To be used as a base class for PropertySets, the subclass must implement + * the 6 protected pure virtual functions. If a mutex is passed to the + * constructor, this is locked before any call to _getSingleValue or + * _setSingleValue and released after all processing has completed + * (including _postSetValues or _postGetValues ) + * + * The implementations of getPropertyValues/setPropertyValues call + * lockMutex and _preGetValues/_preSetValues once before calling + * _getSingleValue/_setSingleValue for each property. After each + * property has been dealt with, _postGetValues/_postSetValues + * are called once. + * + * Any MasterPropertySet implementations that can include an + * implementation of a given ChainablePropertySet must be + * declared as a 'friend' in the implementation of the ChainablePropertySet. + * + */ + +namespace comphelper +{ + class COMPHELPER_DLLPUBLIC ChainablePropertySet : public ::com::sun::star::beans::XPropertySet, + public ::com::sun::star::beans::XPropertyState, + public ::com::sun::star::beans::XMultiPropertySet + { + friend class MasterPropertySet; + protected: + ChainablePropertySetInfo *mpInfo; + osl::SolarMutex* mpMutex; + ::com::sun::star::uno::Reference < com::sun::star::beans::XPropertySetInfo > mxInfo; + void lockMutex(); + void unlockMutex(); + + virtual void _preSetValues () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _setSingleValue( const comphelper::PropertyInfo & rInfo, const ::com::sun::star::uno::Any &rValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _postSetValues () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + + virtual void _preGetValues () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _getSingleValue( const comphelper::PropertyInfo & rInfo, ::com::sun::star::uno::Any & rValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _postGetValues () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + + virtual void _preGetPropertyState () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ); + virtual void _getPropertyState( const comphelper::PropertyInfo& rInfo, ::com::sun::star::beans::PropertyState& rState ) + throw(::com::sun::star::beans::UnknownPropertyException ); + virtual void _postGetPropertyState () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ); + + virtual void _setPropertyToDefault( const comphelper::PropertyInfo& rEntry ) + throw(::com::sun::star::beans::UnknownPropertyException ); + virtual ::com::sun::star::uno::Any _getPropertyDefault( const comphelper::PropertyInfo& rEntry ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException ); + + public: + ChainablePropertySet( comphelper::ChainablePropertySetInfo* pInfo, osl::SolarMutex* pMutex = NULL ) + throw(); + virtual ~ChainablePropertySet() + throw(); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XMultiPropertySet + virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues ) + throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertiesChangeListener( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertiesChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL firePropertiesChangeEvent( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + + // XPropertyState + virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyToDefault( const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( const ::rtl::OUString& aPropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/ChainablePropertySetInfo.hxx b/comphelper/inc/comphelper/ChainablePropertySetInfo.hxx new file mode 100644 index 000000000000..c7e1e88f260e --- /dev/null +++ b/comphelper/inc/comphelper/ChainablePropertySetInfo.hxx @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_CHAINABLEPROPERTYSETINFO_HXX_ +#define _COMPHELPER_CHAINABLEPROPERTYSETINFO_HXX_ + +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <comphelper/PropertyInfoHash.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/TypeGeneration.hxx> +#include "comphelper/comphelperdllapi.h" + +/* + * A ChainablePropertySetInfo is usually initialised with a pointer to the first element + * of a null-terminated static table of PropertyInfo structs. This is placed in a hash_map + * for fast access + * + */ +namespace comphelper +{ + class COMPHELPER_DLLPUBLIC ChainablePropertySetInfo: + public ::cppu::WeakImplHelper1< + ::com::sun::star::beans::XPropertySetInfo > + { + friend class ChainablePropertySet; + friend class MasterPropertySet; + protected: + PropertyInfoHash maMap; + com::sun::star::uno::Sequence < com::sun::star::beans::Property > maProperties; + public: + ChainablePropertySetInfo() + throw(); + ChainablePropertySetInfo( PropertyInfo * pMap ) + throw(); + + virtual ~ChainablePropertySetInfo() + throw(); + + void add( PropertyInfo* pMap, sal_Int32 nCount = -1 ) + throw(); + void remove( const rtl::OUString& aName ) + throw(); + + // XPropertySetInfo + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) + throw(::com::sun::star::uno::RuntimeException); + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/IdPropArrayHelper.hxx b/comphelper/inc/comphelper/IdPropArrayHelper.hxx new file mode 100644 index 000000000000..a624ba7b2f5a --- /dev/null +++ b/comphelper/inc/comphelper/IdPropArrayHelper.hxx @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_IDPROPERTYARRAYUSAGEHELPER_HXX +#define COMPHELPER_IDPROPERTYARRAYUSAGEHELPER_HXX + +#include <cppuhelper/component.hxx> +#include <osl/mutex.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <osl/diagnose.h> +#include <comphelper/stl_types.hxx> +#include <rtl/instance.hxx> +#include <cppuhelper/propshlp.hxx> + +namespace cppu { class IPropertyArrayHelper; } + +namespace comphelper +{ + //************************************************************ + // OIdPropertyArrayUsageHelper + //************************************************************ + template <typename TYPE> struct OIdPropertyArrayUsageHelperMutex + : public rtl::Static< ::osl::Mutex, OIdPropertyArrayUsageHelperMutex<TYPE> > {}; + + typedef std::map< sal_Int32, ::cppu::IPropertyArrayHelper*, std::less< sal_Int32 > > OIdPropertyArrayMap; + template <class TYPE> + class OIdPropertyArrayUsageHelper + { + protected: + static sal_Int32 s_nRefCount; + static OIdPropertyArrayMap* s_pMap; + + public: + OIdPropertyArrayUsageHelper(); + virtual ~OIdPropertyArrayUsageHelper() + { + ::osl::MutexGuard aGuard(OIdPropertyArrayUsageHelperMutex<TYPE>::get()); + OSL_ENSURE(s_nRefCount > 0, "OIdPropertyArrayUsageHelper::~OIdPropertyArrayUsageHelper : suspicious call : have a refcount of 0 !"); + if (!--s_nRefCount) + { + // delete the element + for (OIdPropertyArrayMap::iterator i = s_pMap->begin(); i != s_pMap->end(); ++i) + delete (*i).second; + delete s_pMap; + s_pMap = NULL; + } + } + + /** call this in the getInfoHelper method of your derived class. The method returns the array helper of the + class, which is created if neccessary. + */ + ::cppu::IPropertyArrayHelper* getArrayHelper(sal_Int32 nId); + + protected: + /** used to implement the creation of the array helper which is shared amongst all instances of the class. + This method needs to be implemented in derived classes. + <BR> + The method gets called with Mutex acquired. + <BR> + as long as IPropertyArrayHelper has no virtual destructor, the implementation of ~OPropertyArrayUsageHelper + assumes that you created an ::cppu::OPropertyArrayHelper when deleting s_pProps. + @return an pointer to the newly created array helper. Must not be NULL. + */ + virtual ::cppu::IPropertyArrayHelper* createArrayHelper(sal_Int32 nId) const = 0; + }; + + //------------------------------------------------------------------ + template<class TYPE> + sal_Int32 OIdPropertyArrayUsageHelper< TYPE >::s_nRefCount = 0; + + template<class TYPE> + OIdPropertyArrayMap* OIdPropertyArrayUsageHelper< TYPE >::s_pMap = NULL; + + //------------------------------------------------------------------ + template <class TYPE> + OIdPropertyArrayUsageHelper<TYPE>::OIdPropertyArrayUsageHelper() + { + ::osl::MutexGuard aGuard(OIdPropertyArrayUsageHelperMutex<TYPE>::get()); + // create the map if necessary + if (s_pMap == NULL) + s_pMap = new OIdPropertyArrayMap(); + ++s_nRefCount; + } + + //------------------------------------------------------------------ + template <class TYPE> + ::cppu::IPropertyArrayHelper* OIdPropertyArrayUsageHelper<TYPE>::getArrayHelper(sal_Int32 nId) + { + OSL_ENSURE(s_nRefCount, "OIdPropertyArrayUsageHelper::getArrayHelper : suspicious call : have a refcount of 0 !"); + ::osl::MutexGuard aGuard(OIdPropertyArrayUsageHelperMutex<TYPE>::get()); + // do we have the array already? + if (! (*s_pMap)[nId] ) + { + (*s_pMap)[nId] = createArrayHelper(nId); + OSL_ENSURE((*s_pMap)[nId], "OIdPropertyArrayUsageHelper::getArrayHelper : createArrayHelper returned nonsense !"); + } + return (*s_pMap)[nId]; + } +} +#endif // COMPHELPER_IDPROPERTYARRAYUSAGEHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/InlineContainer.hxx b/comphelper/inc/comphelper/InlineContainer.hxx new file mode 100644 index 000000000000..13ae8a5cabd0 --- /dev/null +++ b/comphelper/inc/comphelper/InlineContainer.hxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_INLINE_CONTAINER_HXX +#define INCLUDED_COMPHELPER_INLINE_CONTAINER_HXX + +#include <com/sun/star/uno/Sequence.hxx> + +#include <vector> +#include <map> +#include <set> + +namespace comphelper +{ + +/** Creates a UNO-Sequence which contains an arbitrary number of elements. + Notice, that every call of the operator() issues a realloc, so this is not + suitable to create very large sequences. + + usage: + + uno::Sequence< t >( MakeSequence< t >( t_1 )( t_2 )...( t_n ) ); + */ +template < typename T > +class MakeSequence : public ::com::sun::star::uno::Sequence< T > +{ +public: + explicit MakeSequence(const T &a) + : ::com::sun::star::uno::Sequence< T >( 1 ) + { + this->operator[](0) = a; + } + MakeSequence& operator()(const T &a) + { + this->realloc( this->getLength() + 1 ); + this->operator[]( this->getLength() - 1 ) = a; + return *this; + } +}; + +// ---------------------------------------- + +/** Creates a vector which contains an arbitrary number of elements. + + usage: + + vector< t > aVec( MakeVector< t >( t_1 )( t_2 )...( t_n ) ); + */ +template < typename T > +class MakeVector : public ::std::vector< T > +{ +public: + explicit MakeVector(const T &a) + : ::std::vector< T >(1, a) + { + } + MakeVector &operator()(const T &a) + { + this->push_back(a); + return *this; + } +}; + +// ---------------------------------------- + +/** Creates a set which contains an arbitrary number of elements. + + usage: + + set< t > aSet( MakeSet< t >( t_1 )( t_2 )...( t_n ) ); + */ +template < typename T > +class MakeSet : public ::std::set< T > +{ +public: + explicit MakeSet(const T &a) + : ::std::set< T >() + { + insert(this->end(), a); + } + MakeSet &operator()(const T &a) + { + this->insert(this->end(), a); + return *this; + } +}; + +// ---------------------------------------- + +/** usage: + + map< k, v > aMap( MakeMap< k, v > + ( key_1, value_1 ) + ( key_2, value_2 ) + ( key_3, value_3 ) + ... + ( key_n, value_n ) + ); + */ +template < typename Key, typename Value > +class MakeMap : public ::std::map< Key, Value > +{ +private: + typedef typename ::std::map< Key, Value >::value_type value_type; +public: + explicit MakeMap( const Key &k, const Value &v ) + { + this->insert( value_type( k, v ) ); + } + MakeMap &operator()( const Key &k, const Value &v ) + { + this->insert( value_type( k, v ) ); + return *this; + } + + MakeMap &operator()( const MakeMap& rSource ) + { + this->insert(rSource.begin(),rSource.end()); + return *this; + } +}; + +} // namespace comphelper + +#endif +// INCLUDED_COMPHELPER_INLINE_CONTAINER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/MasterPropertySet.hxx b/comphelper/inc/comphelper/MasterPropertySet.hxx new file mode 100644 index 000000000000..c5e335d6cf67 --- /dev/null +++ b/comphelper/inc/comphelper/MasterPropertySet.hxx @@ -0,0 +1,154 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_MASTERPROPERTYSETHELPER_HXX_ +#define _COMPHELPER_MASTERPROPERTYSETHELPER_HXX_ +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <comphelper/PropertyInfoHash.hxx> +#include "comphelper/comphelperdllapi.h" +#include <map> + +namespace comphelper +{ + class MasterPropertySetInfo; + class ChainablePropertySet; + struct SlaveData + { + ChainablePropertySet * mpSlave; + ::com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > mxSlave; + sal_Bool mbInit; + SlaveData ( ChainablePropertySet *pSlave); + inline sal_Bool IsInit () { return mbInit;} + inline void SetInit ( sal_Bool bInit) { mbInit = bInit; } + }; +} +typedef std::map < sal_uInt8, comphelper::SlaveData* > SlaveMap; + +/* + * A MasterPropertySet implements all of the features of a ChainablePropertySet + * (it is not inherited from ChainablePropertySet to prevent MasterPropertySets + * being chained to each other), but also allows properties implemented in + * other ChainablePropertySets to be included as 'native' properties in a + * given MasterPropertySet implementation. These are registered using the + * 'registerSlave' method, and require that the implementation of the + * ChainablePropertySet and the implementation of the ChainablePropertySetInfo + * both declare the implementation of the MasterPropertySet as a friend. + */ +namespace comphelper +{ + class COMPHELPER_DLLPUBLIC MasterPropertySet : public ::com::sun::star::beans::XPropertySet, + public ::com::sun::star::beans::XPropertyState, + public ::com::sun::star::beans::XMultiPropertySet + { + protected: + MasterPropertySetInfo *mpInfo; + osl::SolarMutex* mpMutex; + sal_uInt8 mnLastId; + SlaveMap maSlaveMap; + ::com::sun::star::uno::Reference < com::sun::star::beans::XPropertySetInfo > mxInfo; + void lockMutex(); + void unlockMutex(); + + virtual void _preSetValues () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _setSingleValue( const comphelper::PropertyInfo & rInfo, const ::com::sun::star::uno::Any &rValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _postSetValues () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + + virtual void _preGetValues () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _getSingleValue( const comphelper::PropertyInfo & rInfo, ::com::sun::star::uno::Any & rValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _postGetValues () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + + virtual void _preGetPropertyState () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ); + virtual void _getPropertyState( const comphelper::PropertyInfo& rInfo, ::com::sun::star::beans::PropertyState& rState ) + throw(::com::sun::star::beans::UnknownPropertyException ); + virtual void _postGetPropertyState () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ); + + virtual void _setPropertyToDefault( const comphelper::PropertyInfo& rEntry ) + throw(::com::sun::star::beans::UnknownPropertyException ); + virtual ::com::sun::star::uno::Any _getPropertyDefault( const comphelper::PropertyInfo& rEntry ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException ); + + public: + MasterPropertySet( comphelper::MasterPropertySetInfo* pInfo, ::osl::SolarMutex* pMutex = NULL ) + throw(); + virtual ~MasterPropertySet() + throw(); + void registerSlave ( ChainablePropertySet *pNewSet ) + throw(); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XMultiPropertySet + virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues ) + throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertiesChangeListener( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertiesChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL firePropertiesChangeEvent( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException); + + // XPropertyState + virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyToDefault( const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( const ::rtl::OUString& aPropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/MasterPropertySetInfo.hxx b/comphelper/inc/comphelper/MasterPropertySetInfo.hxx new file mode 100644 index 000000000000..c121289622b0 --- /dev/null +++ b/comphelper/inc/comphelper/MasterPropertySetInfo.hxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_MASTERPROPERTYSETINFO_HXX_ +#define _COMPHELPER_MASTERPROPERTYSETINFO_HXX_ +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <comphelper/PropertyInfoHash.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/TypeGeneration.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + class COMPHELPER_DLLPUBLIC MasterPropertySetInfo: + public ::cppu::WeakImplHelper1< + ::com::sun::star::beans::XPropertySetInfo > + { + friend class MasterPropertySet; + protected: + PropertyDataHash maMap; + com::sun::star::uno::Sequence < com::sun::star::beans::Property > maProperties; + public: + MasterPropertySetInfo() + throw(); + MasterPropertySetInfo( PropertyInfo * pMap ) + throw(); + virtual ~MasterPropertySetInfo() + throw(); + void add( PropertyInfo* pMap, sal_Int32 nCount = -1, sal_uInt8 nMapId = 0 ) + throw(); + void add( PropertyInfoHash &rHash, sal_uInt8 nMapId ) + throw(); + void remove( const rtl::OUString& aName ) + throw(); + + // XPropertySetInfo + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) + throw(::com::sun::star::uno::RuntimeException); + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/PropertyInfoHash.hxx b/comphelper/inc/comphelper/PropertyInfoHash.hxx new file mode 100644 index 000000000000..7c75b99335f9 --- /dev/null +++ b/comphelper/inc/comphelper/PropertyInfoHash.hxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTYINFOHASH_HXX_ +#define _COMPHELPER_PROPERTYINFOHASH_HXX_ + +#include <rtl/ustring.hxx> +#include <comphelper/TypeGeneration.hxx> +#include <boost/unordered_map.hpp> +namespace comphelper +{ + struct PropertyInfo + { + const sal_Char* mpName; + sal_uInt16 mnNameLen; + sal_Int32 mnHandle; + CppuTypes meCppuType; + sal_Int16 mnAttributes; + sal_uInt8 mnMemberId; + }; + struct PropertyData + { + sal_uInt8 mnMapId; + PropertyInfo *mpInfo; + PropertyData ( sal_uInt8 nMapId, PropertyInfo *pInfo ) + : mnMapId ( nMapId ) + , mpInfo ( pInfo ) {} + }; + struct eqFunc + { + sal_Bool operator()( const rtl::OUString &r1, + const rtl::OUString &r2) const + { + return r1 == r2; + } + }; +} + +typedef boost::unordered_map < ::rtl::OUString, + ::comphelper::PropertyInfo*, + ::rtl::OUStringHash, + ::comphelper::eqFunc > PropertyInfoHash; +typedef boost::unordered_map < ::rtl::OUString, + ::comphelper::PropertyData*, + ::rtl::OUStringHash, + ::comphelper::eqFunc > PropertyDataHash; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/SelectionMultiplex.hxx b/comphelper/inc/comphelper/SelectionMultiplex.hxx new file mode 100644 index 000000000000..d2ce6ba79d2c --- /dev/null +++ b/comphelper/inc/comphelper/SelectionMultiplex.hxx @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_SELECTION_MULTIPLEX_HXX +#define INCLUDED_COMPHELPER_SELECTION_MULTIPLEX_HXX + +#include <com/sun/star/view/XSelectionChangeListener.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <cppuhelper/implbase1.hxx> +#include "comphelper/comphelperdllapi.h" + +//========================================================================= +//= selection helper classes +//========================================================================= + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + class OSelectionChangeMultiplexer; + + //================================================================== + //= OSelectionChangeListener + //================================================================== + /// simple listener adapter for selections + class COMPHELPER_DLLPUBLIC OSelectionChangeListener + { + friend class OSelectionChangeMultiplexer; + + OSelectionChangeMultiplexer* m_pAdapter; + ::osl::Mutex& m_rMutex; + + public: + OSelectionChangeListener(::osl::Mutex& _rMutex) + : m_pAdapter(NULL), m_rMutex(_rMutex) { } + virtual ~OSelectionChangeListener(); + + virtual void _selectionChanged( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException) = 0; + virtual void _disposing(const ::com::sun::star::lang::EventObject& _rSource) throw( ::com::sun::star::uno::RuntimeException); + + protected: + /** If the derivee also owns the mutex which we know as reference, then call this within your + derivee's dtor. + */ + void disposeAdapter(); + + // pseudo-private. Making it private now could break compatibility + void setAdapter( OSelectionChangeMultiplexer* _pAdapter ); + }; + + //================================================================== + //= OSelectionChangeMultiplexer + //================================================================== + /// multiplexer for selection changes + class COMPHELPER_DLLPUBLIC OSelectionChangeMultiplexer :public cppu::WeakImplHelper1< ::com::sun::star::view::XSelectionChangeListener> + { + friend class OSelectionChangeListener; + ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionSupplier> m_xSet; + OSelectionChangeListener* m_pListener; + sal_Int32 m_nLockCount; + sal_Bool m_bListening : 1; + sal_Bool m_bAutoSetRelease : 1; + + OSelectionChangeMultiplexer(const OSelectionChangeMultiplexer&); + OSelectionChangeMultiplexer& operator=(const OSelectionChangeMultiplexer&); + protected: + virtual ~OSelectionChangeMultiplexer(); + public: + OSelectionChangeMultiplexer(OSelectionChangeListener* _pListener, const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionSupplier>& _rxSet, sal_Bool _bAutoReleaseSet = sal_True); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw( ::com::sun::star::uno::RuntimeException); + + // XSelectionChangeListener + virtual void SAL_CALL selectionChanged( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException); + + /// incremental lock + void lock(); + /// incremental unlock + void unlock(); + /// get the lock count + sal_Int32 locked() const { return m_nLockCount; } + + void dispose(); + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // INCLUDED_COMPHELPER_SELECTION_MULTIPLEX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/SettingsHelper.hxx b/comphelper/inc/comphelper/SettingsHelper.hxx new file mode 100644 index 000000000000..ed951083df71 --- /dev/null +++ b/comphelper/inc/comphelper/SettingsHelper.hxx @@ -0,0 +1,122 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_SETTINGSHELPER_HXX_ +#define _COMPHELPER_SETTINGSHELPER_HXX_ +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase3.hxx> + +namespace comphelper +{ + class MasterPropertySet; + class MasterPropertySetInfo; + class ChainablePropertySet; + class ChainablePropertySetInfo; + + typedef cppu::WeakImplHelper3 + < + ::com::sun::star::beans::XPropertySet, + ::com::sun::star::beans::XMultiPropertySet, + ::com::sun::star::lang::XServiceInfo + > + HelperBaseNoState; + template < class ComphelperBase, class ComphelperBaseInfo > class SettingsHelperNoState : + public HelperBaseNoState, + public ComphelperBase + { + public: + SettingsHelperNoState ( ComphelperBaseInfo *pInfo, ::osl::SolarMutex* pMutex = NULL) + : ComphelperBase ( pInfo, pMutex ) + {} + virtual ~SettingsHelperNoState () throw( ) {} + com::sun::star::uno::Any SAL_CALL queryInterface( const com::sun::star::uno::Type& aType ) throw (com::sun::star::uno::RuntimeException) + { return HelperBaseNoState::queryInterface( aType ); } + void SAL_CALL acquire( ) throw () + { HelperBaseNoState::acquire( ); } + void SAL_CALL release( ) throw () + { HelperBaseNoState::release( ); } + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) + throw(::com::sun::star::uno::RuntimeException) + { return ComphelperBase::getPropertySetInfo(); } + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { ComphelperBase::setPropertyValue ( aPropertyName, aValue ); } + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { return ComphelperBase::getPropertyValue ( PropertyName ); } + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { ComphelperBase::addPropertyChangeListener ( aPropertyName, xListener ); } + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { ComphelperBase::removePropertyChangeListener ( aPropertyName, aListener ); } + virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { ComphelperBase::addVetoableChangeListener ( PropertyName, aListener ); } + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { ComphelperBase::removeVetoableChangeListener ( PropertyName, aListener ); } + + // XMultiPropertySet + virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues ) + throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { ComphelperBase::setPropertyValues ( aPropertyNames, aValues ); } + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) + throw(::com::sun::star::uno::RuntimeException) + { return ComphelperBase::getPropertyValues ( aPropertyNames ); } + virtual void SAL_CALL addPropertiesChangeListener( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException) + { ComphelperBase::addPropertiesChangeListener ( aPropertyNames, xListener ); } + virtual void SAL_CALL removePropertiesChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException) + { ComphelperBase::removePropertiesChangeListener ( xListener ); } + virtual void SAL_CALL firePropertiesChangeEvent( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) + throw(::com::sun::star::uno::RuntimeException) + { ComphelperBase::firePropertiesChangeEvent ( aPropertyNames, xListener ); } + }; + typedef comphelper::SettingsHelperNoState + < + ::comphelper::MasterPropertySet, + ::comphelper::MasterPropertySetInfo + > + MasterHelperNoState; + typedef comphelper::SettingsHelperNoState + < + ::comphelper::ChainablePropertySet, + ::comphelper::ChainablePropertySetInfo + > + ChainableHelperNoState; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/TypeGeneration.hxx b/comphelper/inc/comphelper/TypeGeneration.hxx new file mode 100644 index 000000000000..c987b2adbe50 --- /dev/null +++ b/comphelper/inc/comphelper/TypeGeneration.hxx @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_TYPEGENERATION_HXX_ +#define _COMPHELPER_TYPEGENERATION_HXX_ + +#include <sal/types.h> +#include "comphelper/comphelperdllapi.h" + +#define CPPU_E2T(type) ((com::sun::star::uno::Type*)type) + +namespace com { namespace sun { namespace star { namespace uno { + class Type; +} } } } +namespace comphelper +{ + enum CppuTypes + { + CPPUTYPE_UNKNOWN, // 0 == unknown == error!!!! + + CPPUTYPE_BOOLEAN, //getBooleanCppuType() + CPPUTYPE_INT8, //getCppuType( (sal_Int8*)0 ) + CPPUTYPE_INT16, //getCppuType( (sal_Int16*)0 ) + CPPUTYPE_INT32, //getCppuType( (sal_Int32*)0 ) + CPPUTYPE_DOUBLE, //getCppuType( (double*)0 ) + CPPUTYPE_FLOAT, //getCppuType( (float*)0 ) + CPPUTYPE_OUSTRING, //getCppuType( (OUString*)0 ) + + CPPUTYPE_FONTSLANT, //getCppuType( (FontSlant*)0 ) + CPPUTYPE_LOCALE, //getCppuType( (Locale*)0 ) + CPPUTYPE_PROPERTYVALUE, //getCppuType( (Sequence<PropertyValue>*)0 ) + CPPUTYPE_PROPERTYVALUES, //getCppuType( (Sequence<PropertyValues>*)0 ) + CPPUTYPE_BORDERLINE, //getCppuType( (table::BorderLine*)0 ) + CPPUTYPE_BREAK, //getCppuType( (style::BreakType*)0 ) + CPPUTYPE_GRAPHICLOC, //getCppuType( (style::GraphicLocation*)0 ) + CPPUTYPE_DROPCAPFMT, //getCppuType( (style::DropCapFormat*)0 ) + CPPUTYPE_LINESPACE, //getCppuType( (style::LineSpacing*)0 ) + CPPUTYPE_AWTSIZE, //getCppuType( (awt::Size*)0 ) + CPPUTYPE_SHADOWFMT, //getCppuType( (table::ShadowFormat*)0 ) + CPPUTYPE_TBLCOLSEP, //getCppuType( (Sequence<text::TableColumnSeparator>*)0 ) + CPPUTYPE_PNTSEQSEQ, //getCppuType( (PointSequenceSequence*)0 ) + CPPUTYPE_DOCIDXMRK, //getCppuType( (Sequence< Reference< XDocumentIndexMark > >*)0 ) + CPPUTYPE_SEQINT8, //getCppuType( (Sequence<sal_Int8>*)0 ) + CPPUTYPE_SEQTABSTOP, //getCppuType( (Sequence<style::TabStop>*)0 ) + CPPUTYPE_SEQANCHORTYPE, //getCppuType( (Sequence<text::TextContentAnchorType>*)0 ) + CPPUTYPE_SEQDEPTXTFLD, //getCppuType( (Sequence<Reference<XDependentTextField> >*)0 ) + CPPUTYPE_TXTCNTANCHOR, //getCppuType( (text::TextContentAnchorType*)0 ) + CPPUTYPE_WRAPTXTMODE, //getCppuType( (text::WrapTextMode*)0 ) + CPPUTYPE_COLORMODE, //getCppuType( (drawing::ColorMode*)0 ) + CPPUTYPE_PAGESTYLELAY, //getCppuType( (style::PageStyleLayout*)0 ) + CPPUTYPE_VERTALIGN, //getCppuType( (style::VerticalAlignment*)0 ) + CPPUTYPE_TABLEBORDER, //getCppuType( (table::TableBorder*)0 ) + CPPUTYPE_GRFCROP, //getCppuType( (text::GraphicCrop*)0 ) + CPPUTYPE_SECTFILELNK, //getCppuType( (text::SectionFileLink*)0 ) + CPPUTYPE_PAGENUMTYPE, //getCppuType( (const PageNumberType*)0 ) + CPPUTYPE_DATETIME, //getCppuType( (util::DateTime*)0 ) + CPPUTYPE_DATE, //getCppuType( (util::Date*)0 ) + + CPPUTYPE_REFINTERFACE, //getCppuType( (Reference<XInterface>*)0 ) + CPPUTYPE_REFIDXREPL, //getCppuType( (Reference<container::XIndexReplace>*)0 ) + CPPUTYPE_REFNAMECNT, //getCppuType( (Reference<container::XNameContainer>*)0 ) + CPPUTYPE_REFTEXTFRAME, //getCppuType( (Reference<text::XTextFrame>*)0 ) + CPPUTYPE_REFTEXTSECTION, //getCppuType( (Reference<text::XTextSection>*)0 ) + CPPUTYPE_REFFOOTNOTE, //getCppuType( (Reference<text::XFootnote>*)0 ) + CPPUTYPE_REFTEXT, //getCppuType( (Reference<text::XText>*)0 ) + CPPUTYPE_REFTEXTCOL, //getCppuType( (Reference<text::XTextColumns>*)0 ) + + CPPUTYPE_REFFORBCHARS, //getCppuType( (Reference<XForbiddenCharacters>*)0) + CPPUTYPE_REFIDXCNTNR, //getCppuType( (Reference<XIndexContainer>*)0) + CPPUTYPE_REFTEXTCNTNT, //getCppuType( (Reference<XTextContent>*)0) + CPPUTYPE_REFBITMAP, //getCppuType( (Reference<awt::XBitmap>*)0) + CPPUTYPE_REFNMREPLACE, //getCppuType( (Reference<container::XNameReplace>*)0) + CPPUTYPE_REFCELL, //getCppuType( (Reference<table::XCell>*)0) + CPPUTYPE_REFDOCINDEX, //getCppuType( (Reference<text::XDocumentIndex>*)0) + CPPUTYPE_REFDOCIDXMRK, //getCppuType( (Reference<text::XDocumentIndexMark>*)0) + CPPUTYPE_REFTXTFIELD, //getCppuType( (Reference<text::XTextField>*)0) + CPPUTYPE_REFTXTRANGE, //getCppuType( (Reference<text::XTextRange>*)0) + CPPUTYPE_REFTXTTABLE, //getCppuType( (Reference<text::XTextTable>*)0) + CPPUTYPE_AWTPOINT, //getCppuType( (awt::Point*)0 ) + CPPUTYPE_REFLIBCONTAINER, //getCppuType( (Reference< script::XLibraryContainer >*)0) + CPPUTYPE_SEQANY, //getCppuType( (Sequence< uno::Any >*)0) + CPPUTYPE_REFRESULTSET, //getCppuType( (Reference< sdbc::XResultSet >*)0) + CPPUTYPE_REFCONNECTION, //getCppuType( (Reference< sdbc::XConnection >*)0) + CPPUTYPE_REFMODEL, //getCppuType( (Reference< frame::XModel >*)0) + + CPPUTYPE_OUSTRINGS, //getCppuType( (Sequence<OUString>*)0 ) + CPPUTYPE_REFCOMPONENT, //getCppuType( (Reference< lang::XComponent >*)0 ) + // #i28749# + CPPUTYPE_TRANSFORMATIONINHORIL2R, //getCppuType( (drawing::HomogenMatrix3)* ) + CPPUTYPE_SEQNAMEDVALUE, //getCppuType( (Sequence<beans::NamedValue>*)0 ) + CPPUTYPE_REFXGRAPHIC, //getCppuType( Reference< graphic::XGraphic >*)0) + CPPUTYPE_TABLEBORDERDISTANCES, //getCppuType( (table::TableBorderDistances*)0 ) + CPPUTPYE_REFEMBEDDEDOBJECT, // XEmbeddedObject::static_type + + CPPUTYPE_END + }; + COMPHELPER_DLLPUBLIC void GenerateCppuType ( + CppuTypes eType, const com::sun::star::uno::Type*& pType ); +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accessiblecomponenthelper.hxx b/comphelper/inc/comphelper/accessiblecomponenthelper.hxx new file mode 100644 index 000000000000..582d77a99283 --- /dev/null +++ b/comphelper/inc/comphelper/accessiblecomponenthelper.hxx @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ACCESSIBLE_COMPONENT_HELPER_HXX +#define COMPHELPER_ACCESSIBLE_COMPONENT_HELPER_HXX + +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp> +#include <comphelper/accessiblecontexthelper.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/uno3.hxx> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //===================================================================== + //= OCommonAccessibleComponent + //===================================================================== + /** base class encapsulating common functionality for the helper classes implementing + the XAccessibleComponent respectively XAccessibleExtendendComponent + */ + class COMPHELPER_DLLPUBLIC OCommonAccessibleComponent : public OAccessibleContextHelper + { + protected: + OCommonAccessibleComponent(); + /// see the respective base class ctor for an extensive comment on this, please + OCommonAccessibleComponent( IMutex* _pExternalLock ); + ~OCommonAccessibleComponent(); + + protected: + /// implements the calculation of the bounding rectangle - still waiting to be overwritten + virtual ::com::sun::star::awt::Rectangle SAL_CALL implGetBounds( ) throw (::com::sun::star::uno::RuntimeException) = 0; + + protected: + /** non-virtual versions of the methods which can be implemented using <method>implGetBounds</method> + note: getLocationOnScreen relies on a valid parent (XAccessibleContext::getParent()->getAccessibleContext()), + which itself implements XAccessibleComponent + */ + sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); + }; + + //===================================================================== + //= OAccessibleComponentHelper + //===================================================================== + + struct OAccessibleComponentHelper_Base : + public ::cppu::ImplHelper1< ::com::sun::star::accessibility::XAccessibleComponent > + {}; + + /** a helper class for implementing an AccessibleContext which at the same time + supports an XAccessibleComponent interface. + */ + class COMPHELPER_DLLPUBLIC OAccessibleComponentHelper + :public OCommonAccessibleComponent + ,public OAccessibleComponentHelper_Base + { + protected: + OAccessibleComponentHelper( ); + /// see the respective base class ctor for an extensive comment on this, please + OAccessibleComponentHelper( IMutex* _pExternalLock ); + + public: + // XInterface + DECLARE_XINTERFACE( ) + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleComponent - default implementations + virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); + }; + + //===================================================================== + //= OAccessibleExtendedComponentHelper + //===================================================================== + + typedef ::cppu::ImplHelper1 < ::com::sun::star::accessibility::XAccessibleExtendedComponent + > OAccessibleExtendedComponentHelper_Base; + + /** a helper class for implementing an AccessibleContext which at the same time + supports an XAccessibleExtendedComponent interface. + */ + class COMPHELPER_DLLPUBLIC OAccessibleExtendedComponentHelper + :public OCommonAccessibleComponent + ,public OAccessibleExtendedComponentHelper_Base + { + protected: + OAccessibleExtendedComponentHelper( ); + /// see the respective base class ctor for an extensive comment on this, please + OAccessibleExtendedComponentHelper( IMutex* _pExternalLock ); + + public: + // XInterface + DECLARE_XINTERFACE( ) + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleComponent - default implementations + virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // COMPHELPER_ACCESSIBLE_COMPONENT_HELPER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accessiblecontexthelper.hxx b/comphelper/inc/comphelper/accessiblecontexthelper.hxx new file mode 100644 index 000000000000..310be9321a40 --- /dev/null +++ b/comphelper/inc/comphelper/accessiblecontexthelper.hxx @@ -0,0 +1,378 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX +#define COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX + +#include <cppuhelper/compbase2.hxx> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <comphelper/broadcasthelper.hxx> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + class AccessibleEventBuffer; + + //===================================================================== + //= IMutex + //===================================================================== + + // This whole thingie here (own mutex classes and such) is a HACK. I hate the SolarMutex. + // See below for more explanations .... + + /** abstract interface for implementing a mutex + */ + class IMutex + { + public: + virtual void acquire() = 0; + virtual void release() = 0; + }; + + //===================================================================== + //= OMutexGuard + //===================================================================== + + class OMutexGuard + { + IMutex* m_pMutex; + public: + inline OMutexGuard( IMutex* _pMutex ) + :m_pMutex( _pMutex ) + { + if ( m_pMutex ) + m_pMutex->acquire(); + } + + inline ~OMutexGuard( ) + { + if ( m_pMutex ) + m_pMutex->release(); + } + }; + + //===================================================================== + //= OAccessibleContextHelper + //===================================================================== + + class OContextHelper_Impl; + typedef ::cppu::WeakAggComponentImplHelper2 < ::com::sun::star::accessibility::XAccessibleContext, + ::com::sun::star::accessibility::XAccessibleEventBroadcaster + > OAccessibleContextHelper_Base; + + /** helper class for implementing an AccessibleContext + */ + class COMPHELPER_DLLPUBLIC OAccessibleContextHelper + :public ::comphelper::OBaseMutex + ,public OAccessibleContextHelper_Base + { + private: + OContextHelper_Impl* m_pImpl; + + protected: + OAccessibleContextHelper( ); + ~OAccessibleContextHelper( ); + + /** ctor + + <p>If you need additional object safety for your class, and want to ensure that your own + mutex is locked before the mutex this class provides is, than use this ctor.</p> + + <p>Beware that this is a hack. Unfortunately, OpenOffice.org has two different mutex hierarchies, + which are not compatible. In addition, wide parts of the code (especially VCL) is not thread-safe, + but instead relies on a <em>single global mutex</em>. As a consequence, components using + directly or indirectly such code need to care for this global mutex. Yes, this is as ugly as + anything.</p> + + <p>Note that the external lock is used as additional lock, not as the only one. The own mutex of the + instance is used for internal actions, and every action which potentially involves external code + (for instance every call to a virtual method overridden by derivees) is <em>additionally</em> and + <em>first</em> guarded by with the external lock.</p> + + <p>Beware of the lifetime of the lock - you must ensure that the lock exists at least as long as + the context does. A good approach to implement the lock may be to derive you own context + not only from OAccessibleContextHelper, but also from IMutex.</p> + + <p>One more note. This lock is definately not used once the dtor is reached. Means whatever + the dtor implementation does, it does <em>not</em> guard the external lock. See this as a contract. + <br/>You should ensure the same thing for own derivees which do not supply the lock themself, + but get them from yet another derivee.</p> + @see forgetExternalLock + */ + OAccessibleContextHelper( IMutex* _pExternalLock ); + + /** late construction + @param _rxAccessible + the Accessible object which created this context. + <p>If your derived implementation implements the XAccessible (and does not follow the proposed + separation of XAccessible from XAccessibleContext), you may pass <code>this</code> here.</p> + + <p>The object is hold weak, so it's life time is not affected.</p> + + <p>The object is needed for performance reasons: for <method>getAccessibleIndexInParent</method>, + all children (which are XAccessible's theirself) of our parent have to be asked. If we know our + XAccessible, we can compare it with all the children, instead of asking all children for their + context and comparing this context with ourself.</p> + */ + void lateInit( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxAccessible ); + + /** retrieves the creator previously set with <method>lateInit</method> + */ + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + getAccessibleCreator( ) const; + + /** forgets the reference to the external lock, if present. + + <p>This means any further locking will not be guard the external lock anymore, never.</p> + + <p>To be used in derived classes which do not supply the external lock themself, but instead get + them passed from own derivees (or clients).</p> + */ + void forgetExternalLock(); + + public: + // XAccessibleEventBroadcaster + using WeakAggComponentImplHelperBase::addEventListener; + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + using WeakAggComponentImplHelperBase::removeEventListener; + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleContext - still waiting to be overwritten + virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException) = 0; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) = 0; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException) = 0; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException) = 0; + virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException) = 0; + virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException) = 0; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException) = 0; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException) = 0; + + // XAccessibleContext - default implementations + /** default implementation for retrieving the index of this object within the parent + <p>This basic implementation here returns the index <code>i</code> of the child for which + <code><parent>.getAccessibleChild( i )</code> equals our creator.</p> + */ + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException); + /** default implementation for retrieving the locale + <p>This basic implementation returns the locale of the parent context, + as retrieved via getAccessibleParent()->getAccessibleContext.</p> + */ + virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException); + + public: + // helper struct for granting selective access rights + struct OAccessControl + { + friend class OContextEntryGuard; + friend class OContextHelper_Impl; + friend class OExternalLockGuard; + private: + OAccessControl() { } + }; + + // ensures that the object is alive + inline void ensureAlive( const OAccessControl& ) const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) ); + inline IMutex* getExternalLock( const OAccessControl& ); + inline ::osl::Mutex& GetMutex( const OAccessControl& ); + + protected: + // OComponentHelper + virtual void SAL_CALL disposing(); + + protected: + // helper + /** notifies all AccessibleEventListeners of a certain event + + @precond not too be called with our mutex locked + @param _nEventId + the id of the even. See AccessibleEventType + @param _rOldValue + the old value to be notified + @param _rNewValue + the new value to be notified + */ + virtual void SAL_CALL NotifyAccessibleEvent( + const sal_Int16 _nEventId, + const ::com::sun::star::uno::Any& _rOldValue, + const ::com::sun::star::uno::Any& _rNewValue + ); + + /** records a certain event so that all AccessibleEventListeners can + be notified later on. + + Can even be called with our mutex locked. + + @param _nEventId + the id of the even. See AccessibleEventType + @param _rOldValue + the old value to be notified + @param _rNewValue + the new value to be notified + @param _rBuffer + the buffer that records the event + */ + virtual void SAL_CALL BufferAccessibleEvent( + const sal_Int16 _nEventId, + const ::com::sun::star::uno::Any& _rOldValue, + const ::com::sun::star::uno::Any& _rNewValue, + AccessibleEventBuffer & _rBuffer + ); + + // life time control + /// checks whether the object is alive (returns <TRUE/> then) or disposed + sal_Bool isAlive() const; + /// checks for beeing alive. If the object is already disposed (i.e. not alive), an exception is thrown. + void ensureAlive() const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) ); + + /** ensures that the object is disposed. + @precond + to be called from within the destructor of your derived class only! + */ + void ensureDisposed( ); + + /** shortcut for retrieving the context of the parent (returned by getAccessibleParent) + */ + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > + implGetParentContext() SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) ); + + // access to the base class' broadcast helper/mutex + ::cppu::OBroadcastHelper& GetBroadcastHelper() { return rBHelper; } + const ::cppu::OBroadcastHelper& GetBroadcastHelper() const { return rBHelper; } + ::osl::Mutex& GetMutex() { return m_aMutex; } + IMutex* getExternalLock( ); + }; + + //--------------------------------------------------------------------- + inline void OAccessibleContextHelper::ensureAlive( const OAccessControl& ) const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) ) + { + ensureAlive(); + } + + //--------------------------------------------------------------------- + inline IMutex* OAccessibleContextHelper::getExternalLock( const OAccessControl& ) + { + return getExternalLock(); + } + + //--------------------------------------------------------------------- + inline ::osl::Mutex& OAccessibleContextHelper::GetMutex( const OAccessControl& ) + { + return GetMutex(); + } + + //===================================================================== + //= OContextEntryGuard + //===================================================================== + typedef ::osl::ClearableMutexGuard OContextEntryGuard_Base; + /** helper class for guarding the entry into OAccessibleContextHelper methods. + + <p>The class has two responsibilities: + <ul><li>it locks the mutex of an OAccessibleContextHelper instance, as long as the guard lives</li> + <li>it checks if an given OAccessibleContextHelper instance is alive, else an exception is thrown + our of the constructor of the guard</li> + </ul> + <br/> + This makes it your first choice (hopefully :) for guarding any interface method implementations of + you derived class. + </p> + */ + class OContextEntryGuard : public OContextEntryGuard_Base + { + public: + /** constructs the guard + + <p>The given context (it's mutex, respectively) is locked, and an exception is thrown if the context + is not alive anymore. In the latter case, of course, the mutex is freed, again.</p> + + @param _pContext + the context which shall be guarded + @precond <arg>_pContext</arg> != NULL + */ + inline OContextEntryGuard( OAccessibleContextHelper* _pContext ); + + /** destructs the guard. + <p>The context (it's mutex, respectively) is unlocked.</p> + */ + inline ~OContextEntryGuard(); + }; + + //..................................................................... + inline OContextEntryGuard::OContextEntryGuard( OAccessibleContextHelper* _pContext ) + :OContextEntryGuard_Base( _pContext->GetMutex( OAccessibleContextHelper::OAccessControl() ) ) + { + _pContext->ensureAlive( OAccessibleContextHelper::OAccessControl() ); + } + + //..................................................................... + inline OContextEntryGuard::~OContextEntryGuard() + { + } + + //===================================================================== + //= OExternalLockGuard + //===================================================================== + class OExternalLockGuard + :public OMutexGuard + ,public OContextEntryGuard + { + public: + inline OExternalLockGuard( OAccessibleContextHelper* _pContext ); + inline ~OExternalLockGuard( ); + }; + + //..................................................................... + inline OExternalLockGuard::OExternalLockGuard( OAccessibleContextHelper* _pContext ) + :OMutexGuard( _pContext->getExternalLock( OAccessibleContextHelper::OAccessControl() ) ) + ,OContextEntryGuard( _pContext ) + { + // #102438# + // Only lock the external mutex, + // release the ::osl::Mutex of the OAccessibleContextHelper instance. + // If you call into another UNO object with locked ::osl::Mutex, + // this may lead to dead locks. + clear(); + } + + //..................................................................... + inline OExternalLockGuard::~OExternalLockGuard( ) + { + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accessibleeventbuffer.hxx b/comphelper/inc/comphelper/accessibleeventbuffer.hxx new file mode 100644 index 000000000000..3819651569d7 --- /dev/null +++ b/comphelper/inc/comphelper/accessibleeventbuffer.hxx @@ -0,0 +1,136 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_ACCESSIBLEEVENTBUFFER_HXX +#define INCLUDED_COMPHELPER_ACCESSIBLEEVENTBUFFER_HXX + +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/Sequence.hxx" + +#include <vector> + +namespace com { namespace sun { namespace star { namespace uno { + class XInterface; +} } } } +namespace com { namespace sun { namespace star { + namespace accessibility { struct AccessibleEventObject; } +} } } + +namespace comphelper { + +/** + A buffer for AccessibleEventObjects about to be sent to + XAccessibleEventListeners. + + This buffer records pairs of AccessibleEventObjects and sequences of + XAccessibleEventListeners. At a time when it is safe to do so (e.g., when + no critical mutexes are held), all events can be notified at once. + + This class is not thread-safe in itself, but it is thread-compatible (i.e., + all multi-threaded uses of instances of this class have to ensure proper + mutual exclusion). + */ +class AccessibleEventBuffer +{ +public: + /** + Create an initially empty buffer. + + Internally uses ::std::vector and thus may throw exceptions thrown by + operations on ::std::vector, especially ::std::bad_alloc. + */ + AccessibleEventBuffer(); + + /** + Create a buffer with a copy of another buffer. + + The events from the other buffer are copied, not shared. + + Internally uses ::std::vector and thus may throw exceptions thrown by + operations on ::std::vector, especially ::std::bad_alloc. + */ + AccessibleEventBuffer(AccessibleEventBuffer const & rOther); + + /** + Destroy the buffer. + + If the buffer contains any events that have not yet been sent, those + events are lost. + + Does not throw any exceptions. + */ + ~AccessibleEventBuffer(); + + /** + Copy another buffer into this buffer. + + If this buffer contained any events that had not yet been sent, those + events are lost. The events from the other buffer are copied, not + shared. + + Internally uses ::std::vector and thus may throw exceptions thrown by + operations on ::std::vector, especially ::std::bad_alloc. + */ + AccessibleEventBuffer operator =(AccessibleEventBuffer const & rOther); + + /** + Add an event to the buffer. + + Internally uses ::std::vector and thus may throw exceptions thrown by + operations on ::std::vector, especially ::std::bad_alloc. + */ + void addEvent( + ::com::sun::star::accessibility::AccessibleEventObject const & + rEvent, + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< + ::com::sun::star::uno::XInterface > > const & rListeners); + + /** + Sends all the events accumulated in the buffer. + + If sending any of the events to a specific XAccessibleListener fails with + a RuntimeException, that exception is ignored and the method carries on + with the rest of the notifications. + + After sending all events, the buffer is cleared. + */ + void sendEvents() const; + +private: + struct Entry; + + typedef ::std::vector< Entry > Entries; + + Entries m_aEntries; +}; + +} + +#endif // INCLUDED_COMPHELPER_ACCESSIBLEEVENTBUFFER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accessibleeventnotifier.hxx b/comphelper/inc/comphelper/accessibleeventnotifier.hxx new file mode 100644 index 000000000000..c80b8ffccf14 --- /dev/null +++ b/comphelper/inc/comphelper/accessibleeventnotifier.hxx @@ -0,0 +1,175 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER +#define COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER + +#include <com/sun/star/accessibility/AccessibleEventObject.hpp> +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <osl/thread.hxx> +#include <osl/conditn.hxx> +#include <cppuhelper/interfacecontainer.h> +#include "comphelper/comphelperdllapi.h" + +#include <map> +#include <list> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //===================================================================== + //= AccessibleEventNotifier + //===================================================================== + class COMPHELPER_DLLPUBLIC AccessibleEventNotifier + { + // typedefs + public: + typedef sal_uInt32 TClientId; + + typedef ::std::pair< TClientId, ::com::sun::star::accessibility::AccessibleEventObject > + ClientEvent; + + typedef ::cppu::OInterfaceContainerHelper EventListeners; + typedef ::std::map< TClientId, EventListeners*, ::std::less< TClientId > > ClientMap; + + protected: + AccessibleEventNotifier( ); // never implemented + ~AccessibleEventNotifier( ); // never implemented + + private: + COMPHELPER_DLLPRIVATE AccessibleEventNotifier( const AccessibleEventNotifier& ); // never implemented! + COMPHELPER_DLLPRIVATE AccessibleEventNotifier& operator=( const AccessibleEventNotifier& ); // never implemented! + + public: + /** registers a client of this class, means a broadcaster of AccessibleEvents + + <p>No precaution is taken to care for disposal of this component. When the component + dies, it <b>must</b> call <member>revokeClient</member> or <member>revokeClientNotifyDisposing</member> + explicitly itself.</p> + */ + static TClientId registerClient( ); + + /** revokes a broadcaster of AccessibleEvents + + <p>Note that no disposing event is fired when you use this method, the client is simply revoked. + You can for instance revoke a client if the last listener for it is revoked, but the client + itself is not disposed.<br/> + When the client is disposed, you should prefer <member>revokeClientNotifyDisposing</member></p> + + <p>Any possibly pending events for this client are removed from the queue.</p> + + @seealso revokeClientNotifyDisposing + */ + static void revokeClient( const TClientId _nClient ); + + /** revokes a client, with additionally notifying a disposing event to all listeners registered for + this client + + <p>Any other possibly pending events for this client are removed from the queue</p> + + @param _nClient + the id of the client which should be revoked + @param _rxEventSource + the source to be notified together with the <member scope="com.sun.star.lang">XComponent::disposing</member> + call. + */ + static void revokeClientNotifyDisposing( + const TClientId _nClient, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxEventSource + ) SAL_THROW( ( ) ); + + /** registers a listener for the given client + + @param _nClient + the id of the client for which a listener should be registered + @return + the number of event listeners currently registered for this client + */ + static sal_Int32 addEventListener( + const TClientId _nClient, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& _rxListener + ) SAL_THROW( ( ) ); + + /** revokes a listener for the given client + + @param _nClient + the id of the client for which a listener should be revoked + @return + the number of event listeners currently registered for this client + */ + static sal_Int32 removeEventListener( + const TClientId _nClient, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& _rxListener + ) SAL_THROW( ( ) ); + + /** retrieves the set of listeners registered for a given client + */ + static ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > + getEventListeners( const TClientId _nClient ) SAL_THROW( ( ) ); + + /** adds an event, which is to be braodcasted, to the queue + + @param _nClient + the id of the client which needs to broadcast the event + */ + static void addEvent( + const TClientId _nClient, + const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent + ) SAL_THROW( ( ) ); + + private: + /// generates a new client id + COMPHELPER_DLLPRIVATE static TClientId generateId(); + + /** looks up a client in our client map, asserts if it cannot find it or no event thread is present + + @precond + to be called with our mutex locked + + @param _nClient + the id of the client to loopup + @param _rPos + out-parameter for the position of the client in the client map + + @return + <TRUE/> if and only if the client could be found and <arg>_rPos</arg> has been filled with + it's position + */ + COMPHELPER_DLLPRIVATE static sal_Bool implLookupClient( const TClientId _nClient, ClientMap::iterator& _rPos ); + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accessiblekeybindinghelper.hxx b/comphelper/inc/comphelper/accessiblekeybindinghelper.hxx new file mode 100644 index 000000000000..6ac3373893bc --- /dev/null +++ b/comphelper/inc/comphelper/accessiblekeybindinghelper.hxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX +#define COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX + +#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> +#include <cppuhelper/implbase1.hxx> +#include <osl/mutex.hxx> + +#ifndef INCLUDED_VECTOR +#include <vector> +#define INCLUDED_VECTOR +#endif +#include "comphelper/comphelperdllapi.h" + +//.............................................................................. +namespace comphelper +{ +//.............................................................................. + + //============================================================================== + // OAccessibleKeyBindingHelper + //============================================================================== + + typedef ::cppu::WeakImplHelper1 < ::com::sun::star::accessibility::XAccessibleKeyBinding + > OAccessibleKeyBindingHelper_Base; + + /** a helper class for implementing an accessible keybinding + */ + class COMPHELPER_DLLPUBLIC OAccessibleKeyBindingHelper : public OAccessibleKeyBindingHelper_Base + { + private: + typedef ::std::vector< ::com::sun::star::uno::Sequence< ::com::sun::star::awt::KeyStroke > > KeyBindings; + + KeyBindings m_aKeyBindings; + + protected: + ::osl::Mutex m_aMutex; + + virtual ~OAccessibleKeyBindingHelper(); + + public: + OAccessibleKeyBindingHelper(); + OAccessibleKeyBindingHelper( const OAccessibleKeyBindingHelper& rHelper ); + + void AddKeyBinding( const ::com::sun::star::uno::Sequence< ::com::sun::star::awt::KeyStroke >& rKeyBinding ) throw (::com::sun::star::uno::RuntimeException); + void AddKeyBinding( const ::com::sun::star::awt::KeyStroke& rKeyStroke ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleKeyBinding + virtual sal_Int32 SAL_CALL getAccessibleKeyBindingCount() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::awt::KeyStroke > SAL_CALL getAccessibleKeyBinding( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + }; + +//.............................................................................. +} // namespace comphelper +//.............................................................................. + +#endif // COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accessibleselectionhelper.hxx b/comphelper/inc/comphelper/accessibleselectionhelper.hxx new file mode 100644 index 000000000000..d91693b81185 --- /dev/null +++ b/comphelper/inc/comphelper/accessibleselectionhelper.hxx @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ACCESSIBLE_SELECTION_HELPER_HXX +#define COMPHELPER_ACCESSIBLE_SELECTION_HELPER_HXX + +#include <comphelper/uno3.hxx> +#include <comphelper/accessiblecomponenthelper.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/uno3.hxx> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include "comphelper/comphelperdllapi.h" + +#define ACCESSIBLE_SELECTION_CHILD_ALL ((sal_Int32)-1) +#define ACCESSIBLE_SELECTION_CHILD_SELF ((sal_Int32)-2) + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //===================================================================== + //= OCommonAccessibleSelection + //===================================================================== + /** base class encapsulating common functionality for the helper classes implementing + the XAccessibleSelection + */ + class COMPHELPER_DLLPUBLIC OCommonAccessibleSelection + { + protected: + + OCommonAccessibleSelection(); + + protected: + + // access to context - still waiting to be overwritten + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > + implGetAccessibleContext() + throw ( ::com::sun::star::uno::RuntimeException ) = 0; + + // return if the specified child is visible => watch for special ChildIndexes (ACCESSIBLE_SELECTION_CHILD_xxx) + virtual sal_Bool + implIsSelected( sal_Int32 nAccessibleChildIndex ) + throw (::com::sun::star::uno::RuntimeException) = 0; + + // select the specified child => watch for special ChildIndexes (ACCESSIBLE_SELECTION_CHILD_xxx) + virtual void + implSelect( sal_Int32 nAccessibleChildIndex, sal_Bool bSelect ) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) = 0; + + protected: + + /** non-virtual versions of the methods which can be implemented using <method>implIsSelected</method> and <method>implSelect</method> + */ + void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL clearAccessibleSelection( ) throw (::com::sun::star::uno::RuntimeException); + void SAL_CALL selectAllAccessibleChildren( ) throw (::com::sun::star::uno::RuntimeException); + sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + }; + + //===================================================================== + //= OAccessibleSelectionHelper + //===================================================================== + + typedef ::cppu::ImplHelper1< ::com::sun::star::accessibility::XAccessibleSelection > OAccessibleSelectionHelper_Base; + + /** a helper class for implementing an AccessibleSelection which at the same time + supports an XAccessibleSelection interface. + */ + class COMPHELPER_DLLPUBLIC OAccessibleSelectionHelper : public OAccessibleComponentHelper, + public OCommonAccessibleSelection, + public OAccessibleSelectionHelper_Base + { + protected: + + OAccessibleSelectionHelper( ); + + /// see the respective base class ctor for an extensive comment on this, please + OAccessibleSelectionHelper( IMutex* _pExternalLock ); + + // return ourself here by default + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > implGetAccessibleContext() throw ( ::com::sun::star::uno::RuntimeException ); + + public: + + // XInterface + DECLARE_XINTERFACE( ) + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleSelection - default implementations + virtual void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearAccessibleSelection( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectAllAccessibleChildren( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // COMPHELPER_ACCESSIBLE_SELECTION_HELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accessibletexthelper.hxx b/comphelper/inc/comphelper/accessibletexthelper.hxx new file mode 100644 index 000000000000..4456c99b9bd1 --- /dev/null +++ b/comphelper/inc/comphelper/accessibletexthelper.hxx @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ACCESSIBLE_TEXT_HELPER_HXX +#define COMPHELPER_ACCESSIBLE_TEXT_HELPER_HXX + +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/accessibility/TextSegment.hpp> +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include <com/sun/star/i18n/XCharacterClassification.hpp> +#include <comphelper/accessiblecomponenthelper.hxx> +#include <cppuhelper/implbase1.hxx> +#include "comphelper/comphelperdllapi.h" + + +//.............................................................................. +namespace comphelper +{ +//.............................................................................. + + //============================================================================== + // OCommonAccessibleText + //============================================================================== + /** base class encapsulating common functionality for the helper classes implementing + the XAccessibleText + */ + class COMPHELPER_DLLPUBLIC OCommonAccessibleText + { + private: + ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XBreakIterator > m_xBreakIter; + ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XCharacterClassification > m_xCharClass; + + protected: + OCommonAccessibleText(); + virtual ~OCommonAccessibleText(); + + ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XBreakIterator > implGetBreakIterator(); + ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XCharacterClassification > implGetCharacterClassification(); + sal_Bool implIsValidBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nLength ); + virtual sal_Bool implIsValidIndex( sal_Int32 nIndex, sal_Int32 nLength ); + virtual sal_Bool implIsValidRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex, sal_Int32 nLength ); + virtual ::rtl::OUString implGetText() = 0; + virtual ::com::sun::star::lang::Locale implGetLocale() = 0; + virtual void implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) = 0; + virtual void implGetGlyphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + virtual sal_Bool implGetWordBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + virtual void implGetSentenceBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + virtual void implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + virtual void implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex ); + + /** non-virtual versions of the methods + */ + sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + sal_Int32 SAL_CALL getCharacterCount() throw (::com::sun::star::uno::RuntimeException); + ::rtl::OUString SAL_CALL getSelectedText() throw (::com::sun::star::uno::RuntimeException); + sal_Int32 SAL_CALL getSelectionStart() throw (::com::sun::star::uno::RuntimeException); + sal_Int32 SAL_CALL getSelectionEnd() throw (::com::sun::star::uno::RuntimeException); + ::rtl::OUString SAL_CALL getText() throw (::com::sun::star::uno::RuntimeException); + ::rtl::OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + public: + + /** Helper method, that detects the difference between + two strings and returns the deleted selection and + the inserted selection if available. + + @returns true if there are differences between the + two strings and false if both are equal + + @see ::com::sun::star::accessibility::AccessibleEventId + ::com::sun::star::accessibility::TextSegment + */ + static bool implInitTextChangedEvent( + const rtl::OUString& rOldString, + const rtl::OUString& rNewString, + /*out*/ ::com::sun::star::uno::Any& rDeleted, + /*out*/ ::com::sun::star::uno::Any& rInserted); // throw() + }; + + + //============================================================================== + // OAccessibleTextHelper + //============================================================================== + + typedef ::cppu::ImplHelper1 < ::com::sun::star::accessibility::XAccessibleText + > OAccessibleTextHelper_Base; + + /** a helper class for implementing an AccessibleExtendedComponent which at the same time + supports an XAccessibleText interface + */ + class COMPHELPER_DLLPUBLIC OAccessibleTextHelper : public OAccessibleExtendedComponentHelper, + public OCommonAccessibleText, + public OAccessibleTextHelper_Base + { + protected: + OAccessibleTextHelper(); + // see the respective base class ctor for an extensive comment on this, please + OAccessibleTextHelper( IMutex* _pExternalLock ); + + public: + // XInterface + DECLARE_XINTERFACE( ) + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleText + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getCharacterCount() throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSelectedText() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getSelectionStart() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getSelectionEnd() throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getText() throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + }; + +//.............................................................................. +} // namespace comphelper +//.............................................................................. + +#endif // COMPHELPER_ACCESSIBLE_TEXT_HELPER_HXX + + +// ----------------------------------------------------------------------------- +// +// OAccessibleTextHelper is a helper class for implementing the +// XAccessibleText interface. +// +// The following methods have a default implementation: +// +// getCharacter +// getCharacterCount +// getSelectedText +// getSelectionStart +// getSelectionEnd +// getText +// getTextRange +// getTextAtIndex +// getTextBeforeIndex +// getTextBehindIndex +// +// The following methods must be overriden by derived classes: +// +// implGetText +// implGetLocale +// implGetSelection +// getCaretPosition +// setCaretPosition +// getCharacterAttributes +// getCharacterBounds +// getIndexAtPoint +// setSelection +// copyText +// +// ----------------------------------------------------------------------------- + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accessiblewrapper.hxx b/comphelper/inc/comphelper/accessiblewrapper.hxx new file mode 100644 index 000000000000..d091f9fb458a --- /dev/null +++ b/comphelper/inc/comphelper/accessiblewrapper.hxx @@ -0,0 +1,416 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ACCESSIBLE_WRAPPER_HXX +#define COMPHELPER_ACCESSIBLE_WRAPPER_HXX + +#include <comphelper/proxyaggregation.hxx> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <cppuhelper/compbase3.hxx> +#include <cppuhelper/compbase2.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <comphelper/accessibleeventnotifier.hxx> +#include <comphelper/stl_types.hxx> +#include "comphelper/comphelperdllapi.h" + +//............................................................................. +namespace comphelper +{ +//............................................................................. + + //========================================================================= + //= OAccessibleWrapper + //========================================================================= + + class OAccessibleContextWrapper; + class OWrappedAccessibleChildrenManager; + + struct OAccessibleWrapper_Base : + public ::cppu::ImplHelper1 < ::com::sun::star::accessibility::XAccessible > + {}; + + /** a class which aggregates a proxy for an XAccessible, and wrapping the context returned by this + XAccessible. + */ + class COMPHELPER_DLLPUBLIC OAccessibleWrapper:public OAccessibleWrapper_Base + ,public OComponentProxyAggregation + + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + m_xParentAccessible; + ::com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessibleContext > + m_aContext; + + protected: + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + m_xInnerAccessible; + + public: + /** ctor + @param _rxORB + a service factory + + @param _rxInnerAccessible + the object to wrap + + @param _rxParentAccessible + The XAccessible which is our parent + */ + OAccessibleWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxInnerAccessible, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible + ); + DECLARE_XINTERFACE() + DECLARE_XTYPEPROVIDER() + + // returns the context without creating it + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > + getContextNoCreate( ) const; + + protected: + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL + getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException); + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + getParent() const { return m_xParentAccessible; } + + // own overridables + virtual OAccessibleContextWrapper* createAccessibleContext( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerContext + ); + + protected: + ~OAccessibleWrapper( ); + + private: + COMPHELPER_DLLPRIVATE OAccessibleWrapper( ); // never implemented + COMPHELPER_DLLPRIVATE OAccessibleWrapper( const OAccessibleWrapper& ); // never implemented + COMPHELPER_DLLPRIVATE OAccessibleWrapper& operator=( const OAccessibleWrapper& ); // never implemented + }; + + //========================================================================= + //= OAccessibleContextWrapperHelper + //========================================================================= + + typedef ::cppu::ImplHelper1 < ::com::sun::star::accessibility::XAccessibleEventListener + > OAccessibleContextWrapperHelper_Base; + + /** Helper for wrapping an XAccessibleContext by aggregating a proxy for it. + + <p>This class does not have own ref counting. In addition, it does not implement + the XAccesibleContext interface, but provides all the methods from this interface + which must be implemented using the inner context (such as getAccessibleChild*).</p> + + <p>Children of the aggregated XAccessibleContext are wrapped, too.</p> + + <p>AccessibleEvents fired by the inner context are multiplexed, especially, any references to + children in such events are translated. This means that even in such events, no un-wrapped object + will ever leave this class - if the aggregated context notifies an child event, the child passed + to the event is wrapped</p> + + @seealso OAccessibleContextWrapper + */ + class COMPHELPER_DLLPUBLIC OAccessibleContextWrapperHelper + :private OComponentProxyAggregationHelper + ,public OAccessibleContextWrapperHelper_Base + { + protected: + /// the context we're wrapping (properly typed, in opposite to OComponentProxyAggregationHelper::m_xInner) + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > + m_xInnerContext; + /// the XAccessible which created this context + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + m_xOwningAccessible; + /// the XAccessible which is to be returned in getAccessibleParent + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + m_xParentAccessible; + + OWrappedAccessibleChildrenManager* m_pChildMapper; // for mapping children from our inner context to our callers + + protected: + /** ctor + + @param _rxORB + a service factory + + @param _rxInnerAccessibleContext + the object to wrap + + @param _rxOwningAccessible + The XAccessible which created this object. This is necessary because children + of our wrapped context meed to be wrapped, too, and if they're asked for a parent, + they of course should return the proper parent<br/> + The object will be held with a hard reference + + @param _rxParentAccessible + The XAccessible to return in the getAccessibleParent call + */ + OAccessibleContextWrapperHelper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB, + ::cppu::OBroadcastHelper& _rBHelper, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerAccessibleContext, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxOwningAccessible, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible + ); + + /// to be called from within your ctor - does the aggregation of a proxy for m_xInnerContext + void aggregateProxy( + oslInterlockedCount& _rRefCount, + ::cppu::OWeakObject& _rDelegator + ); + + protected: + // XInterface + ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleContext + virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleEventListener + virtual void SAL_CALL notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent ) 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); + + // XComponent/OComponentProxyAggregationHelper + virtual void SAL_CALL dispose() throw( ::com::sun::star::uno::RuntimeException ); + + // own overridables + /** notify an accessible event which has been translated (if necessary) + + <p>Usually, you derive your clas from both OAccessibleContextWrapperHelper and XAccessibleEventBroadcaster, + and simply call all your XAccessibleEventListener with the given event.</p> + + <p>The mutex of the BroadcastHelper passed to the instance's ctor is <em>not</em> locked when calling + into this method</p> + */ + virtual void notifyTranslatedEvent( const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException) = 0; + + protected: + ~OAccessibleContextWrapperHelper( ); + + OAccessibleContextWrapperHelper( ); // never implemented + OAccessibleContextWrapperHelper( const OAccessibleContextWrapperHelper& ); // never implemented + OAccessibleContextWrapperHelper& operator=( const OAccessibleContextWrapperHelper& ); // never implemented + }; + + //========================================================================= + //= OAccessibleContextWrapper + //========================================================================= + typedef ::cppu::PartialWeakComponentImplHelper2< ::com::sun::star::accessibility::XAccessibleEventBroadcaster + , ::com::sun::star::accessibility::XAccessibleContext + > OAccessibleContextWrapper_CBase; + + class COMPHELPER_DLLPUBLIC OAccessibleContextWrapper + :public OBaseMutex + ,public OAccessibleContextWrapper_CBase + ,public OAccessibleContextWrapperHelper + { + private: + ::comphelper::AccessibleEventNotifier::TClientId m_nNotifierClient; // for notifying AccessibleEvents + + public: + /** ctor + + @param _rxORB + a service factory + + @param _rxInnerAccessibleContext + the object to wrap + + @param _rxOwningAccessible + The XAccessible which created this object. This is necessary because children + of our wrapped context meed to be wrapped, too, and if they're asked for a parent, + they of course should return the proper parent<br/> + The object will be held with a hard reference + + @param _rxParentAccessible + The XAccessible to return in the getAccessibleParent call + */ + OAccessibleContextWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerAccessibleContext, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxOwningAccessible, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible + ); + + // XInterface + DECLARE_XINTERFACE( ) + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XAccessibleContext + virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException); + + // XAccessibleEventBroadcaster + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // OAccessibleContextWrapper + virtual void notifyTranslatedEvent( const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose() throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & xListener)throw (::com::sun::star::uno::RuntimeException) + { WeakComponentImplHelperBase::addEventListener(xListener); } + virtual void SAL_CALL removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & xListener)throw (::com::sun::star::uno::RuntimeException) + { WeakComponentImplHelperBase::removeEventListener(xListener); } + + // OComponentHelper + using OAccessibleContextWrapperHelper::disposing; + virtual void SAL_CALL disposing() throw (::com::sun::star::uno::RuntimeException); + + protected: + virtual ~OAccessibleContextWrapper(); + + private: + COMPHELPER_DLLPRIVATE OAccessibleContextWrapper(); // never implemented + COMPHELPER_DLLPRIVATE OAccessibleContextWrapper( const OAccessibleContextWrapper& ); // never implemented + COMPHELPER_DLLPRIVATE OAccessibleContextWrapper& operator=( const OAccessibleContextWrapper& ); // never implemented + }; + + //========================================================================= + //= OWrappedAccessibleChildrenManager + //========================================================================= + + typedef ::std::map < ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + , ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + , OInterfaceCompare< ::com::sun::star::accessibility::XAccessible > + > AccessibleMap; + // TODO: think about if we should hold these objects weak + + typedef ::cppu::WeakImplHelper1 < ::com::sun::star::lang::XEventListener + > OWrappedAccessibleChildrenManager_Base; + /** manages wrapping XAccessible's to XAccessible's + */ + class COMPHELPER_DLLPUBLIC OWrappedAccessibleChildrenManager : public OWrappedAccessibleChildrenManager_Base + { + protected: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + m_xORB; + ::com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > + m_aOwningAccessible; // the XAccessible which belongs to the XAccessibleContext which we work for + AccessibleMap m_aChildrenMap; // for caching children + sal_Bool m_bTransientChildren; // are we prohibited to cache our children? + + public: + /// ctor + OWrappedAccessibleChildrenManager( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB + ); + + /** specifies if the children are to be consideren transient (i.e.: not cached) + <p>to be called only once per lifetime</p> + */ + void setTransientChildren( sal_Bool _bSet = sal_True ); + + /** sets the XAccessible which belongs to the XAccessibleContext which we work for + <p>to be called only once per lifetime</p> + */ + void setOwningAccessible( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxAcc ); + + /// retrieves a wrapper for the given accessible + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + getAccessibleWrapperFor( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxKey, + sal_Bool _bCreate = sal_True + ); + + /// erases the given key from the map (if it is present there) + void removeFromCache( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxKey ); + + /// invalidates (i.e. empties) the map + void invalidateAll( ); + + /** disposes (i.e. cleares) the manager + + <p>Note that the XAccessibleContext's of the mapped XAccessible objects are disposed, too.</p> + */ + void dispose(); + + /** handles a notification as got from the parent of the children we're managing + <p>This applies only to the notifications which have a direct impact on our map.</p> + */ + void handleChildNotification( const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent ); + + /** translates events as got from the parent of the children we're managing + <p>This applies only to the notifications which deal with child objects which we manage.</p> + */ + void translateAccessibleEvent( + const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent, + ::com::sun::star::accessibility::AccessibleEventObject& _rTranslatedEvent + ); + + protected: + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + + protected: + void implTranslateChildEventValue( const ::com::sun::star::uno::Any& _rInValue, ::com::sun::star::uno::Any& _rOutValue ); + + protected: + ~OWrappedAccessibleChildrenManager( ); + + private: + COMPHELPER_DLLPRIVATE OWrappedAccessibleChildrenManager( ); // never implemented + COMPHELPER_DLLPRIVATE OWrappedAccessibleChildrenManager( const OWrappedAccessibleChildrenManager& ); // never implemented + COMPHELPER_DLLPRIVATE OWrappedAccessibleChildrenManager& operator=( const OWrappedAccessibleChildrenManager& ); // never implemented + }; + +//............................................................................. +} // namespace accessibility +//............................................................................. + +#endif // COMPHELPER_ACCESSIBLE_WRAPPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/accimplaccess.hxx b/comphelper/inc/comphelper/accimplaccess.hxx new file mode 100644 index 000000000000..fbbee6fbfde6 --- /dev/null +++ b/comphelper/inc/comphelper/accimplaccess.hxx @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ACCIMPLACCESS_HXX +#define COMPHELPER_ACCIMPLACCESS_HXX + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include "comphelper/comphelperdllapi.h" + +// forward declaration +namespace com { namespace sun { namespace star { namespace accessibility { + class XAccessible; + class XAccessibleContext; +}}}} + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //===================================================================== + //= OAccessibleImplementationAccess + //===================================================================== + typedef ::cppu::ImplHelper1 < ::com::sun::star::lang::XUnoTunnel + > OAccImpl_Base; + struct OAccImpl_Impl; + + /** This is a helper class which allows accessing several aspects of the the implementation + of an AccessibleContext. + + <p>For instance, when you want to implement a context which can be re-parented, you: + <ul><li>derive your class from <type>OAccessibleImplementationAccess</type></li> + <li>use <code>setAccessibleParent( <em>component</em>, <em>new_parent</em> )</code> + </ul> + </p> + + <p>Another aspect which can be controlled from the outside are states. If you have a class which + has only partial control over it's states, you may consider deriving from OAccessibleImplementationAccess.<br/> + For instance, say you have an implementation (say component A) which is <em>unable</em> to know or to + determine if the represented object is selected, but another component (say B) which uses A (and integrates + it into a tree of accessibility components) is.<br/> + In this case, if A is derived from OAccessibleImplementationAccess, B can manipulate this + foreign-controlled state flag "SELECTED" by using the static helper methods on this class.</p> + + <p>Please note that the support for foreign controlled states is rather restrictive: You can't have states + which <em>may be</em> controlled by a foreign instances. This is implied by the fact that a derived + class can ask for states which are <em>set</em> only, not for the ones which are <em>reset</em> currently. + </p> + */ + class COMPHELPER_DLLPUBLIC OAccessibleImplementationAccess : public OAccImpl_Base + { + private: + OAccImpl_Impl* m_pImpl; + + protected: + /// retrieves the parent previously set via <method>setAccessibleParent</method> + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + implGetForeignControlledParent( ) const; + + /** retrieves the set of currently set states which are controlled by a foreign instance + @return + a bit mask, where a set bit 2^n means that the AccessibleStateType n has been set + */ + sal_Int64 implGetForeignControlledStates( ) const; + + /// sets the accessible parent component + virtual void setAccessibleParent( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxAccParent ); + + /// sets or resets a bit of the foreign controlled states + virtual void setStateBit( const sal_Int16 _nState, const sal_Bool _bSet ); + + protected: + OAccessibleImplementationAccess( ); + virtual ~OAccessibleImplementationAccess( ); + + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& _rIdentifier ) throw (::com::sun::star::uno::RuntimeException); + + public: + /** tries to access the implementation of an OAccessibleImplementationAccess derivee which is known as + interface only. + + @param _rxComponent + is the component which should be examined. + @return + the pointer to the implementation, if successfull. The only known error condition so far + is an invalid context (which means it is <NULL/>, or the implementation is not derived + from <type>OAccessibleImplementationAccess</type>, or retrieving the implementation failed). + */ + static OAccessibleImplementationAccess* getImplementation( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxComponent + ); + + + /** sets the parent for a derived implementation + + @param _rxComponent + is the component which's new parent should be set + @param _rxNewParent + is the new parent of the component + @return + <TRUE/> in case of success, <FALSE/> otherwise. For error condition please look at + <method>getImplementation</method>. + */ + static sal_Bool setAccessibleParent( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxComponent, + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxNewParent + ); + + /** sets or resets a state bit in the set of foreign-controlled states of the component. + + @param _rxComponent + is the component which's state is to be (re)set + @param _nState + the state bit which should be affected. This should be one of the respective UNO constants. + @param _bSet + <TRUE/> if the bit should be set, <FALSE/> otherwise + @return + <TRUE/> in case of success, <FALSE/> otherwise. For error condition please look at + <method>getImplementation</method>. + */ + static sal_Bool setForeignControlledState( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxComponent, + const sal_Int16 _nState, + const sal_Bool _bSet + ); + + + private: + COMPHELPER_DLLPRIVATE static const ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId(); + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +#endif // COMPHELPER_ACCIMPLACCESS_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/anycompare.hxx b/comphelper/inc/comphelper/anycompare.hxx new file mode 100644 index 000000000000..03f41e108ba9 --- /dev/null +++ b/comphelper/inc/comphelper/anycompare.hxx @@ -0,0 +1,226 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ANYCOMPARE_HXX +#define COMPHELPER_ANYCOMPARE_HXX + +#include "comphelper/comphelperdllapi.h" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/i18n/XCollator.hpp> +/** === end UNO includes === **/ + +#include <comphelper/extract.hxx> + +#include <functional> +#include <memory> + +//...................................................................................................................... +namespace comphelper +{ +//...................................................................................................................... + + //================================================================================================================== + //= IKeyPredicateLess + //================================================================================================================== + class SAL_NO_VTABLE IKeyPredicateLess + { + public: + virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const = 0; + virtual ~IKeyPredicateLess() {} + }; + + //================================================================================================================== + //= LessPredicateAdapter + //================================================================================================================== + struct LessPredicateAdapter : public ::std::binary_function< ::com::sun::star::uno::Any, ::com::sun::star::uno::Any, bool > + { + LessPredicateAdapter( const IKeyPredicateLess& _predicate ) + :m_predicate( _predicate ) + { + } + + bool operator()( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const + { + return m_predicate.isLess( _lhs, _rhs ); + } + + private: + IKeyPredicateLess const & m_predicate; + + private: + LessPredicateAdapter(); // never implemented + }; + + //================================================================================================================== + //= ScalarPredicateLess + //================================================================================================================== + template< typename SCALAR > + class ScalarPredicateLess : public IKeyPredicateLess + { + public: + virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const + { + SCALAR lhs(0), rhs(0); + if ( !( _lhs >>= lhs ) + || !( _rhs >>= rhs ) + ) + throw ::com::sun::star::lang::IllegalArgumentException(); + return lhs < rhs; + } + }; + + //================================================================================================================== + //= StringPredicateLess + //================================================================================================================== + class StringPredicateLess : public IKeyPredicateLess + { + public: + virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const + { + ::rtl::OUString lhs, rhs; + if ( !( _lhs >>= lhs ) + || !( _rhs >>= rhs ) + ) + throw ::com::sun::star::lang::IllegalArgumentException(); + return lhs < rhs; + } + }; + + //================================================================================================================== + //= StringCollationPredicateLess + //================================================================================================================== + class StringCollationPredicateLess : public IKeyPredicateLess + { + public: + StringCollationPredicateLess( ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > const & i_collator ) + :m_collator( i_collator ) + { + } + + virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const + { + ::rtl::OUString lhs, rhs; + if ( !( _lhs >>= lhs ) + || !( _rhs >>= rhs ) + ) + throw ::com::sun::star::lang::IllegalArgumentException(); + return m_collator->compareString( lhs, rhs ) < 0; + } + + private: + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > const m_collator; + }; + + //================================================================================================================== + //= TypePredicateLess + //================================================================================================================== + class TypePredicateLess : public IKeyPredicateLess + { + public: + virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const + { + ::com::sun::star::uno::Type lhs, rhs; + if ( !( _lhs >>= lhs ) + || !( _rhs >>= rhs ) + ) + throw ::com::sun::star::lang::IllegalArgumentException(); + return lhs.getTypeName() < rhs.getTypeName(); + } + }; + + //================================================================================================================== + //= EnumPredicateLess + //================================================================================================================== + class EnumPredicateLess : public IKeyPredicateLess + { + public: + EnumPredicateLess( ::com::sun::star::uno::Type const & _enumType ) + :m_enumType( _enumType ) + { + } + + virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const + { + sal_Int32 lhs(0), rhs(0); + if ( !::cppu::enum2int( lhs, _lhs ) + || !::cppu::enum2int( rhs, _rhs ) + || !_lhs.getValueType().equals( m_enumType ) + || !_rhs.getValueType().equals( m_enumType ) + ) + throw ::com::sun::star::lang::IllegalArgumentException(); + return lhs < rhs; + } + + private: + ::com::sun::star::uno::Type const m_enumType; + }; + + //================================================================================================================== + //= InterfacePredicateLess + //================================================================================================================== + class InterfacePredicateLess : public IKeyPredicateLess + { + public: + virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const + { + if ( ( _lhs.getValueTypeClass() != ::com::sun::star::uno::TypeClass_INTERFACE ) + || ( _rhs.getValueTypeClass() != ::com::sun::star::uno::TypeClass_INTERFACE ) + ) + throw ::com::sun::star::lang::IllegalArgumentException(); + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > lhs( _lhs, ::com::sun::star::uno::UNO_QUERY ); + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > rhs( _rhs, ::com::sun::star::uno::UNO_QUERY ); + return lhs.get() < rhs.get(); + } + }; + + //================================================================================================================== + //= getStandardLessPredicate + //================================================================================================================== + /** creates a default IKeyPredicateLess instance for the given UNO type + @param i_type + the type for which a predicate instance should be created + @param i_collator + specifies a collator instance to use, or <NULL/>. If <NULL/>, strings will be compared using the <code><</code> + operator, otherwise the collator will be used. The parameter is ignored if <arg>i_type</arg> does not specify + the string type. + @return + a default implementation of IKeyPredicateLess, which is able to compare values of the given type. If no + such default implementation is known for the given type, then <NULL/> is returned. + */ + ::std::auto_ptr< IKeyPredicateLess > COMPHELPER_DLLPUBLIC + getStandardLessPredicate( + ::com::sun::star::uno::Type const & i_type, + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > const & i_collator + ); + +//...................................................................................................................... +} // namespace comphelper +//...................................................................................................................... + +#endif // COMPHELPER_ANYCOMPARE_HXX diff --git a/comphelper/inc/comphelper/anytostring.hxx b/comphelper/inc/comphelper/anytostring.hxx new file mode 100644 index 000000000000..f1f91b2c6e00 --- /dev/null +++ b/comphelper/inc/comphelper/anytostring.hxx @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_ANYTOSTRING_HXX) +#define INCLUDED_COMPHELPER_ANYTOSTRING_HXX + +#include "rtl/ustring.hxx" +#include "com/sun/star/uno/Any.hxx" +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + +/** Creates a STRING representation out of an ANY value. + + @param value + ANY value + @return + STRING representation of given ANY value +*/ +COMPHELPER_DLLPUBLIC ::rtl::OUString anyToString( ::com::sun::star::uno::Any const & value ); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/asyncnotification.hxx b/comphelper/inc/comphelper/asyncnotification.hxx new file mode 100644 index 000000000000..6f2f1af34dee --- /dev/null +++ b/comphelper/inc/comphelper/asyncnotification.hxx @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_ASYNCNOTIFICATION_HXX +#define COMPHELPER_ASYNCNOTIFICATION_HXX + +#include <osl/thread.hxx> +#include <rtl/ref.hxx> +#include <comphelper/comphelperdllapi.h> +#include <rtl/alloc.h> + +#include <memory> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //==================================================================== + //= AnyEvent + //==================================================================== + /** the very basic instance to hold a description of an event + */ + class COMPHELPER_DLLPUBLIC AnyEvent : ::rtl::IReference + { + private: + oslInterlockedCount m_refCount; + + public: + AnyEvent(); + + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + + protected: + virtual ~AnyEvent(); + + private: + AnyEvent( AnyEvent& ); // not defined + void operator=( AnyEvent& ); // not defined + }; + + //==================================================================== + //= typedefs + //==================================================================== + typedef ::rtl::Reference< AnyEvent > AnyEventRef; + + //==================================================================== + //= IEventProcessor + //==================================================================== + /** an event processor + + @see AsyncEventNotifier + */ + class SAL_NO_VTABLE IEventProcessor + { + public: + /** process a single event + */ + virtual void processEvent( const AnyEvent& _rEvent ) = 0; + + virtual void SAL_CALL acquire() = 0; + virtual void SAL_CALL release() = 0; + }; + + //==================================================================== + //= AsyncEventNotifier + //==================================================================== + typedef ::osl::Thread AsyncEventNotifier_TBASE; + struct EventNotifierImpl; + + /** a helper class for notifying events asynchronously + + If you need to notify certain events to external components, you usually should + not do this while you have mutexes locked, to prevent multi-threading issues. + + However, you do not always have complete control over all mutex guards on the stack. + If, in such a case, the listener notification is one-way, you can decide to do it + asynchronously. + + The ->AsyncEventNotifier helps you to process such events asynchronously. Every + event is tied to an ->IEventProcessor which is responsible for processing it. + + The AsyncEventNotifier is implemented as a thread itself, which sleeps as long as there are no + events in the queue. As soon as you add an event, the thread is woken up, processes the event, + and sleeps again. + */ + class COMPHELPER_DLLPUBLIC AsyncEventNotifier :protected AsyncEventNotifier_TBASE + ,public ::rtl::IReference + { + friend struct EventNotifierImpl; + + private: + ::std::auto_ptr< EventNotifierImpl > m_pImpl; + + protected: + // Thread + virtual void SAL_CALL run(); + virtual void SAL_CALL onTerminated(); + + public: + /** constructs a notifier thread + */ + AsyncEventNotifier(); + + // IReference implementations + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + + using AsyncEventNotifier_TBASE::create; + using AsyncEventNotifier_TBASE::join; + using AsyncEventNotifier_TBASE::getIdentifier; + + using AsyncEventNotifier_TBASE::operator new; + using AsyncEventNotifier_TBASE::operator delete; + + /** terminates the thread + + Note that this is a cooporative termination - if you call this from a thread different + from the notification thread itself, then it will block until the notification thread + finished processing the current event. If you call it from the notification thread + itself, it will return immediately, and the thread will be terminated as soon as + the current notification is finished. + */ + virtual void SAL_CALL terminate(); + + /** adds an event to the queue, together with the instance which is responsible for + processing it + + @param _rEvent + the event to add to the queue + @param _xProcessor + the processor for the event.<br/> + Beware of life time issues here. If your event processor dies or becomes otherwise + nonfunctional, you are responsible for removing all respective events from the queue. + You can do this by calling ->removeEventsForProcessor + */ + void addEvent( const AnyEventRef& _rEvent, const ::rtl::Reference< IEventProcessor >& _xProcessor ); + + /** removes all events for the given event processor from the queue + */ + void removeEventsForProcessor( const ::rtl::Reference< IEventProcessor >& _xProcessor ); + + protected: + virtual ~AsyncEventNotifier(); + }; + + //==================================================================== + //= EventHolder + //==================================================================== + /** AnyEvent derivee holding an foreign event instance + */ + template < typename EVENT_OBJECT > + class EventHolder : public AnyEvent + { + public: + typedef EVENT_OBJECT EventObjectType; + + private: + EventObjectType m_aEvent; + + public: + inline EventHolder( const EventObjectType& _rEvent ) + :m_aEvent( _rEvent ) + { + } + + inline const EventObjectType& getEventObject() const { return m_aEvent; } + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_ASYNCNOTIFICATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/attributelist.hxx b/comphelper/inc/comphelper/attributelist.hxx new file mode 100644 index 000000000000..d34b32f00ac6 --- /dev/null +++ b/comphelper/inc/comphelper/attributelist.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_ATTRIBUTE_LIST_HXX +#define _COMPHELPER_ATTRIBUTE_LIST_HXX + +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/comphelperdllapi.h> + + +namespace comphelper +{ + +struct AttributeList_Impl; + +class COMPHELPER_DLLPUBLIC AttributeList : public ::cppu::WeakImplHelper1 +< + ::com::sun::star::xml::sax::XAttributeList +> +{ + AttributeList_Impl *m_pImpl; +public: + AttributeList(); + virtual ~AttributeList(); + + // methods that are not contained in any interface + void AddAttribute( const ::rtl::OUString &sName , const ::rtl::OUString &sType , const ::rtl::OUString &sValue ); + void Clear(); + void RemoveAttribute( const ::rtl::OUString sName ); + void SetAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & ); + void AppendAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & ); + + // ::com::sun::star::xml::sax::XAttributeList + virtual sal_Int16 SAL_CALL getLength(void) + throw( ::com::sun::star::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getNameByIndex(sal_Int16 i) + throw( ::com::sun::star::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getTypeByIndex(sal_Int16 i) + throw( ::com::sun::star::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getTypeByName(const ::rtl::OUString& aName) + throw( ::com::sun::star::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getValueByIndex(sal_Int16 i) + throw( ::com::sun::star::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getValueByName(const ::rtl::OUString& aName) + throw( ::com::sun::star::uno::RuntimeException ); + +}; + +} // namespace comphelper + +#endif // _COMPHELPER_ATTRIBUTE_LIST_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/basicio.hxx b/comphelper/inc/comphelper/basicio.hxx new file mode 100644 index 000000000000..7604b1a7029d --- /dev/null +++ b/comphelper/inc/comphelper/basicio.hxx @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_BASIC_IO_HXX_ +#define _COMPHELPER_BASIC_IO_HXX_ + +#include <com/sun/star/io/XPersistObject.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +namespace stario = ::com::sun::star::io; +namespace staruno = ::com::sun::star::uno; +namespace starawt = ::com::sun::star::awt; + +// sal_Bool +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Bool& _rVal); +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Bool _bVal); + +// ::rtl::OUString +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, ::rtl::OUString& _rStr); +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, const ::rtl::OUString& _rStr); + +// sal_Int16 +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Int16& _rValue); +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Int16 _nValue); + +// sal_uInt16 +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_uInt16& _rValue); +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_uInt16 _nValue); + +// sal_uInt32 +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_uInt32& _rValue); +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_uInt32 _nValue); + +// sal_Int16 +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Int32& _rValue); +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Int32 _nValue); + +// FontDescriptor +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& InStream, starawt::FontDescriptor& rVal); +COMPHELPER_DLLPUBLIC const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& OutStream, const starawt::FontDescriptor& rVal); + +// sequences +template <class ELEMENT> +const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, staruno::Sequence<ELEMENT>& _rSeq) +{ + sal_Int32 nLen = _rxInStream->readLong(); + _rSeq.realloc(nLen); + if (nLen) + { + ELEMENT* pElement = _rSeq.getArray(); + for (sal_Int32 i=0; i<nLen; ++i, ++pElement) + _rxInStream >> *pElement; + } + return _rxInStream; +} + +template <class ELEMENT> +const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, const staruno::Sequence<ELEMENT>& _rSeq) +{ + sal_Int32 nLen = _rSeq.getLength(); + _rxOutStream->writeLong(nLen); + if (nLen) + { + const ELEMENT* pElement = _rSeq.getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i, ++pElement) + _rxOutStream << *pElement; + } + return _rxOutStream; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_BASIC_IO_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/broadcasthelper.hxx b/comphelper/inc/comphelper/broadcasthelper.hxx new file mode 100644 index 000000000000..aa61db5d3ff8 --- /dev/null +++ b/comphelper/inc/comphelper/broadcasthelper.hxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_BROADCASTHELPER_HXX_ +#define _COMPHELPER_BROADCASTHELPER_HXX_ + +#include <osl/mutex.hxx> +#include <cppuhelper/interfacecontainer.h> + +//... namespace comphelper ....................................................... +namespace comphelper +{ +//......................................................................... + + //================================================================================== + //= OMutexAndBroadcastHelper - a class which holds a Mutex and a OBroadcastHelper; + //= needed because when deriving from OPropertySetHelper, + //= the OBroadcastHelper has to be initialized before + //= the OPropertySetHelper + //================================================================================== + class OMutexAndBroadcastHelper + { + protected: + ::osl::Mutex m_aMutex; + ::cppu::OBroadcastHelper m_aBHelper; + + public: + OMutexAndBroadcastHelper() : m_aBHelper( m_aMutex ) { } + + ::osl::Mutex& GetMutex() { return m_aMutex; } + ::cppu::OBroadcastHelper& GetBroadcastHelper() { return m_aBHelper; } + const ::cppu::OBroadcastHelper& GetBroadcastHelper() const { return m_aBHelper; } + + }; + + // base class for all classes who are derived from OPropertySet and from OComponent + // @deprecated, you should use cppu::BaseMutex instead (cppuhelper/basemutex.hxx) + + class OBaseMutex + { + protected: + mutable ::osl::Mutex m_aMutex; + }; +} +#endif // _COMPHELPER_BROADCASTHELPER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/classids.hxx b/comphelper/inc/comphelper/classids.hxx new file mode 100644 index 000000000000..dcfe50248d20 --- /dev/null +++ b/comphelper/inc/comphelper/classids.hxx @@ -0,0 +1,577 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_CLASSIDS_HXX +#define _COMPHELPER_CLASSIDS_HXX + +/* + * StarWriter + */ + +/* 3.0 */ + +#define SO3_SW_CLASSID_30 \ + 0xDC5C7E40L, 0xB35C, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 + +// #110743# +#define BF_SO3_SW_CLASSID_30 \ + 0xDC5C7E40L, 0xB35C, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 +/* 4.0 */ + +#define SO3_SW_CLASSID_40 \ + 0x8b04e9b0, 0x420e, 0x11d0, 0xa4, 0x5e, 0x0, \ + 0xa0, 0x24, 0x9d, 0x57, 0xb1 + +// #110743# +#define BF_SO3_SW_CLASSID_40 \ + 0x8b04e9b0, 0x420e, 0x11d0, 0xa4, 0x5e, 0x0, \ + 0xa0, 0x24, 0x9d, 0x57, 0xb1 +/* 5.0 */ + +#define SO3_SW_CLASSID_50 \ + 0xc20cf9d1, 0x85ae, 0x11d1, 0xaa, 0xb4, 0x0, \ + 0x60, 0x97, 0xda, 0x56, 0x1a + +// #110743# +#define BF_SO3_SW_CLASSID_50 \ + 0xc20cf9d1, 0x85ae, 0x11d1, 0xaa, 0xb4, 0x0, \ + 0x60, 0x97, 0xda, 0x56, 0x1a + + /* 6.0, 7, 8 */ + +#define SO3_SW_CLASSID_60 \ + 0x8BC6B165, 0xB1B2, 0x4EDD, 0xAA, 0x47, 0xDA, \ + 0xE2, 0xEE, 0x68, 0x9D, 0xD6 + +// #110743# +#define BF_SO3_SW_CLASSID_60 \ + 0x8BC6B165, 0xB1B2, 0x4EDD, 0xAA, 0x47, 0xDA, \ + 0xE2, 0xEE, 0x68, 0x9D, 0xD6 + + /* ole embed 6.0, 7 */ + +#define SO3_SW_OLE_EMBED_CLASSID_60 \ + 0x30a2652a, 0xddf7, 0x45e7, 0xac, 0xa6, 0x3e, \ + 0xab, 0x26, 0xfc, 0x8a, 0x4e + + /* ole embed 8 */ + +#define SO3_SW_OLE_EMBED_CLASSID_8 \ + 0xf616b81f, 0x7bb8, 0x4f22, 0xb8, 0xa5, 0x47, \ + 0x42, 0x8d, 0x59, 0xf8, 0xad + +/* aktuell */ + +#define SO3_SW_CLASSID SO3_SW_CLASSID_60 + +// #110743# +#define BF_SO3_SW_CLASSID BF_SO3_SW_CLASSID_50 + +/* + * StarWriter/Web + */ + +/* 4.0 */ + +#define SO3_SWWEB_CLASSID_40 \ + 0xf0caa840, 0x7821, 0x11d0, 0xa4, 0xa7, 0x0, \ + 0xa0, 0x24, 0x9d, 0x57, 0xb1 + +// #110743# +#define BF_SO3_SWWEB_CLASSID_40 \ + 0xf0caa840, 0x7821, 0x11d0, 0xa4, 0xa7, 0x0, \ + 0xa0, 0x24, 0x9d, 0x57, 0xb1 +/* 5.0 */ + +#define SO3_SWWEB_CLASSID_50 \ + 0xc20cf9d2, 0x85ae, 0x11d1, 0xaa, 0xb4, 0x0, \ + 0x60, 0x97, 0xda, 0x56, 0x1a + +// #110743# +#define BF_SO3_SWWEB_CLASSID_50 \ + 0xc20cf9d2, 0x85ae, 0x11d1, 0xaa, 0xb4, 0x0, \ + 0x60, 0x97, 0xda, 0x56, 0x1a +/* 6.0, 7, 8 */ + +#define SO3_SWWEB_CLASSID_60 \ + 0xA8BBA60C, 0x7C60, 0x4550, 0x91, 0xCE, 0x39, \ + 0xC3, 0x90, 0x3F, 0xAC, 0x5E + +// #110743# +#define BF_SO3_SWWEB_CLASSID_60 \ + 0xA8BBA60C, 0x7C60, 0x4550, 0x91, 0xCE, 0x39, \ + 0xC3, 0x90, 0x3F, 0xAC, 0x5E + +/* aktuell */ + +#define SO3_SWWEB_CLASSID SO3_SWWEB_CLASSID_60 + +// #110743# +#define BF_SO3_SWWEB_CLASSID BF_SO3_SWWEB_CLASSID_50 + +/* + * Globaldokument + */ + +/* 4.0 */ + +#define SO3_SWGLOB_CLASSID_40 \ + 0x340ac970, 0xe30d, 0x11d0, 0xa5, 0x3f, 0x0, \ + 0xa0, 0x24, 0x9d, 0x57, 0xb1 + +// #110743# +#define BF_SO3_SWGLOB_CLASSID_40 \ + 0x340ac970, 0xe30d, 0x11d0, 0xa5, 0x3f, 0x0, \ + 0xa0, 0x24, 0x9d, 0x57, 0xb1 + +/* 5.0 */ + +#define SO3_SWGLOB_CLASSID_50 \ + 0xc20cf9d3, 0x85ae, 0x11d1, 0xaa, 0xb4, 0x0, \ + 0x60, 0x97, 0xda, 0x56, 0x1a + +// #110743# +#define BF_SO3_SWGLOB_CLASSID_50 \ + 0xc20cf9d3, 0x85ae, 0x11d1, 0xaa, 0xb4, 0x0, \ + 0x60, 0x97, 0xda, 0x56, 0x1a +/* 6.0, 7, 8 */ + +#define SO3_SWGLOB_CLASSID_60 \ + 0xB21A0A7C, 0xE403, 0x41FE, 0x95, 0x62, 0xBD, \ + 0x13, 0xEA, 0x6F, 0x15, 0xA0 + +// #110743# +#define BF_SO3_SWGLOB_CLASSID_60 \ + 0xB21A0A7C, 0xE403, 0x41FE, 0x95, 0x62, 0xBD, \ + 0x13, 0xEA, 0x6F, 0x15, 0xA0 +/* aktuell */ + +#define SO3_SWGLOB_CLASSID SO3_SWGLOB_CLASSID_60 + +// #110743# +#define BF_SO3_SWGLOB_CLASSID BF_SO3_SWGLOB_CLASSID_50 + +//--------------------------------------------------- + +/* + * StarCalc + */ + +/* 3.0 */ + +#define SO3_SC_CLASSID_30 \ + 0x3F543FA0L, 0xB6A6, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 + +// #110743# +#define BF_SO3_SC_CLASSID_30 \ + 0x3F543FA0L, 0xB6A6, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 +/* 4.0 */ + +#define SO3_SC_CLASSID_40 \ + 0x6361d441L, 0x4235, 0x11d0, 0x89, 0xcb, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SC_CLASSID_40 \ + 0x6361d441L, 0x4235, 0x11d0, 0x89, 0xcb, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 5.0 */ + +#define SO3_SC_CLASSID_50 \ + 0xc6a5b861L, 0x85d6, 0x11d1, 0x89, 0xcb, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SC_CLASSID_50 \ + 0xc6a5b861L, 0x85d6, 0x11d1, 0x89, 0xcb, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 6.0 */ + +#define SO3_SC_CLASSID_60 \ + 0x47BBB4CB, 0xCE4C, 0x4E80, 0xA5, 0x91, 0x42, \ + 0xD9, 0xAE, 0x74, 0x95, 0x0F + +// #110743# +#define BF_SO3_SC_CLASSID_60 \ + 0x47BBB4CB, 0xCE4C, 0x4E80, 0xA5, 0x91, 0x42, \ + 0xD9, 0xAE, 0x74, 0x95, 0x0F + +/* ole embed 6.0, 7 */ + +#define SO3_SC_OLE_EMBED_CLASSID_60 \ + 0x7b342dc4, 0x139a, 0x4a46, 0x8a, 0x93, 0xdb, \ + 0x8, 0x27, 0xcc, 0xee, 0x9c + +/* ole embed 8 */ + +#define SO3_SC_OLE_EMBED_CLASSID_8 \ + 0x7fa8ae11, 0xb3e3, 0x4d88, 0xaa, 0xbf, 0x25, \ + 0x55, 0x26, 0xcd, 0x1c, 0xe8 + +/* aktuell */ + +#define SO3_SC_CLASSID SO3_SC_CLASSID_60 + +// #110743# +#define BF_SO3_SC_CLASSID BF_SO3_SC_CLASSID_50 + +/**************************************************** +* StarImpress +****************************************************/ + +/* 3.0 */ + +#define SO3_SIMPRESS_CLASSID_30 \ + 0xAF10AAE0L, 0xB36D, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 + +// #110743# +#define BF_SO3_SIMPRESS_CLASSID_30 \ + 0xAF10AAE0L, 0xB36D, 0x101B, 0x99, 0x61, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 +/* 4.0 */ + +#define SO3_SIMPRESS_CLASSID_40 \ + 0x12d3cc0L, 0x4216, 0x11d0, 0x89, 0xcb, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SIMPRESS_CLASSID_40 \ + 0x12d3cc0L, 0x4216, 0x11d0, 0x89, 0xcb, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 5.0 */ + +#define SO3_SIMPRESS_CLASSID_50 \ + 0x565c7221L, 0x85bc, 0x11d1, 0x89, 0xd0, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SIMPRESS_CLASSID_50 \ + 0x565c7221L, 0x85bc, 0x11d1, 0x89, 0xd0, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 6.0 */ + +#define SO3_SIMPRESS_CLASSID_60 \ + 0x9176E48A, 0x637A, 0x4D1F, 0x80, 0x3B, 0x99, \ + 0xD9, 0xBF, 0xAC, 0x10, 0x47 + +// #110743# +#define BF_SO3_SIMPRESS_CLASSID_60 \ + 0x9176E48A, 0x637A, 0x4D1F, 0x80, 0x3B, 0x99, \ + 0xD9, 0xBF, 0xAC, 0x10, 0x47 + +/* ole embed 6.0, 7 */ + +#define SO3_SIMPRESS_OLE_EMBED_CLASSID_60 \ + 0xe5a0b632, 0xdfba, 0x4549, 0x93, 0x46, 0xe4, \ + 0x14, 0xda, 0x6, 0xe6, 0xf8 + +/* ole embed 8 */ + +#define SO3_SIMPRESS_OLE_EMBED_CLASSID_8 \ + 0xee5d1ea4, 0xd445, 0x4289, 0xb2, 0xfc, 0x55, \ + 0xfc, 0x93, 0x69, 0x39, 0x17 + +/* aktuell */ + +#define SO3_SIMPRESS_CLASSID SO3_SIMPRESS_CLASSID_60 + +// #110743# +#define BF_SO3_SIMPRESS_CLASSID BF_SO3_SIMPRESS_CLASSID_50 + +/**************************************************** +* StarDraw +****************************************************/ + +/* 5.0 */ + +#define SO3_SDRAW_CLASSID_50 \ + 0x2e8905a0L, 0x85bd, 0x11d1, 0x89, 0xd0, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SDRAW_CLASSID_50 \ + 0x2e8905a0L, 0x85bd, 0x11d1, 0x89, 0xd0, 0x0, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 6.0 */ +#define SO3_SDRAW_CLASSID_60 \ + 0x4BAB8970, 0x8A3B, 0x45B3, 0x99, 0x1C, 0xCB, \ + 0xEE, 0xAC, 0x6B, 0xD5, 0xE3 + +// #110743# +#define BF_SO3_SDRAW_CLASSID_60 \ + 0x4BAB8970, 0x8A3B, 0x45B3, 0x99, 0x1C, 0xCB, \ + 0xEE, 0xAC, 0x6B, 0xD5, 0xE3 + +/* ole embed 6.0, 7 */ + +#define SO3_SDRAW_OLE_EMBED_CLASSID_60 \ + 0x41662fc2, 0xd57, 0x4aff, 0xab, 0x27, 0xad, \ + 0x2e, 0x12, 0xe7, 0xc2, 0x73 + +/* ole embed 8 */ + +#define SO3_SDRAW_OLE_EMBED_CLASSID_8 \ + 0x448bb771, 0xcfe2, 0x47c4, 0xbc, 0xdf, 0x1f, \ + 0xbf, 0x37, 0x8e, 0x20, 0x2c + +/* aktuell */ + +#define SO3_SDRAW_CLASSID SO3_SDRAW_CLASSID_60 + +// #110743# +#define BF_SO3_SDRAW_CLASSID BF_SO3_SDRAW_CLASSID_50 + +/**************************************************** +* StarChart +****************************************************/ + +/* 3.0 */ + +#define SO3_SCH_CLASSID_30 \ + 0xFB9C99E0L, 0x2C6D, 0x101C, 0x8E, 0x2C, 0x00, \ + 0x00, 0x1B, 0x4C, 0xC7, 0x11 + +// #110743# +#define BF_SO3_SCH_CLASSID_30 \ + 0xFB9C99E0L, 0x2C6D, 0x101C, 0x8E, 0x2C, 0x00, \ + 0x00, 0x1B, 0x4C, 0xC7, 0x11 +/* 4.0 */ + +#define SO3_SCH_CLASSID_40 \ + 0x2b3b7e0L, 0x4225, 0x11d0, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SCH_CLASSID_40 \ + 0x2b3b7e0L, 0x4225, 0x11d0, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 5.0 */ + +#define SO3_SCH_CLASSID_50 \ + 0xbf884321L, 0x85dd, 0x11d1, 0x89, 0xd0, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SCH_CLASSID_50 \ + 0xbf884321L, 0x85dd, 0x11d1, 0x89, 0xd0, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 6.0 */ + +#define SO3_SCH_CLASSID_60 \ + 0x12DCAE26, 0x281F, 0x416F, 0xA2, 0x34, 0xC3, \ + 0x08, 0x61, 0x27, 0x38, 0x2E + +// #110743# +#define BF_SO3_SCH_CLASSID_60 \ + 0x12DCAE26, 0x281F, 0x416F, 0xA2, 0x34, 0xC3, \ + 0x08, 0x61, 0x27, 0x38, 0x2E + +/* ole embed 6.0, 7 */ + +#define SO3_SCH_OLE_EMBED_CLASSID_60 \ + 0xd415cd93, 0x35c4, 0x4c6f, 0x81, 0x9d, 0xa6, \ + 0x64, 0xa1, 0xc8, 0x13, 0xae + +/* ole embed 8 */ + +#define SO3_SCH_OLE_EMBED_CLASSID_8 \ + 0xdd0a57f, 0xcf3b, 0x4fd2, 0xbd, 0xa4, 0x94, \ + 0x42, 0x71, 0x9b, 0x2a, 0x73 + +/* aktuell */ + +#define SO3_SCH_CLASSID SO3_SCH_CLASSID_60 + +// #110743# +#define BF_SO3_SCH_CLASSID BF_SO3_SCH_CLASSID_50 + +/**************************************************** +* StarImage +****************************************************/ + +/* 3.0 */ + +#define SO3_SIM_CLASSID_30 \ + 0xEA60C941L, 0x2C6C, 0x101C, 0x8E, 0x2C, 0x00, \ + 0x00, 0x1B, 0x4C, 0xC7, 0x11 + +// #110743# +#define BF_SO3_SIM_CLASSID_30 \ + 0xEA60C941L, 0x2C6C, 0x101C, 0x8E, 0x2C, 0x00, \ + 0x00, 0x1B, 0x4C, 0xC7, 0x11 +/* 4.0 */ + +#define SO3_SIM_CLASSID_40 \ + 0x447BB8A0L, 0x41FB, 0x11D0, 0x89, 0xCA, 0x00, \ + 0x80, 0x29, 0xE4, 0xB0, 0xB1 + +// #110743# +#define BF_SO3_SIM_CLASSID_40 \ + 0x447BB8A0L, 0x41FB, 0x11D0, 0x89, 0xCA, 0x00, \ + 0x80, 0x29, 0xE4, 0xB0, 0xB1 +/* 5.0 */ + +#define SO3_SIM_CLASSID_50 \ + 0x65c68d00L, 0x85de, 0x11d1, 0x89, 0xd0, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SIM_CLASSID_50 \ + 0x65c68d00L, 0x85de, 0x11d1, 0x89, 0xd0, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +/* aktuell */ + +#define SO3_SIM_CLASSID SO3_SIM_CLASSID_50 + +// #110743# +#define BF_SO3_SIM_CLASSID BF_SO3_SIM_CLASSID_50 + +/*************************************************** +* StarMath +***************************************************/ + +/* 3.0 */ + +#define SO3_SM_CLASSID_30 \ + 0xD4590460L, 0x35FD, 0x101C, 0xB1, 0x2A, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 + +// #110743# +#define BF_SO3_SM_CLASSID_30 \ + 0xD4590460L, 0x35FD, 0x101C, 0xB1, 0x2A, 0x04, \ + 0x02, 0x1C, 0x00, 0x70, 0x02 +/* 4.0 */ + +#define SO3_SM_CLASSID_40 \ + 0x2b3b7e1L, 0x4225, 0x11d0, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SM_CLASSID_40 \ + 0x2b3b7e1L, 0x4225, 0x11d0, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 5.0 */ + +#define SO3_SM_CLASSID_50 \ + 0xffb5e640L, 0x85de, 0x11d1, 0x89, 0xd0, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_SM_CLASSID_50 \ + 0xffb5e640L, 0x85de, 0x11d1, 0x89, 0xd0, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 +/* 6.0, 7, 8 */ + +#define SO3_SM_CLASSID_60 \ + 0x078B7ABA, 0x54FC, 0x457F, 0x85, 0x51, 0x61, \ + 0x47, 0xE7, 0x76, 0xA9, 0x97 + +// #110743# +#define BF_SO3_SM_CLASSID_60 \ + 0x078B7ABA, 0x54FC, 0x457F, 0x85, 0x51, 0x61, \ + 0x47, 0xE7, 0x76, 0xA9, 0x97 + +/* ole embed 6.0, 7 */ + +#define SO3_SM_OLE_EMBED_CLASSID_60 \ + 0xd0484de6, 0xaaee, 0x468a, 0x99, 0x1f, 0x8d, \ + 0x4b, 0x7, 0x37, 0xb5, 0x7a + +/* ole embed 8 */ + +#define SO3_SM_OLE_EMBED_CLASSID_8 \ + 0xd2d59cd1, 0xa6a, 0x4d36, 0xae, 0x20, 0x47, \ + 0x81, 0x70, 0x77, 0xd5, 0x7c + +/* aktuell */ + +#define SO3_SM_CLASSID SO3_SM_CLASSID_60 + +// #110743# +#define BF_SO3_SM_CLASSID BF_SO3_SM_CLASSID_50 + +#define SO3_OUT_CLASSID \ + 0x970b1e82, 0xcf2d, 0x11cf, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_OUT_CLASSID \ + 0x970b1e83, 0xcf2d, 0x11cf, 0x89, 0xca, 0x00, \ + 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +#define SO3_DUMMY_CLASSID \ + 0x970b1fff, 0xcf2d, 0x11cf, \ + 0x89,0xca,0x00,0x80,0x29,0xe4,0xb0,0xb1 + +#define SO3_APPLET_CLASSID \ + 0x970b1e81, 0xcf2d, 0x11cf, \ + 0x89,0xca,0x00,0x80,0x29,0xe4,0xb0,0xb1 + +// #110743# +#define BF_SO3_APPLET_CLASSID \ + 0x970b1e82, 0xcf2d, 0x11cf, \ + 0x89,0xca,0x00,0x80,0x29,0xe4,0xb0,0xb1 +#define SO3_PLUGIN_CLASSID \ + 0x4caa7761, 0x6b8b, 0x11cf, \ + 0x89,0xca,0x0,0x80,0x29,0xe4,0xb0,0xb1 + +// #110743# +#define BF_SO3_PLUGIN_CLASSID \ + 0x4caa7762, 0x6b8b, 0x11cf, \ + 0x89,0xca,0x0,0x80,0x29,0xe4,0xb0,0xb1 + +#define SO3_IFRAME_CLASSID \ + 0x1a8a6701, 0xde58, 0x11cf, \ + 0x89, 0xca, 0x0, 0x80, 0x29, 0xe4, 0xb0, 0xb1 + +// #110743# +#define BF_SO3_IFRAME_CLASSID \ + 0x1a8a6702, 0xde58, 0x11cf, \ + 0x89, 0xca, 0x0, 0x80, 0x29, 0xe4, 0xb0, 0xb2 + +#define SO3_GLOBAL_CLASSID \ + 0x475198a8, 0x694c, 0x4bd8, \ + 0xb0, 0x2f, 0xd9, 0xb7, 0x6b, 0xcf, 0x31, 0x28 + +#define SO3_RPT_CLASSID_90 \ + 0xd7896d52, 0xb7af, 0x4820, \ + 0x9d, 0xfe, 0xd4, 0x04, 0xd0, 0x15, 0x96, 0x0f + +#define SO3_RPT_SCH_CLASSID_90 \ + 0x80243d39, 0x6741, 0x46c5, \ + 0x92, 0x6e, 0x06, 0x91, 0x64, 0xff, 0x87, 0xbb + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/comphelperdllapi.h b/comphelper/inc/comphelper/comphelperdllapi.h new file mode 100644 index 000000000000..32c86f8fd3b7 --- /dev/null +++ b/comphelper/inc/comphelper/comphelperdllapi.h @@ -0,0 +1,16 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#ifndef INCLUDED_COMPHELPERDLLAPI_H +#define INCLUDED_COMPHELPERDLLAPI_H + +#include "sal/types.h" + +#if defined(COMPHELPER_DLLIMPLEMENTATION) +#define COMPHELPER_DLLPUBLIC SAL_DLLPUBLIC_EXPORT +#else +#define COMPHELPER_DLLPUBLIC SAL_DLLPUBLIC_IMPORT +#endif +#define COMPHELPER_DLLPRIVATE SAL_DLLPRIVATE + +#endif /* INCLUDED_COMPHELPERDLLAPI_H */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/componentbase.hxx b/comphelper/inc/comphelper/componentbase.hxx new file mode 100644 index 000000000000..db3e558904b9 --- /dev/null +++ b/comphelper/inc/comphelper/componentbase.hxx @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_COMPONENTBASE_HXX +#define COMPHELPER_COMPONENTBASE_HXX + +#include "comphelper/comphelperdllapi.h" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +#include <cppuhelper/interfacecontainer.hxx> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //==================================================================== + //= ComponentBase + //==================================================================== + class COMPHELPER_DLLPUBLIC ComponentBase + { + protected: + /** creates a ComponentBase instance + + The instance is not initialized. As a consequence, every ComponentMethodGuard instantiated for + this component will throw a <type scope="com::sun::star::lang">NotInitializedException</type>, + until ->setInitialized() is called. + */ + ComponentBase( ::cppu::OBroadcastHelper& _rBHelper ) + :m_rBHelper( _rBHelper ) + ,m_bInitialized( false ) + { + } + + struct NoInitializationNeeded { }; + + /** creates a ComponentBase instance + + The instance is already initialized, so there's no need to call setInitialized later on. Use this + constructor for component implementations which do not require explicit initialization. + */ + ComponentBase( ::cppu::OBroadcastHelper& _rBHelper, NoInitializationNeeded ) + :m_rBHelper( _rBHelper ) + ,m_bInitialized( true ) + { + } + + /** marks the instance as initialized + + Subsequent instantiations of a ComponentMethodGuard won't throw the NotInitializedException now. + */ + inline void setInitialized() { m_bInitialized = true; } + + public: + /// helper struct to grant access to selected public methods to the ComponentMethodGuard class + struct GuardAccess { friend class ComponentMethodGuard; private: GuardAccess() { } }; + + /// retrieves the component's mutex + inline ::osl::Mutex& getMutex( GuardAccess ) { return getMutex(); } + /// checks whether the component is already disposed, throws a DisposedException if so. + inline void checkDisposed( GuardAccess ) const { impl_checkDisposed_throw(); } + /// checks whether the component is already initialized, throws a NotInitializedException if not. + inline void checkInitialized( GuardAccess ) const { impl_checkInitialized_throw(); } + + protected: + /// retrieves the component's broadcast helper + inline ::cppu::OBroadcastHelper& getBroadcastHelper() { return m_rBHelper; } + /// retrieves the component's mutex + inline ::osl::Mutex& getMutex() { return m_rBHelper.rMutex; } + /// determines whether the instance is already disposed + inline bool impl_isDisposed() const { return m_rBHelper.bDisposed; } + + /// checks whether the component is already disposed. Throws a DisposedException if so. + void impl_checkDisposed_throw() const; + + /// checks whether the component is already initialized. Throws a NotInitializedException if not. + void impl_checkInitialized_throw() const; + + /// determines whether the component is already initialized + inline bool + impl_isInitialized_nothrow() const { return m_bInitialized; } + + /** returns the context to be used when throwing exceptions + + The default implementation returns <NULL/>. + */ + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + getComponent() const; + + private: + ::cppu::OBroadcastHelper& m_rBHelper; + bool m_bInitialized; + }; + + class ComponentMethodGuard + { + public: + enum MethodType + { + /// allow the method to be called only when being initialized and not being disposed + Default, + /// allow the method to be called without being initialized + WithoutInit + + }; + + ComponentMethodGuard( ComponentBase& _rComponent, const MethodType _eType = Default ) + :m_aMutexGuard( _rComponent.getMutex( ComponentBase::GuardAccess() ) ) + { + if ( _eType != WithoutInit ) + _rComponent.checkInitialized( ComponentBase::GuardAccess() ); + _rComponent.checkDisposed( ComponentBase::GuardAccess() ); + } + + ~ComponentMethodGuard() + { + } + + inline void clear() + { + m_aMutexGuard.clear(); + } + inline void reset() + { + m_aMutexGuard.reset(); + } + + private: + ::osl::ResettableMutexGuard m_aMutexGuard; + }; + +//........................................................................ +} // namespace ComponentBase +//........................................................................ + +#endif // COMPHELPER_COMPONENTBASE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/componentcontext.hxx b/comphelper/inc/comphelper/componentcontext.hxx new file mode 100644 index 000000000000..5b6a901385c3 --- /dev/null +++ b/comphelper/inc/comphelper/componentcontext.hxx @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_COMPONENTCONTEXT_HXX +#define COMPHELPER_COMPONENTCONTEXT_HXX + +#include <comphelper/comphelperdllapi.h> + +/** === begin UNO includes === **/ +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +/** === end UNO includes === **/ + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //==================================================================== + //= ComponentContext + //==================================================================== + /** a helper class for working with a component context + */ + class COMPHELPER_DLLPUBLIC ComponentContext + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiComponentFactory > m_xORB; + + public: + /** constructs an instance + @param _rxContext + the component context to manage + @throws ::com::sun::star::lang::NullPointerException + if the given context, or its component factory, are <NULL/> + */ + ComponentContext( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext ); + + /** constructs an instance + @param _rxLegacyFactory + the legacy service factor to obtain the <type scope="com::sun::star::uno">XComponentContext</type> from + @throws ::com::sun::star::uno::RuntimeException + if the given factory or does not have a DefaultContext property to obtain + a component context + @throws ::com::sun::star::lang::NullPointerException + if the given factory is <NULL/>, or provides a component context being <NULL/>, or provides + a component context whose component factory is <NULL/> + */ + ComponentContext( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxLegacyFactory ); + + /** returns the ->XComponentContext interface + */ + inline ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > + getUNOContext() const { return m_xContext; } + + /** determines whether the context is not <NULL/> + */ + inline sal_Bool is() const + { + return m_xContext.is(); + } + + /** creates a component using our component factory/context + @throws ::com::sun::star::uno::Exception + @return + <TRUE/> if and only if the component could be successfully created + */ + template < typename INTERFACE > + bool createComponent( const ::rtl::OUString& _rServiceName, ::com::sun::star::uno::Reference< INTERFACE >& _out_rxComponent ) const + { + _out_rxComponent.clear(); + _out_rxComponent = _out_rxComponent.query( + m_xORB->createInstanceWithContext( _rServiceName, m_xContext ) + ); + return _out_rxComponent.is(); + } + + /** creates a component using our component factory/context + @throws ::com::sun::star::uno::Exception + @return + <TRUE/> if and only if the component could be successfully created + */ + template < typename INTERFACE > + bool createComponent( const sal_Char* _pAsciiServiceName, ::com::sun::star::uno::Reference< INTERFACE >& _out_rxComponent ) const + { + return createComponent( ::rtl::OUString::createFromAscii( _pAsciiServiceName ), _out_rxComponent ); + } + + /** creates a component using our component factory/context, passing creation arguments + @throws ::com::sun::star::uno::Exception + @return + <TRUE/> if and only if the component could be successfully created + */ + template < typename INTERFACE > + bool createComponentWithArguments( const ::rtl::OUString& _rServiceName, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments, ::com::sun::star::uno::Reference< INTERFACE >& _out_rxComponent ) const + { + _out_rxComponent.clear(); + _out_rxComponent = _out_rxComponent.query( + m_xORB->createInstanceWithArgumentsAndContext( _rServiceName, _rArguments, m_xContext ) + ); + return _out_rxComponent.is(); + } + + /** creates a component using our component factory/context, passing creation arguments + @throws ::com::sun::star::uno::Exception + @return + <TRUE/> if and only if the component could be successfully created + */ + template < typename INTERFACE > + bool createComponentWithArguments( const sal_Char* _pAsciiServiceName, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments, ::com::sun::star::uno::Reference< INTERFACE >& _out_rxComponent ) const + { + return createComponentWithArguments( ::rtl::OUString::createFromAscii( _pAsciiServiceName ), _rArguments, _out_rxComponent ); + } + + /** creates a component using our component factory/context + + @throws ::com::sun::star::lang::ServiceNotRegisteredException + if the given service is not registered + @throws Exception + if an exception occurred during creating the component + @return + the newly created component. Is never <NULL/>. + */ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > createComponent( const ::rtl::OUString& _rServiceName ) const; + + /** creates a component using our component factory/context + + @throws ::com::sun::star::lang::ServiceNotRegisteredException + if the given service is not registered + @throws Exception + if an exception occurred during creating the component + @return + the newly created component. Is never <NULL/>. + */ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > createComponent( const sal_Char* _pAsciiServiceName ) const + { + return createComponent( ::rtl::OUString::createFromAscii( _pAsciiServiceName ) ); + } + + /** creates a component using our component factory/context, passing creation arguments + + @throws ::com::sun::star::lang::ServiceNotRegisteredException + if the given service is not registered + @throws Exception + if an exception occurred during creating the component + @return + the newly created component. Is never <NULL/>. + */ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > createComponentWithArguments( + const ::rtl::OUString& _rServiceName, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments + ) const; + + /** creates a component using our component factory/context, passing creation arguments + + @throws ::com::sun::star::lang::ServiceNotRegisteredException + if the given service is not registered + @throws Exception + if an exception occurred during creating the component + @return + the newly created component. Is never <NULL/>. + */ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > createComponentWithArguments( + const sal_Char* _pAsciiServiceName, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments + ) const + { + return createComponentWithArguments( ::rtl::OUString::createFromAscii( _pAsciiServiceName ), _rArguments ); + } + + /** retrieves a singleton instance from the context + + Singletons are collected below the <code>/singletons</code> key in a component context, + so accessing them means retrieving the value under <code>/singletons/<instance_name></code>. + */ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getSingleton( const ::rtl::OUString& _rInstanceName ) const; + + /** retrieves a singleton instance from the context + + Singletons are collected below the <code>/singletons</code> key in a component context, + so accessing them means retrieving the value under <code>/singletons/<instance_name></code>. + */ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getSingleton( const sal_Char* _pAsciiInstanceName ) const + { + return getSingleton( ::rtl::OUString::createFromAscii( _pAsciiInstanceName ) ); + } + + /** returns the ->XMultiServiceFactory interface of ->m_xORB, for passing to + older code which does not yet support ->XMultiComponentFactory + @throws ::com::sun::star::uno::RuntimeException + if our our component factory does not support this interface + */ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + getLegacyServiceFactory() const; + + /** retrieves a value from our component context + @param _rName + the name of the value to retrieve + @return + the context value with the given name + @seealso XComponentContext::getValueByName + @seealso getContextValueByAsciiName + */ + ::com::sun::star::uno::Any + getContextValueByName( const ::rtl::OUString& _rName ) const; + + /** retrieves a value from our component context, specified by 8-bit ASCII string + @param _rName + the name of the value to retrieve, as ASCII character string + @return + the context value with the given name + @seealso XComponentContext::getValueByName + @seealso getContextValueByName + */ + inline ::com::sun::star::uno::Any + getContextValueByAsciiName( const sal_Char* _pAsciiName ) const + { + return getContextValueByName( ::rtl::OUString::createFromAscii( _pAsciiName ) ); + } + + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_COMPONENTCONTEXT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/componentfactory.hxx b/comphelper/inc/comphelper/componentfactory.hxx new file mode 100644 index 000000000000..2da7de3f3c82 --- /dev/null +++ b/comphelper/inc/comphelper/componentfactory.hxx @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_COMPONENTFACTORY_HXX +#define _COMPHELPER_COMPONENTFACTORY_HXX +#include "comphelper/comphelperdllapi.h" + +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + + +/** + * @Descr + * Utilities to get an instance of a component if a ProcessServiceFactory + * is not available like it is the case in "small tools" as the Setup. + */ +#include <com/sun/star/uno/Reference.h> + + +#ifdef UNX +// "libNAMExy.so" (__DLLEXTENSION == "xy.so") +#define LLCF_LIBNAME( name ) "lib" name __DLLEXTENSION +#else +// "NAMExy.dll" (__DLLEXTENSION == "xy") +#define LLCF_LIBNAME( name ) name __DLLEXTENSION ".dll" +#endif + + +namespace rtl { + class OUString; +} +namespace com { namespace sun { namespace star { + namespace uno { + class XInterface; + } + namespace lang { + class XSingleServiceFactory; + class XMultiServiceFactory; + } + namespace registry { + class XRegistryKey; + } +}}} + + +namespace comphelper +{ + +/** + * Get an instance of the component <code>rImplementationName</code> located + * in library <code>rLibraryName</code>. The instance must then be queried + * for the desired interface with a queryInterface call. + * The library name must be constructed with the macro + * <code>LLCF_LIBNAME( name )</code> if it is a library from the normal build + * process which includes build number and platform name. + * + * @example:C++ + * <listing> + + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + Reference< whatever::XYourComponent > xComp; + // library name, e.g. xyz603mi.dll or libxyz603.so + ::rtl::OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( "xyz" ) ) ); + ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.whatever.YourComponent" ) ); + Reference< Xinterface > xI = ::comphelper::getComponentInstance( aLibName, aImplName ); + if ( xI.is() ) + { + Any x = xI->queryInterface( ::getCppuType((const Reference< whatever::XYourComponent >*)0) ); + x >>= xComp; + } + if ( !xComp.is() ) + // you're lost + + * </listing> + */ +COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + getComponentInstance( + const ::rtl::OUString & rLibraryName, + const ::rtl::OUString & rImplementationName + ); + + +::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > + loadLibComponentFactory( + const ::rtl::OUString & rLibraryName, + const ::rtl::OUString & rImplementationName, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF, + const ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey > & xKey + ); + + +} // namespace comphelper + +#endif // _COMPHELPER_COMPONENTFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/componentguard.hxx b/comphelper/inc/comphelper/componentguard.hxx new file mode 100644 index 000000000000..820b901a5c55 --- /dev/null +++ b/comphelper/inc/comphelper/componentguard.hxx @@ -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. + * + ************************************************************************/ + +#ifndef COMPHELPER_COMPONENTGUARD_HXX +#define COMPHELPER_COMPONENTGUARD_HXX + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ + +#include <cppuhelper/weak.hxx> +#include <cppuhelper/interfacecontainer.hxx> + +//...................................................................................................................... +namespace comphelper +{ +//...................................................................................................................... + + //================================================================================================================== + //= ComponentGuard + //================================================================================================================== + class ComponentGuard + { + public: + ComponentGuard( ::cppu::OWeakObject& i_component, ::cppu::OBroadcastHelper & i_broadcastHelper ) + :m_aGuard( i_broadcastHelper.rMutex ) + { + if ( i_broadcastHelper.bDisposed ) + throw ::com::sun::star::lang::DisposedException( ::rtl::OUString(), &i_component ); + } + + ~ComponentGuard() + { + } + + void clear() { m_aGuard.clear(); } + void reset() { m_aGuard.reset(); } + + private: + ::osl::ResettableMutexGuard m_aGuard; + }; + +//...................................................................................................................... +} // namespace comphelper +//...................................................................................................................... + +#endif // COMPHELPER_COMPONENTGUARD_HXX diff --git a/comphelper/inc/comphelper/componentmodule.hxx b/comphelper/inc/comphelper/componentmodule.hxx new file mode 100644 index 000000000000..5893313c8497 --- /dev/null +++ b/comphelper/inc/comphelper/componentmodule.hxx @@ -0,0 +1,279 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_INC_COMPHELPER_COMPONENTMODULE_HXX +#define COMPHELPER_INC_COMPHELPER_COMPONENTMODULE_HXX + +#include <comphelper/comphelperdllapi.h> + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/uno/Sequence.hxx> +/** === end UNO includes === **/ + +#include <cppuhelper/factory.hxx> + +#include <osl/mutex.hxx> + +#include <rtl/string.hxx> +#include <rtl/instance.hxx> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + /** factory factory declaration + */ + typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleComponentFactory > (SAL_CALL *FactoryInstantiation) + ( + ::cppu::ComponentFactoryFunc _pFactoryFunc, + ::rtl::OUString const& _rComponentName, + ::com::sun::star::uno::Sequence< ::rtl::OUString > const & _rServiceNames, + rtl_ModuleCount* _pModuleCounter + ) SAL_THROW(()); + + //========================================================================= + //= ComponentDescription + //========================================================================= + struct COMPHELPER_DLLPUBLIC ComponentDescription + { + /// the implementation name of the component + ::rtl::OUString sImplementationName; + /// the services supported by the component implementation + ::com::sun::star::uno::Sequence< ::rtl::OUString > aSupportedServices; + /** the name under which the component implementation should be registered as singleton, + or empty if the component does not implement a singleton. + */ + ::rtl::OUString sSingletonName; + /// the function to create an instance of the component + ::cppu::ComponentFactoryFunc pComponentCreationFunc; + /// the function to create a factory for the component (usually <code>::cppu::createSingleComponentFactory</code>) + FactoryInstantiation pFactoryCreationFunc; + + ComponentDescription() + :sImplementationName() + ,aSupportedServices() + ,sSingletonName() + ,pComponentCreationFunc( NULL ) + ,pFactoryCreationFunc( NULL ) + { + } + + ComponentDescription( + const ::rtl::OUString& _rImplementationName, + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rSupportedServices, + const ::rtl::OUString& _rSingletonName, + ::cppu::ComponentFactoryFunc _pComponentCreationFunc, + FactoryInstantiation _pFactoryCreationFunc + ) + :sImplementationName( _rImplementationName ) + ,aSupportedServices( _rSupportedServices ) + ,sSingletonName( _rSingletonName ) + ,pComponentCreationFunc( _pComponentCreationFunc ) + ,pFactoryCreationFunc( _pFactoryCreationFunc ) + { + } + }; + + //========================================================================= + //= OModule + //========================================================================= + class OModuleImpl; + class COMPHELPER_DLLPUBLIC OModule + { + private: + oslInterlockedCount m_nClients; /// number of registered clients + OModuleImpl* m_pImpl; /// impl class. lives as long as at least one client for the module is registered + + protected: + mutable ::osl::Mutex m_aMutex; /// access safety + + public: + OModule(); + + virtual ~OModule(); + + /** register a component implementing a service with the given data. + @param _rImplementationName + the implementation name of the component + @param _rServiceNames + the services the component supports + @param _pCreateFunction + a function for creating an instance of the component + @param _pFactoryFunction + a function for creating a factory for that component + */ + void registerImplementation( + const ::rtl::OUString& _rImplementationName, + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rServiceNames, + ::cppu::ComponentFactoryFunc _pCreateFunction, + FactoryInstantiation _pFactoryFunction = ::cppu::createSingleComponentFactory ); + + /** registers a component given by <type>ComponentDescription</type> + */ + void registerImplementation( const ComponentDescription& _rComp ); + + /** creates a Factory for the component with the given implementation name. + <p>Usually used from within component_getFactory.<p/> + @param _rxServiceManager + a pointer to an XMultiServiceFactory interface as got in component_getFactory + @param _pImplementationName + the implementation name of the component + @return + the XInterface access to a factory for the component + */ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getComponentFactory( + const ::rtl::OUString& _rImplementationName, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxServiceManager + ); + + /** version of getComponentFactory which directly takes the arguments you got in your component_getFactory call + */ + void* getComponentFactory( + const sal_Char* _pImplementationName, void* _pServiceManager, void* _pRegistryKey + ); + + public: + class ClientAccess { friend class OModuleClient; private: ClientAccess() { } }; + /// register a client for the module + void registerClient( ClientAccess ); + /// revoke a client for the module + void revokeClient( ClientAccess ); + + protected: + /** called when the first client has been registered + @precond + <member>m_aMutex</member> is locked + */ + virtual void onFirstClient(); + + /** called when the last client has been revoked + @precond + <member>m_aMutex</member> is locked + */ + virtual void onLastClient(); + + private: + OModule( const OModule& ); // never implemented + OModule& operator=( const OModule& ); // never implemented + }; + + //========================================================================= + //= OModuleClient + //========================================================================= + /** base class for objects which uses any global module-specific ressources + */ + class COMPHELPER_DLLPUBLIC OModuleClient + { + protected: + OModule& m_rModule; + + public: + OModuleClient( OModule& _rModule ) :m_rModule( _rModule ) { m_rModule.registerClient( OModule::ClientAccess() ); } + ~OModuleClient() { m_rModule.revokeClient( OModule::ClientAccess() ); } + }; + + //========================================================================== + //= OAutoRegistration + //========================================================================== + template <class TYPE> + class OAutoRegistration + { + public: + /** automatically provides all component information to an OModule instance + <p>Assumed that the template argument has the three methods + <ul> + <li><code>static ::rtl::OUString getImplementationName_static()</code><li/> + <li><code>static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static()</code><li/> + <li><code>static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&)</code> + </li> + <ul/> + the instantiation of this object will automatically register the class via <member>OModule::registerImplementation</member>. + <p/> + The factory creation function used is <code>::cppu::createSingleComponentFactory</code>. + */ + OAutoRegistration( OModule& _rModule ); + }; + + template <class TYPE> + OAutoRegistration<TYPE>::OAutoRegistration( OModule& _rModule ) + { + _rModule.registerImplementation( + TYPE::getImplementationName_static(), + TYPE::getSupportedServiceNames_static(), + TYPE::Create + ); + } + + //========================================================================== + //= OSingletonRegistration + //========================================================================== + template <class TYPE> + class OSingletonRegistration + { + public: + /** automatically provides all component information to an OModule instance, + for a singleton component + + <p>Assumed that the template argument has the three methods + <ul> + <li><code>static ::rtl::OUString getImplementationName_static()</code><li/> + <li><code>static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static()</code><li/> + <li><code>static ::rtl::OUString getSingletonName_static()</code></li> + <li><code>static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&)</code> + </li> + <ul/> + the instantiation of this object will automatically register the class via <member>OModule::registerImplementation</member>. + </p> + */ + OSingletonRegistration( OModule& _rModule ); + }; + + template <class TYPE> + //-------------------------------------------------------------------------- + OSingletonRegistration<TYPE>::OSingletonRegistration( OModule& _rModule ) + { + _rModule.registerImplementation( ComponentDescription( + TYPE::getImplementationName_static(), + TYPE::getSupportedServiceNames_static(), + TYPE::getSingletonName_static(), + &TYPE::Create, + &::cppu::createSingleComponentFactory + ) ); + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_INC_COMPHELPER_COMPONENTMODULE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/composedprops.hxx b/comphelper/inc/comphelper/composedprops.hxx new file mode 100644 index 000000000000..74a9cf30acd1 --- /dev/null +++ b/comphelper/inc/comphelper/composedprops.hxx @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_COMPOSEDPROPS_HXX_ +#define _COMPHELPER_COMPOSEDPROPS_HXX_ + +#include <cppuhelper/implbase2.hxx> +#include <comphelper/types.hxx> +#include <comphelper/stl_types.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <osl/mutex.hxx> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + //===================================================================== + //= IPropertySetComposerCallback + //===================================================================== + class IPropertySetComposerCallback + { + public: + /** determines whether or not a property should appear in the composed property set + @param _rPropertyName + the name of the property + */ + virtual sal_Bool isComposeable(const ::rtl::OUString& _rPropertyName) const = 0; + }; + + //===================================================================== + //= OComposedPropertySet + //===================================================================== + class OComposedPropertySetInfo; + typedef ::cppu::WeakImplHelper2 < ::com::sun::star::beans::XPropertySet + , ::com::sun::star::beans::XPropertyState + > OComposedPropertySet_Base; + /** helper class for composing a property set from a sequence of other property sets. + <p>First: This class is a fast shot, so don't sue me :) (To be honest, it's the migration of an old ugly + implementation. It's still ugly).</p> + <p>The property listener mechanisms are not supported (you can't add property listeners).</p> + <p>Speaking strictly, the property defaults (getPropertyDefault) do not work correctly, as there's always + an empty <type scope="com.sun.star.uno">Any</type> returned.</p> + */ + class COMPHELPER_DLLPUBLIC OComposedPropertySet : public OComposedPropertySet_Base + { + private: + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > + m_aProperties; + OComposedPropertySetInfo* m_pInfo; + + protected: + ::osl::Mutex m_aMutex; + DECLARE_STL_VECTOR(::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>, PropertySetArray); + PropertySetArray m_aSingleSets; + + public: + /** constructs a composed property set + + @param _rElements + the single property sets to compose + <p>The first property set in the sequence is the master set, any properties not present here + are not present in the composed set.<br/> + This may change in the future (as it's just missing implementation), so don't rely on this behaviour.</p> + + @param _pPropertyMetaData + the callback for retrieving property meta data (namely composeability)<br/> + if not specified, all properties are assumed to be composable + */ + OComposedPropertySet( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> > & _rElements, + const IPropertySetComposerCallback* _pPropertyMetaData = NULL + ); + + // XPropertyState + virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + protected: + ~OComposedPropertySet(); + void compose(const IPropertySetComposerCallback* _pMetaData); + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_COMPOSEDPROPS_HXX_ + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/configurationhelper.hxx b/comphelper/inc/comphelper/configurationhelper.hxx new file mode 100644 index 000000000000..3800cea7a0ba --- /dev/null +++ b/comphelper/inc/comphelper/configurationhelper.hxx @@ -0,0 +1,264 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_CONFIGURATIONHELPER_HXX_ +#define _COMPHELPER_CONFIGURATIONHELPER_HXX_ + +//_______________________________________________ +// includes + +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <comphelper/sequenceasvector.hxx> +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include "comphelper/comphelperdllapi.h" + +//_______________________________________________ +// namespaces + +// no panic .. this define will be reseted at the end of this file. +// BUT doing so it's neccessary to add all includes BEFORE this css-value +// will be defined :_) +#ifdef css +#error "Who use css? I need it as namespace alias." +#else +#define css ::com::sun::star +#endif + +namespace comphelper{ + +//_______________________________________________ +// definitions + +//----------------------------------------------- +class COMPHELPER_DLLPUBLIC ConfigurationHelper +{ + public: + + //----------------------------------------------- + /** specify all possible modes, which can be used to open a configuration access. + * + * @see openConfig() + * @see readDirectKey() + * @see writeDirectKey() + */ + enum EConfigurationModes + { + /// opens configuration in read/write mode (without LAZY writing!) + E_STANDARD = 0, + /// configuration will be opened readonly + E_READONLY = 1, + /// all localized nodes will be interpreted as XInterface instead of interpreting it as atomic value nodes + E_ALL_LOCALES = 2, + /// enable lazy writing + E_LAZY_WRITE = 4 + }; + + //----------------------------------------------- + /** returns access to the specified configuration package. + * + * This method should be used, if e.g. more then one request to the same + * configuration package is needed. The configuration access can be cached + * outside and used inbetween. + * + * @param xSMGR + * the uno service manager, which should be used to create the + * configuration access. + * + * @param sPackage + * the name of the configuration package. + * e.g. <ul> + * <li>org.openoffice.Office.Common</li> + * <li>org.openoffice.Office.Common/Menu</li> + * </ul> + * + * @param eMode + * specify the open mode for the returned configuration access. + * It's interpreted as a flag field and can be any usefull combination + * of values of EConfigurationModes. + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::uno::Exception if the configuration could not be opened. + */ + static css::uno::Reference< css::uno::XInterface > openConfig(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR , + const ::rtl::OUString& sPackage, + sal_Int32 eMode ); + + //----------------------------------------------- + /** reads the value of an existing(!) configuration key, + * which is searched relative to the specified configuration access. + * + * This method must be used in combination with openConfig(). + * The cached configuration access must be provided here ... and + * all operations are made relativ to this access point. + * + * @param xCFG + * the configuration root, where sRelPath should be interpreted. + * as relativ path + * + * @param sRelPath + * path relative to xCFG parameter. + * + * @param sKey + * the configuration node, where we should read the value. + * + * @return [css.uno.Any] + * the value of sKey. + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::container::NoSuchElementException if the specified + * key does not exists. + */ + static css::uno::Any readRelativeKey(const css::uno::Reference< css::uno::XInterface > xCFG , + const ::rtl::OUString& sRelPath, + const ::rtl::OUString& sKey ); + + //----------------------------------------------- + /** writes a new value for an existing(!) configuration key, + * which is searched relative to the specified configuration access. + * + * This method must be used in combination with openConfig(). + * The cached configuration access must be provided here ... and + * all operations are made relativ to this access point. + * + * @param xCFG + * the configuration root, where sRelPath should be interpreted. + * as relativ path + * + * @param sRelPath + * path relative to xCFG parameter. + * + * @param sKey + * the configuration node, where we should write the new value. + * + * @param aValue + * the new value for sKey. + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::container::NoSuchElementException if the specified + * key does not exists or css::uno::Exception if the provided configuration + * access does not allow writing for this key. + */ + static void writeRelativeKey(const css::uno::Reference< css::uno::XInterface > xCFG , + const ::rtl::OUString& sRelPath, + const ::rtl::OUString& sKey , + const css::uno::Any& aValue ); + + //----------------------------------------------- + /** it checks if the specified set node exists ... or create an empty one + * otherwise. + * + * This method must be used in combination with openConfig(). + * The cached configuration access must be provided here ... and + * all operations are made relativ to this access point. + * + * Further this method must be used only with configuration set's. + * Atomic keys can't be "created" ... they "exists everytimes". + * + * @param xCFG + * the configuration root, where sRelPathToSet should be interpreted + * as relativ path. + * + * @param sRelPathToSet + * path relative to xCFG parameter. + * + * @param sSetNode + * the set node, which should be checked if its exists ... + * or which should be created with default values. + * + * @return A reference to the found (or new created) set node. + * Cant be NULL .. in such case an exception occure ! + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::uno::Exception if the provided configuration + * access does not allow writing for this set. + */ + static css::uno::Reference< css::uno::XInterface > makeSureSetNodeExists(const css::uno::Reference< css::uno::XInterface > xCFG , + const ::rtl::OUString& sRelPathToSet, + const ::rtl::OUString& sSetNode ); + + //----------------------------------------------- + /** commit all changes made on the specified configuration access. + * + * This method must be used in combination with openConfig(). + * The cached configuration access must be provided here. + * + * @param xCFG + * the configuration root, where changes should be commited. + * + * @throw Any exceptions the underlying configuration can throw. + * E.g. css::uno::Exception if the provided configuration + * access does not allow writing for this set. + */ + static void flush(const css::uno::Reference< css::uno::XInterface >& xCFG); + + //----------------------------------------------- + /** does the same then openConfig() & readRelativeKey() together. + * + * This method should be used for reading one key at one code place only. + * Because it opens the specified configuration package, reads the key and + * closes the configuration again. + * + * So its not very usefull to use this method for reading multiple keys at the same time. + * (Excepting these keys exists inside different configuration packages ...)) + */ + static css::uno::Any readDirectKey(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR , + const ::rtl::OUString& sPackage, + const ::rtl::OUString& sRelPath, + const ::rtl::OUString& sKey , + sal_Int32 eMode ); + + //----------------------------------------------- + /** does the same then openConfig() / writeRelativeKey() & flush() together. + * + * This method should be used for writing one key at one code place only. + * Because it opens the specified configuration package, writes the key, flush + * all changes and closes the configuration again. + * + * So its not very usefull to use this method for writing multiple keys at the same time. + * (Excepting these keys exists inside different configuration packages ...)) + */ + static void writeDirectKey(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR , + const ::rtl::OUString& sPackage, + const ::rtl::OUString& sRelPath, + const ::rtl::OUString& sKey , + const css::uno::Any& aValue , + sal_Int32 eMode ); +}; + +} // namespace comphelper + +#undef css // important! + +#endif // _COMPHELPER_CONFIGURATIONHELPER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/container.hxx b/comphelper/inc/comphelper/container.hxx new file mode 100644 index 000000000000..f0466fe3ae5e --- /dev/null +++ b/comphelper/inc/comphelper/container.hxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_CONTAINER_HXX_ +#define _COMPHELPER_CONTAINER_HXX_ + +#include <vector> +#include "com/sun/star/uno/Reference.hxx" +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +//======================================================================== +//= IndexAccessIterator +//======================================================================== +/** ein Iterator, der von einem XIndexAccess ausgehend alle Elemente durchiteriert (pre-order) +*/ +class COMPHELPER_DLLPUBLIC IndexAccessIterator +{ +protected: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> m_xStartingPoint; + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> m_xCurrentObject; + // das aktuelle Objekt + ::std::vector<sal_Int32> m_arrChildIndizies; + // ich bewege mich eigentlich durch einen Baum, dummerweise haben dessen + // Elemente aber kein GetNextSibling, also muss ich mir merken, wo die Childs + // innerhalb ihres Parents sitzen (das ist sozusagen der Pfad von der Wurzel + // zu m_xCurrentObject + + ::rtl::OUString m_ustrProperty; + // der Name der gesuchten property + +public: + IndexAccessIterator(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xStartingPoint); + + virtual ~IndexAccessIterator(); + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> Next(); + + virtual void Invalidate() { m_xCurrentObject = NULL; } + +protected: + virtual sal_Bool ShouldHandleElement(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& /*rElement*/) { return sal_True; } + // damit kann man bestimmte Elemente ausschliessen, die werden dann einfach + // uebergangen + // wenn hier sal_True zurueckkommt, wird dieses Element von Next zurueckgeliefert, man kann sich hier also auch + // gleich ein paar zusaetzliche Angaben zu dem Element holen (deswegen ist die Methode auch nicht const) + virtual sal_Bool ShouldStepInto(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>& /*xContainer*/) const { return sal_True; } +}; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_CONTAINER_HXX_ + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/containermultiplexer.hxx b/comphelper/inc/comphelper/containermultiplexer.hxx new file mode 100644 index 000000000000..68990ec694f6 --- /dev/null +++ b/comphelper/inc/comphelper/containermultiplexer.hxx @@ -0,0 +1,117 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_CONTAINERMULTIPLEXER_HXX_ +#define _COMPHELPER_CONTAINERMULTIPLEXER_HXX_ + +#include <com/sun/star/container/XContainer.hpp> +#include <cppuhelper/implbase1.hxx> +#include <osl/mutex.hxx> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + class OContainerListenerAdapter; + //===================================================================== + //= OContainerListener + //===================================================================== + /** a non-UNO container listener + <p>Usefull if you have a non-refcountable class which should act as container listener.<br/> + In this case, derive this class from OContainerListener, and create an adapter + <type>OContainerListenerAdapter</type> which multiplexes the changes.</p> + */ + class COMPHELPER_DLLPUBLIC OContainerListener + { + friend class OContainerListenerAdapter; + protected: + OContainerListenerAdapter* m_pAdapter; + ::osl::Mutex& m_rMutex; + + public: + OContainerListener(::osl::Mutex& _rMutex); + virtual ~OContainerListener(); + + virtual void _elementInserted( const ::com::sun::star::container::ContainerEvent& _rEvent ) throw(::com::sun::star::uno::RuntimeException); + virtual void _elementRemoved( const ::com::sun::star::container::ContainerEvent& _Event ) throw(::com::sun::star::uno::RuntimeException); + virtual void _elementReplaced( const ::com::sun::star::container::ContainerEvent& _rEvent ) throw(::com::sun::star::uno::RuntimeException); + virtual void _disposing(const ::com::sun::star::lang::EventObject& _rSource) throw( ::com::sun::star::uno::RuntimeException); + + protected: + void setAdapter(OContainerListenerAdapter* _pAdapter); + }; + + //===================================================================== + //= OContainerListenerAdapter + //===================================================================== + class COMPHELPER_DLLPUBLIC OContainerListenerAdapter + :public cppu::WeakImplHelper1< ::com::sun::star::container::XContainerListener > + { + friend class OContainerListener; + + protected: + ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer > + m_xContainer; + OContainerListener* m_pListener; + sal_Int32 m_nLockCount; + + virtual ~OContainerListenerAdapter(); + + public: + OContainerListenerAdapter(OContainerListener* _pListener, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >& _rxContainer); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw( ::com::sun::star::uno::RuntimeException); + + // XContainerListener + virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw(::com::sun::star::uno::RuntimeException); + + // locking the multiplexer + void lock(); + void unlock(); + sal_Int32 locked() const { return m_nLockCount; } + + /// dispose the object. No multiplexing anymore + void dispose(); + + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >& + getContainer() const { return m_xContainer; } + }; + +//......................................................................... +} // namespace dbaui +//......................................................................... + +#endif // _COMPHELPER_CONTAINERMULTIPLEXER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/docpasswordhelper.hxx b/comphelper/inc/comphelper/docpasswordhelper.hxx new file mode 100644 index 000000000000..51c44d821def --- /dev/null +++ b/comphelper/inc/comphelper/docpasswordhelper.hxx @@ -0,0 +1,377 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_DOCPASSWORDHELPR_HXX +#define COMPHELPER_DOCPASSWORDHELPR_HXX + +#include <com/sun/star/beans/NamedValue.hpp> +#include "comphelper/comphelperdllapi.h" +#include <vector> +#include "comphelper/docpasswordrequest.hxx" + +namespace com { namespace sun { namespace star { namespace task { class XInteractionHandler; } } } } +namespace com { namespace sun { namespace star { namespace beans { struct PropertyValue; } } } } + +namespace comphelper { + +class MediaDescriptor; + +// ============================================================================ + +enum DocPasswordVerifierResult +{ + DocPasswordVerifierResult_OK, + DocPasswordVerifierResult_WRONG_PASSWORD, + DocPasswordVerifierResult_ABORT +}; + +// ============================================================================ + +/** Base class for a password verifier used by the DocPasswordHelper class + below. + + Users have to implement the virtual functions and pass an instance of the + verifier to one of the password request functions. + */ +class COMPHELPER_DLLPUBLIC IDocPasswordVerifier +{ +public: + virtual ~IDocPasswordVerifier(); + + /** Will be called everytime a password needs to be verified. + + @param rPassword + The password to be verified + + @param o_rEncryptionData + Output parameter, that is filled with the EncryptionData generated + from the password. The data is filled only if the validation was + successful. + + @return The result of the verification. + - DocPasswordVerifierResult_OK, if and only if the passed password + is valid and can be used to process the related document. + - DocPasswordVerifierResult_WRONG_PASSWORD, if the password is + wrong. The user may be asked again for a new password. + - DocPasswordVerifierResult_ABORT, if an unrecoverable error + occurred while password verification. The password request loop + will be aborted. + */ + virtual DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ) = 0; + + /** Will be called everytime an encryption data needs to be verified. + + @param rEncryptionData + The data will be validated + + @return The result of the verification. + - DocPasswordVerifierResult_OK, if and only if the passed encryption data + is valid and can be used to process the related document. + - DocPasswordVerifierResult_WRONG_PASSWORD, if the encryption data is + wrong. + - DocPasswordVerifierResult_ABORT, if an unrecoverable error + occured while data verification. The password request loop + will be aborted. + */ + virtual DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ) = 0; + +}; + +// ============================================================================ + +/** Helper that asks for a document password and checks its validity. + */ +class COMPHELPER_DLLPUBLIC DocPasswordHelper +{ +public: + // ------------------------------------------------------------------------ + + /** This helper function generates the information related + to "Password to modify" provided by user. The result + sequence contains the hash and the algorithm-related + info. + + @param aString + The string for which the info should be generated + + @return + The sequence containing the hash and the algorithm-related info + */ + + static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > + GenerateNewModifyPasswordInfo( const ::rtl::OUString& aPassword ); + + // ------------------------------------------------------------------------ + + /** This helper function allows to check whether + the "Password to modify" provided by user is the correct one. + + @param aString + The string containing the provided password + + @param aInfo + The sequence containing the hash and the algorithm-info + + @return + <TRUE/> if the password is correct one + <FALSE/> otherwise + */ + + static sal_Bool IsModifyPasswordCorrect( + const ::rtl::OUString& aPassword, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aInfo ); + + + // ------------------------------------------------------------------------ + + /** This helper function generates the hash code based on the algorithm + specified by MS for "Password to modify" feature of Word. + + @param aString + The string for which the hash should be calculated + + @return + The hash represented by sal_uInt32 + */ + + static sal_uInt32 GetWordHashAsUINT32( + const ::rtl::OUString& aString ); + + // ------------------------------------------------------------------------ + + /** This helper function generates the hash code based on the algorithm + specified by MS for "Password to modify" feature of Word. + + @param aString + The string for which the hash should be calculated + + @return + The hash represented by sequence of bytes in BigEndian form + */ + + static ::com::sun::star::uno::Sequence< sal_Int8 > GetWordHashAsSequence( + const ::rtl::OUString& aString ); + + // ------------------------------------------------------------------------ + + /** This helper function generates the hash code based on the algorithm + specified by MS for "Password to modify" and passwords related to + table protection of Excel. + + @param aString + The string for which the hash should be calculated + + @param nEnc + The encoding that should be used to generate the 8-bit string + before the hash is generated + + @return + The hash represented by sal_uInt16 + */ + + static sal_uInt16 GetXLHashAsUINT16( + const ::rtl::OUString& aString, + rtl_TextEncoding nEnc = RTL_TEXTENCODING_UTF8 ); + + // ------------------------------------------------------------------------ + + /** This helper function generates the hash code based on the algorithm + specified by MS for "Password to modify" and passwords related to + table protection. + + @param aString + The string for which the hash should be calculated + + @param nEnc + The encoding that should be used to generate the 8-bit string + before the hash is generated + + @return + The hash represented by sequence of bytes in BigEndian form + */ + + static ::com::sun::star::uno::Sequence< sal_Int8 > GetXLHashAsSequence( + const ::rtl::OUString& aString, + rtl_TextEncoding nEnc = RTL_TEXTENCODING_UTF8 ); + + // ------------------------------------------------------------------------ + + /** This helper function generates a random sequence of bytes of + requested length. + */ + + static ::com::sun::star::uno::Sequence< sal_Int8 > GenerateRandomByteSequence( + sal_Int32 nLength ); + + // ------------------------------------------------------------------------ + + /** This helper function generates a byte sequence representing the + key digest value used by MSCodec_Std97 codec. + */ + + static ::com::sun::star::uno::Sequence< sal_Int8 > GenerateStd97Key( + const ::rtl::OUString& aPassword, + const ::com::sun::star::uno::Sequence< sal_Int8 >& aDocId ); + + // ------------------------------------------------------------------------ + + /** This helper function generates a byte sequence representing the + key digest value used by MSCodec_Std97 codec. + */ + + static ::com::sun::star::uno::Sequence< sal_Int8 > GenerateStd97Key( + const sal_uInt16 pPassData[16], + const ::com::sun::star::uno::Sequence< sal_Int8 >& aDocId ); + + // ------------------------------------------------------------------------ + + /** This helper function tries to request and verify a password to load a + protected document. + + First, the list of default passwords will be tried if provided. This is + needed by import filters for external file formats that have to check a + predefined password in some cases without asking the user for a + password. Every password is checked using the passed password verifier. + + If not successful, the passed password of a medium is tried, that has + been set e.g. by an API call to load a document. If existing, the + password is checked using the passed password verifier. + + If still not successful, the passed interaction handler is used to + request a password from the user. This will be repeated until the + passed password verifier validates the entered password, or if the user + chooses to cancel password input. + + @param rVerifier + The password verifier used to check every processed password. + + @param rMediaPassword + If not empty, will be passed to the password validator before + requesting a password from the user. This password usually should + be querried from a media descriptor. + + @param rxInteractHandler + The interaction handler that will be used to request a password + from the user, e.g. by showing a password input dialog. + + @param rDocumentName + The name of the related document that will be shown in the password + input dialog. + + @param eRequestType + The password request type that will be passed to the + DocPasswordRequest object created internally. See + docpasswordrequest.hxx for more details. + + @param pDefaultPasswords + If not null, contains default passwords that will be tried before a + password will be requested from the media descriptor or the user. + + @param pbIsDefaultPassword + (output parameter) If not null, the type of the found password will + be returned. True means the password has been found in the passed + list of default passwords. False means the password has been taken + from the rMediaPassword parameter or has been entered by the user. + + @return + If not empty, contains the password that has been validated by the + passed password verifier. If empty, no valid password has been + found, or the user has chossen to cancel password input. + */ + static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestAndVerifyDocPassword( + IDocPasswordVerifier& rVerifier, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rMediaEncData, + const ::rtl::OUString& rMediaPassword, + const ::com::sun::star::uno::Reference< + ::com::sun::star::task::XInteractionHandler >& rxInteractHandler, + const ::rtl::OUString& rDocumentName, + DocPasswordRequestType eRequestType, + const ::std::vector< ::rtl::OUString >* pDefaultPasswords = 0, + bool* pbIsDefaultPassword = 0 ); + + // ------------------------------------------------------------------------ + + /** This helper function tries to find a password for the document + described by the passed media descriptor. + + First, the list of default passwords will be tried if provided. This is + needed by import filters for external file formats that have to check a + predefined password in some cases without asking the user for a + password. Every password is checked using the passed password verifier. + + If not successful, the passed media descriptor is asked for a password, + that has been set e.g. by an API call to load a document. If existing, + the password is checked using the passed password verifier. + + If still not successful, the interaction handler contained in the + passed nmedia descriptor is used to request a password from the user. + This will be repeated until the passed password verifier validates the + entered password, or if the user chooses to cancel password input. + + @param rVerifier + The password verifier used to check every processed password. + + @param rMediaDesc + The media descriptor of the document that needs to be opened with + a password. If a valid password (that is not contained in the + passed list of default passwords) was found, it will be inserted + into the "Password" property of this descriptor. + + @param eRequestType + The password request type that will be passed to the + DocPasswordRequest object created internally. See + docpasswordrequest.hxx for more details. + + @param pDefaultPasswords + If not null, contains default passwords that will be tried before a + password will be requested from the media descriptor or the user. + + @return + If not empty, contains the password that has been validated by the + passed password verifier. If empty, no valid password has been + found, or the user has chossen to cancel password input. + */ + static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestAndVerifyDocPassword( + IDocPasswordVerifier& rVerifier, + MediaDescriptor& rMediaDesc, + DocPasswordRequestType eRequestType, + const ::std::vector< ::rtl::OUString >* pDefaultPasswords = 0 ); + + // ------------------------------------------------------------------------ + +private: + ~DocPasswordHelper(); +}; + +// ============================================================================ + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/docpasswordrequest.hxx b/comphelper/inc/comphelper/docpasswordrequest.hxx new file mode 100644 index 000000000000..2d42dcf453c8 --- /dev/null +++ b/comphelper/inc/comphelper/docpasswordrequest.hxx @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_DOCPASSWORDREQUEST_HXX +#define COMPHELPER_DOCPASSWORDREQUEST_HXX + +#include "comphelper/comphelperdllapi.h" +#include <com/sun/star/task/PasswordRequestMode.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/weak.hxx> + + +namespace comphelper { + +class AbortContinuation; +class PasswordContinuation; + +// ============================================================================ + +/** Selects which UNO document password request type to use. */ +enum DocPasswordRequestType +{ + DocPasswordRequestType_STANDARD, /// Uses the standard com.sun.star.task.DocumentPasswordRequest request. + DocPasswordRequestType_MS /// Uses the com.sun.star.task.DocumentMSPasswordRequest request. +}; + +// ============================================================================ + +class COMPHELPER_DLLPUBLIC SimplePasswordRequest : + public ::com::sun::star::task::XInteractionRequest, + public ::cppu::OWeakObject +{ +public: + explicit SimplePasswordRequest( com::sun::star::task::PasswordRequestMode eMode ); + virtual ~SimplePasswordRequest(); + + // XInterface / OWeakObject + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire( ) throw (); + virtual void SAL_CALL release( ) throw (); + + sal_Bool isAbort() const; + sal_Bool isPassword() const; + + ::rtl::OUString getPassword() const; + +private: + // XInteractionRequest + virtual ::com::sun::star::uno::Any SAL_CALL getRequest() throw( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > SAL_CALL getContinuations() throw( ::com::sun::star::uno::RuntimeException ); + +private: + ::com::sun::star::uno::Any maRequest; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > maContinuations; + AbortContinuation * mpAbort; + PasswordContinuation * mpPassword; +}; + +// ============================================================================ + +/** Implements the task.XInteractionRequest interface for requesting a password + string for a document. + */ +class COMPHELPER_DLLPUBLIC DocPasswordRequest : + public ::com::sun::star::task::XInteractionRequest, + public ::cppu::OWeakObject +{ +public: + explicit DocPasswordRequest( + DocPasswordRequestType eType, + ::com::sun::star::task::PasswordRequestMode eMode, + const ::rtl::OUString& rDocumentName, + sal_Bool bPasswordToModify = sal_False ); + virtual ~DocPasswordRequest(); + + // XInterface / OWeakObject + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire( ) throw (); + virtual void SAL_CALL release( ) throw (); + + sal_Bool isAbort() const; + sal_Bool isPassword() const; + + ::rtl::OUString getPassword() const; + + ::rtl::OUString getPasswordToModify() const; + sal_Bool getRecommendReadOnly() const; + +private: + // XInteractionRequest + virtual ::com::sun::star::uno::Any SAL_CALL getRequest() throw( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > SAL_CALL getContinuations() throw( ::com::sun::star::uno::RuntimeException ); + +private: + ::com::sun::star::uno::Any maRequest; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > maContinuations; + AbortContinuation * mpAbort; + PasswordContinuation * mpPassword; +}; + +// ============================================================================ + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/documentconstants.hxx b/comphelper/inc/comphelper/documentconstants.hxx new file mode 100644 index 000000000000..06653b023002 --- /dev/null +++ b/comphelper/inc/comphelper/documentconstants.hxx @@ -0,0 +1,151 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_DOCUMENTCONSTANTS_HXX +#define _COMPHELPER_DOCUMENTCONSTANTS_HXX + +#include <rtl/ustring.hxx> + +// formats of SO6/7 +#define MIMETYPE_VND_SUN_XML_WRITER_ASCII "application/vnd.sun.xml.writer" +#define MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII "application/vnd.sun.xml.writer.web" +#define MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII "application/vnd.sun.xml.writer.global" +#define MIMETYPE_VND_SUN_XML_DRAW_ASCII "application/vnd.sun.xml.draw" +#define MIMETYPE_VND_SUN_XML_IMPRESS_ASCII "application/vnd.sun.xml.impress" +#define MIMETYPE_VND_SUN_XML_CALC_ASCII "application/vnd.sun.xml.calc" +#define MIMETYPE_VND_SUN_XML_CHART_ASCII "application/vnd.sun.xml.chart" +#define MIMETYPE_VND_SUN_XML_MATH_ASCII "application/vnd.sun.xml.math" +#define MIMETYPE_VND_SUN_XML_BASE_ASCII "application/vnd.sun.xml.base" + +#define MIMETYPE_VND_SUN_XML_WRITER ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_WRITER_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_WRITER_WEB ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_WRITER_GLOBAL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_DRAW ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_DRAW_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_IMPRESS ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_CALC ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_CALC_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_CHART ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_CHART_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_MATH ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_MATH_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_BASE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_BASE_ASCII ) ) + +// template formats of SO6/7 +#define MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII "application/vnd.sun.xml.writer.template" +#define MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII "application/vnd.sun.xml.draw.template" +#define MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII "application/vnd.sun.xml.impress.template" +#define MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII "application/vnd.sun.xml.calc.template" + +#define MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_WRITER_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_DRAW_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ) ) +#define MIMETYPE_VND_SUN_XML_CALC_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_VND_SUN_XML_CALC_ASCII ) ) + +// formats of SO8 +#define MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII "application/vnd.oasis.opendocument.text" +#define MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII "application/vnd.oasis.opendocument.text-web" +#define MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII "application/vnd.oasis.opendocument.text-master" +#define MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII "application/vnd.oasis.opendocument.graphics" +#define MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII "application/vnd.oasis.opendocument.presentation" +#define MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII "application/vnd.oasis.opendocument.spreadsheet" +#define MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII "application/vnd.oasis.opendocument.chart" +#define MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII "application/vnd.oasis.opendocument.formula" +#define MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII "application/vnd.oasis.opendocument.base" +#define MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII "application/vnd.sun.xml.report" +#define MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII "application/vnd.sun.xml.report.chart" + +#define MIMETYPE_OASIS_OPENDOCUMENT_TEXT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_DRAWING ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_CHART ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_FORMULA ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_DATABASE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_REPORT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII ) ) + +// template formats of SO8 +#define MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII "application/vnd.oasis.opendocument.text-template" +#define MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII "application/vnd.oasis.opendocument.graphics-template" +#define MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII "application/vnd.oasis.opendocument.presentation-template" +#define MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII "application/vnd.oasis.opendocument.spreadsheet-template" +#define MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII "application/vnd.oasis.opendocument.chart-template" +#define MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII "application/vnd.oasis.opendocument.formula-template" + +#define MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII ) ) +#define MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII ) ) + +// ODF versions +#define ODFVER_010_TEXT_ASCII "1.0" +#define ODFVER_011_TEXT_ASCII "1.1" +#define ODFVER_012_TEXT_ASCII "1.2" + +#define ODFVER_010_TEXT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ODFVER_010_TEXT_ASCII ) ) +#define ODFVER_011_TEXT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ODFVER_011_TEXT_ASCII ) ) +#define ODFVER_012_TEXT ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ODFVER_012_TEXT_ASCII ) ) +#endif + +// filter flags +// TODO/LATER: The flags should be part of the UNO specification +#define SFX_FILTER_IMPORT 0x00000001L +#define SFX_FILTER_EXPORT 0x00000002L +#define SFX_FILTER_TEMPLATE 0x00000004L +#define SFX_FILTER_INTERNAL 0x00000008L +#define SFX_FILTER_TEMPLATEPATH 0x00000010L +#define SFX_FILTER_OWN 0x00000020L +#define SFX_FILTER_ALIEN 0x00000040L +#define SFX_FILTER_USESOPTIONS 0x00000080L + +#define SFX_FILTER_DEFAULT 0x00000100L +#define SFX_FILTER_EXECUTABLE 0x00000200L +#define SFX_FILTER_SUPPORTSSELECTION 0x00000400L +#define SFX_FILTER_MAPTOAPPPLUG 0x00000800L +#define SFX_FILTER_NOTINFILEDLG 0x00001000L +#define SFX_FILTER_NOTINCHOOSER 0x00002000L +#define SFX_FILTER_ASYNC 0x00004000L +#define SFX_FILTER_CREATOR 0x00008000L +#define SFX_FILTER_OPENREADONLY 0x00010000L +#define SFX_FILTER_MUSTINSTALL 0x00020000L +#define SFX_FILTER_CONSULTSERVICE 0x00040000L + +#define SFX_FILTER_STARONEFILTER 0x00080000L +#define SFX_FILTER_PACKED 0x00100000L + +#define SFX_FILTER_BROWSERPREFERED 0x00400000L + +#define SFX_FILTER_ENCRYPTION 0x01000000L +#define SFX_FILTER_PASSWORDTOMODIFY 0x02000000L + +#define SFX_FILTER_PREFERED 0x10000000L + +#define SFX_FILTER_VERSION_NONE 0 +#define SFX_FILTER_NOTINSTALLED SFX_FILTER_MUSTINSTALL | SFX_FILTER_CONSULTSERVICE + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/documentinfo.hxx b/comphelper/inc/comphelper/documentinfo.hxx new file mode 100644 index 000000000000..baa06e7d7d4b --- /dev/null +++ b/comphelper/inc/comphelper/documentinfo.hxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_DOCUMENTINFO_HXX +#define COMPHELPER_DOCUMENTINFO_HXX + +#include "comphelper/comphelperdllapi.h" + +/** === begin UNO includes === **/ +#include <com/sun/star/frame/XModel.hpp> +/** === end UNO includes === **/ + +//........................................................................ +namespace comphelper { +//........................................................................ + + //==================================================================== + //= DocumentInfo + //==================================================================== + class COMPHELPER_DLLPUBLIC DocumentInfo + { + public: + /** retrieves the UI title of the given document + */ + static ::rtl::OUString getDocumentTitle( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxDocument ); + + private: + DocumentInfo(); // never implemented + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_DOCUMENTINFO_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/embeddedobjectcontainer.hxx b/comphelper/inc/comphelper/embeddedobjectcontainer.hxx new file mode 100644 index 000000000000..7983dec4b662 --- /dev/null +++ b/comphelper/inc/comphelper/embeddedobjectcontainer.hxx @@ -0,0 +1,190 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_OBJECTCONTAINER_HXX_ +#define _COMPHELPER_OBJECTCONTAINER_HXX_ + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include "comphelper/comphelperdllapi.h" + +#include <rtl/ustring.hxx> + +namespace comphelper +{ + class EmbeddedObjectContainer; + /** Helper interface to give access to some common object which replace the SfxObjectShell + */ + class SAL_NO_VTABLE IEmbeddedHelper + { + public: + virtual EmbeddedObjectContainer& getEmbeddedObjectContainer() const = 0; + virtual com::sun::star::uno::Reference < com::sun::star::embed::XStorage > getStorage() const = 0; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > getInteractionHandler() const = 0; + virtual bool isEnableSetModified() const = 0; + }; + +struct EmbedImpl; +class COMPHELPER_DLLPUBLIC EmbeddedObjectContainer +{ + EmbedImpl* pImpl; + + ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > Get_Impl( const ::rtl::OUString&, + const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xCopy); + +public: + // add an embedded object to the container storage + sal_Bool StoreEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, ::rtl::OUString&, sal_Bool ); + + // add an embedded object that has been imported from the container storage - should only be called by filters! + void AddEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, const ::rtl::OUString& ); + + EmbeddedObjectContainer(); + EmbeddedObjectContainer( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& ); + EmbeddedObjectContainer( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, + const com::sun::star::uno::Reference < com::sun::star::uno::XInterface >& ); + ~EmbeddedObjectContainer(); + + void SwitchPersistence( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& ); + sal_Bool CommitImageSubStorage(); + void ReleaseImageSubStorage(); + + ::rtl::OUString CreateUniqueObjectName(); + + // get a list of object names that have been added so far + com::sun::star::uno::Sequence < ::rtl::OUString > GetObjectNames(); + + // check for existence of objects at all + sal_Bool HasEmbeddedObjects(); + + // check existence of an object - either by identity or by name + sal_Bool HasEmbeddedObject( const ::rtl::OUString& ); + sal_Bool HasEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& ); + sal_Bool HasInstantiatedEmbeddedObject( const ::rtl::OUString& ); + + // get the object name of an object - this is the persist name if the object has persistence + ::rtl::OUString GetEmbeddedObjectName( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& ); + + // retrieve an embedded object by name that either has been added already or is available in the container storage + ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > GetEmbeddedObject( const ::rtl::OUString& ); + + // create an object from a ClassId + ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > + CreateEmbeddedObject( const com::sun::star::uno::Sequence < sal_Int8 >&, ::rtl::OUString& ); + + ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > + CreateEmbeddedObject( const com::sun::star::uno::Sequence < sal_Int8 >&, + const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >&, ::rtl::OUString& ); + + // insert an embedded object into the container - objects persistant representation will be added to the storage + sal_Bool InsertEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, ::rtl::OUString& ); + + // load an embedded object from a MediaDescriptor and insert it into the container + // a new object will be created from the new content and returned + ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > + InsertEmbeddedObject( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >&, ::rtl::OUString& ); + + // create an embedded link based on a MediaDescriptor and insert it into the container + // a new object will be created from the new content and returned + ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > + InsertEmbeddedLink( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >&, ::rtl::OUString& ); + + // create an object from a stream that contains its persistent representation and insert it as usual (usually called from clipboard) + // a new object will be created from the new content and returned + ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > + InsertEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream >&, ::rtl::OUString& ); + + // copy an embedded object into the storage + sal_Bool CopyEmbeddedObject( EmbeddedObjectContainer& rSrc, const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, ::rtl::OUString& ); + + // copy an embedded object into the storage, open the new copy and return it + ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject > CopyAndGetEmbeddedObject( EmbeddedObjectContainer& rSrc, const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, /* TODO const ::rtl::OUString& aOrigName,*/ ::rtl::OUString& rName ); + + // move an embedded object from one container to another one + sal_Bool MoveEmbeddedObject( EmbeddedObjectContainer& rSrc, const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, ::rtl::OUString& ); + + // remove an embedded object from the container and from the storage; if object can't be closed + sal_Bool RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose=sal_True ); + sal_Bool RemoveEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, sal_Bool bClose=sal_True ); + + // close and remove an embedded object from the container without removing it from the storage + sal_Bool CloseEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& ); + + // move an embedded object to another container (keep the persistent name) + sal_Bool MoveEmbeddedObject( const ::rtl::OUString& rName, EmbeddedObjectContainer& ); + + // get the stored graphical representation for the object + com::sun::star::uno::Reference < com::sun::star::io::XInputStream > GetGraphicStream( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >&, ::rtl::OUString* pMediaType=0 ); + + // get the stored graphical representation by the object name + com::sun::star::uno::Reference < com::sun::star::io::XInputStream > GetGraphicStream( const ::rtl::OUString& aName, ::rtl::OUString* pMediaType=0 ); + + // add a graphical representation for an object + sal_Bool InsertGraphicStream( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const ::rtl::OUString& rMediaType ); + + // try to add a graphical representation for an object in optimized way ( might fail ) + sal_Bool InsertGraphicStreamDirectly( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType ); + + // remove a graphical representation for an object + sal_Bool RemoveGraphicStream( const ::rtl::OUString& rObjectName ); + + // copy the graphical representation from different container + sal_Bool TryToCopyGraphReplacement( EmbeddedObjectContainer& rSrc, + const ::rtl::OUString& aOrigName, + const ::rtl::OUString& aTargetName ); + + void CloseEmbeddedObjects(); + sal_Bool StoreChildren(sal_Bool _bOasisFormat,sal_Bool _bObjectsOnly); + sal_Bool StoreAsChildren( sal_Bool _bOasisFormat + ,sal_Bool _bCreateEmbedded + ,const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& _xStorage); + + static com::sun::star::uno::Reference< com::sun::star::io::XInputStream > GetGraphicReplacementStream( + sal_Int64 nViewAspect, + const com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >&, + ::rtl::OUString* pMediaType ); + + /** call setPersistentEntry for each embedded object in the container + * + * \param _xStorage The storeage where to store the objects. + * \param _bClearModifedFlag If <TRUE/> then the modifed flag will be set to <FALSE/> otherwise nothing happen. + * \return <FALSE/> if no error occurred, otherwise <TRUE/>. + */ + sal_Bool SetPersistentEntries(const com::sun::star::uno::Reference< com::sun::star::embed::XStorage >& _xStorage,bool _bClearModifedFlag = true); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/enumhelper.hxx b/comphelper/inc/comphelper/enumhelper.hxx new file mode 100644 index 000000000000..fbf42d0d5673 --- /dev/null +++ b/comphelper/inc/comphelper/enumhelper.hxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_ENUMHELPER_HXX_ +#define _COMPHELPER_ENUMHELPER_HXX_ + +#include <vector> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XEnumeration.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <osl/mutex.hxx> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + namespace starcontainer = ::com::sun::star::container; + namespace staruno = ::com::sun::star::uno; + namespace starlang = ::com::sun::star::lang; + +//================================================================== +//= OEnumerationLock +//================================================================== +struct OEnumerationLock +{ + public: + ::osl::Mutex m_aLock; +}; + +//================================================================== +//= OEnumerationByName +//================================================================== +/** provides an <type scope="com.sun.star.container">XEnumeration</type> access based + on an object implementing the <type scope="com.sun.star.container">XNameAccess</type> interface +*/ +class COMPHELPER_DLLPUBLIC OEnumerationByName : private OEnumerationLock + , public ::cppu::WeakImplHelper2< starcontainer::XEnumeration , + starlang::XEventListener > +{ + staruno::Sequence< ::rtl::OUString > m_aNames; + sal_Int32 m_nPos; + staruno::Reference< starcontainer::XNameAccess > m_xAccess; + sal_Bool m_bListening; + +public: + OEnumerationByName(const staruno::Reference< starcontainer::XNameAccess >& _rxAccess); + OEnumerationByName(const staruno::Reference< starcontainer::XNameAccess >& _rxAccess, + const staruno::Sequence< ::rtl::OUString >& _aNames ); + virtual ~OEnumerationByName(); + + virtual sal_Bool SAL_CALL hasMoreElements( ) throw(staruno::RuntimeException); + virtual staruno::Any SAL_CALL nextElement( ) + throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException); + + virtual void SAL_CALL disposing(const starlang::EventObject& aEvent) throw(staruno::RuntimeException); + +private: + COMPHELPER_DLLPRIVATE void impl_startDisposeListening(); + COMPHELPER_DLLPRIVATE void impl_stopDisposeListening(); +}; + +//================================================================== +//= OEnumerationByIndex +//================================================================== +/** provides an <type scope="com.sun.star.container">XEnumeration</type> access based + on an object implementing the <type scope="com.sun.star.container">XNameAccess</type> interface +*/ +class COMPHELPER_DLLPUBLIC OEnumerationByIndex : private OEnumerationLock + , public ::cppu::WeakImplHelper2< starcontainer::XEnumeration , + starlang::XEventListener > +{ + sal_Int32 m_nPos; + staruno::Reference< starcontainer::XIndexAccess > m_xAccess; + sal_Bool m_bListening; + +public: + OEnumerationByIndex(const staruno::Reference< starcontainer::XIndexAccess >& _rxAccess); + virtual ~OEnumerationByIndex(); + + virtual sal_Bool SAL_CALL hasMoreElements( ) throw(staruno::RuntimeException); + virtual staruno::Any SAL_CALL nextElement( ) + throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException); + + virtual void SAL_CALL disposing(const starlang::EventObject& aEvent) throw(staruno::RuntimeException); + +private: + COMPHELPER_DLLPRIVATE void impl_startDisposeListening(); + COMPHELPER_DLLPRIVATE void impl_stopDisposeListening(); +}; + +//================================================================== +//= OAnyEnumeration +//================================================================== +/** provides an <type scope="com.sun.star.container">XEnumeration</type> + for an outside set vector of Any's. + +*/ +class COMPHELPER_DLLPUBLIC OAnyEnumeration : private OEnumerationLock + , public ::cppu::WeakImplHelper1< starcontainer::XEnumeration > +{ + sal_Int32 m_nPos; + staruno::Sequence< staruno::Any > m_lItems; + +public: + OAnyEnumeration(const staruno::Sequence< staruno::Any >& lItems); + virtual ~OAnyEnumeration(); + + virtual sal_Bool SAL_CALL hasMoreElements( ) throw(staruno::RuntimeException); + virtual staruno::Any SAL_CALL nextElement( ) + throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException); + +}; + +//......................................................................... +} +//... namespace comphelper ....................................................... + +#endif // _COMPHELPER_ENUMHELPER_HXX_ + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/eventattachermgr.hxx b/comphelper/inc/comphelper/eventattachermgr.hxx new file mode 100644 index 000000000000..f534ba26dbe5 --- /dev/null +++ b/comphelper/inc/comphelper/eventattachermgr.hxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_EVENTATTACHERMGR_HXX_ +#define _COMPHELPER_EVENTATTACHERMGR_HXX_ + +#include <com/sun/star/uno/Reference.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace com { namespace sun { namespace star { +namespace uno { + class Exception; +} +namespace lang { + class XMultiServiceFactory; +} +namespace script { + class XEventAttacherManager; +} +namespace beans { + class XIntrospection; +} +} } } + + +namespace comphelper +{ + +COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::script::XEventAttacherManager > +createEventAttacherManager( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospection > & rIntrospection, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr ) + throw( ::com::sun::star::uno::Exception ); + + +COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::script::XEventAttacherManager > +createEventAttacherManager( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr ) + throw( ::com::sun::star::uno::Exception ); + +} + +#endif // _COMPHELPER_EVENTATTACHERMGR_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/evtlistenerhlp.hxx b/comphelper/inc/comphelper/evtlistenerhlp.hxx new file mode 100644 index 000000000000..8abf94b915ce --- /dev/null +++ b/comphelper/inc/comphelper/evtlistenerhlp.hxx @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_EVENTLISTENERHELPER_HXX +#define COMPHELPER_EVENTLISTENERHELPER_HXX + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/lang/XEventListener.hpp> +#include <osl/diagnose.h> +#include <cppuhelper/weakref.hxx> +#include "comphelper/comphelperdllapi.h" + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //========================================================================== + //= OCommandsListener + // is helper class to avoid a cycle in refcount between the XEventListener + // and the member XEventBroadcaster + //========================================================================== + class COMPHELPER_DLLPUBLIC OEventListenerHelper : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener > + { + ::com::sun::star::uno::WeakReference< ::com::sun::star::lang::XEventListener> m_xListener; + public: + OEventListenerHelper(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener); + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); + }; +//........................................................................ +} // namespace comphelper +//........................................................................ +#endif // COMPHELPER_EVENTLISTENERHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/evtmethodhelper.hxx b/comphelper/inc/comphelper/evtmethodhelper.hxx new file mode 100644 index 000000000000..e65b73dc207b --- /dev/null +++ b/comphelper/inc/comphelper/evtmethodhelper.hxx @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef COMPHELPER_EVENTMEHODHELPER_HXX +#define COMPHELPER_EVENMETHODHELPER_HXX +#include <comphelper/sequence.hxx> +//........................................................................ +namespace comphelper +{ + COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Sequence< ::rtl::OUString> getEventMethodsForType(const ::com::sun::star::uno::Type& type); +//........................................................................ + +} // namespace comphelper +//........................................................................ +#endif // COMPHELPER_EVENTMEHODHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/extract.hxx b/comphelper/inc/comphelper/extract.hxx new file mode 100644 index 000000000000..4fcaab595b96 --- /dev/null +++ b/comphelper/inc/comphelper/extract.hxx @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_EXTRACT_HXX_ +#define _COMPHELPER_EXTRACT_HXX_ + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/uno/TypeClass.hpp> +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/uno/Any.hxx> +#include "cppu/unotype.hxx" + +namespace cppu +{ + +/** + * Sets enum from int32 value. This function does NOT check for valid enum values! + *<BR> + * @param nEnum int32 enum value + * @param rType enum type + * @return enum or emoty any. + */ +inline ::com::sun::star::uno::Any SAL_CALL int2enum( + sal_Int32 nEnum, const ::com::sun::star::uno::Type & rType ) +{ + if (rType.getTypeClass() == ::com::sun::star::uno::TypeClass_ENUM) + { + int nVal = nEnum; + return ::com::sun::star::uno::Any( &nVal, rType ); + } + return ::com::sun::star::uno::Any(); +} + +/** + * Sets int32 from enum or int in any. + *<BR> + * @param rnEnum [out] int32 enum value + * @param rAny enum or int + * @param sal_True if enum or int value was set else sal_False. + */ +inline sal_Bool SAL_CALL enum2int( sal_Int32 & rnEnum, const ::com::sun::star::uno::Any & rAny ) +{ + if (rAny.getValueTypeClass() == ::com::sun::star::uno::TypeClass_ENUM) + { + rnEnum = * reinterpret_cast< const int * >( rAny.getValue() ); + return sal_True; + } + + return rAny >>= rnEnum; +} + +/** + * Sets int32 from enum or int in any with additional typecheck + * <BR> + * @param rAny enum or int + * @param eRet the enum value as int. If there is not enum of the given type or + * a ::com::sun::star::lang::IllegalArgumentException is thrown + */ +template< typename E > +inline void SAL_CALL any2enum( E & eRet, const ::com::sun::star::uno::Any & rAny ) + throw( ::com::sun::star::lang::IllegalArgumentException ) +{ + // check for type save enum + if (! (rAny >>= eRet)) + { + // if not enum, maybe integer? + sal_Int32 nValue = 0; + if (! (rAny >>= nValue)) + throw ::com::sun::star::lang::IllegalArgumentException(); + + eRet = (E)nValue; + } +} + +/** + * Template function to create an uno::Any from an enum + * + * @DEPRECATED : use makeAny< E >() + * + */ +template< typename E > +inline ::com::sun::star::uno::Any SAL_CALL enum2any( E eEnum ) +{ + return ::com::sun::star::uno::Any( &eEnum, ::cppu::UnoType< E >::get() ); +} + +/** + * Extracts interface from an any. If given any does not hold the demanded interface, + * it will be queried for it. + * If no interface is available, the out ref will be cleared. + *<BR> + * @param rxOut [out] demanded interface + * @param rAny interface + * @return sal_True if any reference (including the null ref) was retrieved from any else sal_False. + */ +template< class T > +inline sal_Bool SAL_CALL extractInterface( + ::com::sun::star::uno::Reference< T > & rxOut, + const ::com::sun::star::uno::Any & rAny ) +{ + rxOut.clear(); + return (rAny >>= rxOut); +} + +/** + * extracts a boolean either as a sal_Bool or an integer from + * an any. If there is no sal_Bool or integer inside the any + * a ::com::sun::star::lang::IllegalArgumentException is thrown + * + */ +inline sal_Bool SAL_CALL any2bool( const ::com::sun::star::uno::Any & rAny ) + throw( ::com::sun::star::lang::IllegalArgumentException ) +{ + if (rAny.getValueTypeClass() == ::com::sun::star::uno::TypeClass_BOOLEAN) + { + return *(sal_Bool *)rAny.getValue(); + } + else + { + sal_Int32 nValue = 0; + if (! (rAny >>= nValue)) + throw ::com::sun::star::lang::IllegalArgumentException(); + return nValue != 0; + } +} + +/** + * Puts a boolean in an any. + * + * @DEPRECATED : use makeAny< sal_Bool >() + * + */ +inline ::com::sun::star::uno::Any SAL_CALL bool2any( sal_Bool bBool ) +{ + return ::com::sun::star::uno::Any( &bBool, ::getCppuBooleanType() ); +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/fileformat.h b/comphelper/inc/comphelper/fileformat.h new file mode 100644 index 000000000000..7b047e73d349 --- /dev/null +++ b/comphelper/inc/comphelper/fileformat.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_FILEFORMAT_H_ +#define _COMPHELPER_FILEFORMAT_H_ + +/* file format versions *************************************************/ + +#define SOFFICE_FILEFORMAT_31 3450 +#define SOFFICE_FILEFORMAT_40 3580 +#define SOFFICE_FILEFORMAT_50 5050 +#define SOFFICE_FILEFORMAT_60 6200 +#define SOFFICE_FILEFORMAT_8 6800 +#define SOFFICE_FILEFORMAT_CURRENT SOFFICE_FILEFORMAT_8 + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/flagguard.hxx b/comphelper/inc/comphelper/flagguard.hxx new file mode 100644 index 000000000000..4fc1f4e97833 --- /dev/null +++ b/comphelper/inc/comphelper/flagguard.hxx @@ -0,0 +1,83 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_FLAGGUARD_HXX +#define COMPHELPER_FLAGGUARD_HXX + +#include "comphelper/scopeguard.hxx" + +//...................................................................................................................... +namespace comphelper +{ +//...................................................................................................................... + + //================================================================================================================== + //= FlagRestorationGuard + //================================================================================================================== + class COMPHELPER_DLLPUBLIC FlagRestorationGuard : public ScopeGuard + { + public: + FlagRestorationGuard( bool& i_flagRef, bool i_temporaryValue, exc_handling i_excHandling = IGNORE_EXCEPTIONS ) + :ScopeGuard( ::boost::bind( RestoreFlag, ::boost::ref( i_flagRef ), !!i_flagRef ), i_excHandling ) + { + i_flagRef = i_temporaryValue; + } + + ~FlagRestorationGuard(); + + private: + static void RestoreFlag( bool& i_flagRef, bool i_originalValue ) + { + i_flagRef = i_originalValue; + } + }; + + //================================================================================================================== + //= FlagGuard + //================================================================================================================== + class COMPHELPER_DLLPUBLIC FlagGuard : public ScopeGuard + { + public: + explicit FlagGuard( bool& i_flagRef, exc_handling i_excHandling = IGNORE_EXCEPTIONS ) + :ScopeGuard( ::boost::bind( ResetFlag, ::boost::ref( i_flagRef ) ), i_excHandling ) + { + i_flagRef = true; + } + + ~FlagGuard(); + + private: + static void ResetFlag( bool& i_flagRef ) + { + i_flagRef = false; + } + }; + +//...................................................................................................................... +} // namespace comphelper +//...................................................................................................................... + +#endif // COMPHELPER_FLAGGUARD_HXX diff --git a/comphelper/inc/comphelper/genericpropertyset.hxx b/comphelper/inc/comphelper/genericpropertyset.hxx new file mode 100644 index 000000000000..a5b3608fc964 --- /dev/null +++ b/comphelper/inc/comphelper/genericpropertyset.hxx @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_GENERICPROPERTYSET_HXX_ +#define _COMPHELPER_GENERICPROPERTYSET_HXX_ + +#include <comphelper/propertysetinfo.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > GenericPropertySet_CreateInstance( PropertySetInfo* pInfo ); +} + +#endif // _COMPHELPER_GENERICPROPERTYSET_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/guarding.hxx b/comphelper/inc/comphelper/guarding.hxx new file mode 100644 index 000000000000..7593b4846cd6 --- /dev/null +++ b/comphelper/inc/comphelper/guarding.hxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_GUARDING_HXX_ +#define _COMPHELPER_GUARDING_HXX_ + +#include <osl/mutex.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +// =================================================================================================== +// = class MutexRelease - +// =================================================================================================== + +/** opposite of OGuard :) + (a mutex is released within the constructor and acquired within the desctructor) + use only when you're sure the mutex is acquired ! +*/ +template <class MUTEX> +class ORelease +{ + MUTEX& m_rMutex; + +public: + ORelease(MUTEX& _rMutex) : m_rMutex(_rMutex) { _rMutex.release(); } + ~ORelease() { m_rMutex.acquire(); } +}; + +typedef ORelease< ::osl::Mutex > MutexRelease; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_GUARDING_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/ihwrapnofilter.hxx b/comphelper/inc/comphelper/ihwrapnofilter.hxx new file mode 100644 index 000000000000..773946cd9af1 --- /dev/null +++ b/comphelper/inc/comphelper/ihwrapnofilter.hxx @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_INTERACTIONHANDLERWRAPPER_HXX_ +#define _COMPHELPER_INTERACTIONHANDLERWRAPPER_HXX_ + +#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_ +#include <com/sun/star/task/XInteractionHandler.hpp> +#endif +#ifndef _COM_SUN_STAR_TASK_XINTERACITONREQUEST_ +#include <com/sun/star/task/XInteractionRequest.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_ +#include <com/sun/star/lang/XInitialization.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_ +#include <com/sun/star/lang/XServiceInfo.hpp> +#endif +#ifndef _COM_SUN_STAR_FRAME_DOUBLEINITIALIZATIONEXCEPTION_ +#include <com/sun/star/frame/DoubleInitializationException.hpp> +#endif + +#include <cppuhelper/implbase3.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper { + + class COMPHELPER_DLLPUBLIC OIHWrapNoFilterDialog : public ::cppu::WeakImplHelper3 + < ::com::sun::star::task::XInteractionHandler + , ::com::sun::star::lang::XInitialization + , ::com::sun::star::lang::XServiceInfo > + { + com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter; + + public: + OIHWrapNoFilterDialog( com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteraction ); + ~OIHWrapNoFilterDialog(); + + static ::rtl::OUString SAL_CALL impl_staticGetImplementationName(); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL impl_staticGetSupportedServiceNames(); + + + //____________________________________________________________________________________________________ + // XInteractionHandler + //____________________________________________________________________________________________________ + + virtual void SAL_CALL handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest) + 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, + ::com::sun::star::frame::DoubleInitializationException ) ; + + //____________________________________________________________________________________________________ + // 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 ); + + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/implbase_var.hxx b/comphelper/inc/comphelper/implbase_var.hxx new file mode 100644 index 000000000000..4ced6b8fce93 --- /dev/null +++ b/comphelper/inc/comphelper/implbase_var.hxx @@ -0,0 +1,451 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/** This header generates the following template classes with a variable number + of interfaces: + + comphelper::ImplHelper<N> <typename Ifc1, ..., typename Ifc<N> > + comphelper::WeakImplHelper<N> <typename Ifc1, ..., typename Ifc<N> > + comphelper::WeakComponentImplHelper<N> <typename Ifc1, ..., + typename Ifc<N> > + comphelper::ImplInheritanceHelper<N> <typename BaseClass, + typename Ifc1, ..., typename Ifc<N> > + + as already present in headers cppuhelper/implbase<1-12>.hxx and + cppuhelper/compbase<1-12>.hxx. + <N> denotes the number of interface types passed as template arguments. + Don't use this header for interface numbers up to 12; + always use the existing cppuhelper/(impl|comp)base<1-12>.hxx headers + for this purpose, which eases debugging. + + Including this header requires a little discipline, because it has no + include guards. Please use the following external include guard rule + where <N> is the number of interface types: + + #if ! defined(INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_<N>) + #define INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_<N> + #define COMPHELPER_IMPLBASE_INTERFACE_NUMBER <N> + #include "comphelper/implbase_var.hxx" + #endif + + Additionally you can + + #define COMPHELPER_IMPLBASE_MAX_CTOR_ARGS <N> + + to control the maximum number of templated ctor arguments for the + ImplInheritanceHelper<N> classes. + The default is a maximum of 6 arguments. +*/ + +#if ! defined(COMPHELPER_IMPLBASE_INTERFACE_NUMBER) +#error "you have to define COMPHELPER_IMPLBASE_INTERFACE_NUMBER prior to including comphelper/implbase_var.hxx!" +#endif // ! defined(COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + +#if !defined(COMPHELPER_IMPLBASE_TEST_PHASE) && COMPHELPER_IMPLBASE_INTERFACE_NUMBER <= 12 +#error "include proper header file: cppuhelper/implbase<N>.hxx or cppuhelper/compbase<N>.hxx!" +#endif + +#if ! defined(COMPHELPER_IMPLBASE_MAX_CTOR_ARGS) +#define COMPHELPER_IMPLBASE_MAX_CTOR_ARGS 6 // default +#endif + +#if ! defined(_CPPUHELPER_IMPLBASE_EX_HXX_) +#include "cppuhelper/implbase_ex.hxx" +#endif +#if ! defined(INCLUDED_RTL_INSTANCE_HXX) +#include "rtl/instance.hxx" +#endif +#if ! defined(_CPPUHELPER_COMPBASE_EX_HXX_) +#include "cppuhelper/compbase_ex.hxx" +#endif + +#include "boost/preprocessor/cat.hpp" +#include "boost/preprocessor/repetition.hpp" +#include "boost/preprocessor/arithmetic/add.hpp" + +namespace comphelper { + +// Suppress warnings about hidden functions in case any of the IfcN has +// functions named dispose, addEventListener, or removeEventListener: +#if defined __SUNPRO_CC +#pragma disable_warn +#endif + +namespace detail { + +struct BOOST_PP_CAT(class_data, COMPHELPER_IMPLBASE_INTERFACE_NUMBER) +{ + sal_Int16 m_nTypes; + sal_Bool m_storedTypeRefs; + sal_Bool m_storedId; + sal_Int8 m_id[16]; + ::cppu::type_entry m_typeEntries[COMPHELPER_IMPLBASE_INTERFACE_NUMBER + 1]; +}; + +/// @internal +template < BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, + typename Ifc), typename Impl > +struct BOOST_PP_CAT(ImplClassData, COMPHELPER_IMPLBASE_INTERFACE_NUMBER) +{ + ::cppu::class_data * operator()() { + static BOOST_PP_CAT(class_data, COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + s_cd = { + COMPHELPER_IMPLBASE_INTERFACE_NUMBER + 1, sal_False, sal_False, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { +#define COMPHELPER_IMPLBASE_classdataList(z_, n_, unused_) \ +{ { BOOST_PP_CAT(Ifc, n_)::static_type }, \ + reinterpret_cast<sal_IntPtr>( static_cast< BOOST_PP_CAT(Ifc, n_) * >( \ + reinterpret_cast<Impl *>(16) ) ) - 16 }, + BOOST_PP_REPEAT(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, + COMPHELPER_IMPLBASE_classdataList, ~) +#undef COMPHELPER_IMPLBASE_classdataList + { { ::com::sun::star::lang::XTypeProvider::static_type }, + reinterpret_cast<sal_IntPtr>( + static_cast< ::com::sun::star::lang::XTypeProvider * >( + reinterpret_cast<Impl *>(16) ) ) - 16 } + } + }; + return reinterpret_cast< ::cppu::class_data * >(&s_cd); + } +}; + +} // namespace detail + +/** Implementation helper implementing interface + ::com::sun::star::lang::XTypeProvider and method + XInterface::queryInterface(), but no reference counting. + + @derive + Inherit from this class giving your interface(s) to be implemented as + template argument(s). Your sub class defines method implementations for + these interface(s) including acquire()/release() and delegates incoming + queryInterface() calls to this base class. +*/ +template< BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, + typename Ifc) > +class SAL_NO_VTABLE BOOST_PP_CAT(ImplHelper, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + : public ::com::sun::star::lang::XTypeProvider, + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc) +{ + /// @internal + struct cd : public ::rtl::StaticAggregate< + ::cppu::class_data, + BOOST_PP_CAT(detail::ImplClassData, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + < + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc), + BOOST_PP_CAT(ImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)< + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)> + > > {}; + +protected: + BOOST_PP_CAT(ImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)() {} + virtual ~BOOST_PP_CAT(ImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)() {} + +public: + virtual ::com::sun::star::uno::Any + SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType ) + throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::ImplHelper_query( rType, cd::get(), this ); } + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > + SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::ImplHelper_getTypes( cd::get() ); } + virtual ::com::sun::star::uno::Sequence<sal_Int8> + SAL_CALL getImplementationId() + throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::ImplHelper_getImplementationId( cd::get() ); } +}; + +/** Implementation helper implementing interfaces + ::com::sun::star::lang::XTypeProvider and + ::com::sun::star::uno::XInterface + which supports weak mechanism to be held weakly + (supporting ::com::sun::star::uno::XWeak thru ::cppu::OWeakObject). + + @derive + Inherit from this class giving your interface(s) to be implemented as + template argument(s). Your sub class defines method implementations for + these interface(s). +*/ +template< BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, + typename Ifc) > +class SAL_NO_VTABLE BOOST_PP_CAT(WeakImplHelper, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + : public ::cppu::OWeakObject, + public ::com::sun::star::lang::XTypeProvider, + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc) +{ + /// @internal + struct cd : public ::rtl::StaticAggregate< + ::cppu::class_data, + BOOST_PP_CAT(detail::ImplClassData, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + < + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc), + BOOST_PP_CAT(WeakImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)< + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)> + > > {}; + +public: + virtual ::com::sun::star::uno::Any + SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType ) + throw (::com::sun::star::uno::RuntimeException) + { + return ::cppu::WeakImplHelper_query( + rType, cd::get(), this, static_cast<OWeakObject *>(this) ); + } + virtual void SAL_CALL acquire() throw () + { OWeakObject::acquire(); } + virtual void SAL_CALL release() throw () + { OWeakObject::release(); } + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > + SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::WeakImplHelper_getTypes( cd::get() ); } + virtual ::com::sun::star::uno::Sequence<sal_Int8> + SAL_CALL getImplementationId() + throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::ImplHelper_getImplementationId( cd::get() ); } +}; + +/** Implementation helper implementing interfaces + ::com::sun::star::lang::XTypeProvider and + ::com::sun::star::uno::XInterface inherting from a BaseClass. + + All acquire() and release() calls are delegated to the BaseClass. + Upon queryInterface(), if a demanded interface is not supported by this + class directly, the request is delegated to the BaseClass. + + @attention + The BaseClass has to be complete in a sense, that + ::com::sun::star::uno::XInterface and + ::com::sun::star::lang::XTypeProvider are implemented properly. + The BaseClass must have at least one ctor that can be called with + COMPHELPER_IMPLBASE_MAX_CTOR_ARGS or fewer arguments. + + @derive + Inherit from this class giving your additional interface(s) to be + implemented as template argument(s). Your sub class defines method + implementations for these interface(s). +*/ +template <typename BaseClass, + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, + typename Ifc) > +class SAL_NO_VTABLE BOOST_PP_CAT(ImplInheritanceHelper, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + : public BaseClass, + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc) +{ + /// @internal + struct cd : public ::rtl::StaticAggregate< + ::cppu::class_data, + BOOST_PP_CAT(detail::ImplClassData, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + < + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc), + BOOST_PP_CAT(ImplInheritanceHelper, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER)< + BaseClass, + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)> + > > {}; + +protected: +#define COMPHELPER_IMPLBASE_templctor_args(z_, n_, unused_) \ + BOOST_PP_CAT(T, n_) const& BOOST_PP_CAT(arg, n_) +#define COMPHELPER_IMPLBASE_templctor(z_, n_, classname_) \ + template< BOOST_PP_ENUM_PARAMS( BOOST_PP_ADD(n_, 1), typename T) > \ + explicit BOOST_PP_CAT(classname_, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)( \ + BOOST_PP_ENUM(BOOST_PP_ADD(n_, 1), \ + COMPHELPER_IMPLBASE_templctor_args, ~) ) \ + : BaseClass( BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n_, 1), arg) ) {} + + BOOST_PP_CAT(ImplInheritanceHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)() + : BaseClass() {} + BOOST_PP_REPEAT(COMPHELPER_IMPLBASE_MAX_CTOR_ARGS, + COMPHELPER_IMPLBASE_templctor, ImplInheritanceHelper) + +public: + virtual ::com::sun::star::uno::Any + SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType ) + throw (::com::sun::star::uno::RuntimeException) + { + ::com::sun::star::uno::Any const aRet( + ::cppu::ImplHelper_queryNoXInterface( rType, cd::get(), this ) ); + if (aRet.hasValue()) + return aRet; + return BaseClass::queryInterface( rType ); + } + virtual void SAL_CALL acquire() throw () + { BaseClass::acquire(); } + virtual void SAL_CALL release() throw () + { BaseClass::release(); } + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > + SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) + { + return ::cppu::ImplInhHelper_getTypes( + cd::get(), BaseClass::getTypes() ); + } + virtual ::com::sun::star::uno::Sequence<sal_Int8> + SAL_CALL getImplementationId() + throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::ImplHelper_getImplementationId( cd::get() ); } +}; + +// not needed anymore: +#undef COMPHELPER_IMPLBASE_templctor_args +#undef COMPHELPER_IMPLBASE_templctor + +/** Implementation helper supporting + ::com::sun::star::lang::XTypeProvider and + ::com::sun::star::lang::XComponent. + + Upon disposing objects of this class, sub-classes receive a disposing() + call. Objects of this class can be held weakly, i.e. by a + ::com::sun::star::uno::WeakReference. + + @attention + The life-cycle of the passed mutex reference has to be longer than objects + of this class. + + @derive + Inherit from this class giving your interface(s) to be implemented as + template argument(s). Your sub class defines method implementations for + these interface(s). +*/ +template < BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, + typename Ifc) > +class SAL_NO_VTABLE BOOST_PP_CAT(WeakComponentImplHelper, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + : public ::cppu::WeakComponentImplHelperBase, + public ::com::sun::star::lang::XTypeProvider, + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc) +{ + /// @internal + struct cd : public ::rtl::StaticAggregate< + ::cppu::class_data, + BOOST_PP_CAT(detail::ImplClassData, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + < + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc), + BOOST_PP_CAT(WeakComponentImplHelper, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER)< + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)> + > > {}; + +public: + BOOST_PP_CAT(WeakComponentImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)( + ::osl::Mutex & rMutex ) : WeakComponentImplHelperBase(rMutex) {} + + virtual ::com::sun::star::uno::Any + SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType ) + throw (::com::sun::star::uno::RuntimeException) + { + return ::cppu::WeakComponentImplHelper_query( + rType, cd::get(), this, + static_cast< ::cppu::WeakComponentImplHelperBase * >(this) ); + } + virtual void SAL_CALL acquire() throw () + { WeakComponentImplHelperBase::acquire(); } + virtual void SAL_CALL release() throw () + { WeakComponentImplHelperBase::release(); } + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > + SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::WeakComponentImplHelper_getTypes( cd::get() ); } + virtual ::com::sun::star::uno::Sequence<sal_Int8> + SAL_CALL getImplementationId() + throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::ImplHelper_getImplementationId( cd::get() ); } + + // implement XComponent directly avoiding ambiguities: + virtual void SAL_CALL dispose() + throw (::com::sun::star::uno::RuntimeException) + { WeakComponentImplHelperBase::dispose(); } + virtual void SAL_CALL addEventListener( + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener> + const & xListener ) throw (::com::sun::star::uno::RuntimeException) + { WeakComponentImplHelperBase::addEventListener( xListener ); } + virtual void SAL_CALL removeEventListener( + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener> + const & xListener ) throw (::com::sun::star::uno::RuntimeException) + { WeakComponentImplHelperBase::removeEventListener( xListener ); } +}; + +template < BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, + typename Ifc) > +class SAL_NO_VTABLE BOOST_PP_CAT(PartialWeakComponentImplHelper, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + : public ::cppu::WeakComponentImplHelperBase, + public ::com::sun::star::lang::XTypeProvider, + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc) +{ + /// @internal + struct cd : public ::rtl::StaticAggregate< + ::cppu::class_data, + BOOST_PP_CAT(detail::ImplClassData, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER) + < + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc), + BOOST_PP_CAT(PartialWeakComponentImplHelper, + COMPHELPER_IMPLBASE_INTERFACE_NUMBER)< + BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)> + > > {}; + +public: + BOOST_PP_CAT(PartialWeakComponentImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)( + ::osl::Mutex & rMutex ) : WeakComponentImplHelperBase(rMutex) {} + + virtual ::com::sun::star::uno::Any + SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType ) + throw (::com::sun::star::uno::RuntimeException) + { + return ::cppu::WeakComponentImplHelper_query( + rType, cd::get(), this, + static_cast< ::cppu::WeakComponentImplHelperBase * >(this) ); + } + virtual void SAL_CALL acquire() throw () + { WeakComponentImplHelperBase::acquire(); } + virtual void SAL_CALL release() throw () + { WeakComponentImplHelperBase::release(); } + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > + SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::WeakComponentImplHelper_getTypes( cd::get() ); } + virtual ::com::sun::star::uno::Sequence<sal_Int8> + SAL_CALL getImplementationId() + throw (::com::sun::star::uno::RuntimeException) + { return ::cppu::ImplHelper_getImplementationId( cd::get() ); } +}; + + +} // namespace comphelper + +// undef for multiple use/inclusion of this header: +#undef COMPHELPER_IMPLBASE_MAX_CTOR_ARGS +#undef COMPHELPER_IMPLBASE_INTERFACE_NUMBER + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/implementationreference.hxx b/comphelper/inc/comphelper/implementationreference.hxx new file mode 100644 index 000000000000..dff242b78307 --- /dev/null +++ b/comphelper/inc/comphelper/implementationreference.hxx @@ -0,0 +1,276 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX +#define _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/XInterface.hpp> + +namespace comphelper +{ + + /** Holds a uno::Reference alongside a C++ implementation pointer + + This template is useful to accomplish the following task: the + client needs an implementation pointer to an object providing + UNO interfaces. It is unsafe to simply store a C++ pointer, + because of the automatic UNO lifetime control. It is + inconvenient to always cast the UNO interface to the C++ + implementation, and what's more, it's mostly unclear to the + casual code reader. + + Thus, this template nicely encapsulate the stated intention, + by holding a uno::Reference internally, and providing simple + C++ pointer semantics to the outside. As a differentiator to + ::rtl::Reference, this template features a getRef() method, + giving you friction-less access to the internal UNO interface, + without extra querying. + + By the way, the pointer semantic of this template include + transitive constness. That means, if this template's instance + is const (e.g. because it is a member of a class which is + accessed in a const method), the pointer returned is also + const. + + As this template is geared towards fast, internal pointer + access, validity of the UNO reference is _not_ checked for + every pointer access. The client of this template is + responsible to check that, whereever necessary, via the is() + method. + + @tpl CppType + The C++ type this class should mimick a pointer to (not the + pointer type itself!). + + @tpl UnoType + The UNO interface type of the object (a uno::Reference to this + type is held internally). + + @tpl XIfType + An unambiguous derivative of UnoType. This is defaulted to + the second template parameter (UnoType), which should normally + just work, since one typically has only single inheritance in + UNO.<p> + Alternatively, when using the + ImplementationReference::createFromQuery() method to create an + instance, this type can serve a different need: if the + provided CppType only derives from XInterface (generally + speaking, derives from a UNO interface above UnoType in the + class hierarchy), then the default XIfType constitutes a + possibly invalid downcast to UnoType. Setting XIfType equal to + CppTypes's most derived UNO interface type then solves this + problem (which is not as arcane as it seems to be. Just + imagine you're providing a C++ abstract interface, which must + provide UNO reference semantics. Naturally, you will derive + this C++ interface only from XInterface, to reduce the number + of ambiguous classes. Even more naturally, it is reasonable to + have UnoType be something different from XInterface, governed + by the usage of the C++ interface) + + @sample ImplementationReference< MyCppType, XMyInterface > + + @sample ImplementationReference< MyAbstractCppType, XMyInterface, XInterface > + for an abstract C++ class + + @see ::rtl::Reference + + */ + template < class CppType, + class UnoType, + class XIfType=UnoType > class ImplementationReference + { + public: + + typedef UnoType UnoInterfaceType; + typedef CppType ImplementationType; + typedef XIfType UnambiguousXInterfaceType; + + /** Default-construct an ImplementationReference + + Uno reference will be invalid, implementation pointer will + be NULL. + */ + ImplementationReference() : + mxRef(), + mpImpl( NULL ) + { + } + + /** Create an ImplementationReference from C++ pointer. + + This constructor does not perform an explicit + QueryInterface on the provided implementation object, but + constructs the UNO reference directly from the given + pointer. This is the fastest, and most often the best way + to create an ImplementationReference. If the conversion + between the implementation object and the required UNO + interface is ambiguous, provide the third template + parameter with a type that can be unambiguously upcasted + to the UNO interface (the second template parameter). + + There are cases, however, where performing a + QueryInterface is the better, albeit slower choice. In + these cases, createFromQuery() should be used. + + @param pImpl + Pointer to the C++ implementation type + + @see createFromQuery() + */ + explicit ImplementationReference( ImplementationType* pImpl ) : + mxRef( static_cast<UnambiguousXInterfaceType*>(pImpl) ), + mpImpl( pImpl ) + { + } + + struct CreateFromQuery { }; + /** Create an ImplementationReference from C++ pointer + + @param pImpl + The pointer to the C++ implementation type, which is + queried for the template-parameterized UNO type. + + @param dummy + Dummy parameter, to distinguish this contructor from the + default unary one (which does not perform a + QueryInterface) + */ + ImplementationReference( ImplementationType* pImpl, CreateFromQuery ) : + mxRef( static_cast<UnambiguousXInterfaceType*>(pImpl), + ::com::sun::star::uno::UNO_QUERY ), + mpImpl( pImpl ) + { + } + + /** Factory method to create an ImplementationReference from + C++ pointer. + + This is a static version of the constructor which creates + an instance of an implementation type which is explicitely + queried for the ImplementationReference's + template-parameterized UNO type. + + @sample + mpRef = mpRef.createFromQuery( new ImplementationType ); + */ + static ImplementationReference createFromQuery( ImplementationType* pImpl ) + { + return ImplementationReference( pImpl, CreateFromQuery() ); + } + + /** Query whether the pointer is still valid. + + Hands off also from the implementation pointer if this + returns false! + */ + bool is() const { return mxRef.is(); } + + /** Get a pointer to the implementation object + + Compatibility method to get an auto_ptr-compatible + interface + */ + ImplementationType* get() { return mpImpl; } + const ImplementationType* get() const { return mpImpl; } + + /** Release all references + + Compatibility method to get an auto_ptr-compatible + interface + */ + void reset() { dispose(); } + + /** Release all references + + This method releases the UNO interface reference, and + clears the C++ pointer to NULL. + */ + void dispose() { mxRef = NULL; mpImpl=NULL; } + + ImplementationType* operator->() { return mpImpl; } + const ImplementationType* operator->() const { return mpImpl; } + + ImplementationType& operator*() { return *mpImpl; } + const ImplementationType& operator*() const { return *mpImpl; } + + /// Access to the underlying UNO reference, without extra querying + ::com::sun::star::uno::Reference< UnoInterfaceType > getRef() { return mxRef; } + + /// Access to the underlying UNO reference, without extra querying + const ::com::sun::star::uno::Reference< UnoInterfaceType >& getRef() const { return mxRef; } + + // default destructor, copy constructor and assignment will do + // ~ImplementationReference(); + // ImplementationReference( const ImplementationReference& ); + // ImplementationReference& operator= ( const ImplementationReference& ); + + /** Comparison operator + + Object identity is defined to be identity of the + implementation pointers. This is in general invalid when + comparing pointers to UNO objects (ambiguous class + hierarchies, optimizations in the bridges, etc.), but okay + for raw C++ pointers (which is what's compared herein). + */ + bool operator==( const ImplementationReference& rhs ) const + { + return mpImpl == rhs.mpImpl; + } + + /** less-than operator + + Object order is defined to be the ordering of the + implementation pointers. This is in general invalid when + comparing pointers to UNO objects (ambiguous class + hierarchies, optimizations in the bridges, etc.), but okay + for raw C++ pointers (which is what's used herein). + + This ordering complies with STL's strict weak ordering + concept. + */ + bool operator<( const ImplementationReference& rhs ) const + { + return mpImpl < rhs.mpImpl; + } + + private: + + // the interface, hard reference to prevent object from vanishing + ::com::sun::star::uno::Reference< UnoInterfaceType > mxRef; + + // the c++ object, for our internal stuff + ImplementationType* mpImpl; + + }; + +} + +#endif // _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/interaction.hxx b/comphelper/inc/comphelper/interaction.hxx new file mode 100644 index 000000000000..a8f0df51b0bd --- /dev/null +++ b/comphelper/inc/comphelper/interaction.hxx @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_INTERACTION_HXX_ +#define _COMPHELPER_INTERACTION_HXX_ + +#include <comphelper/uno3.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/task/XInteractionApprove.hpp> +#include <com/sun/star/task/XInteractionDisapprove.hpp> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionRetry.hpp> +#include <com/sun/star/task/XInteractionPassword.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //========================================================================= + //= OInteractionSelect + //========================================================================= + /** base class for concrete XInteractionContinuation implementations.<p/> + Instances of the classes maintain a flag indicating if the handler was called. + */ + class OInteractionSelect + { + sal_Bool m_bSelected : 1; /// indicates if the select event occurred + + protected: + OInteractionSelect() : m_bSelected(sal_False) { } + + public: + /// determines whether or not this handler was selected + sal_Bool wasSelected() const { return m_bSelected; } + /// resets the state to "not selected", so you may reuse the handler + void reset() { m_bSelected = sal_False; } + + protected: + void implSelected() { m_bSelected = sal_True; } + }; + + //========================================================================= + //= OInteraction + //========================================================================= + /** template for instantiating concret interaction handlers<p/> + the template argument must eb an interface derived from XInteractionContinuation + */ + template <class INTERACTION> + class OInteraction + :public ::cppu::WeakImplHelper1< INTERACTION > + ,public OInteractionSelect + { + public: + OInteraction() { } + + // XInteractionContinuation + virtual void SAL_CALL select( ) throw(::com::sun::star::uno::RuntimeException); + }; + + //......................................................................... + template <class INTERACTION> + void SAL_CALL OInteraction< INTERACTION >::select( ) throw(::com::sun::star::uno::RuntimeException) + { + implSelected(); + } + + //========================================================================= + //= OInteractionApprove + //========================================================================= + typedef OInteraction< ::com::sun::star::task::XInteractionApprove > OInteractionApprove; + + //========================================================================= + //= OInteractionDispprove + //========================================================================= + typedef OInteraction< ::com::sun::star::task::XInteractionDisapprove > OInteractionDisapprove; + + //========================================================================= + //= OInteractionAbort + //========================================================================= + typedef OInteraction< ::com::sun::star::task::XInteractionAbort > OInteractionAbort; + + //========================================================================= + //= OInteractionRetry + //========================================================================= + typedef OInteraction< ::com::sun::star::task::XInteractionRetry > OInteractionRetry; + + //========================================================================= + //= OInteractionPassword + //========================================================================= + class COMPHELPER_DLLPUBLIC OInteractionPassword : public OInteraction< ::com::sun::star::task::XInteractionPassword > + { + public: + OInteractionPassword() + { + } + + OInteractionPassword( const ::rtl::OUString& _rInitialPassword ) + :m_sPassword( _rInitialPassword ) + { + } + + // XInteractionPassword + virtual void SAL_CALL setPassword( const ::rtl::OUString& _Password ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getPassword( ) throw (::com::sun::star::uno::RuntimeException); + + private: + ::rtl::OUString m_sPassword; + }; + + //========================================================================= + //= OInteractionRequest + //========================================================================= + typedef ::cppu::WeakImplHelper1 < ::com::sun::star::task::XInteractionRequest + > OInteractionRequest_Base; + /** implements an interaction request (<type scope="com.sun.star.task">XInteractionRequest</type>)<p/> + at run time, you can freely add any interaction continuation objects + */ + class COMPHELPER_DLLPUBLIC OInteractionRequest : public OInteractionRequest_Base + { + ::com::sun::star::uno::Any + m_aRequest; /// the request we represent + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > + m_aContinuations; /// all registered continuations + + public: + OInteractionRequest(const ::com::sun::star::uno::Any& _rRequestDescription); + + /// add a new continuation + void addContinuation(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >& _rxContinuation); + /// clear all continuations + void clearContinuations(); + + // XInteractionRequest + virtual ::com::sun::star::uno::Any SAL_CALL getRequest( ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > SAL_CALL getContinuations( ) throw(::com::sun::star::uno::RuntimeException); + }; +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_INTERACTION_HXX_ + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/listenernotification.hxx b/comphelper/inc/comphelper/listenernotification.hxx new file mode 100644 index 000000000000..98143f1d3242 --- /dev/null +++ b/comphelper/inc/comphelper/listenernotification.hxx @@ -0,0 +1,310 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX +#define COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX + +#include <cppuhelper/interfacecontainer.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XEventListener.hpp> +/** === end UNO includes === **/ +#include "comphelper/comphelperdllapi.h" + +#include <memory> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //==================================================================== + //= OListenerContainer + //==================================================================== + /** abstract base class which manages a listener container, including + THB's listener notification pattern which cares for removing listeners + which throw an DisposedException upon notification + + Using this class is pretty easy: + <ul> + <li>Derive from it, and overwrite implNotify.</li> + <li>Use <member>impl_addListener</member> and <member>impl_removeListener</member> in your + XFoo::addFooListener and XFoo::removeFooListener methods.</li> + <li>call <member>impl_notify</member> whenever the event you want to notify happened</li> + <li>call <member>disposing</member> upon the disposal of your broadcaster.</li> + </ul> + + See <type>OListenerContainerBase</type> for an implementation which even saves + you some more work, by doing the casts for you. + + @see http://www.openoffice.org/servlets/ReadMsg?list=interface-announce&msgId=494345 + @see OListenerContainerBase + */ + class COMPHELPER_DLLPUBLIC OListenerContainer + { + private: + ::cppu::OInterfaceContainerHelper m_aListeners; + + public: + /** sends a XEventObject::disposing notification to all listeners, and clears the + listener container + + You'll usually call this from within your own dispose/disposing method + */ + void disposing( const ::com::sun::star::lang::EventObject& _rEventSource ); + + /** clears the container without calling <member scope="com::sun::star::lang">XEventListener::disposing</member> + at the listeners + */ + void clear(); + + /** determines whether the listener container is currently empty + */ + inline bool + empty() const SAL_THROW(()); + + /** determines the number of elements in the container + */ + inline size_t + size() const SAL_THROW(()); + + /** creates an iterator for looping through all registered listeners + */ + inline ::std::auto_ptr< ::cppu::OInterfaceIteratorHelper > + createIterator(); + + protected: + OListenerContainer( ::osl::Mutex& _rMutex ); + + virtual ~OListenerContainer(); + + void impl_addListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener ); + void impl_removeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener ); + + /** notifies all listeners of the given event, using THB's notification pattern + + internally, this method will call <member>implNotify</member> for every listener + + @return + <TRUE/> if all listeners have been notified, <FALSE/> else. The latter can happen + if <member>implNotify</member> cancelles the notification loop. + + @see implNotify + */ + bool impl_notify( const ::com::sun::star::lang::EventObject& _rEvent ) SAL_THROW(( ::com::sun::star::uno::Exception )); + + protected: + /** call a single listener + + @pure + + @throws ::com::sun::star::uno::Exception + if the listener throws an exception during notification. Please don't catch + any listener exceptions in your implementation of this method, simply let them + pass to the caller. + + @param _rxListener + specifies the listener to call. Is guaranteed to not be <NULL/> + @param _rEvent + the event to broadcast. This is the same as passed to <member>notify</member>, so if + your base class knows the type passed into <member>notify</member>, it can safely assume + that <arg>_rEvent</arg> is also of this type. + + @return + <TRUE/> if the remaining listeners should be called, <FALSE/> if the notification + loop should be cancelled + + @see notify + */ + virtual bool implNotify( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener, + const ::com::sun::star::lang::EventObject& _rEvent + ) SAL_THROW( ( ::com::sun::star::uno::Exception ) ) = 0; + }; + + //==================================================================== + inline bool OListenerContainer::empty() const SAL_THROW(()) + { + return ( m_aListeners.getLength() == 0 ); + } + + inline size_t OListenerContainer::size() const SAL_THROW(()) + { + return m_aListeners.getLength(); + } + + inline ::std::auto_ptr< ::cppu::OInterfaceIteratorHelper > OListenerContainer::createIterator() + { + ::std::auto_ptr< ::cppu::OInterfaceIteratorHelper > pIterator( new ::cppu::OInterfaceIteratorHelper( m_aListeners ) ); + return pIterator; + } + + //==================================================================== + //= OSimpleListenerContainer + //==================================================================== + /** helper class for simple notification of the form LISTENER::METHOD( EVENT ) + + This class is not threadsafe! + + @param LISTENER + the listener class to call, e.g. <type scope="com::sun::star::lang">XEventListener</type> + @param EVENT + the event type to notify, e.g. <type scope="com::sun::star::lang">EventObject</type> + */ + template< class LISTENER, class EVENT > + class OSimpleListenerContainer : protected OListenerContainer + { + public: + typedef LISTENER ListenerClass; + typedef EVENT EventClass; + typedef void ( SAL_CALL LISTENER::*NotificationMethod )( const EventClass& ); + + private: + NotificationMethod m_pNotificationMethod; + + public: + OSimpleListenerContainer( ::osl::Mutex& _rMutex ) + :OListenerContainer( _rMutex ) + ,m_pNotificationMethod( NULL ) + { + } + + inline void addListener( const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener ) + { + OListenerContainer::impl_addListener( _rxListener.get() ); + } + + inline void removeListener( const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener ) + { + OListenerContainer::impl_removeListener( _rxListener.get() ); + } + + // publish some otherwise hidden base functionality + using OListenerContainer::disposing; + using OListenerContainer::clear; + using OListenerContainer::empty; + using OListenerContainer::size; + using OListenerContainer::createIterator; + + /// typed notification + inline bool notify( const EventClass& _rEvent, NotificationMethod _pNotify ) SAL_THROW(( ::com::sun::star::uno::Exception )); + + protected: + inline virtual bool implNotify( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener, + const ::com::sun::star::lang::EventObject& _rEvent + ) SAL_THROW( ( ::com::sun::star::uno::Exception ) ); + }; + + //-------------------------------------------------------------------- + template< class LISTENER, class EVENT > + inline bool OSimpleListenerContainer< LISTENER, EVENT >::notify( const EventClass& _rEvent, NotificationMethod _pNotify ) SAL_THROW(( ::com::sun::star::uno::Exception )) + { + m_pNotificationMethod = _pNotify; + bool bRet = OListenerContainer::impl_notify( _rEvent ); + m_pNotificationMethod = NULL; + return bRet; + } + + //-------------------------------------------------------------------- + template< class LISTENER, class EVENT > + inline bool OSimpleListenerContainer< LISTENER, EVENT >::implNotify( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener, + const ::com::sun::star::lang::EventObject& _rEvent ) SAL_THROW( ( ::com::sun::star::uno::Exception ) ) + { + const EventClass& rTypedEvent( static_cast< const EventClass& >( _rEvent ) ); + ListenerClass* pTypedListener( static_cast< ListenerClass* >( _rxListener.get() ) ); + (pTypedListener->*m_pNotificationMethod)( rTypedEvent ); + return true; + } + + //==================================================================== + //= OListenerContainerBase + //==================================================================== + /** is a specialization of OListenerContainer which saves you some additional type casts, + by making the required listener and event types template arguments. + */ + template< class LISTENER, class EVENT > + class OListenerContainerBase : public OListenerContainer + { + public: + typedef LISTENER ListenerClass; + typedef EVENT EventClass; + + public: + inline OListenerContainerBase( ::osl::Mutex& _rMutex ) : OListenerContainer( _rMutex ) + { + } + + inline void addTypedListener( const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener ) + { + OListenerContainer::impl_addListener( _rxListener.get() ); + } + + inline void removeTypedListener( const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener ) + { + OListenerContainer::impl_removeListener( _rxListener.get() ); + } + + inline bool notify( const EventClass& _rEvent ) + { + return OListenerContainer::impl_notify( _rEvent ); + } + + using OListenerContainer::impl_notify; + + protected: + inline virtual bool implNotify( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener, + const ::com::sun::star::lang::EventObject& _rEvent + ) SAL_THROW( ( ::com::sun::star::uno::Exception ) ); + + virtual bool implTypedNotify( + const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener, + const EventClass& _rEvent + ) SAL_THROW( ( ::com::sun::star::uno::Exception ) ) = 0; + }; + + template< class LISTENER, class EVENT > + inline bool OListenerContainerBase< LISTENER, EVENT >::implNotify( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener, + const ::com::sun::star::lang::EventObject& _rEvent ) SAL_THROW( ( ::com::sun::star::uno::Exception ) ) + { + return implTypedNotify( + ::com::sun::star::uno::Reference< ListenerClass >( static_cast< ListenerClass* >( _rxListener.get() ) ), + static_cast< const EventClass& >( _rEvent ) + ); + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/locale.hxx b/comphelper/inc/comphelper/locale.hxx new file mode 100644 index 000000000000..85821dd28a89 --- /dev/null +++ b/comphelper/inc/comphelper/locale.hxx @@ -0,0 +1,391 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_LOCALE_HXX_ +#define _COMPHELPER_LOCALE_HXX_ + +//_______________________________________________ +// includes + +#include <vector> +#include <rtl/ustring.hxx> +#include "comphelper/comphelperdllapi.h" + +//_______________________________________________ +// namespace + +namespace comphelper{ + +//_______________________________________________ +// definitions + +/** @short A Locale object represents a specific geographical, political, or cultural region. + + @descr This Locale class can be used to: + - provide the different parts of a Locale (Language, Country, Variant) + - converting it from/to ISO formated string values (like e.g. "en-US") + - provide some predefined (static) Locale objects + */ +class COMPHELPER_DLLPUBLIC Locale +{ + //------------------------------------------- + // const + + public: + + /** @short seperates LANGUAGE and COUNTRY part of an ISO formated Locale. */ + static const sal_Unicode SEPERATOR_LC; + + /** @short seperates COUNTRY and VARIANT part of an ISO formated Locale. */ + static const sal_Unicode SEPERATOR_CV; + + /** @short seperates COUNTRY and VARIANT part of an ISO formated Locale. + @descr Its true for some linux derivates only :-( */ + static const sal_Unicode SEPERATOR_CV_LINUX; + + /** @short some predefined Locale objects. */ + static const Locale EN_US(); + static const Locale X_DEFAULT(); + static const Locale X_NOTRANSLATE(); + + //------------------------------------------- + // types + + public: + + /** @short will be throw during convertion, if a Locale cant be interpreted. */ + struct MalFormedLocaleException + { + public: + ::rtl::OUString Message; + + MalFormedLocaleException() + {} + + MalFormedLocaleException(const ::rtl::OUString& sMessage) + : Message(sMessage) + {} + }; + + //------------------------------------------- + // member + + private : + + //--------------------------------------- + /** @short must be a valid ISO Language Code. + + @descr These codes are the lower-case two-letter codes as defined by ISO-639. + You can find a full list of these codes at a number of sites, such as: + <BR><a href ="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt"> + http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a> + */ + ::rtl::OUString m_sLanguage; + + //--------------------------------------- + /** @short must be a valid ISO Country Code. + @descr These codes are the upper-case two-letter codes as defined by ISO-3166. + You can find a full list of these codes at a number of sites, such as: + <BR><a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html"> + http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</a> + */ + ::rtl::OUString m_sCountry; + + //--------------------------------------- + /** @short Variant codes are vendor and browser-specific. + @descr For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX. + Where there are two variants, separate them with an underscore, and + put the most important one first. For example, a Traditional Spanish collation + might be referenced, with "ES", "ES", "Traditional_WIN". + */ + ::rtl::OUString m_sVariant; + + //------------------------------------------- + // interface + + public : + + //--------------------------------------- + /** @short needed by outside users! + + @descr Otherwise it wouldnt be possible to use + any instance of such Locale static ... + */ + Locale(); + + //--------------------------------------- + /** @short construct a Locale from an ISO formated string value. + + @seealso fromISO() + + @param sISO + an ISO formated string value, which can be parsed and + tokenized into a Lamnguage, Country and Variant part. + + @throw MalFormedLocaleException + if conversion failed. + */ + Locale(const ::rtl::OUString& sISO) + throw(MalFormedLocaleException); + + //--------------------------------------- + /** @short construct a Locale from language, country and variant. + + @seealso setLanguage() + @seealso setCountry() + @seealso setVariant() + + @param sLanguage + lowercase two-letter ISO-639 code. + + @param sCountry + uppercase two-letter ISO-3166 code. + + @param sVariant + vendor and browser specific code. + */ + Locale(const ::rtl::OUString& sLanguage , + const ::rtl::OUString& sCountry , + const ::rtl::OUString& sVariant = ::rtl::OUString()); + + //--------------------------------------- + /** @short copy constructor. + + @param aCopy + the copy object. + */ + Locale(const Locale& aCopy); + + //--------------------------------------- + /** @short returns the language code for this locale. + + @descr That will either be the empty string or + a lowercase ISO 639 code. + + @return [string] + the language code. + */ + ::rtl::OUString getLanguage() const; + + //--------------------------------------- + /** @short returns the country/region code for this locale. + + @descr That will either be the empty string or an + upercase ISO 3166 2-letter code. + + @return [string] + the country code. + */ + ::rtl::OUString getCountry() const; + + //--------------------------------------- + /** @short returns the variant code for this locale. + + @return [string] + the variant code. + */ + ::rtl::OUString getVariant() const; + + //--------------------------------------- + /** @short set the new language code for this locale. + + @descr That will either be the empty string or + a lowercase ISO 639 code. + + @param sLanguage + the language code. + */ + void setLanguage(const ::rtl::OUString& sLanguage); + + //--------------------------------------- + /** @short set the new country/region code for this locale. + + @descr That will either be the empty string or an + upercase ISO 3166 2-letter code. + + @param sCountry + the country code. + */ + void setCountry(const ::rtl::OUString& sCountry); + + //--------------------------------------- + /** @short set the new variant code for this locale. + + @param sVariant + the variant code. + */ + void setVariant(const ::rtl::OUString& sVariant); + + //--------------------------------------- + /** @short take over new Locale informations. + + @seealso Locale(const ::rtl::OUString& sISO) + + @param sISO + an ISO formated string value, which can be parsed and + tokenized into a Lamnguage, Country and Variant part. + e.g. "en-US" or "en-US_WIN" + + @throw MalFormedLocaleException + if conversion failed. + */ + void fromISO(const ::rtl::OUString& sISO) + throw(MalFormedLocaleException); + + //--------------------------------------- + /** @short converts this Locale to an ISO formated string value. + + @descr The different parts of this Locale will be assempled + e.g. to "en-US" or "en-US_WIN" + + @return [string] + the ISO formated string. + */ + ::rtl::OUString toISO() const; + + //--------------------------------------- + /** @short check, if two Locale objects are equals. + + @descr All parts of a Locale (means Language, Country and Variant) + will be checked. + + @param aComparable + the Locale object for compare. + + @return [boolean] + TRUE if both objects uses the same values for + Language, Country and Variant. + */ + sal_Bool equals(const Locale& aComparable) const; + + //--------------------------------------- + /** @short check, if two Locale objects + uses the same language. + + @descr The Country and Variant parts of a Locale + wont be checked here. + + @return [boolean] + TRUE if both objects uses the same + Language value. + */ + sal_Bool similar(const Locale& aComparable) const; + + //--------------------------------------- + /** @short search for an equal or at least for a similar + Locale in a list of possible ones. + + @descr First it searches for a Locale, which is equals + to the reference Locale. + (means: same Language, Country, Variant) + + If the reference Locale couldnt be located, it will + tried again - but we are checking for "similar" Locales then. + (means: same Language) + + If no similar Locale could be located, we search + for a Locale "en-US" inside the given Locale list. + + If "en-US" could not be located, we search for + a Locale "en" inside the given list. + + If no "same" nor any "similar" locale could be found, + we try "x-default" and "x-notranslate" explicitly. + Sometimes localized variables are optimized and doesnt use + localzation realy. E.g. in case the localized value is a fix + product name. + + If no locale match till now, we use any other existing + locale, which exists inside the set of given ones! + + @seealso equals() + @seealso similar() + + @param lISOList + the list of possible Locales + (as formated ISO strings). + + @param sReferenceISO + the reference Locale, which should be searched + if its equals or similar to any Locale inside + the provided Locale list. + + @return An iterator, which points to the found element + inside the given Locale list. + If no matching Locale could be found, it points + to the end of the list. + + @throw [MalFormedLocaleException] + if at least one ISO formated string couldnt + be converted to a valid Locale Object. + */ + static ::std::vector< ::rtl::OUString >::const_iterator getFallback(const ::std::vector< ::rtl::OUString >& lISOList , + const ::rtl::OUString& sReferenceISO) + throw(MalFormedLocaleException); + + //--------------------------------------- + /** @short assign elements of another locale + to this instance. + + @param rCopy + another locale object. + */ + void operator=(const Locale& rCopy); + + //--------------------------------------- + /** @short check if two Locale objects are equals. + + @seealso equals() + + @param aComparable + the Locale object for compare. + + @return [boolean] + TRUE if both objects uses the same values for + Language, Country and Variant. + */ + sal_Bool operator==(const Locale& aComparable) const; + + //--------------------------------------- + /** @short check if two Locale objects are different. + + @param aComparable + the Locale object for compare. + + @return [boolean] + TRUE if at least one part of such Locale + isnt the same. + */ + sal_Bool operator!=(const Locale& aComparable) const; +}; + +} // namespace salhelper + +#endif // _COMPHELPER_LOCALE_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/logging.hxx b/comphelper/inc/comphelper/logging.hxx new file mode 100644 index 000000000000..e332f0541594 --- /dev/null +++ b/comphelper/inc/comphelper/logging.hxx @@ -0,0 +1,797 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_LOGGING_HXX +#define COMPHELPER_LOGGING_HXX + +#include <comphelper/comphelperdllapi.h> + +/** === begin UNO includes === **/ +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/logging/XLogHandler.hpp> +#include <com/sun/star/logging/LogLevel.hpp> +/** === end UNO includes === **/ + +#include <boost/shared_ptr.hpp> +#include <boost/optional.hpp> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //==================================================================== + //= string conversions, employed by the templatized log* members of + //= EventLogger + //==================================================================== + + namespace log { namespace convert + { + inline const ::rtl::OUString& convertLogArgToString( const ::rtl::OUString& _rValue ) + { + return _rValue; + } + + inline ::rtl::OUString convertLogArgToString( const sal_Char* _pAsciiValue ) + { + return ::rtl::OUString::createFromAscii( _pAsciiValue ); + } + + inline ::rtl::OUString convertLogArgToString( double _nValue ) { return ::rtl::OUString::valueOf( _nValue ); } + inline ::rtl::OUString convertLogArgToString( float _nValue ) { return ::rtl::OUString::valueOf( _nValue ); } + inline ::rtl::OUString convertLogArgToString( sal_Int64 _nValue ) { return ::rtl::OUString::valueOf( _nValue ); } + inline ::rtl::OUString convertLogArgToString( sal_Int32 _nValue ) { return ::rtl::OUString::valueOf( _nValue ); } + inline ::rtl::OUString convertLogArgToString( sal_Int16 _nValue ) { return ::rtl::OUString::valueOf( (sal_Int32)_nValue ); } + inline ::rtl::OUString convertLogArgToString( sal_Unicode _nValue ) { return ::rtl::OUString::valueOf( _nValue ); } + inline ::rtl::OUString convertLogArgToString( sal_Bool _nValue ) { return ::rtl::OUString::valueOf( _nValue ); } + + } } // namespace log::convert + + //==================================================================== + //= EventLogger + //==================================================================== + class EventLogger_Impl; + typedef ::boost::optional< ::rtl::OUString > OptionalString; + + /** encapsulates an <type scope="com::sun::star::logging">XLogger</type> + + The class silences several (unlikely) errors which could potentially happen + when working with a logger. Additionally, it provides some convenience methods + for logging events. + + You can use this class as follows +<pre> + EventLogger aLogger( xContext, sLoggerName ); + .... + aLogger.log( LogLevel::SEVERE, sSomeMessage ); + aLogger.logp( LogLevel::CONFIG, "MyClass", "MyMethod", sSomeMessage, SomeParameter1, SomeParameter2, SomeParameter3 ); +</pre> + + The <code>log</code> and <code>logp</code> calls support up to 6 parameters, which can be of + arbitrary type. For every parameter, there must exist a function <code>convertLogArgToString</code> + which takes an argument of the respective type, and returns a string. + + After a parameter has been converted to a string using the above mentioned + <code>convertLogArgToString</code> function, a placeholder $1$ (resp. $2$ resp. $4$ ...) + in the message will be replaced with this string, and the resulting message will be logged. + */ + class COMPHELPER_DLLPUBLIC EventLogger + { + protected: + ::boost::shared_ptr< EventLogger_Impl > m_pImpl; + + public: + /** creates an <code>EventLogger</code> instance working with a css.logging.XLogger + instance given by name. + + @param _rxContext + the component context to create services + @param _rLoggerName + the name of the logger to create. If empty, the office-wide default logger will be used. + */ + EventLogger( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext, + const ::rtl::OUString& _rLoggerName = ::rtl::OUString() + ); + + /** creates an <code>EventLogger</code> instance working with a css.logging.XLogger + instance given by ASCII name. + + @param _rxContext + the component context to create services + + @param _rLoggerName + the ASCII name of the logger to create. + */ + EventLogger( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext, + const sal_Char* _pAsciiLoggerName + ); + + ~EventLogger(); + + public: + /** returns the name of the logger + */ + const ::rtl::OUString& getName() const; + + /// returns the current log level threshold of the logger + sal_Int32 getLogLevel() const; + + /// sets a new log level threshold of the logger + void setLogLevel( const sal_Int32 _nLogLevel ) const; + + /// determines whether an event with the given level would be logged + bool isLoggable( const sal_Int32 _nLogLevel ) const; + + /** adds the given log handler to the logger's set of handlers. + + Note that normally, you would not use this method: The logger implementations + initialize themselves from the configuration, where usually, a default log handler + is specified. In this case, the logger will create and use this handler. + + @return + <TRUE/> if and only if the addition was successful (as far as this can be detected + from outside the <code>XLogger</code>'s implementation. + */ + bool addLogHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::logging::XLogHandler >& _rxLogHandler ); + + /** removes the given log handler from the logger's set of handlers. + + @return + <TRUE/> if and only if the addition was successful (as far as this can be detected + from outside the <code>XLogger</code>'s implementation. + */ + bool removeLogHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::logging::XLogHandler >& _rxLogHandler ); + + //---------------------------------------------------------------- + //- XLogger::log equivalents/wrappers + //- string messages + + /// logs a given message, without any arguments, or source class/method names + bool log( const sal_Int32 _nLogLevel, const ::rtl::OUString& _rMessage ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, _rMessage ); + return false; + } + + /** logs a given message, replacing a placeholder in the message with an argument + + The function takes, additionally to the log level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + bool log( const sal_Int32 _nLogLevel, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + return false; + } + + /// logs a given message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + bool log( const sal_Int32 _nLogLevel, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + return false; + } + + /// logs a given message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + bool log( const sal_Int32 _nLogLevel, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + return false; + } + + /// logs a given message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + bool log( const sal_Int32 _nLogLevel, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + return false; + } + + /// logs a given message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + bool log( const sal_Int32 _nLogLevel, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + return false; + } + + /// logs a given message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + bool log( const sal_Int32 _nLogLevel, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + return false; + } + + //---------------------------------------------------------------- + //- XLogger::log equivalents/wrappers + //- ASCII messages + + /// logs a given message, without any arguments, or source class/method names + bool log( const sal_Int32 _nLogLevel, const sal_Char* _pMessage ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, ::rtl::OUString::createFromAscii( _pMessage ) ); + return false; + } + + /** logs a given message, replacing a placeholder in the message with an argument + + The function takes, additionally to the log level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + bool log( const sal_Int32 _nLogLevel, const sal_Char* _pMessage, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, ::rtl::OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + return false; + } + + /// logs a given message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + bool log( const sal_Int32 _nLogLevel, const sal_Char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, ::rtl::OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + return false; + } + + /// logs a given message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + bool log( const sal_Int32 _nLogLevel, const sal_Char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, ::rtl::OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + return false; + } + + /// logs a given message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + bool log( const sal_Int32 _nLogLevel, const sal_Char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, ::rtl::OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + return false; + } + + /// logs a given message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + bool log( const sal_Int32 _nLogLevel, const sal_Char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, ::rtl::OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + return false; + } + + /// logs a given message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + bool log( const sal_Int32 _nLogLevel, const sal_Char* _pMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, ::rtl::OUString::createFromAscii( _pMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + return false; + } + + //---------------------------------------------------------------- + //- XLogger::logp equivalents/wrappers + //- string messages + + /// logs a given message, without any arguments, or source class/method names + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const ::rtl::OUString& _rMessage ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage ); + return false; + } + + /** logs a given message, replacing a placeholder in the message with an argument + + The function takes, additionally to the logp level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + return false; + } + + /// logs a given message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + return false; + } + + /// logs a given message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + return false; + } + + /// logs a given message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + return false; + } + + /// logs a given message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + return false; + } + + /// logs a given message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const ::rtl::OUString& _rMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, _rMessage, + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + return false; + } + + //---------------------------------------------------------------- + //- XLogger::logp equivalents/wrappers + //- ASCII messages + + /// logs a given ASCII message, without any arguments, or source class/method names + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Char* _pAsciiMessage ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, ::rtl::OUString::createFromAscii( _pAsciiMessage ) ); + return false; + } + + /** logs a given ASCII message, replacing a placeholder in the message with an argument + + The function takes, additionally to the logp level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Char* _pAsciiMessage, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, ::rtl::OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, ::rtl::OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, ::rtl::OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, ::rtl::OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, ::rtl::OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Char* _pAsciiMessage, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, ::rtl::OUString::createFromAscii( _pAsciiMessage ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + return false; + } + + protected: + bool impl_log( + const sal_Int32 _nLogLevel, + const sal_Char* _pSourceClass, + const sal_Char* _pSourceMethod, + const ::rtl::OUString& _rMessage, + const OptionalString& _rArgument1 = OptionalString(), + const OptionalString& _rArgument2 = OptionalString(), + const OptionalString& _rArgument3 = OptionalString(), + const OptionalString& _rArgument4 = OptionalString(), + const OptionalString& _rArgument5 = OptionalString(), + const OptionalString& _rArgument6 = OptionalString() + ) const; + }; + + //==================================================================== + //= ResourceBasedEventLogger + //==================================================================== + struct ResourceBasedEventLogger_Data; + /** extends the EventLogger class with functionality to load log messages from + a resource bundle. + */ + class COMPHELPER_DLLPUBLIC ResourceBasedEventLogger : public EventLogger + { + private: + ::boost::shared_ptr< ResourceBasedEventLogger_Data > m_pData; + + public: + /** creates a resource based event logger + @param _rxContext + the component context for creating new components + @param _rResourceBundleBaseName + the base name of the resource bundle to use. Will be used + in conjunction with XResourceBundleLoader::loadResource. + @param _rLoggerName + the name of the logger to work with. If empty, the office-wide + default logger will be used. + + */ + ResourceBasedEventLogger( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext, + const ::rtl::OUString& _rResourceBundleBaseName, + const ::rtl::OUString& _rLoggerName = ::rtl::OUString() + ); + + /** creates a resource based event logger + @param _rxContext + the component context for creating new components + @param _pResourceBundleBaseName + the ASCII base name of the resource bundle to use. Will be used + in conjunction with XResourceBundleLoader::loadResource. + @param _pAsciiLoggerName + the ASCII name of the logger to work with. If NULL, the office-wide + default logger will be used. + + */ + ResourceBasedEventLogger( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext, + const sal_Char* _pResourceBundleBaseName, + const sal_Char* _pAsciiLoggerName = NULL + ); + + //---------------------------------------------------------------- + //- XLogger::log equivalents/wrappers + //- resource IDs + + /// logs a given message, without any arguments, or source class/method names + bool log( const sal_Int32 _nLogLevel, const sal_Int32 _nMessageResID ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, impl_loadStringMessage_nothrow( _nMessageResID ) ); + return false; + } + + /** logs a given message, replacing a placeholder in the message with an argument + + The function takes, additionally to the log level and the message, an arbitrary + argument. This argument is converted to a string using an overloaded function + named <code>convertLogArgToString</code>. Then, a placeholder "$1$" + is searched in the message string, and replaced with the argument string. + */ + template< typename ARGTYPE1 > + bool log( const sal_Int32 _nLogLevel, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + return false; + } + + /// logs a given message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + bool log( const sal_Int32 _nLogLevel, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + return false; + } + + /// logs a given message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + bool log( const sal_Int32 _nLogLevel, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + return false; + } + + /// logs a given message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + bool log( const sal_Int32 _nLogLevel, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + return false; + } + + /// logs a given message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + bool log( const sal_Int32 _nLogLevel, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + return false; + } + + /// logs a given message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + bool log( const sal_Int32 _nLogLevel, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, NULL, NULL, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + return false; + } + + //---------------------------------------------------------------- + //- XLogger::logp equivalents/wrappers + //- resource IDs + + /// logs a given ASCII message, without any arguments, or source class/method names + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Int32 _nMessageResID ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, impl_loadStringMessage_nothrow( _nMessageResID ) ); + return false; + } + + /** logs a given ASCII message, replacing a placeholder in the message with an argument + */ + template< typename ARGTYPE1 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 2 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 3 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 4 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 5 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ) ); + return false; + } + + /// logs a given ASCII message, replacing 6 placeholders in the message with respective values + template< typename ARGTYPE1, typename ARGTYPE2, typename ARGTYPE3, typename ARGTYPE4, typename ARGTYPE5, typename ARGTYPE6 > + bool logp( const sal_Int32 _nLogLevel, const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const sal_Int32 _nMessageResID, ARGTYPE1 _argument1, ARGTYPE2 _argument2, ARGTYPE3 _argument3, ARGTYPE4 _argument4, ARGTYPE5 _argument5, ARGTYPE6 _argument6 ) const + { + if ( isLoggable( _nLogLevel ) ) + return impl_log( _nLogLevel, _pSourceClass, _pSourceMethod, impl_loadStringMessage_nothrow( _nMessageResID ), + OptionalString( log::convert::convertLogArgToString( _argument1 ) ), + OptionalString( log::convert::convertLogArgToString( _argument2 ) ), + OptionalString( log::convert::convertLogArgToString( _argument3 ) ), + OptionalString( log::convert::convertLogArgToString( _argument4 ) ), + OptionalString( log::convert::convertLogArgToString( _argument5 ) ), + OptionalString( log::convert::convertLogArgToString( _argument6 ) ) ); + return false; + } + + private: + ::rtl::OUString impl_loadStringMessage_nothrow( const sal_Int32 _nMessageResID ) const; + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_LOGGING_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/make_shared_from_uno.hxx b/comphelper/inc/comphelper/make_shared_from_uno.hxx new file mode 100644 index 000000000000..4cbb3a17c362 --- /dev/null +++ b/comphelper/inc/comphelper/make_shared_from_uno.hxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_MAKE_SHARED_FROM_UNO_HXX) +#define INCLUDED_COMPHELPER_MAKE_SHARED_FROM_UNO_HXX + +#include "boost/shared_ptr.hpp" +#include <functional> + +namespace comphelper { + +/// @internal +namespace detail { +/// @internal +template <typename T> struct ReleaseFunc : ::std::unary_function<T *, void> { + void operator()( T * p ) const { p->release(); } +}; +} // namespace detail + +/** Makes a boost::shared_ptr from a ref-counted UNO object pointer. + This makes sense if the object is used via UNO (implementing some X + interface) and also internally using its implementation class, e.g. + + <pre> + boost::shared_ptr<MyUnoImpl> const ptr( + comphelper::make_shared_from_UNO( new MyUnoImpl ) ); + ... + xUno->callingUno( uno::Reference<XSomeInterface>( ptr.get() ) ); + ... + takeSharedPtr( ptr ); + ... + </pre> + + @attention The shared_ptr operates on a separate reference counter, so + weak pointers (boost::weak_ptr) are invalidated when the last + shared_ptr is destroyed, although the UNO object may still be + alive. + + @param p object pointer + @return shared_ptr to object +*/ +template <typename T> +inline ::boost::shared_ptr<T> make_shared_from_UNO( T * p ) +{ + p->acquire(); + return ::boost::shared_ptr<T>( p, detail::ReleaseFunc<T>() ); +} + +} // namespace comphelper + +#endif // ! defined(INCLUDED_COMPHELPER_MAKE_SHARED_FROM_UNO_HXX) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/makesequence.hxx b/comphelper/inc/comphelper/makesequence.hxx new file mode 100644 index 000000000000..d4e724309e94 --- /dev/null +++ b/comphelper/inc/comphelper/makesequence.hxx @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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(COMPHELPER_MAKESEQUENCE_HXX_INCLUDED) +#define COMPHELPER_MAKESEQUENCE_HXX_INCLUDED + +#include "com/sun/star/uno/Sequence.hxx" +#include "boost/preprocessor/cat.hpp" +#include "boost/preprocessor/repetition.hpp" +#include "boost/preprocessor/arithmetic/add.hpp" + +namespace comphelper { + +/** Creates a uno::Sequence out of one parameter. +*/ +template <typename T> +inline ::com::sun::star::uno::Sequence<T> makeSequence( T const& element ) +{ + return ::com::sun::star::uno::Sequence<T>( &element, 1 ); +} + +#define COMPHELPER_MAKESEQUENCE_assign(z_, n_, unused_) \ + p[n_] = BOOST_PP_CAT(element, n_); + +/** The following preprocessor repetitions generate functions like + + <pre> + template <typename T> + inline ::com::sun::star::uno::Sequence<T> makeSequence( + T const& element0, T const& element1, ... ); + </pre> + + which make a sequence out of the passed elements. + + The maximum number of elements can be set by defining + COMPHELPER_MAKESEQUENCE_MAX_ARGS; its default is 12. +*/ +#define COMPHELPER_MAKESEQUENCE_make(z_, n_, unused_) \ +template <typename T> \ +inline ::com::sun::star::uno::Sequence<T> makeSequence( \ + BOOST_PP_ENUM_PARAMS(n_, T const& element) ) \ +{ \ + ::com::sun::star::uno::Sequence<T> seq( n_ ); \ + T * p = seq.getArray(); \ + BOOST_PP_REPEAT(n_, COMPHELPER_MAKESEQUENCE_assign, ~) \ + return seq; \ +} + +#if ! defined(COMPHELPER_MAKESEQUENCE_MAX_ARGS) +#define COMPHELPER_MAKESEQUENCE_MAX_ARGS 12 +#endif + +BOOST_PP_REPEAT_FROM_TO(2, BOOST_PP_ADD(COMPHELPER_MAKESEQUENCE_MAX_ARGS, 1), + COMPHELPER_MAKESEQUENCE_make, ~) + +#undef COMPHELPER_MAKESEQUENCE_MAX_ARGS +#undef COMPHELPER_MAKESEQUENCE_make +#undef COMPHELPER_MAKESEQUENCE_assign + +} // namespace comphelper + +#endif // ! defined(COMPHELPER_MAKESEQUENCE_HXX_INCLUDED) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/mediadescriptor.hxx b/comphelper/inc/comphelper/mediadescriptor.hxx new file mode 100644 index 000000000000..55b89a25fdf8 --- /dev/null +++ b/comphelper/inc/comphelper/mediadescriptor.hxx @@ -0,0 +1,327 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_MEDIADESCRIPTOR_HXX_ +#define _COMPHELPER_MEDIADESCRIPTOR_HXX_ + +//_______________________________________________ +// includes + +#include <comphelper/sequenceashashmap.hxx> +#include <rtl/ustring.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace com { namespace sun { namespace star { namespace io { + class XInputStream; +} } } } + +//_______________________________________________ +// namespace + +namespace comphelper{ + +//_______________________________________________ +// definitions + +/** @short can be used to work with a <type scope="::com::sun::star::document">MediaDescriptor</type> + struct. + + @descr It wraps a ::boost::unordered_map around the Sequence< css::beans::PropertyValue >, which + represent the MediaDescriptor item. + Further this helper defines often used functions (as e.g. open of the required streams, + consistent checks etcpp.) and it defines all useable property names. + + @attention This class isnt threadsafe and must be guarded from outside! + */ +class COMPHELPER_DLLPUBLIC MediaDescriptor : public SequenceAsHashMap +{ + //------------------------------------------- + // const + public: + + //--------------------------------------- + /** @short these methods can be used to get the different property names + as static const OUString values. + + @descr Because definition and declaration of static const class members + does not work as expected under windows (under unix it works as well) + these way must be used :-( + */ + static const ::rtl::OUString& PROP_ABORTED(); + static const ::rtl::OUString& PROP_ASTEMPLATE(); + static const ::rtl::OUString& PROP_COMPONENTDATA(); + static const ::rtl::OUString& PROP_DOCUMENTSERVICE(); + static const ::rtl::OUString& PROP_ENCRYPTIONDATA(); + static const ::rtl::OUString& PROP_FILENAME(); + static const ::rtl::OUString& PROP_FILTERNAME(); + static const ::rtl::OUString& PROP_FILTEROPTIONS(); + static const ::rtl::OUString& PROP_FRAME(); + static const ::rtl::OUString& PROP_FRAMENAME(); + static const ::rtl::OUString& PROP_HIDDEN(); + static const ::rtl::OUString& PROP_INPUTSTREAM(); + static const ::rtl::OUString& PROP_INTERACTIONHANDLER(); + static const ::rtl::OUString& PROP_JUMPMARK(); + static const ::rtl::OUString& PROP_MACROEXECUTIONMODE(); + static const ::rtl::OUString& PROP_MEDIATYPE(); + static const ::rtl::OUString& PROP_MINIMIZED(); + static const ::rtl::OUString& PROP_NOAUTOSAVE(); + static const ::rtl::OUString& PROP_OPENNEWVIEW(); + static const ::rtl::OUString& PROP_OUTPUTSTREAM(); + static const ::rtl::OUString& PROP_PASSWORD(); + static const ::rtl::OUString& PROP_POSTDATA(); + static const ::rtl::OUString& PROP_PREVIEW(); + static const ::rtl::OUString& PROP_READONLY(); + static const ::rtl::OUString& PROP_REFERRER(); + static const ::rtl::OUString& PROP_SALVAGEDFILE(); + static const ::rtl::OUString& PROP_STATUSINDICATOR(); + static const ::rtl::OUString& PROP_STREAM(); + static const ::rtl::OUString& PROP_STREAMFOROUTPUT(); + static const ::rtl::OUString& PROP_TEMPLATENAME(); + static const ::rtl::OUString& PROP_TITLE(); + static const ::rtl::OUString& PROP_TYPENAME(); + static const ::rtl::OUString& PROP_UCBCONTENT(); + static const ::rtl::OUString& PROP_UPDATEDOCMODE(); + static const ::rtl::OUString& PROP_URL(); + static const ::rtl::OUString& PROP_VERSION(); + static const ::rtl::OUString& PROP_DOCUMENTTITLE(); + static const ::rtl::OUString& PROP_MODEL(); + static const ::rtl::OUString& PROP_VIEWONLY(); + static const ::rtl::OUString& PROP_DOCUMENTBASEURL(); + + //------------------------------------------- + // interface + public: + //--------------------------------------- + /** @short these ctors do nothing - excepting that they forward + the given parameters to the base class ctors. + + @descr The ctros must be overwritten to resolve conflicts with + the default ctors of the compiler :-(. + */ + MediaDescriptor(); + MediaDescriptor(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lSource); + + //--------------------------------------- + /** @short it checks if the descriptor already has a valid + InputStream item and creates a new one, if not. + + @descr This method uses the current items of this MediaDescriptor, + to open the stream (as e.g. URL, ReadOnly, PostData etcpp.). + It creates a seekable stream and put it into the descriptor. + + A might existing InteractionHandler will be used automaticly, + to solve problems! + + In case of local file the system file locking is used. + + @return TRUE, if the stream was already part of the descriptor or could + be created as new item. FALSE otherwhise. + */ + sal_Bool addInputStream(); + + //--------------------------------------- + /** @short it checks if the descriptor already has a valid + InputStream item and creates a new one, if not. + + @descr This method uses the current items of this MediaDescriptor, + to open the stream (as e.g. URL, ReadOnly, PostData etcpp.). + It creates a seekable stream and put it into the descriptor. + + A might existing InteractionHandler will be used automaticly, + to solve problems! + + In case of local file the system file locking is used based on + configuration settings. + + @return TRUE, if the stream was already part of the descriptor or could + be created as new item. FALSE otherwhise. + */ + sal_Bool addInputStreamOwnLock(); + + //--------------------------------------- + /** @short it checks if the descriptor describes a readonly stream. + + @descr The descriptor itself isnt changed doing so. + It's only checked if the stream seems to be based + of a real readonly file. + + @Attention + We dont check the property "ReadOnly" here. Because + this property can be set from outside and overwrites + the readonly state of the stream. + If e.g. the stream could be opened read/write ... + but "ReadOnly" property is set to TRUE, this means: + show a readonly UI on top of this read/write stream. + + @return TRUE, if the stream must be interpreted as readonly ... + FALSE otherwhise. + */ + sal_Bool isStreamReadOnly() const; + + //--------------------------------------- + /** Returns a value from the sequence contained in the property + 'ComponentData' of this media descriptor. + + @descr The property 'ComponentData' should be empty, or should + contain a value of type sequence<com.sun.star.beans.NamedValue> + or sequence<com.sun.star.beans.PropertyValue>. + + @return The value with the specified name, if existing in the + sequence of the 'ComponentData' property, otherwise an empty + Any. + */ + ::com::sun::star::uno::Any getComponentDataEntry( + const ::rtl::OUString& rName ) const; + + //--------------------------------------- + /** Inserts a value into the sequence contained in the property + 'ComponentData' of the media descriptor. + + @descr The property 'ComponentData' should be empty, or should + contain a value of type sequence<com.sun.star.beans.NamedValue> + or sequence<com.sun.star.beans.PropertyValue>. The passed value + will be inserted into the sequence, or, if already existing, + will be overwritten. + + @param rName The name of the value to be inserted into the + sequence of the 'ComponentData' property. + + @param rValue The value to be inserted into the sequence of the + 'ComponentData' property. + */ + void setComponentDataEntry( + const ::rtl::OUString& rName, + const ::com::sun::star::uno::Any& rValue ); + + //--------------------------------------- + /** Removes a value from the sequence contained in the property + 'ComponentData' of the media descriptor. + + @descr The property 'ComponentData' should be empty, or should + contain a value of type sequence<com.sun.star.beans.NamedValue> + or sequence<com.sun.star.beans.PropertyValue>. The value with + the passed name will be removed from the sequence, if existing. + + @param rName The name of the value to be removed from the sequence + of the 'ComponentData' property. + */ + void clearComponentDataEntry( + const ::rtl::OUString& rName ); + + //------------------------------------------- + // helper + private: + + //--------------------------------------- + /** @short tries to open a stream by using the given PostData stream. + + @descr The stream is used directly ... + + The MediaDescriptor itself is changed inside this method. + Means: the stream is added internal and not returned by a value. + + @param _rxPostData + the PostData stream. + + @return TRUE if the stream could be added successfully. + Note: If FALSE is returned, the error was already handled inside! + + @throw [css::uno::RuntimeException] + if the MediaDescriptor seems to be invalid! + + @throw [css::lang::IllegalArgumentException] + if the given PostData stream is <NULL/>. + */ + COMPHELPER_DLLPRIVATE sal_Bool impl_openStreamWithPostData( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& _rxPostData + ) throw(::com::sun::star::uno::RuntimeException); + + //--------------------------------------- + /** @short tries to open a stream by using the given URL. + + @descr First it tries to open the content in r/w mode (if its + allowed to do so). Only in case its not allowed or it failed + the stream will be tried to open in readonly mode. + + The MediaDescriptor itself is changed inside this method. + Means: the stream is added internal and not returned by a value. + + @param sURL + the URL for open. + + @param bLockFile + specifies whether the file should be locked + + @return TRUE if the stream could be added successfully. + Note: If FALSE is returned, the error was already handled inside! + + @throw [css::uno::RuntimeException] + if the MediaDescriptor seems to be invalid! + */ + COMPHELPER_DLLPRIVATE sal_Bool impl_openStreamWithURL( + const ::rtl::OUString& sURL, + sal_Bool bLockFile + ) throw(::com::sun::star::uno::RuntimeException); + + //--------------------------------------- + /** @short some URL parts can make trouble for opening streams (e.g. jumpmarks.) + An URL should be "normalized" before its used. + + @param sURL + the original URL (e.g. including a jumpmark) + + @return [string] + the "normalized" URL (e.g. without jumpmark) + */ + COMPHELPER_DLLPRIVATE ::rtl::OUString impl_normalizeURL(const ::rtl::OUString& sURL); + + //--------------------------------------- + /** @short it checks if the descriptor already has a valid + InputStream item and creates a new one, if not. + + @descr This method uses the current items of this MediaDescriptor, + to open the stream (as e.g. URL, ReadOnly, PostData etcpp.). + It creates a seekable stream and put it into the descriptor. + + A might existing InteractionHandler will be used automaticly, + to solve problems! + + @param bLockFile + specifies whether the file should be locked + + @return TRUE, if the stream was already part of the descriptor or could + be created as new item. FALSE otherwhise. + */ + COMPHELPER_DLLPRIVATE sal_Bool impl_addInputStream( sal_Bool bLockFile ); +}; + +} // namespace comphelper + +#endif // _COMPHELPER_MEDIADESCRIPTOR_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/mimeconfighelper.hxx b/comphelper/inc/comphelper/mimeconfighelper.hxx new file mode 100644 index 000000000000..992f367d67df --- /dev/null +++ b/comphelper/inc/comphelper/mimeconfighelper.hxx @@ -0,0 +1,150 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_MIMECONFIGHELPER_HXX_ +#define _COMPHELPER_MIMECONFIGHELPER_HXX_ + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XContainerQuery.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/embed/VerbDescriptor.hpp> +#include "comphelper/comphelperdllapi.h" + + +namespace comphelper { + +class COMPHELPER_DLLPUBLIC MimeConfigurationHelper +{ + ::osl::Mutex m_aMutex; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xConfigProvider; + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xObjectConfig; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xVerbsConfig; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xMediaTypeConfig; + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xFilterFactory; + +public: + + MimeConfigurationHelper( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ); + + + static ::rtl::OUString GetStringClassIDRepresentation( const ::com::sun::star::uno::Sequence< sal_Int8 >& aClassID ); + + static ::com::sun::star::uno::Sequence< sal_Int8 > GetSequenceClassIDRepresentation( const ::rtl::OUString& aClassID ); + + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > + GetConfigurationByPath( const ::rtl::OUString& aPath ); + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > GetObjConfiguration(); + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > GetVerbsConfiguration(); + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > GetMediaTypeConfiguration(); + + + ::rtl::OUString GetDocServiceNameFromFilter( const ::rtl::OUString& aFilterName ); + + ::rtl::OUString GetDocServiceNameFromMediaType( const ::rtl::OUString& aMediaType ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetObjPropsFromConfigEntry( + const ::com::sun::star::uno::Sequence< sal_Int8 >& aClassID, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xObjectProps ); + + sal_Bool GetVerbByShortcut( const ::rtl::OUString& aVerbShortcut, + ::com::sun::star::embed::VerbDescriptor& aDescriptor ); + + ::rtl::OUString GetExplicitlyRegisteredObjClassID( const ::rtl::OUString& aMediaType ); + + + // retrieving object description from configuration + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetObjectPropsByStringClassID( + const ::rtl::OUString& aStringClassID ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetObjectPropsByClassID( + const ::com::sun::star::uno::Sequence< sal_Int8 >& aClassID ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetObjectPropsByMediaType( + const ::rtl::OUString& aMediaType ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetObjectPropsByFilter( + const ::rtl::OUString& aFilterName ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetObjectPropsByDocumentName( + const ::rtl::OUString& aDocumentName ); + + // retrieving object factory from configuration + ::rtl::OUString GetFactoryNameByStringClassID( const ::rtl::OUString& aStringClassID ); + ::rtl::OUString GetFactoryNameByClassID( const ::com::sun::star::uno::Sequence< sal_Int8 >& aClassID ); + ::rtl::OUString GetFactoryNameByDocumentName( const ::rtl::OUString& aDocName ); + ::rtl::OUString GetFactoryNameByMediaType( const ::rtl::OUString& aMediaType ); + + // typedetection related + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > GetFilterFactory(); + + sal_Int32 GetFilterFlags( const ::rtl::OUString& aFilterName ); + + ::rtl::OUString UpdateMediaDescriptorWithFilterName( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aMediaDescr, + sal_Bool bIgnoreType ); + ::rtl::OUString UpdateMediaDescriptorWithFilterName( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aMediaDescr, + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aObject ); + sal_Bool AddFilterNameCheckOwnFile( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aMediaDescr ); + + ::rtl::OUString GetDefaultFilterFromServiceName( const ::rtl::OUString& aServName, sal_Int32 nVersion ); + + ::rtl::OUString GetExportFilterFromImportFilter( const ::rtl::OUString& aImportFilterName ); + + static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SearchForFilter( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery >& xFilterQuery, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aSearchRequest, + sal_Int32 nMustFlags, + sal_Int32 nDontFlags ); + + static sal_Bool ClassIDsEqual( const ::com::sun::star::uno::Sequence< sal_Int8 >& aClassID1, + const ::com::sun::star::uno::Sequence< sal_Int8 >& aClassID2 ); + static ::com::sun::star::uno::Sequence< sal_Int8 > GetSequenceClassID( sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3, + sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11, + sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15 ); + + ::com::sun::star::uno::Sequence<sal_Int8> GetSequenceClassIDFromObjectName(const ::rtl::OUString& _sObjectName) ; + +}; + +} + +#endif // _COMPHELPER_MIMECONFIGHELPER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/namecontainer.hxx b/comphelper/inc/comphelper/namecontainer.hxx new file mode 100644 index 000000000000..b251c553efd2 --- /dev/null +++ b/comphelper/inc/comphelper/namecontainer.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_NAMECONTAINER_HXX_ +#define _COMPHELPER_NAMECONTAINER_HXX_ + +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > + NameContainer_createInstance( ::com::sun::star::uno::Type aType ); +} + +#endif // _COMPHELPER_NAMECONTAINER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/namedvaluecollection.hxx b/comphelper/inc/comphelper/namedvaluecollection.hxx new file mode 100644 index 000000000000..6ec12a6aa5c2 --- /dev/null +++ b/comphelper/inc/comphelper/namedvaluecollection.hxx @@ -0,0 +1,369 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_NAMEDVALUECOLLECTION_HXX +#define COMPHELPER_NAMEDVALUECOLLECTION_HXX + +#include <comphelper/comphelperdllapi.h> + +/** === begin UNO includes === **/ +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +/** === end UNO includes === **/ + +#include <memory> +#include <algorithm> +#include <vector> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + // ==================================================================== + // = NamedValueCollection + // ==================================================================== + struct NamedValueCollection_Impl; + /** a collection of named values, packed in various formats. + */ + class COMPHELPER_DLLPUBLIC NamedValueCollection + { + private: + ::std::auto_ptr< NamedValueCollection_Impl > m_pImpl; + + public: + NamedValueCollection(); + + NamedValueCollection( const NamedValueCollection& _rCopySource ); + + NamedValueCollection& operator=( const NamedValueCollection& i_rCopySource ); + + /** constructs a collection + @param _rElements + the wrapped elements of the collection. The <code>Any</code> might contain a sequence of + property values, a sequence of named values, or directly a property value or named value. + All other cases are worth an assertion in non-product builds. + */ + NamedValueCollection( const ::com::sun::star::uno::Any& _rElements ); + + /** constructs a collection + @param _rArguments + a sequence of Any's containing either PropertyValue's or NamedValue's. + */ + NamedValueCollection( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments ); + + /** constructs a collection + @param _rArguments + a sequence of PropertyValues's + */ + NamedValueCollection( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArguments ); + + /** constructs a collection + @param _rArguments + a sequence of NamedValue's + */ + NamedValueCollection( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _rArguments ); + + ~NamedValueCollection(); + + inline void assign( const ::com::sun::star::uno::Any& i_rWrappedElements ) + { + impl_assign( i_rWrappedElements ); + } + + inline void assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments ) + { + impl_assign( _rArguments ); + } + + inline void assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArguments ) + { + impl_assign( _rArguments ); + } + + inline void assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _rArguments ) + { + impl_assign( _rArguments ); + } + + inline void clear() + { + impl_assign( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >() ); + } + + /// returns the number of elements in the collection + size_t size() const; + + /// determines whether the collection is empty + bool empty() const; + + /** returns the names of all elements in the collection + */ + ::std::vector< ::rtl::OUString > + getNames() const; + + /** merges the content of another collection into |this| + @param _rAdditionalValues + the collection whose values are to be merged + @param _bOverwriteExisting + defines whether or not elements which are already present in |this| + should be overwritten (<TRUE/>) or preserved (<FALSE/>). + @return |*this| + */ + NamedValueCollection& + merge( + const NamedValueCollection& _rAdditionalValues, + bool _bOverwriteExisting + ); + + /** retrieves a value with a given name from the collection, if it is present + + @param _pAsciiValueName + the ASCII name of the value to retrieve + + @param _out_rValue + is the output parameter taking the desired value upon successful return. If + a value with the given name is not present in the collection, or if a wrong-typed + value is present, then this parameter will not be touched. + + @return + <TRUE/> if there is a value with the given name, which could successfully + be extraced. In this case, <arg>_out_rValue</arg> will contain the requested + value.<br/> + <FALSE/>, if there is no value with the given name. + @throws IllegalArgumentException + in case there is a value with the given name, but it cannot legally assigned to + _out_rValue. + */ + template < typename VALUE_TYPE > + bool get_ensureType( const sal_Char* _pAsciiValueName, VALUE_TYPE& _out_rValue ) const + { + return get_ensureType( ::rtl::OUString::createFromAscii( _pAsciiValueName ), &_out_rValue, ::cppu::UnoType< VALUE_TYPE >::get() ); + } + + template < typename VALUE_TYPE > + bool get_ensureType( const ::rtl::OUString& _rValueName, VALUE_TYPE& _out_rValue ) const + { + return get_ensureType( _rValueName, &_out_rValue, ::cppu::UnoType< VALUE_TYPE >::get() ); + } + + /** retrieves a value with a given name, or defaults it to a given value, if its not present + in the colllection + */ + template < typename VALUE_TYPE > + VALUE_TYPE getOrDefault( const sal_Char* _pAsciiValueName, const VALUE_TYPE& _rDefault ) const + { + return getOrDefault( ::rtl::OUString::createFromAscii( _pAsciiValueName ), _rDefault ); + } + + template < typename VALUE_TYPE > + VALUE_TYPE getOrDefault( const ::rtl::OUString& _rValueName, const VALUE_TYPE& _rDefault ) const + { + VALUE_TYPE retVal( _rDefault ); + get_ensureType( _rValueName, retVal ); + return retVal; + } + + /** retrieves a (untyped) value with a given name + + If the collection does not contain a value with the given name, an empty + Any is returned. + */ + const ::com::sun::star::uno::Any& get( const sal_Char* _pAsciiValueName ) const + { + return get( ::rtl::OUString::createFromAscii( _pAsciiValueName ) ); + } + + /** retrieves a (untyped) value with a given name + + If the collection does not contain a value with the given name, an empty + Any is returned. + */ + const ::com::sun::star::uno::Any& get( const ::rtl::OUString& _rValueName ) const + { + return impl_get( _rValueName ); + } + + /// determines whether a value with a given name is present in the collection + inline bool has( const sal_Char* _pAsciiValueName ) const + { + return impl_has( ::rtl::OUString::createFromAscii( _pAsciiValueName ) ); + } + + /// determines whether a value with a given name is present in the collection + inline bool has( const ::rtl::OUString& _rValueName ) const + { + return impl_has( _rValueName ); + } + + /** puts a value into the collection + + @return <TRUE/> if and only if a value was already present previously, in + which case it has been overwritten. + */ + template < typename VALUE_TYPE > + inline bool put( const sal_Char* _pAsciiValueName, const VALUE_TYPE& _rValue ) + { + return impl_put( ::rtl::OUString::createFromAscii( _pAsciiValueName ), ::com::sun::star::uno::makeAny( _rValue ) ); + } + + /** puts a value into the collection + + @return <TRUE/> if and only if a value was already present previously, in + which case it has been overwritten. + */ + template < typename VALUE_TYPE > + inline bool put( const ::rtl::OUString& _rValueName, const VALUE_TYPE& _rValue ) + { + return impl_put( _rValueName, ::com::sun::star::uno::makeAny( _rValue ) ); + } + + inline bool put( const sal_Char* _pAsciiValueName, const ::com::sun::star::uno::Any& _rValue ) + { + return impl_put( ::rtl::OUString::createFromAscii( _pAsciiValueName ), _rValue ); + } + + inline bool put( const ::rtl::OUString& _rValueName, const ::com::sun::star::uno::Any& _rValue ) + { + return impl_put( _rValueName, _rValue ); + } + + /** removes the value with the given name from the collection + + @return <TRUE/> if and only if a value with the given name existed in the collection. + */ + inline bool remove( const sal_Char* _pAsciiValueName ) + { + return impl_remove( ::rtl::OUString::createFromAscii( _pAsciiValueName ) ); + } + + /** removes the value with the given name from the collection + + @return <TRUE/> if and only if a value with the given name existed in the collection. + */ + inline bool remove( const ::rtl::OUString& _rValueName ) + { + return impl_remove( _rValueName ); + } + + /** transforms the collection to a sequence of PropertyValues + + @return + the number of elements in the sequence + */ + sal_Int32 operator >>= ( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _out_rValues ) const; + + /** transforms the collection to a sequence of NamedValues + + @return + the number of elements in the sequence + */ + sal_Int32 operator >>= ( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _out_rValues ) const; + + /** transforms the collection into a sequence of PropertyValues + */ + inline ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > + getPropertyValues() const + { + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues; + *this >>= aValues; + return aValues; + } + + /** returns a Sequence< Any >, containing PropertyValues + */ + inline ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > + getWrappedPropertyValues() const + { + return impl_wrap< ::com::sun::star::beans::PropertyValue >(); + } + + /** returns a Sequence< Any >, containing NamedValues + */ + inline ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > + getWrappedNamedValues() const + { + return impl_wrap< ::com::sun::star::beans::NamedValue >(); + } + + /** transforms the collection into a sequence of NamedValues + */ + inline ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + getNamedValues() const + { + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > aValues; + *this >>= aValues; + return aValues; + } + + private: + void impl_assign( const ::com::sun::star::uno::Any& i_rWrappedElements ); + void impl_assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments ); + void impl_assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArguments ); + void impl_assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _rArguments ); + + bool get_ensureType( + const ::rtl::OUString& _rValueName, + void* _pValueLocation, + const ::com::sun::star::uno::Type& _rExpectedValueType + ) const; + + const ::com::sun::star::uno::Any& + impl_get( const ::rtl::OUString& _rValueName ) const; + + bool impl_has( const ::rtl::OUString& _rValueName ) const; + + bool impl_put( const ::rtl::OUString& _rValueName, const ::com::sun::star::uno::Any& _rValue ); + + bool impl_remove( const ::rtl::OUString& _rValueName ); + + template< class VALUE_TYPE > + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > impl_wrap() const + { + ::com::sun::star::uno::Sequence< VALUE_TYPE > aValues; + *this >>= aValues; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aWrappedValues( aValues.getLength() ); + ::std::transform( + aValues.getConstArray(), + aValues.getConstArray() + aValues.getLength(), + aWrappedValues.getArray(), + ::com::sun::star::uno::makeAny< VALUE_TYPE > + ); + return aWrappedValues; + } + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_NAMEDVALUECOLLECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/numberedcollection.hxx b/comphelper/inc/comphelper/numberedcollection.hxx new file mode 100644 index 000000000000..19bd542eaaab --- /dev/null +++ b/comphelper/inc/comphelper/numberedcollection.hxx @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_NUMBEREDCOLLECTION_HXX_ +#define _COMPHELPER_NUMBEREDCOLLECTION_HXX_ + +//_______________________________________________ +// includes + +#include "comphelper/comphelperdllapi.h" + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/frame/XUntitledNumbers.hpp> + +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/weakref.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <vector> +#include <boost/unordered_map.hpp> + +//_______________________________________________ +// namespace + +namespace comphelper{ + +#ifdef css + #error "Ambigious namespace definition of css." +#else + #define css ::com::sun::star +#endif + +//_______________________________________________ +// definitions + +/** @short defines a collection of UNO components, where every component will get it's own unique number. + + @descr Such number will be unique at runtime only ... but it supports fragmentation. + Note: This collection uses weak refrences only to know her components. + So lifetime of thise components must be controlled outside. + + @threadsafe + */ +class COMPHELPER_DLLPUBLIC NumberedCollection : private ::cppu::BaseMutex + , public ::cppu::WeakImplHelper1< css::frame::XUntitledNumbers > +{ + //------------------------------------------- + // types, const + private: + + struct TNumberedItem + { + css::uno::WeakReference< css::uno::XInterface > xItem; + ::sal_Int32 nNumber; + }; + + typedef ::boost::unordered_map< + long , + TNumberedItem , + ::boost::hash< long > , + ::std::equal_to< long > > TNumberedItemHash; + + typedef ::std::vector< long > TDeadItemList; + + //------------------------------------------- + // interface + public: + + //--------------------------------------- + /** @short lightweight constructor. + */ + NumberedCollection(); + + //--------------------------------------- + /** @short free all internaly used resources. + */ + virtual ~NumberedCollection(); + + //--------------------------------------- + /** set an outside component which uses this container and must be set + as source of all broadcasted messages, exceptions. + + It's holded weak only so we do not need any complex dispose sessions. + + Note: Passing NULL as parameter will be allowed. It will reset the internal + member reference only. + + @param xOwner + the new owner of this collection. + */ + void setOwner (const css::uno::Reference< css::uno::XInterface >& xOwner); + + //--------------------------------------- + /** set the localized prefix to be used for untitled components. + + Localization has to be done outside. This container will return + those value then. There are no further checks. Its up to you to define + a suitable string here :-) + + @param sPrefix + the new prefix for untitled components. + */ + void setUntitledPrefix(const ::rtl::OUString& sPrefix); + + //--------------------------------------- + /** @see css.frame.XUntitledNumbers */ + virtual ::sal_Int32 SAL_CALL leaseNumber(const css::uno::Reference< css::uno::XInterface >& xComponent) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + //--------------------------------------- + /** @see css.frame.XUntitledNumbers */ + virtual void SAL_CALL releaseNumber(::sal_Int32 nNumber) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + //--------------------------------------- + /** @see css.frame.XUntitledNumbers */ + virtual void SAL_CALL releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface >& xComponent) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + //--------------------------------------- + /** @see css.frame.XUntitledNumbers */ + virtual ::rtl::OUString SAL_CALL getUntitledPrefix() + throw (css::uno::RuntimeException); + + //------------------------------------------- + // internal + private: + + //--------------------------------------- + /** @short trys to find an unique number not already used within this collection. + + @descr It reuses the smalles number which isnt used by any component + of this collection. (fragmentation!) If collection is full (means there + is no free number) the special value INVALID_NUMBER will be returned. + + @note Those method cant be called within a multithreaded environment .. + Because such number wont be "reserved" for the calli of these method + it can happen that two calls returns the same number (reasoned by the fact that first calli + doesnt used the returned number already. + + So the outside code has to make sure that retrieving and using of those number + will be an atomic operation. + + @return an unique number or special value INVALID_NUMBER if collection is full. + */ + ::sal_Int32 impl_searchFreeNumber (); + + void impl_cleanUpDeadItems ( TNumberedItemHash& lItems , + const TDeadItemList& lDeadItems); + + //------------------------------------------- + // member + private: + + /// localized string to be used for untitled components + ::rtl::OUString m_sUntitledPrefix; + + /// cache of all "leased numbers" and its bound components + TNumberedItemHash m_lComponents; + + /// used as source of broadcasted messages or exceptions (can be null !) + css::uno::WeakReference< css::uno::XInterface > m_xOwner; +}; + +#undef css + +} // namespace comphelper + +#endif // _COMPHELPER_NUMBEREDCOLLECTION_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/numbers.hxx b/comphelper/inc/comphelper/numbers.hxx new file mode 100644 index 000000000000..179889c7b720 --- /dev/null +++ b/comphelper/inc/comphelper/numbers.hxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_NUMBERS_HXX_ +#define _COMPHELPER_NUMBERS_HXX_ + +#include <com/sun/star/util/XNumberFormats.hpp> +#include <com/sun/star/util/XNumberFormatter.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + namespace staruno = ::com::sun::star::uno; + namespace starlang = ::com::sun::star::lang; + namespace starutil = ::com::sun::star::util; + + /// returns the ::com::sun::star::util::NumberFormat of the given key under the given formats + COMPHELPER_DLLPUBLIC sal_Int16 getNumberFormatType(const staruno::Reference<starutil::XNumberFormats>& xFormats, sal_Int32 nKey); + + /// returns the ::com::sun::star::util::NumberFormat of the given key under the given formatter + COMPHELPER_DLLPUBLIC sal_Int16 getNumberFormatType(const staruno::Reference<starutil::XNumberFormatter>& xFormatter, sal_Int32 nKey); + + /// returns the decimals of the given numeric number formatunder the given formats + COMPHELPER_DLLPUBLIC staruno::Any getNumberFormatDecimals(const staruno::Reference<starutil::XNumberFormats>& xFormats, sal_Int32 nKey); + + /** returns the standard format for the given type and the given _rLocale + */ + sal_Int32 getStandardFormat( + const staruno::Reference<starutil::XNumberFormatter>& xFormatter, + sal_Int16 nType, + const starlang::Locale& _rLocale); + + /** retrieves a the value of a given property for a given format key, relating to a given formatter + */ + COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Any getNumberFormatProperty( + const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter, + sal_Int32 _nKey, + const rtl::OUString& _rPropertyName + ); + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_NUMBERS_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/officeresourcebundle.hxx b/comphelper/inc/comphelper/officeresourcebundle.hxx new file mode 100644 index 000000000000..345790e733f2 --- /dev/null +++ b/comphelper/inc/comphelper/officeresourcebundle.hxx @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_OFFICE_RESOURCE_BUNDLE_HXX +#define COMPHELPER_OFFICE_RESOURCE_BUNDLE_HXX + +#include <comphelper/comphelperdllapi.h> + +/** === begin UNO includes === **/ +#include <com/sun/star/uno/XComponentContext.hpp> +/** === end UNO includes === **/ +#include <rtl/ustring.hxx> + +#include <memory> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //==================================================================== + //= OfficeResourceBundle + //==================================================================== + class ResourceBundle_Impl; + /** wraps the <type scope="com::sun::star::resource">OfficeResourceAccess</type> service + */ + class COMPHELPER_DLLPUBLIC OfficeResourceBundle + { + private: + ::std::auto_ptr< ResourceBundle_Impl > m_pImpl; + + public: + /** constructs a resource bundle + @param _context + the component context to operate in + @param _bundleBaseName + the base name of the resource file which should be accessed (*without* the SUPD!) + @raises ::com::sun::star::lang::NullPointerException + if the given component context is <NULL/> + */ + OfficeResourceBundle( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _context, + const ::rtl::OUString& _bundleBaseName + ); + + /** constructs a resource bundle with the resource bundle given as 8-bit ASCII name + + This is a convenience constructor only, it does nothing different than the constructor + taking an unicode string. + + @param _context + the component context to operate in + @param _bundleBaseName + the base name of the resource file which should be accessed (*without* the SUPD!) + @raises ::com::sun::star::lang::NullPointerException + if the given component context is <NULL/> + */ + OfficeResourceBundle( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _context, + const sal_Char* _bundleBaseAsciiName + ); + + /** destroys the instance + */ + ~OfficeResourceBundle(); + + /** loads the string with the given resource id from the resource bundle + @param _resourceId + the id of the string to load + @return + the requested resource string. If no string with the given id exists in the resource bundle, + an empty string is returned. In a non-product version, an OSL_ENSURE will notify you of this + then. + */ + ::rtl::OUString loadString( sal_Int32 _resourceId ) const; + + /** determines whether the resource bundle has a string with the given id + @param _resourceId + the id of the string whose existence is to be checked + @return + <TRUE/> if and only if a string with the given ID exists in the resource + bundle. + */ + bool hasString( sal_Int32 _resourceId ) const; + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_OFFICE_RESOURCE_BUNDLE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/ofopxmlhelper.hxx b/comphelper/inc/comphelper/ofopxmlhelper.hxx new file mode 100644 index 000000000000..8043ea818afd --- /dev/null +++ b/comphelper/inc/comphelper/ofopxmlhelper.hxx @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_OFOPXMLHELPER_HXX +#define _COMPHELPER_OFOPXMLHELPER_HXX + +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/beans/StringPair.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/comphelperdllapi.h> + + +namespace comphelper +{ + +// this helper class is designed to allow to parse ContentType- and Relationship-related information from OfficeOpenXML format +class COMPHELPER_DLLPUBLIC OFOPXMLHelper : public cppu::WeakImplHelper1 < com::sun::star::xml::sax::XDocumentHandler > +{ + sal_uInt16 m_nFormat; // which format to parse + + // Relations info related strings + ::rtl::OUString m_aRelListElement; + ::rtl::OUString m_aRelElement; + ::rtl::OUString m_aIDAttr; + ::rtl::OUString m_aTypeAttr; + ::rtl::OUString m_aTargetModeAttr; + ::rtl::OUString m_aTargetAttr; + + // ContentType related strings + ::rtl::OUString m_aTypesElement; + ::rtl::OUString m_aDefaultElement; + ::rtl::OUString m_aOverrideElement; + ::rtl::OUString m_aExtensionAttr; + ::rtl::OUString m_aPartNameAttr; + ::rtl::OUString m_aContentTypeAttr; + + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > m_aResultSeq; + ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aElementsSeq; // stack of elements being parsed + + OFOPXMLHelper( sal_uInt16 nFormat ); // must not be created directly + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > GetParsingResult(); + + static COMPHELPER_DLLPRIVATE ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL ReadSequence_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream, const ::rtl::OUString& aStringID, sal_uInt16 nFormat, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory ) + throw( ::com::sun::star::uno::Exception ); + +public: + ~OFOPXMLHelper(); + + // returns sequence of elements, where each element is described by sequence of tags, + // where each tag is described by StringPair ( First - name, Second - value ) + // the first tag of each element sequence must be "Id" + static + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > + SAL_CALL + ReadRelationsInfoSequence( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream, + const ::rtl::OUString aStreamName, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory ) + throw( ::com::sun::star::uno::Exception ); + + // returns sequence containing two entries of type sequence<StringPair> + // the first sequence describes "Default" elements, where each element is described + // by StringPair object ( First - Extension, Second - ContentType ) + // the second sequence describes "Override" elements, where each element is described + // by StringPair object ( First - PartName, Second - ContentType ) + static + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > + SAL_CALL + ReadContentTypeSequence( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory ) + throw( ::com::sun::star::uno::Exception ); + + // writes sequence of elements, where each element is described by sequence of tags, + // where each tag is described by StringPair ( First - name, Second - value ) + // the first tag of each element sequence must be "Id" + static + void SAL_CALL WriteRelationsInfoSequence( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutStream, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > >& aSequence, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory ) + throw( ::com::sun::star::uno::Exception ); + + // writes two entries of type sequence<StringPair> + // the first sequence describes "Default" elements, where each element is described + // by StringPair object ( First - Extension, Second - ContentType ) + // the second sequence describes "Override" elements, where each element is described + // by StringPair object ( First - PartName, Second - ContentType ) + static + void SAL_CALL WriteContentSequence( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutStream, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aDefaultsSequence, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aOverridesSequence, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory ) + throw( ::com::sun::star::uno::Exception ); + + // XDocumentHandler + virtual void SAL_CALL startDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); +}; + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/optional.hxx b/comphelper/inc/comphelper/optional.hxx new file mode 100644 index 000000000000..2ffec9b55b02 --- /dev/null +++ b/comphelper/inc/comphelper/optional.hxx @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_OPTIONAL_HXX) +#define INCLUDED_COMPHELPER_OPTIONAL_HXX + +#if ! defined(_COM_SUN_STAR_BEANS_OPTIONAL_HPP_) +#include "com/sun/star/beans/Optional.hpp" +#endif +#include "boost/optional.hpp" + +namespace comphelper { + +/// Object generators for boost::optional<T>, beans::Optional<T>: + +template <typename T> +inline ::boost::optional<T> make_optional( T const& v ) +{ + return ::boost::optional<T>(v); +} + +template <typename T> +inline ::boost::optional<T> make_optional( + ::com::sun::star::beans::Optional<T> const& o ) +{ + if (o.IsPresent) + return ::boost::optional<T>(o.Value); + else + return ::boost::optional<T>(); +} + +template <typename T> +inline ::com::sun::star::beans::Optional<T> makeOptional( T const& v ) +{ +// CPPU_IS_CPP_MAPPING_OF_NON_VOID_UNO_TYPE(T); + return ::com::sun::star::beans::Optional<T>(true, v); +} + +template <typename T> +inline ::com::sun::star::beans::Optional<T> makeOptional( + ::boost::optional<T> const& o ) +{ +// CPPU_IS_CPP_MAPPING_OF_NON_VOID_UNO_TYPE(T); + if (o) + return ::com::sun::star::beans::Optional<T>(true, *o); + else + return ::com::sun::star::beans::Optional<T>(); +} + +inline ::com::sun::star::beans::Optional<sal_Bool> makeOptional( + ::boost::optional<bool> const& o ) +{ + if (o) + return ::com::sun::star::beans::Optional<sal_Bool>(true, *o); + else + return ::com::sun::star::beans::Optional<sal_Bool>(); +} + +inline ::com::sun::star::beans::Optional<sal_Bool> makeOptional( bool v ) +{ + return ::com::sun::star::beans::Optional<sal_Bool>(true, v); +} + +} // namespace comphelper + +#endif // ! defined(INCLUDED_COMPHELPER_OPTIONAL_HXX) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/oslfile2streamwrap.hxx b/comphelper/inc/comphelper/oslfile2streamwrap.hxx new file mode 100644 index 000000000000..d62ca3db4108 --- /dev/null +++ b/comphelper/inc/comphelper/oslfile2streamwrap.hxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_STREAM_OSLFILEWRAPPER_HXX_ +#define _COMPHELPER_STREAM_OSLFILEWRAPPER_HXX_ + +#include <osl/mutex.hxx> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <cppuhelper/implbase1.hxx> +#include <osl/file.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + namespace stario = ::com::sun::star::io; + namespace staruno = ::com::sun::star::uno; + +//================================================================== +// FmUnoIOStream, +// stream zum schreiben un lesen von Daten, basieren auf File +//================================================================== +class COMPHELPER_DLLPUBLIC OSLInputStreamWrapper : public ::cppu::WeakImplHelper1<stario::XInputStream> +{ + ::osl::Mutex m_aMutex; + ::osl::File* m_pFile; + sal_Bool m_bFileOwner : 1; + +public: + OSLInputStreamWrapper(::osl::File& _rStream); + OSLInputStreamWrapper(::osl::File* pStream, sal_Bool bOwner=sal_False); + virtual ~OSLInputStreamWrapper(); + +// stario::XInputStream + virtual sal_Int32 SAL_CALL readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException); + virtual sal_Int32 SAL_CALL readSomeBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException); + virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException); + virtual sal_Int32 SAL_CALL available() throw(stario::NotConnectedException, staruno::RuntimeException); + virtual void SAL_CALL closeInput() throw(stario::NotConnectedException, staruno::RuntimeException); +}; + +//================================================================== +// FmUnoOutStream, +// Datensenke fuer Files +//================================================================== +class COMPHELPER_DLLPUBLIC OSLOutputStreamWrapper : public ::cppu::WeakImplHelper1<stario::XOutputStream> +{ + ::osl::File& rFile; + +public: + OSLOutputStreamWrapper(::osl::File& _rFile) :rFile(_rFile) { } + +// stario::XOutputStream + virtual void SAL_CALL writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException); + virtual void SAL_CALL flush() throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException); + virtual void SAL_CALL closeOutput() throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException); +}; + +} // namespace comphelper + + +#endif // _COMPHELPER_STREAM_OSLFILEWRAPPER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/otransactedfilestream.hxx b/comphelper/inc/comphelper/otransactedfilestream.hxx new file mode 100644 index 000000000000..248aa22f02eb --- /dev/null +++ b/comphelper/inc/comphelper/otransactedfilestream.hxx @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_OTRANSACTEDFILESTREAM_HXX +#define _COMPHELPER_OTRANSACTEDFILESTREAM_HXX + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/implbase7.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + + +//================================================================== +// OTransactedFileStream +// allows to get transacted stream access to a file +// the file contents are automatically truncated, but the file +// itself is changed only on commit +// after the first commit the stream switches to direct mode +//================================================================== + +struct TTFileStreamData_Impl; +class COMPHELPER_DLLPUBLIC OTruncatedTransactedFileStream + : public ::cppu::WeakImplHelper7 < + ::com::sun::star::io::XStream, + ::com::sun::star::io::XInputStream, + ::com::sun::star::io::XOutputStream, + ::com::sun::star::io::XTruncate, + ::com::sun::star::io::XSeekable, + ::com::sun::star::beans::XPropertySetInfo, + ::com::sun::star::beans::XPropertySet > +{ + ::osl::Mutex m_aMutex; + TTFileStreamData_Impl* m_pStreamData; + + void CommonInit_Impl( + const ::rtl::OUString& aURL, + const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory, + sal_Bool bDeleteOptionIsProvided ); + + void CloseAll_Impl(); + +public: + + OTruncatedTransactedFileStream( const ::rtl::OUString& aURL, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ); + + OTruncatedTransactedFileStream( const ::rtl::OUString& aURL, const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ); + + OTruncatedTransactedFileStream( const ::rtl::OUString& aURL, const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory, sal_Bool bDeleteIfNotCommited ); + + ~OTruncatedTransactedFileStream(); + + void Commit_Impl(); + void Revert_Impl(); + +// com::sun::star::io::XStream + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) throw (::com::sun::star::uno::RuntimeException); + +// com::sun::star::io::XInputStream + virtual ::sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL available( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeInput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + +// com::sun::star::io::XOutputStream + virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL flush( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeOutput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + +// com::sun::star::io::XTruncate + virtual void SAL_CALL truncate( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + +// com::sun::star::io::XSeekable + virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int64 SAL_CALL getPosition( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int64 SAL_CALL getLength( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + +// ::com::sun::star::beans::XPropertySetInfo + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw (::com::sun::star::uno::RuntimeException); + +// com::sun::star::beans::XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +}; + +} // namespace comphelper + +#endif //_COMPHELPER_OTRANSACTEDFILESTREAM_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/processfactory.hxx b/comphelper/inc/comphelper/processfactory.hxx new file mode 100644 index 000000000000..b20d7302241d --- /dev/null +++ b/comphelper/inc/comphelper/processfactory.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROCESSFACTORY_HXX_ +#define _COMPHELPER_PROCESSFACTORY_HXX_ + +#if ! defined(_COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HXX_) +#include "com/sun/star/uno/XComponentContext.hpp" +#endif +#include <com/sun/star/uno/Sequence.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace com { namespace sun { namespace star { namespace lang { + class XMultiServiceFactory; +} } } } + +namespace comphelper +{ + +/** + * This function set the process service factory. + * + * @author Juergen Schmidt + */ +COMPHELPER_DLLPUBLIC void setProcessServiceFactory(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr); + +/** + * This function get the process service factory. If no service factory is set the function returns + * a null interface. + * + * @author Juergen Schmidt + */ +COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getProcessServiceFactory(); + +/** creates a component, using the process factory if set + @see getProcessServiceFactory + @see setProcessServiceFactory +*/ +COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + createProcessComponent( + const ::rtl::OUString& _rServiceSpecifier + ) SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) ); + +/** creates a component with arguments, using the process factory if set + + @see getProcessServiceFactory + @see setProcessServiceFactory +*/ +COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + createProcessComponentWithArguments( + const ::rtl::OUString& _rServiceSpecifier, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArgs + ) SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) ); + +/** + * This function gets the process service factory's default component context. + * If no service factory is set the function returns a null interface. + */ +COMPHELPER_DLLPUBLIC +::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > +getProcessComponentContext(); + +} + + +extern "C" { +/// @internal ATTENTION returns ACQUIRED pointer! release it explicitly! +COMPHELPER_DLLPUBLIC +::com::sun::star::uno::XComponentContext * +comphelper_getProcessComponentContext(); +} // extern "C" + +#endif // _COMPHELPER_PROCESSFACTORY_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propagg.hxx b/comphelper/inc/comphelper/propagg.hxx new file mode 100644 index 000000000000..6286e9d79088 --- /dev/null +++ b/comphelper/inc/comphelper/propagg.hxx @@ -0,0 +1,331 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTY_AGGREGATION_HXX_ +#define _COMPHELPER_PROPERTY_AGGREGATION_HXX_ + +#include <com/sun/star/uno/XAggregation.hpp> +#include <comphelper/propstate.hxx> +#include "comphelper/comphelperdllapi.h" + +#include <map> + +//========================================================================= +//= property helper classes +//========================================================================= + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +//================================================================== +//= OPropertyAccessor +//= internal helper class for OPropertyArrayAggregationHelper +//================================================================== +namespace internal +{ + struct OPropertyAccessor + { + sal_Int32 nOriginalHandle; + sal_Int32 nPos; + sal_Bool bAggregate; + + OPropertyAccessor(sal_Int32 _nOriginalHandle, sal_Int32 _nPos, sal_Bool _bAggregate) + :nOriginalHandle(_nOriginalHandle) ,nPos(_nPos) ,bAggregate(_bAggregate) { } + OPropertyAccessor() + :nOriginalHandle(-1) ,nPos(-1) ,bAggregate(sal_False) { } + + sal_Bool operator==(const OPropertyAccessor& rOb) const { return nPos == rOb.nPos; } + sal_Bool operator <(const OPropertyAccessor& rOb) const { return nPos < rOb.nPos; } + }; + + typedef std::map< sal_Int32, OPropertyAccessor, ::std::less< sal_Int32 > > PropertyAccessorMap; + typedef PropertyAccessorMap::iterator PropertyAccessorMapIterator; + typedef PropertyAccessorMap::const_iterator ConstPropertyAccessorMapIterator; +} + +//================================================================== +/** + * used as callback for a OPropertyArrayAggregationHelper + */ +class IPropertyInfoService +{ +public: + /** get the prefered handle for the given property + @param _rName the property name + @return the handle the property should be refered by, or -1 if there are no + preferences for the given property + */ + virtual sal_Int32 getPreferedPropertyId(const ::rtl::OUString& _rName) = 0; +}; + +/** + * used for implementing an cppu::IPropertyArrayHelper for classes + * aggregating property sets + */ + +#define DEFAULT_AGGREGATE_PROPERTY_ID 10000 +//------------------------------------------------------------------ +class COMPHELPER_DLLPUBLIC OPropertyArrayAggregationHelper: public ::cppu::IPropertyArrayHelper +{ + friend class OPropertySetAggregationHelper; +protected: + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> m_aProperties; + internal::PropertyAccessorMap m_aPropertyAccessors; + +public: + /** construct the object. + @param _rProperties the properties of the object doing the aggregation. These properties + are used without any checks, so the caller has to ensure that the names and + handles are valid. + @param _rAggProperties the properties of the aggregate, usually got via an call to getProperties on the + XPropertySetInfo of the aggregate. + The names of the properties are used without any checks, so the caller has to ensure + that there are no doubles. + The handles are stored for later quick access, but the outside-handles the + aggregate properties get depend from the following two parameters. + @param _pInfoService + If not NULL, the object pointed to is used to calc handles which should be used + for refering the aggregate's properties from outside. + If one of the properties returned from the info service conflict with other handles + alread present (e.g. through _rProperties), the property is handled as if -1 was returned. + If NULL (or, for a special property, a call to getPreferedPropertyId returns -1), + the aggregate property(ies) get a new handle which they can be refered by from outside. + @param _nFirstAggregateId + if the object is about to create new handles for the aggregate properties, it uses + id's ascending from this given id. + No checks are made if the handle range determined by _nFirstAggregateId conflicts with other + handles within _rProperties. + */ + OPropertyArrayAggregationHelper(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property>& _rProperties, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property>& _rAggProperties, + IPropertyInfoService* _pInfoService = NULL, + sal_Int32 _nFirstAggregateId = DEFAULT_AGGREGATE_PROPERTY_ID); + + + /// inherited from IPropertyArrayHelper + virtual sal_Bool SAL_CALL fillPropertyMembersByHandle( ::rtl::OUString* _pPropName, sal_Int16* _pAttributes, + sal_Int32 _nHandle) ; + + /// inherited from IPropertyArrayHelper + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> SAL_CALL getProperties(); + /// inherited from IPropertyArrayHelper + virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName(const ::rtl::OUString& _rPropertyName) + throw(::com::sun::star::beans::UnknownPropertyException); + + /// inherited from IPropertyArrayHelper + virtual sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& _rPropertyName) ; + /// inherited from IPropertyArrayHelper + virtual sal_Int32 SAL_CALL getHandleByName(const ::rtl::OUString & _rPropertyName); + /// inherited from IPropertyArrayHelper + virtual sal_Int32 SAL_CALL fillHandles( /*out*/sal_Int32* _pHandles, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropNames ); + + /** returns information about a property of the aggregate. + @param _pPropName points to a string to recieve the property name. No name is returned if this is NULL. + @param _pOriginalHandle points to a sal_Int32 to recieve the original property hande. No original handle is returned + if this is NULL. + @param _nHandle the handle of the property as got by, for instance, fillHandles + + @return sal_True, if _nHandle marks an aggregate property, otherwise sal_False + */ + virtual sal_Bool SAL_CALL fillAggregatePropertyInfoByHandle(::rtl::OUString* _pPropName, sal_Int32* _pOriginalHandle, + sal_Int32 _nHandle) const; + + /** returns information about a property given by handle + */ + sal_Bool getPropertyByHandle( sal_Int32 _nHandle, ::com::sun::star::beans::Property& _rProperty ) const; + + + enum PropertyOrigin + { + AGGREGATE_PROPERTY, + DELEGATOR_PROPERTY, + UNKNOWN_PROPERTY + }; + /** prefer this one over the XPropertySetInfo of the aggregate! + + <p>The reason is that OPropertyArrayAggregationHelper is the only instance which really knows + which properties of the aggregate are to be exposed. <br/> + + For instance, some derivee of OPropertySetAggregationHelper may decide to create an + OPropertyArrayAggregationHelper which contains only a subset of the aggregate properties. This way, + some of the aggregate properties may be hidded to the public.<br/> + + When using the XPropertySetInfo of the aggregate set to determine the existence of a property, then this + would return false positives.</p> + */ + PropertyOrigin classifyProperty( const ::rtl::OUString& _rName ); + +protected: + const ::com::sun::star::beans::Property* findPropertyByName(const ::rtl::OUString& _rName) const; +}; + +//================================================================== +namespace internal +{ + class PropertyForwarder; +} + +/** + * helper class for implementing the property-set-related interfaces + * for an object doin' aggregation + * supports at least XPropertySet and XMultiPropertySet + * + */ +class COMPHELPER_DLLPUBLIC OPropertySetAggregationHelper :public OPropertyStateHelper + ,public ::com::sun::star::beans::XPropertiesChangeListener + ,public ::com::sun::star::beans::XVetoableChangeListener +{ + friend class internal::PropertyForwarder; + +protected: + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState> m_xAggregateState; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> m_xAggregateSet; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet> m_xAggregateMultiSet; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet> m_xAggregateFastSet; + + internal::PropertyForwarder* m_pForwarder; + sal_Bool m_bListening : 1; + +public: + OPropertySetAggregationHelper( ::cppu::OBroadcastHelper& rBHelper ); + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type& aType) 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); + +// XFastPropertySet + virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +// XPropertySet + virtual void SAL_CALL addPropertyChangeListener(const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener(const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +// XPropertiesChangeListener + virtual void SAL_CALL propertiesChange(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent >& evt) throw(::com::sun::star::uno::RuntimeException); + +// XVetoableChangeListener + virtual void SAL_CALL vetoableChange(const ::com::sun::star::beans::PropertyChangeEvent& aEvent) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException); + +// XMultiPropertySet + virtual void SAL_CALL setPropertyValues(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& PropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertiesChangeListener(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener) throw(::com::sun::star::uno::RuntimeException); + +// XPropertyState + virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyToDefault(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault(const ::rtl::OUString& aPropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + +// OPropertySetHelper + /** still waiting to be overwritten ... + you <B>must<B/> use an OPropertyArrayAggregationHelper here, as the implementation strongly relies on this. + */ + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() = 0; + + /** only implemented for "forwarded" properties, every other property must be handled + in the derivee, and will assert if passed herein + */ + virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw(::com::sun::star::lang::IllegalArgumentException); + + /** only implemented for "forwarded" properties, every other property must be handled + in the derivee, and will assert if passed herein + */ + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw ( ::com::sun::star::uno::Exception ); + +protected: + ~OPropertySetAggregationHelper(); + + virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const; + virtual void SAL_CALL disposing(); + + sal_Int32 getOriginalHandle( sal_Int32 _nHandle ) const; + ::rtl::OUString getPropertyName( sal_Int32 _nHandle ) const; + + /** declares the property with the given (public) handle as one to be forwarded to the aggregate + + Sometimes, you might want to <em>overwrite</em> properties at the aggregate. That is, + though the aggregate implements this property, and still is to hold the property value, + you want to do additional handling upon setting the property, but then forward the value + to the aggregate. + + Use this method to declare such properties. + + When a "forwarded property" is set from outside, the class first calls + <member>forwardingPropertyValue</member> for any preprocessing, then forwards the property + value to the aggregate, and then calls <member>forwardedPropertyValue</member>. + + When you declare a property as "forwarded", the class takes care for some multi-threading + issues, for instance, it won't fire any property change notifications which result from + forwarding a property value, unless it's safe to do so (i.e. unless our mutex is + released). + + @see forwardingPropertyValue + @see forwardedPropertyValue + */ + void declareForwardedProperty( sal_Int32 _nHandle ); + + /** checks whether we're actually forwarding a property value to our aggregate + + @see declareForwardedProperty + @see forwardingPropertyValue + @see forwardedPropertyValue + */ + bool isCurrentlyForwardingProperty( sal_Int32 _nHandle ) const; + + /** called immediately before a property value which is overwritten in this instance + is forwarded to the aggregate + + @see declareForwardedProperty + @see forwardedPropertyValue + */ + virtual void SAL_CALL forwardingPropertyValue( sal_Int32 _nHandle ); + + /** called immediately after a property value which is overwritten in this instance + has been forwarded to the aggregate + + @see declareForwardedProperty + @see forwardingPropertyValue + */ + virtual void SAL_CALL forwardedPropertyValue( sal_Int32 _nHandle, bool _bSuccess ); + + /// must be called before aggregation, if aggregation is used + void setAggregation(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >&) throw( ::com::sun::star::lang::IllegalArgumentException ); + void startListening(); +}; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_PROPERTY_AGGREGATION_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/proparrhlp.hxx b/comphelper/inc/comphelper/proparrhlp.hxx new file mode 100644 index 000000000000..6af317420327 --- /dev/null +++ b/comphelper/inc/comphelper/proparrhlp.hxx @@ -0,0 +1,184 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_ +#define _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_ + +#include <comphelper/stl_types.hxx> +#include <comphelper/propagg.hxx> +#include <cppuhelper/propshlp.hxx> +#include <osl/mutex.hxx> +#include <osl/diagnose.h> +#include <rtl/instance.hxx> + +namespace cppu { + class IPropertyArrayHelper; +} + +//... namespace comphelper ................................................ +namespace comphelper +{ +//......................................................................... + + namespace staruno = ::com::sun::star::uno; + namespace starbeans = ::com::sun::star::beans; + + +//================================================================== + +template <typename TYPE> struct OPropertyArrayUsageHelperMutex + : public rtl::Static< ::osl::Mutex, OPropertyArrayUsageHelperMutex<TYPE> > {}; + + +template <class TYPE> +class OPropertyArrayUsageHelper +{ +protected: + static sal_Int32 s_nRefCount; + static ::cppu::IPropertyArrayHelper* s_pProps; + +public: + OPropertyArrayUsageHelper(); + virtual ~OPropertyArrayUsageHelper() + { // ARGHHHHHHH ..... would like to implement this after the class + // definition (as we do with all other methods) but SUNPRO 5 compiler + // (linker) doesn't like this + ::osl::MutexGuard aGuard(OPropertyArrayUsageHelperMutex<TYPE>::get()); + OSL_ENSURE(s_nRefCount > 0, "OPropertyArrayUsageHelper::~OPropertyArrayUsageHelper : suspicious call : have a refcount of 0 !"); + if (!--s_nRefCount) + { + delete s_pProps; + s_pProps = NULL; + } + } + + /** call this in the getInfoHelper method of your derived class. The method returns the array helper of the + class, which is created if neccessary. + */ + ::cppu::IPropertyArrayHelper* getArrayHelper(); + +protected: + /** used to implement the creation of the array helper which is shared amongst all instances of the class. + This method needs to be implemented in derived classes. + <BR> + The method gets called with Mutex acquired. + <BR> + as long as IPropertyArrayHelper has no virtual destructor, the implementation of ~OPropertyArrayUsageHelper + assumes that you created an ::cppu::OPropertyArrayHelper when deleting s_pProps. + @return an pointer to the newly created array helper. Must not be NULL. + */ + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const = 0; +}; + +//================================================================== +/** a OPropertyArrayUsageHelper which will create an OPropertyArrayAggregationHelper +*/ +template <class TYPE> +class OAggregationArrayUsageHelper: public OPropertyArrayUsageHelper<TYPE> +{ +protected: + /** overwrite this in your derived class. initialize the two sequences with your and your aggregate's + properties. + <BR> + The method gets called with Mutex acquired. + @param _rProps out parameter to be filled with the property descriptions of your own class + @param _rAggregateProps out parameter to be filled with the properties of your aggregate. + */ + virtual void fillProperties( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps, + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps + ) const = 0; + + /** creates an OPropertyArrayAggregationHelper filled with properties for which's initialization + fillProperties is called. getInfoService and getFirstAggregateId may be overwritten to determine + the additional parameters of the OPropertyArrayAggregationHelper. + */ + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; + + /** the return value is used for the construction of the OPropertyArrayAggregationHelper. + Beware of the lifetime of the returned object, as it has to exist 'til the last instance + of this class dies. + */ + virtual IPropertyInfoService* getInfoService() const { return NULL; } + + /** the return value is used for the construction of the OPropertyArrayAggregationHelper. + */ + virtual sal_Int32 getFirstAggregateId() const { return DEFAULT_AGGREGATE_PROPERTY_ID; } +}; + +//------------------------------------------------------------------ +template<class TYPE> +sal_Int32 OPropertyArrayUsageHelper< TYPE >::s_nRefCount = 0; + +template<class TYPE> +::cppu::IPropertyArrayHelper* OPropertyArrayUsageHelper< TYPE >::s_pProps = NULL; + +//------------------------------------------------------------------ +template <class TYPE> +OPropertyArrayUsageHelper<TYPE>::OPropertyArrayUsageHelper() +{ + ::osl::MutexGuard aGuard(OPropertyArrayUsageHelperMutex<TYPE>::get()); + ++s_nRefCount; +} + +//------------------------------------------------------------------ +template <class TYPE> +::cppu::IPropertyArrayHelper* OPropertyArrayUsageHelper<TYPE>::getArrayHelper() +{ + OSL_ENSURE(s_nRefCount, "OPropertyArrayUsageHelper::getArrayHelper : suspicious call : have a refcount of 0 !"); + if (!s_pProps) + { + ::osl::MutexGuard aGuard(OPropertyArrayUsageHelperMutex<TYPE>::get()); + if (!s_pProps) + { + s_pProps = createArrayHelper(); + OSL_ENSURE(s_pProps, "OPropertyArrayUsageHelper::getArrayHelper : createArrayHelper returned nonsense !"); + } + } + return s_pProps; +} + +//------------------------------------------------------------------ +template <class TYPE> inline +::cppu::IPropertyArrayHelper* OAggregationArrayUsageHelper<TYPE>::createArrayHelper() const +{ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aAggregateProps; + fillProperties(aProps, aAggregateProps); + OSL_ENSURE(aProps.getLength(), "OAggregationArrayUsageHelper::createArrayHelper : fillProperties returned nonsense !"); + return new OPropertyArrayAggregationHelper(aProps, aAggregateProps, getInfoService(), getFirstAggregateId()); +} + +//......................................................................... +} +//... namespace comphelper ................................................ + +#endif // _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_ + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/property.hxx b/comphelper/inc/comphelper/property.hxx new file mode 100644 index 000000000000..a294b3363b5d --- /dev/null +++ b/comphelper/inc/comphelper/property.hxx @@ -0,0 +1,227 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTY_HXX_ +#define _COMPHELPER_PROPERTY_HXX_ + +#include <cppuhelper/proptypehlp.hxx> +#include <comphelper/extract.hxx> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <functional> +#include "comphelper/comphelperdllapi.h" +#include "cppu/unotype.hxx" + +//========================================================================= +//= property helper classes +//========================================================================= + +//... namespace comphelper ....................................................... +namespace comphelper +{ +//......................................................................... + + namespace starbeans = ::com::sun::star::beans; + namespace staruno = ::com::sun::star::uno; + +/** compare two properties by name +*/ + //-------------------------------------------------------------------------- + // comparing two property instances + struct PropertyCompareByName : public ::std::binary_function< ::com::sun::star::beans::Property, ::com::sun::star::beans::Property, bool > + { + bool operator() (const ::com::sun::star::beans::Property& x, const ::com::sun::star::beans::Property& y) const + { + return x.Name.compareTo(y.Name) < 0;// ? true : false; + } + }; + + //-------------------------------------------------------------------------- + /** compare two properties by name + */ + struct PropertyStringEqualFunctor : ::std::binary_function< ::com::sun::star::beans::Property, ::rtl::OUString, bool > + { + // ................................................................ + inline bool operator()( const ::com::sun::star::beans::Property& lhs, const ::rtl::OUString& rhs ) const + { + return lhs.Name.compareTo(rhs) == 0; + } + // ................................................................ + inline bool operator()( const ::rtl::OUString& lhs, const ::com::sun::star::beans::Property& rhs ) const + { + return lhs.compareTo(rhs.Name) == 0; + } + }; + //-------------------------------------------------------------------------- + // comparing two property instances + struct PropertyEqualByName : public ::std::binary_function< ::com::sun::star::beans::Property, ::com::sun::star::beans::Property, bool > + { + bool operator() (const ::com::sun::star::beans::Property& x, const ::com::sun::star::beans::Property& y) const + { + return x.Name.compareTo(y.Name) == 0; + } + }; + +//------------------------------------------------------------------ +/** find property with given name + + @param o_rProp + Output parameter receiving the property, if found + + @param i_rPropName + Name of the property to find + + @return false, if property was not found + */ +COMPHELPER_DLLPUBLIC bool findProperty(starbeans::Property& o_rProp, staruno::Sequence<starbeans::Property>& i_seqProps, const ::rtl::OUString& i_rPropName); + +//------------------------------------------------------------------ +/// remove the property with the given name from the given sequence +COMPHELPER_DLLPUBLIC void RemoveProperty(staruno::Sequence<starbeans::Property>& seqProps, const ::rtl::OUString& _rPropName); + +//------------------------------------------------------------------ +/** within the given property sequence, modify attributes of a special property + @param _rProps the sequence of properties to search in + @param _sPropName the name of the property which's attributes should be modified + @param _nAddAttrib the attributes which should be added + @param _nRemoveAttrib the attributes which should be removed +*/ +COMPHELPER_DLLPUBLIC void ModifyPropertyAttributes(staruno::Sequence<starbeans::Property>& _rProps, const ::rtl::OUString& _sPropName, sal_Int16 _nAddAttrib, sal_Int16 _nRemoveAttrib); + +//------------------------------------------------------------------ +/** check if the given set has the given property. +*/ +COMPHELPER_DLLPUBLIC sal_Bool hasProperty(const rtl::OUString& _rName, const staruno::Reference<starbeans::XPropertySet>& _rxSet); + +//------------------------------------------------------------------ +/** copy properties between property sets, in compliance with the property + attributes of the target object +*/ +COMPHELPER_DLLPUBLIC void copyProperties(const staruno::Reference<starbeans::XPropertySet>& _rxSource, + const staruno::Reference<starbeans::XPropertySet>& _rxDest); + +//================================================================== +//= property conversion helpers +//================================================================== + +/** helper for implementing ::cppu::OPropertySetHelper::convertFastPropertyValue + @param _rConvertedValue the conversion result (if successfull) + @param _rOldValue the old value of the property, calculated from _rCurrentValue + @param _rValueToSet the new value which is about to be set + @param _rCurrentValue the current value of the property + @return sal_True, if the value could be converted and has changed + sal_False, if the value could be converted and has not changed + @exception InvalidArgumentException thrown if the value could not be converted to the requested type (which is the template argument) +*/ +template <typename T> +sal_Bool tryPropertyValue(staruno::Any& /*out*/_rConvertedValue, staruno::Any& /*out*/_rOldValue, const staruno::Any& _rValueToSet, const T& _rCurrentValue) +{ + sal_Bool bModified(sal_False); + T aNewValue = T(); + ::cppu::convertPropertyValue(aNewValue, _rValueToSet); + if (aNewValue != _rCurrentValue) + { + _rConvertedValue <<= aNewValue; + _rOldValue <<= _rCurrentValue; + bModified = sal_True; + } + return bModified; +} + +/** helper for implementing ::cppu::OPropertySetHelper::convertFastPropertyValue for enum values + @param _rConvertedValue the conversion result (if successfull) + @param _rOldValue the old value of the property, calculated from _rCurrentValue + @param _rValueToSet the new value which is about to be set + @param _rCurrentValue the current value of the property + @return sal_True, if the value could be converted and has changed + sal_False, if the value could be converted and has not changed + @exception InvalidArgumentException thrown if the value could not be converted to the requested type (which is the template argument) +*/ +template <class ENUMTYPE> +sal_Bool tryPropertyValueEnum(staruno::Any& /*out*/_rConvertedValue, staruno::Any& /*out*/_rOldValue, const staruno::Any& _rValueToSet, const ENUMTYPE& _rCurrentValue) +{ + if (cppu::getTypeFavourUnsigned(&_rCurrentValue).getTypeClass() + != staruno::TypeClass_ENUM) + return tryPropertyValue(_rConvertedValue, _rOldValue, _rValueToSet, _rCurrentValue); + + sal_Bool bModified(sal_False); + ENUMTYPE aNewValue; + ::cppu::any2enum(aNewValue, _rValueToSet); + // will throw an exception if not convertible + + if (aNewValue != _rCurrentValue) + { + _rConvertedValue <<= aNewValue; + _rOldValue <<= _rCurrentValue; + bModified = sal_True; + } + return bModified; +} + +/** helper for implementing ::cppu::OPropertySetHelper::convertFastPropertyValue for boolean properties + @param _rConvertedValue the conversion result (if successfull) + @param _rOldValue the old value of the property, calculated from _rCurrentValue + @param _rValueToSet the new value which is about to be set + @param _rCurrentValue the current value of the property + @return sal_True, if the value could be converted and has changed + sal_False, if the value could be converted and has not changed + @exception InvalidArgumentException thrown if the value could not be converted to a boolean type +*/ +inline sal_Bool tryPropertyValue(staruno::Any& /*out*/_rConvertedValue, staruno::Any& /*out*/_rOldValue, const staruno::Any& _rValueToSet, sal_Bool _bCurrentValue) +{ + sal_Bool bModified(sal_False); + sal_Bool bNewValue(sal_False); + ::cppu::convertPropertyValue(bNewValue, _rValueToSet); + if (bNewValue != _bCurrentValue) + { + _rConvertedValue.setValue(&bNewValue, ::getBooleanCppuType()); + _rOldValue.setValue(&_bCurrentValue, ::getBooleanCppuType()); + bModified = sal_True; + } + return bModified; +} + +/** helper for implementing ::cppu::OPropertySetHelper::convertFastPropertyValue + @param _rConvertedValue the conversion result (if successfull) + @param _rOldValue the old value of the property, calculated from _rCurrentValue + @param _rValueToSet the new value which is about to be set + @param _rCurrentValue the current value of the property + @param _rExpectedType the type which the property should have (if not void) + @return sal_True, if the value could be converted and has changed + sal_False, if the value could be converted and has not changed + @exception InvalidArgumentException thrown if the value could not be converted to the requested type (which is the template argument) +*/ +COMPHELPER_DLLPUBLIC sal_Bool tryPropertyValue(staruno::Any& _rConvertedValue, staruno::Any& _rOldValue, const staruno::Any& _rValueToSet, const staruno::Any& _rCurrentValue, const staruno::Type& _rExpectedType); + +//......................................................................... +} +//... namespace comphelper ....................................................... + +#endif // _COMPHELPER_PROPERTY_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propertybag.hxx b/comphelper/inc/comphelper/propertybag.hxx new file mode 100644 index 000000000000..74aa87d71517 --- /dev/null +++ b/comphelper/inc/comphelper/propertybag.hxx @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_PROPERTYBAG_HXX +#define COMPHELPER_PROPERTYBAG_HXX + +#include "comphelper/comphelperdllapi.h" +#include <comphelper/propertycontainerhelper.hxx> + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +#include <memory> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + struct PropertyBag_Impl; + //==================================================================== + //= PropertyBag + //==================================================================== + /** provides a bag of properties associated with their values + + This class can, for instance, be used for components which need to implement + the com.sun.star.beans.PropertyBag service. + */ + class COMPHELPER_DLLPUBLIC PropertyBag : protected OPropertyContainerHelper + { + private: + ::std::auto_ptr< PropertyBag_Impl > m_pImpl; + + public: + PropertyBag(); + virtual ~PropertyBag(); + + /** allow adding property with empty string as name + (by default, such names are rejected with IllegalActionException). + @param i_isAllowed + iff true, empty property name will be allowed + */ + void setAllowEmptyPropertyName(bool i_isAllowed = true); + + /** adds a property to the bag + + The type of the property is determined from its initial value (<code>_rInitialValue</code>). + + @param _rName + the name of the new property. Must not be empty unless + explicitly allowed with setAllowEmptyPropertyName. + @param _nHandle + the handle of the new property + @param _nAttributes + the attributes of the property + @param _rInitialValue + the initial value of the property. Must not be <NULL/>, to allow + determining the property type. + + @throws ::com::sun::star::beans::IllegalTypeException + if the initial value is <NULL/> + @throws ::com::sun::star::beans::PropertyExistException + if the name or the handle are already used + @throws ::com::sun::star::beans::IllegalArgumentException + if the name is empty + */ + void addProperty( + const ::rtl::OUString& _rName, + sal_Int32 _nHandle, + sal_Int32 _nAttributes, + const ::com::sun::star::uno::Any& _rInitialValue + ); + + /** adds a property to the bag + + The initial value of the property is <NULL/>. + + @param _rName + the name of the new property. Must not be empty unless + explicitly allowed with setAllowEmptyPropertyName. + @param _rType + the type of the new property + @param _nHandle + the handle of the new property + @param _nAttributes + the attributes of the property + + @throws ::com::sun::star::beans::IllegalTypeException + if the initial value is <NULL/> + @throws ::com::sun::star::beans::PropertyExistException + if the name or the handle are already used + @throws ::com::sun::star::beans::IllegalArgumentException + if the name is empty + */ + void addVoidProperty( + const ::rtl::OUString& _rName, + const ::com::sun::star::uno::Type& _rType, + sal_Int32 _nHandle, + sal_Int32 _nAttributes + ); + + /** removes a property from the bag + @param _rName + the name of the to-be-removed property. + @throws UnknownPropertyException + if the bag does not contain a property with the given name + @throws NotRemoveableException + if the property with the given name is not removeable, as indicated + by the property attributes used in a previous <code>addProperty</code> + call. + */ + void removeProperty( + const ::rtl::OUString& _rName + ); + + /** describes all properties in the bag + @param _out_rProps + takes, upon return, the descriptions of all properties in the bag + */ + inline void describeProperties( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rProps + ) const + { + OPropertyContainerHelper::describeProperties( _out_rProps ); + } + + /** retrieves the value of a property given by handle + @param _nHandle + the handle of the property whose value is to be retrieved + @param _out_rValue + output parameter taking the property value + @throws UnknownPropertyException + if the given handle does not denote a property in the bag + */ + void getFastPropertyValue( + sal_Int32 _nHandle, + ::com::sun::star::uno::Any& _out_rValue + ) const; + + /** converts a to-be-set value of a property (given by handle) so that it can + be used in subsequent calls to setFastPropertyValue + @param _nHandle + the handle of the property + @param _rNewValue + the new value, which should be converted + @param _out_rConvertedValue + output parameter taking the converted value + @param _out_rCurrentValue + output parameter taking the current value of the + property + @throws UnknownPropertyException + if the given handle does not denote a property in the bag + @throws IllegalArgumentException + if the given value cannot be lossless converted into a value + for the given property. + */ + bool convertFastPropertyValue( + sal_Int32 _nHandle, + const ::com::sun::star::uno::Any& _rNewValue, + ::com::sun::star::uno::Any& _out_rConvertedValue, + ::com::sun::star::uno::Any& _out_rCurrentValue + ) const; + + /** sets a new value for a property given by handle + @throws UnknownPropertyException + if the given handle does not denote a property in the bag + */ + void setFastPropertyValue( + sal_Int32 _nHandle, + const ::com::sun::star::uno::Any& _rValue + ); + + /** returns the default value for a property given by handle + + The default value of a property is its initial value, as passed + to ->addProperty. + + @param _nHandle + handle of the property whose default value is to be obtained + @param _out_rValue + the default value + @throws UnknownPropertyException + if the given handle does not denote a property in the bag + */ + void getPropertyDefaultByHandle( + sal_Int32 _nHandle, + ::com::sun::star::uno::Any& _out_rValue + ) const; + + /** determines whether a property with a given name is part of the bag + */ + inline bool hasPropertyByName( const ::rtl::OUString& _rName ) const + { + return isRegisteredProperty( _rName ); + } + + /** determines whether a property with a given handle is part of the bag + */ + inline bool hasPropertyByHandle( sal_Int32 _nHandle ) const + { + return isRegisteredProperty( _nHandle ); + } + protected: + using OPropertyContainerHelper::convertFastPropertyValue; + using OPropertyContainerHelper::getFastPropertyValue; + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_PROPERTYBAG_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propertycontainer.hxx b/comphelper/inc/comphelper/propertycontainer.hxx new file mode 100644 index 000000000000..49961e559ea7 --- /dev/null +++ b/comphelper/inc/comphelper/propertycontainer.hxx @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTYCONTAINER_HXX_ +#define _COMPHELPER_PROPERTYCONTAINER_HXX_ + +#include <comphelper/propertycontainerhelper.hxx> +#include <cppuhelper/propshlp.hxx> +#include <com/sun/star/uno/Type.hxx> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +//========================================================================== +//= OPropertyContainer +//========================================================================== +typedef ::cppu::OPropertySetHelper OPropertyContainer_Base; +/** a OPropertySetHelper implementation which is just a simple container for properties represented + by class members, usually in a derived class. + <BR> + A restriction of this class is that no value conversions are made on a setPropertyValue call. Though + the base class supports this with the convertFastPropertyValue method, the OPropertyContainer accepts only + values which already have the correct type, it's unable to convert, for instance, a long to a short. +*/ +class COMPHELPER_DLLPUBLIC OPropertyContainer + :public OPropertyContainer_Base + ,public OPropertyContainerHelper +{ +public: + // this dtor is needed otherwise we can get a wrong delete operator + virtual ~OPropertyContainer(); + +protected: + OPropertyContainer(::cppu::OBroadcastHelper& _rBHelper); + + /// for scripting : the types of the interfaces supported by this class + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + +// OPropertySetHelper overridables + virtual sal_Bool SAL_CALL convertFastPropertyValue( + ::com::sun::star::uno::Any & rConvertedValue, + ::com::sun::star::uno::Any & rOldValue, + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::lang::IllegalArgumentException); + + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue + ) + throw (::com::sun::star::uno::Exception); + + using OPropertyContainer_Base::getFastPropertyValue; + virtual void SAL_CALL getFastPropertyValue( + ::com::sun::star::uno::Any& rValue, + sal_Int32 nHandle + ) const; + + // disambiguate a base class method (XFastPropertySet) + virtual void SAL_CALL setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); +}; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_PROPERTYCONTAINER_HXX_ + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propertycontainerhelper.hxx b/comphelper/inc/comphelper/propertycontainerhelper.hxx new file mode 100644 index 000000000000..e6439ea34e96 --- /dev/null +++ b/comphelper/inc/comphelper/propertycontainerhelper.hxx @@ -0,0 +1,219 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_PROPERTYCONTAINERHELPER_HXX +#define COMPHELPER_PROPERTYCONTAINERHELPER_HXX + +#include <cppuhelper/propshlp.hxx> +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/beans/Property.hpp> +#include <vector> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +// infos about one single property +struct COMPHELPER_DLLPUBLIC PropertyDescription +{ + // the possibilities where a property holding object may be located + enum LocationType + { + ltDerivedClassRealType, // within the derived class, it's a "real" (non-Any) type + ltDerivedClassAnyType, // within the derived class, it's a <type scope="com.sun.star.uno">Any</type> + ltHoldMyself // within m_aHoldProperties + }; + // the location of an object holding a property value : + union LocationAccess + { + void* pDerivedClassMember; // a pointer to a member of an object of a derived class + sal_Int32 nOwnClassVectorIndex; // an index within m_aHoldProperties + }; + + ::com::sun::star::beans::Property + aProperty; + LocationType eLocated; // where is the object containing the value located ? + LocationAccess aLocation; // access to the property value + + PropertyDescription() + :aProperty( ::rtl::OUString(), -1, ::com::sun::star::uno::Type(), 0 ) + ,eLocated( ltHoldMyself ) + { + aLocation.nOwnClassVectorIndex = -1; + } +}; + +//========================================================================== +//= OPropertyContainerHelper +//========================================================================== +/** helper class for managing property values, and implementing most of the X*Property* interfaces + + The property values are usually held in derived classes, but can also be given to the + responsibility of this class here. + + For more information, see http://wiki.services.openoffice.org/wiki/Development/Cpp/Helper/PropertyContainerHelper. +*/ +class COMPHELPER_DLLPUBLIC OPropertyContainerHelper +{ + typedef ::std::vector< ::com::sun::star::uno::Any > PropertyContainer; + typedef PropertyContainer::iterator PropertyContainerIterator; + typedef PropertyContainer::const_iterator ConstPropertyContainerIterator; + PropertyContainer m_aHoldProperties; + // the properties which are hold by this class' instance, not the derived one's + +private: + typedef ::std::vector< PropertyDescription > Properties; + typedef Properties::iterator PropertiesIterator; + typedef Properties::const_iterator ConstPropertiesIterator; + Properties m_aProperties; + + sal_Bool m_bUnused; + +protected: + OPropertyContainerHelper(); + ~OPropertyContainerHelper(); + + /** register a property. The property is represented through a member of the derived class which calls + this methdod. + @param _rName the name of the property + @param _nHandle the handle of the property + @param _nAttributes the attributes of the property + @param _pPointerToMember the pointer to the member representing the property + within the derived class. + @param _rMemberType the cppu type of the property represented by the object + to which _pPointerToMember points. + */ + void registerProperty(const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, + void* _pPointerToMember, const ::com::sun::star::uno::Type& _rMemberType); + + + /** register a property. The property is represented through a ::com::sun::star::uno::Any member of the + derived class which calls this methdod. + @param _rName the name of the property + @param _nHandle the handle of the property + @param _nAttributes the attributes of the property + @param _pPointerToMember the pointer to the member representing the property + within the derived class, which has to be a ::com::sun::star::uno::Any. + @param _rExpectedType the expected type of the property. NOT the type of the object to which + _pPointerToMember points (this is always an Any). + */ + void registerMayBeVoidProperty(const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, + ::com::sun::star::uno::Any* _pPointerToMember, const ::com::sun::star::uno::Type& _rExpectedType); + + /** register a property. The repository will create an own object holding this property, so there is no + need to declare an extra member in your derived class + @param _rName the name of the property + @param _nHandle the handle of the property + @param _nAttributes the attributes of the property + @param _rType the type of the property + @param _pInitialValue the initial value of the property. May be null if _nAttributes includes + the ::com::sun::star::beans::PropertyAttribute::MAYBEVOID flag. + Else it must be a pointer to an object of the type described by _rType. + */ + void registerPropertyNoMember(const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, + const ::com::sun::star::uno::Type& _rType, const void* _pInitialValue); + + /** revokes a previously registered property + @throw com::sun::star::beans::UnknownPropertyException + if no property with the given handle is registered + */ + void revokeProperty( sal_Int32 _nHandle ); + + + /// checkes whether a property with the given handle has been registered + sal_Bool isRegisteredProperty( sal_Int32 _nHandle ) const; + + /// checkes whether a property with the given name has been registered + sal_Bool isRegisteredProperty( const ::rtl::OUString& _rName ) const; + + + // helper for implementing OPropertySetHelper overridables + sal_Bool convertFastPropertyValue( + ::com::sun::star::uno::Any & rConvertedValue, + ::com::sun::star::uno::Any & rOldValue, + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue + ) + SAL_THROW((::com::sun::star::lang::IllegalArgumentException)); + + void setFastPropertyValue( + sal_Int32 nHandle, + const ::com::sun::star::uno::Any& rValue + ) + SAL_THROW((::com::sun::star::uno::Exception)); + + void getFastPropertyValue( + ::com::sun::star::uno::Any& rValue, + sal_Int32 nHandle + ) const; + +// helper + /** appends the descriptions of all properties which were registered 'til that moment to the given sequence, + keeping the array sorted (by name) + @precond + the given sequence is already sorted by name + @param _rProps + initial property sequence which is to be extended + */ + void describeProperties(::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps) const; + + /** modify the attributes of an already registered property. + + You may want to use this if you're a derived from OPropertyContainer indirectly and want to override + some settings your base class did. + */ + void modifyAttributes(sal_Int32 _nHandle, sal_Int32 _nAddAttrib, sal_Int32 _nRemoveAttrib); + + /** retrieves the description for a registered property + @throw com::sun::star::beans::UnknownPropertyException + if no property with the given name is registered + */ + const ::com::sun::star::beans::Property& + getProperty( const ::rtl::OUString& _rName ) const; + +private: + /// insertion of _rProp into m_aProperties, keeping the sort order + COMPHELPER_DLLPRIVATE void implPushBackProperty(const PropertyDescription& _rProp); + + /// search the PropertyDescription for the given handle (within m_aProperties) + COMPHELPER_DLLPRIVATE PropertiesIterator searchHandle(sal_Int32 _nHandle); + +private: + COMPHELPER_DLLPRIVATE OPropertyContainerHelper( const OPropertyContainerHelper& ); // never implemented + COMPHELPER_DLLPRIVATE OPropertyContainerHelper& operator=( const OPropertyContainerHelper& ); // never implemented +}; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // COMPHELPER_PROPERTYCONTAINERHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propertysethelper.hxx b/comphelper/inc/comphelper/propertysethelper.hxx new file mode 100644 index 000000000000..ea6204d6795f --- /dev/null +++ b/comphelper/inc/comphelper/propertysethelper.hxx @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTYSETHELPER_HXX_ +#define _COMPHELPER_PROPERTYSETHELPER_HXX_ + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include "comphelper/comphelperdllapi.h" + +//========================================================================= +//= property helper classes +//========================================================================= + +//... namespace comphelper ................................................ +namespace comphelper +{ +//......................................................................... + +class PropertySetInfo; +struct PropertyMapEntry; +class PropertySetHelperImpl; + +class COMPHELPER_DLLPUBLIC PropertySetHelper : public ::com::sun::star::beans::XPropertySet, + public ::com::sun::star::beans::XPropertyState, + public ::com::sun::star::beans::XMultiPropertySet +{ +private: + PropertySetHelperImpl* mp; + +protected: + virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const ::com::sun::star::uno::Any* pValues ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) = 0; + virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, ::com::sun::star::uno::Any* pValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException ) = 0; + + virtual void _getPropertyStates( const comphelper::PropertyMapEntry** ppEntries, ::com::sun::star::beans::PropertyState* pStates ) throw(::com::sun::star::beans::UnknownPropertyException ); + virtual void _setPropertyToDefault( const comphelper::PropertyMapEntry* pEntry ) throw(::com::sun::star::beans::UnknownPropertyException ); + virtual ::com::sun::star::uno::Any _getPropertyDefault( const comphelper::PropertyMapEntry* pEntry ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException ); + + // allow setting of properties after construction + void setInfo( comphelper::PropertySetInfo* pInfo ) throw(); + +public: + PropertySetHelper( ); + PropertySetHelper( comphelper::PropertySetInfo* pInfo ) throw(); + PropertySetHelper( comphelper::PropertySetInfo* pInfo, __sal_NoAcquire ) throw(); + virtual ~PropertySetHelper() throw(); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XMultiPropertySet +// virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues ) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertiesChangeListener( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertiesChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL firePropertiesChangeEvent( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException); + + // XPropertyState + virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); +}; + +//......................................................................... +} +//... namespace comphelper.................................................. + +#endif // _UTL_PROPERTYSETHELPER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propertysetinfo.hxx b/comphelper/inc/comphelper/propertysetinfo.hxx new file mode 100644 index 000000000000..80a200a79b3a --- /dev/null +++ b/comphelper/inc/comphelper/propertysetinfo.hxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTSETINFO_HXX_ +#define _COMPHELPER_PROPERTSETINFO_HXX_ + +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/stl_types.hxx> +#include "comphelper/comphelperdllapi.h" + +//========================================================================= +//= property helper classes +//========================================================================= + +//... namespace comphelper ....................................................... +namespace comphelper +{ +//......................................................................... + +struct PropertyMapEntry +{ + const sal_Char* mpName; + sal_uInt16 mnNameLen; + sal_Int32 mnHandle; + const com::sun::star::uno::Type* mpType; + sal_Int16 mnAttributes; + sal_uInt8 mnMemberId; +}; + +DECLARE_STL_USTRINGACCESS_MAP( PropertyMapEntry*, PropertyMap ); + +class PropertyMapImpl; + +/** this class implements a XPropertySetInfo that is initialized with arrays of PropertyMapEntry. + It is used by the class PropertySetHelper. +*/ +class COMPHELPER_DLLPUBLIC PropertySetInfo : public ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo > +{ +private: + PropertyMapImpl* mpMap; +public: + PropertySetInfo() throw(); + PropertySetInfo( PropertyMapEntry* pMap ) throw(); + virtual ~PropertySetInfo() throw(); + + /** returns a stl map with all PropertyMapEntry pointer.<p> + The key is the property name. + */ + const PropertyMap* getPropertyMap() const throw(); + + /** adds an array of PropertyMapEntry to this instance.<p> + The end is marked with a PropertyMapEntry where mpName equals NULL</p> + */ + void add( PropertyMapEntry* pMap ) throw(); + + /** adds an array of PropertyMapEntry to this instance + + <p>At most the number of entries given will be added, if no terminating entry (<code>mpName == <NULL/></code>) is encountered.</p> + + <p>If <arg>nCount</arg> is less than 0, it is ignored and all entries (up to, but not including, the terminating + one) are added.</p> + */ + void add( PropertyMapEntry* pMap, sal_Int32 nCount ) throw(); + + /** removes an already added PropertyMapEntry which string in mpName equals to aName */ + void remove( const rtl::OUString& aName ) throw(); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties() throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw(::com::sun::star::uno::RuntimeException); +}; + +//......................................................................... +} +//... namespace comphelper ....................................................... + +#endif // _UTL_PROPERTSETINFO_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propertystatecontainer.hxx b/comphelper/inc/comphelper/propertystatecontainer.hxx new file mode 100644 index 000000000000..443c52fdf753 --- /dev/null +++ b/comphelper/inc/comphelper/propertystatecontainer.hxx @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_PROPERTYSTATECONTAINER_HXX +#define COMPHELPER_PROPERTYSTATECONTAINER_HXX + +#include <comphelper/propertycontainer.hxx> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/uno3.hxx> +#include <osl/diagnose.h> +#include "comphelper/comphelperdllapi.h" + +#include <map> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //===================================================================== + //= OPropertyStateContainer + //===================================================================== + typedef ::cppu::ImplHelper1 < ::com::sun::star::beans::XPropertyState + > OPropertyStateContainer_TBase; + + /** helper implementation for components which have properties with a default + + <p>This class is not intended for direct use, you need to derive from it.</p> + + @see com.sun.star.beans.XPropertyState + */ + class COMPHELPER_DLLPUBLIC OPropertyStateContainer + :public OPropertyContainer + ,public OPropertyStateContainer_TBase + { + protected: + /** ctor + @param _rBHelper + help to be used for broadcasting events + */ + OPropertyStateContainer( ::cppu::OBroadcastHelper& _rBHelper ); + + // ................................................................ + // XPropertyState + virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( const ::rtl::OUString& PropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // ................................................................ + // own overridables + // these are the impl-methods for the XPropertyState members - they are implemented already by this class, + // but you may want to override them for whatever reasons (for instance, if your derived class + // supports the AMBIGUOUS state for properties) + + /** get the PropertyState of the property denoted by the given handle + + <p>Already implemented by this base class, no need to override</p> + @precond <arg>_nHandle</arg> is a valid property handle + */ + virtual ::com::sun::star::beans::PropertyState getPropertyStateByHandle( sal_Int32 _nHandle ); + + /** set the property denoted by the given handle to it's default value + + <p>Already implemented by this base class, no need to override</p> + @precond <arg>_nHandle</arg> is a valid property handle + */ + virtual void setPropertyToDefaultByHandle( sal_Int32 _nHandle ); + + /** get the default value for the property denoted by the given handle + + @precond + <arg>_nHandle</arg> is a valid property handle + */ + virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _rDefault ) const = 0; + + protected: + // XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + protected: + /** returns the handle for the given name + + @throw UnknownPropertyException if the given name is not a registered property + */ + sal_Int32 getHandleForName( const ::rtl::OUString& _rPropertyName ) SAL_THROW( ( ::com::sun::star::beans::UnknownPropertyException ) ); + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // COMPHELPER_PROPERTYSTATECONTAINER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propmultiplex.hxx b/comphelper/inc/comphelper/propmultiplex.hxx new file mode 100644 index 000000000000..3c82dee247dd --- /dev/null +++ b/comphelper/inc/comphelper/propmultiplex.hxx @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTY_MULTIPLEX_HXX_ +#define _COMPHELPER_PROPERTY_MULTIPLEX_HXX_ + +#include <comphelper/propstate.hxx> +#include <cppuhelper/implbase1.hxx> +#include "comphelper/comphelperdllapi.h" + +//========================================================================= +//= property helper classes +//========================================================================= + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + class OPropertyChangeMultiplexer; + + //================================================================== + //= OPropertyChangeListener + //================================================================== + /// simple listener adapter for property sets + class COMPHELPER_DLLPUBLIC OPropertyChangeListener + { + friend class OPropertyChangeMultiplexer; + + OPropertyChangeMultiplexer* m_pAdapter; + ::osl::Mutex& m_rMutex; + + public: + OPropertyChangeListener(::osl::Mutex& _rMutex) + : m_pAdapter(NULL), m_rMutex(_rMutex) { } + virtual ~OPropertyChangeListener(); + + virtual void _propertyChanged(const ::com::sun::star::beans::PropertyChangeEvent& _rEvent) throw( ::com::sun::star::uno::RuntimeException) = 0; + virtual void _disposing(const ::com::sun::star::lang::EventObject& _rSource) throw( ::com::sun::star::uno::RuntimeException); + + protected: + /** If the derivee also owns the mutex which we know as reference, then call this within your + derivee's dtor. + */ + void disposeAdapter(); + + // pseudo-private. Making it private now could break compatibility + void setAdapter( OPropertyChangeMultiplexer* _pAdapter ); + }; + + //================================================================== + //= OPropertyChangeMultiplexer + //================================================================== + /// multiplexer for property changes + class COMPHELPER_DLLPUBLIC OPropertyChangeMultiplexer :public cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertyChangeListener> + { + friend class OPropertyChangeListener; + ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aProperties; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> m_xSet; + OPropertyChangeListener* m_pListener; + sal_Int32 m_nLockCount; + sal_Bool m_bListening : 1; + sal_Bool m_bAutoSetRelease : 1; + + + virtual ~OPropertyChangeMultiplexer(); + public: + OPropertyChangeMultiplexer(OPropertyChangeListener* _pListener, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _rxSet, sal_Bool _bAutoReleaseSet = sal_True); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw( ::com::sun::star::uno::RuntimeException); + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw( ::com::sun::star::uno::RuntimeException); + + /// incremental lock + void lock(); + /// incremental unlock + void unlock(); + /// get the lock count + sal_Int32 locked() const { return m_nLockCount; } + + void addProperty(const ::rtl::OUString& aPropertyName); + void dispose(); + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_PROPERTY_MULTIPLEX_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/propstate.hxx b/comphelper/inc/comphelper/propstate.hxx new file mode 100644 index 000000000000..2c8f06f4118a --- /dev/null +++ b/comphelper/inc/comphelper/propstate.hxx @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_PROPERTY_STATE_HXX_ +#define _COMPHELPER_PROPERTY_STATE_HXX_ + +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/uno/Sequence.hxx> + + +#include <cppuhelper/propshlp.hxx> +#include <cppuhelper/proptypehlp.hxx> +#include <cppuhelper/weak.hxx> +#include <comphelper/uno3.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include "comphelper/comphelperdllapi.h" + +//========================================================================= +//= property helper classes +//========================================================================= + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //================================================================== + //= OPropertyStateHelper + //================================================================== + /// helper class for implementing property states + class COMPHELPER_DLLPUBLIC OPropertyStateHelper :public ::cppu::OPropertySetHelper + ,public ::com::sun::star::beans::XPropertyState + { + public: + OPropertyStateHelper(::cppu::OBroadcastHelper& rBHlp):OPropertySetHelper(rBHlp) { } + OPropertyStateHelper(::cppu::OBroadcastHelper& rBHlp, + ::cppu::IEventNotificationHook *i_pFireEvents); + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type& aType) throw(::com::sun::star::uno::RuntimeException); + + // XPropertyState + virtual ::com::sun::star::beans::PropertyState SAL_CALL + getPropertyState(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState> SAL_CALL + getPropertyStates(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL + setPropertyToDefault(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL + getPropertyDefault(const ::rtl::OUString& aPropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // access via handle + virtual ::com::sun::star::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle); + virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle); + virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle(sal_Int32 nHandle) const; + + protected: + virtual ~OPropertyStateHelper(); + + void firePropertyChange(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aNewValue, const ::com::sun::star::uno::Any& aOldValue); + + protected: + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); + }; + + //================================================================== + //= OPropertyStateHelper + //================================================================== + class COMPHELPER_DLLPUBLIC OStatefulPropertySet :public ::cppu::OWeakObject + ,public ::com::sun::star::lang::XTypeProvider + ,public OMutexAndBroadcastHelper // order matters: before OPropertyStateHelper/OPropertySetHelper + ,public OPropertyStateHelper + { + protected: + OStatefulPropertySet(); + virtual ~OStatefulPropertySet(); + + protected: + DECLARE_XINTERFACE() + DECLARE_XTYPEPROVIDER() + }; + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_PROPERTY_STATE_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/proxyaggregation.hxx b/comphelper/inc/comphelper/proxyaggregation.hxx new file mode 100644 index 000000000000..490569844a81 --- /dev/null +++ b/comphelper/inc/comphelper/proxyaggregation.hxx @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_PROXY_AGGREGATION +#define COMPHELPER_PROXY_AGGREGATION + +#include <com/sun/star/uno/XAggregation.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <comphelper/uno3.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <cppuhelper/compbase_ex.hxx> +#include "comphelper/comphelperdllapi.h" + +/* class hierarchy herein: + + +-------------------+ helper class for aggregating the proxy to another object + | OProxyAggregation | - not ref counted + +-------------------+ - no UNO implementation, i.e. not derived from XInterface + ^ (neither direct nor indirect) + | + | + +----------------------------------+ helper class for aggregating a proxy to an XComponent + | OComponentProxyAggregationHelper | - life time coupling: if the inner component (the "aggregate") + +----------------------------------+ is disposed, the outer (the delegator) is disposed, too, and + ^ vice versa + | - UNO based, implementing XEventListener + | + +----------------------------+ component aggregating another XComponent + | OComponentProxyAggregation | - life time coupling as above + +----------------------------+ - ref-counted + - implements an XComponent itself + + If you need to + + - wrap a foreign object which is a XComponent + => use OComponentProxyAggregation + - call componentAggregateProxyFor in your ctor + - call implEnsureDisposeInDtor in your dtor + + - wrap a foreign object which is a XComponent, but already have ref-counting mechanisms + inherited from somewhere else + => use OComponentProxyAggregationHelper + - override dispose - don't forget to call the base class' dispose! + - call componentAggregateProxyFor in your ctor + + - wrap a foreign object which is no XComponent + => use OProxyAggregation + - call baseAggregateProxyFor in your ctor +*/ + +//............................................................................. +namespace comphelper +{ +//............................................................................. + + //========================================================================= + //= OProxyAggregation + //========================================================================= + /** helper class for aggregating a proxy for a foreign object + */ + class OProxyAggregation + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation > m_xProxyAggregate; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XTypeProvider > m_xProxyTypeAccess; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xORB; + + protected: + inline const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& getORB() + { + return m_xORB; + } + + protected: + OProxyAggregation( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB ); + ~OProxyAggregation(); + + /// to be called from within your ctor + void baseAggregateProxyFor( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxComponent, + oslInterlockedCount& _rRefCount, + ::cppu::OWeakObject& _rDelegator + ); + + // XInterface and XTypeProvider + ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw (::com::sun::star::uno::RuntimeException); + + private: + OProxyAggregation( ); // never implemented + OProxyAggregation( const OProxyAggregation& ); // never implemented + OProxyAggregation& operator=( const OProxyAggregation& ); // never implemented + }; + + //========================================================================= + //= OComponentProxyAggregationHelper + //========================================================================= + /** a helper class for aggregating a proxy to an XComponent + + <p>The object couples the life time of itself and the component: if one of the both + dies (in a sense of being disposed), the other one dies, too.</p> + + <p>The class itself does not implement XComponent so you need to forward any XComponent::dispose + calls which your derived class gets to the dispose method of this class.</p> + */ + + class COMPHELPER_DLLPUBLIC OComponentProxyAggregationHelper :public ::cppu::ImplHelper1 < com::sun::star::lang::XEventListener + > + ,private OProxyAggregation + { + private: + typedef ::cppu::ImplHelper1 < ::com::sun::star::lang::XEventListener + > BASE; // prevents some MSVC problems + + protected: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > + m_xInner; + ::cppu::OBroadcastHelper& m_rBHelper; + + protected: + // OProxyAggregation + using OProxyAggregation::getORB; + + // XInterface + ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + protected: + OComponentProxyAggregationHelper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB, + ::cppu::OBroadcastHelper& _rBHelper + ); + virtual ~OComponentProxyAggregationHelper( ); + + /// to be called from within your ctor + void componentAggregateProxyFor( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& _rxComponent, + oslInterlockedCount& _rRefCount, + ::cppu::OWeakObject& _rDelegator + ); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose() throw( ::com::sun::star::uno::RuntimeException ); + + private: + COMPHELPER_DLLPRIVATE OComponentProxyAggregationHelper( ); // never implemented + COMPHELPER_DLLPRIVATE OComponentProxyAggregationHelper( const OComponentProxyAggregationHelper& ); // never implemented + COMPHELPER_DLLPRIVATE OComponentProxyAggregationHelper& operator=( const OComponentProxyAggregationHelper& ); // never implemented + }; + + //========================================================================= + //= OComponentProxyAggregation + //========================================================================= + typedef ::cppu::WeakComponentImplHelperBase OComponentProxyAggregation_CBase; + + class COMPHELPER_DLLPUBLIC OComponentProxyAggregation :public OBaseMutex + ,public OComponentProxyAggregation_CBase + ,public OComponentProxyAggregationHelper + { + protected: + OComponentProxyAggregation( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& _rxComponent + ); + + virtual ~OComponentProxyAggregation(); + + // XInterface + DECLARE_XINTERFACE() + // XTypeProvider + DECLARE_XTYPEPROVIDER() + + // OComponentHelper + virtual void SAL_CALL disposing() throw (::com::sun::star::uno::RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& _rSource ) throw (::com::sun::star::uno::RuntimeException); + + // XComponent/OComponentProxyAggregationHelper + virtual void SAL_CALL dispose() throw( ::com::sun::star::uno::RuntimeException ); + + protected: + // be called from within the dtor of derived classes + void implEnsureDisposeInDtor( ); + + private: + COMPHELPER_DLLPRIVATE OComponentProxyAggregation( ); // never implemented + COMPHELPER_DLLPRIVATE OComponentProxyAggregation( const OComponentProxyAggregation& ); // never implemented + COMPHELPER_DLLPRIVATE OComponentProxyAggregation& operator=( const OComponentProxyAggregation& ); // never implemented + }; + +//............................................................................. +} // namespace comphelper +//............................................................................. + + +#endif // COMPHELPER_PROXY_AGGREGATION + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/regpathhelper.hxx b/comphelper/inc/comphelper/regpathhelper.hxx new file mode 100644 index 000000000000..27bbcb84287a --- /dev/null +++ b/comphelper/inc/comphelper/regpathhelper.hxx @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_REGPATHHELPER_HXX_ +#define _COMPHELPER_REGPATHHELPER_HXX_ + +#include <rtl/ustring.hxx> + +namespace comphelper +{ + +/** + * This function returns a path to the user registry file. + * Search for the user registry using the following rules: + * <dl> + * <dt> 1. (for further use) search in sversion.ini (.sversionrc) for an entry + * REGISTRY_VERSION_STRING (example: UserRegistry 5.0/505=test.rdb) in the section + * [Registry]. If found, then take this value instead of the name "user.rdb". + * <dt> 2. Search in the config directory of the user for a file "user.rdb". If + * found return the full path and name of the file. If not found, retry this + * step with a dot before ".user.rdb". + * <dt> 3. If not found a new user registry with name "user.rdb" will be created in the user + * config directory. + * </dl> + *<BR> + * @author Juergen Schmidt + */ +::rtl::OUString getPathToUserRegistry(); + +/** + * This function returns a path to the system registry file. + * The system registry will always be searched in the same directory of the + * executable. The name of the system registry is "applicat.rdb". If the system + * registry was not found, then the environment variable STAR_REGISTRY will be checked. + * If this variable was set, it must contain a full path to a valid system registry. + * Search for the user registry using the following rules: + * + *<BR> + * @author Juergen Schmidt + */ + +::rtl::OUString getPathToSystemRegistry(); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/scoped_disposing_ptr.hxx b/comphelper/inc/comphelper/scoped_disposing_ptr.hxx new file mode 100644 index 000000000000..7278126c2633 --- /dev/null +++ b/comphelper/inc/comphelper/scoped_disposing_ptr.hxx @@ -0,0 +1,178 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is + * Caolán McNamara <caolanm@redhat.com> (Red Hat, Inc.) + * Portions created by the Initial Developer are Copyright (C) 2011 the + * Initial Developer. All Rights Reserved. + * + * Contributor(s): Caolán McNamara <caolanm@redhat.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ +#ifndef _SCOPED_DISPOSING_PTR +#define _SCOPED_DISPOSING_PTR + +#include <cppuhelper/implbase1.hxx> +#include <boost/utility.hpp> +#include <boost/scoped_ptr.hpp> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/frame/XDesktop.hpp> + +// for locking SolarMutex: svapp + mutex +#include <vcl/svapp.hxx> +#include <osl/mutex.hxx> + +namespace comphelper +{ +//Similar to boost::scoped_ptr, except additionally releases the ptr on XComponent::disposing and/or XTerminateListener::notifyTermination if supported +template<class T> class scoped_disposing_ptr : private boost::noncopyable +{ +private: + boost::scoped_ptr<T> m_aItem; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTerminateListener> m_xTerminateListener; +public: + scoped_disposing_ptr( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > &rComponent, T * p = 0 ) + : m_aItem(p) + { + m_xTerminateListener = new TerminateListener(rComponent, *this); + } + + virtual void reset(T * p = 0) + { + m_aItem.reset(p); + } + + T & operator*() const + { + return *m_aItem; + } + + T * get() const + { + return m_aItem.get(); + } + + T * operator->() const + { + return m_aItem.get(); + } + + operator bool () const + { + return m_aItem; + } + + virtual ~scoped_disposing_ptr() + { + reset(); + } +private: + class TerminateListener : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XTerminateListener > + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > m_xComponent; + scoped_disposing_ptr<T>& m_rItem; + public: + TerminateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > &rComponent, + scoped_disposing_ptr<T>& rItem) : m_xComponent(rComponent), m_rItem(rItem) + { + if (m_xComponent.is()) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop> xDesktop(m_xComponent, ::com::sun::star::uno::UNO_QUERY); + if (xDesktop.is()) + xDesktop->addTerminateListener(this); + else + m_xComponent->addEventListener(this); + } + } + + ~TerminateListener() + { + if ( m_xComponent.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop> xDesktop(m_xComponent, ::com::sun::star::uno::UNO_QUERY); + if (xDesktop.is()) + xDesktop->removeTerminateListener(this); + else + m_xComponent->removeEventListener(this); + } + } + + private: + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& rEvt ) + throw (::com::sun::star::uno::RuntimeException) + { + bool shutDown = (rEvt.Source == m_xComponent); + + if (shutDown && m_xComponent.is()) + { + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop> xDesktop(m_xComponent, ::com::sun::star::uno::UNO_QUERY); + if (xDesktop.is()) + xDesktop->removeTerminateListener(this); + else + m_xComponent->removeEventListener(this); + m_xComponent.clear(); + } + + if (shutDown) + m_rItem.reset(); + } + + // XTerminateListener + virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& ) + throw(::com::sun::star::frame::TerminationVetoException, + ::com::sun::star::uno::RuntimeException) + { + } + + virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& rEvt ) + throw (::com::sun::star::uno::RuntimeException) + { + disposing(rEvt); + } + }; +}; + +//Something like an OutputDevice requires the SolarMutex to be taken before use +//for threadsafety. The user can ensure this, except in the case of its dtor +//being called from reset due to a terminate on the XComponent being called +//from an aribitrary thread +template<class T> class scoped_disposing_solar_mutex_reset_ptr + : public scoped_disposing_ptr<T> +{ +public: + scoped_disposing_solar_mutex_reset_ptr( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > &rComponent, T * p = 0 ) + : scoped_disposing_ptr<T>(rComponent, p) + { + } + + virtual void reset(T * p = 0) + { + SolarMutexGuard aGuard; + scoped_disposing_ptr<T>::reset(p); + } +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/scopeguard.hxx b/comphelper/inc/comphelper/scopeguard.hxx new file mode 100644 index 000000000000..33c4f710c945 --- /dev/null +++ b/comphelper/inc/comphelper/scopeguard.hxx @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_SCOPEGUARD_HXX) +#define INCLUDED_COMPHELPER_SCOPEGUARD_HXX + +#if ! defined(INCLUDED_COMPHELPERDLLAPI_H) +#include "comphelper/comphelperdllapi.h" +#endif +#include "boost/function.hpp" +#include "boost/noncopyable.hpp" +#include "boost/bind.hpp" + +namespace comphelper { + +/** ScopeGuard to ease writing exception-safe code. + */ +class COMPHELPER_DLLPUBLIC ScopeGuard : private ::boost::noncopyable + // noncopyable until we have + // good reasons... +{ +public: + enum exc_handling { IGNORE_EXCEPTIONS, ALLOW_EXCEPTIONS }; + + /** @param func function object to be executed in dtor + @param excHandling switches whether thrown exceptions in dtor will be + silently ignored (but OSL_ asserted) + */ + template <typename func_type> + explicit ScopeGuard( func_type const & func, + exc_handling excHandling = IGNORE_EXCEPTIONS ) + : m_func( func ), m_excHandling( excHandling ) {} + + ~ScopeGuard(); + + /** Dismisses the scope guard, i.e. the function won't + be executed. + */ + void dismiss(); + +private: + ::boost::function0<void> m_func; // preferring portable syntax + exc_handling const m_excHandling; +}; + +} // namespace comphelper + +#endif // ! defined(INCLUDED_COMPHELPER_SCOPEGUARD_HXX) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/seekableinput.hxx b/comphelper/inc/comphelper/seekableinput.hxx new file mode 100644 index 000000000000..455ed7bb183c --- /dev/null +++ b/comphelper/inc/comphelper/seekableinput.hxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_STREAM_SEEKABLEINPUT_HXX_ +#define _COMPHELPER_STREAM_SEEKABLEINPUT_HXX_ + +#include <osl/mutex.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <cppuhelper/implbase2.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + +class COMPHELPER_DLLPUBLIC OSeekableInputWrapper : public ::cppu::WeakImplHelper2< ::com::sun::star::io::XInputStream, + ::com::sun::star::io::XSeekable > +{ + ::osl::Mutex m_aMutex; + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xOriginalStream; + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xCopyInput; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable > m_xCopySeek; + +private: + COMPHELPER_DLLPRIVATE void PrepareCopy_Impl(); + +public: + OSeekableInputWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ); + + virtual ~OSeekableInputWrapper(); + + static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > CheckSeekableCanWrap( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ); + +// XInputStream + virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL available() throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeInput() throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + +// XSeekable + virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + +}; + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/seqstream.hxx b/comphelper/inc/comphelper/seqstream.hxx new file mode 100644 index 000000000000..82c335616926 --- /dev/null +++ b/comphelper/inc/comphelper/seqstream.hxx @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_SEQSTREAM_HXX +#define _COMPHELPER_SEQSTREAM_HXX + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <osl/mutex.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + + typedef ::com::sun::star::uno::Sequence<sal_Int8> ByteSequence; + +//================================================================== +// SequenceInputStream +// stream for reading data from a sequence of bytes +//================================================================== + + +class COMPHELPER_DLLPUBLIC SequenceInputStream +: public ::cppu::WeakImplHelper2< ::com::sun::star::io::XInputStream, ::com::sun::star::io::XSeekable > +{ + ::osl::Mutex m_aMutex; + ByteSequence m_aData; + sal_Int32 m_nPos; + +public: + SequenceInputStream(const ByteSequence& rData); + +// com::sun::star::io::XInputStream + virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, + ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, + ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, + ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL available( ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL closeInput( ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getPosition( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getLength( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + +private: + inline sal_Int32 avail(); +}; +typedef ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream > OSequenceOutputStream_Base; + +class OSequenceOutputStream : public OSequenceOutputStream_Base +{ +protected: + ::com::sun::star::uno::Sequence< sal_Int8 >& m_rSequence; + double m_nResizeFactor; + sal_Int32 m_nMinimumResize; + sal_Int32 m_nMaximumResize; + sal_Int32 m_nSize; + // the size of the virtual stream. This is not the size of the sequence, but the number of bytes written + // into the stream at a given moment. + + sal_Bool m_bConnected; + // closeOutput has been called ? + + ::osl::Mutex m_aMutex; + +protected: + ~OSequenceOutputStream() { if (m_bConnected) closeOutput(); } + +public: + /** constructs the object. Everything written into the stream through the XOutputStream methods will be forwarded + to the sequence, reallocating it if neccessary. Writing will start at offset 0 within the sequence. + @param _rSeq a reference to the sequence which will be used for output. + The caller is responsible for taking care of the lifetime of the stream + object and the sequence. If you're in doubt about this, use <code>closeOutput</code> + before destroying the sequence + @param _nResizeFactor the factor which is used for resizing the sequence when neccessary. In every + resize step, the new sequence size will be calculated by multiplying the current + size with this factor, rounded off to the next multiple of 4. + @param _nMinimumResize the minmal number of bytes which is additionally allocated on resizing + @param _nMaximumResize as the growth of the stream size is exponential, you may want to specify a + maxmimum amount of memory which the sequence will grow by. If -1 is used, + no limit is applied + @see closeOutput + */ + OSequenceOutputStream( + ::com::sun::star::uno::Sequence< sal_Int8 >& _rSeq, + double _nResizeFactor = 1.3, + sal_Int32 _nMinimumResize = 128, + sal_Int32 _nMaximumResize = -1 + ); + + /// same as XOutputStream::writeBytes (as expected :) + virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + /// this is a dummy in this implementation, no buffering is used + virtual void SAL_CALL flush( ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + /** closes the output stream. In the case of this class, this means that the sequence used for writing is + resized to the really used size and not used any further, every subsequent call to one of the XOutputStream + methods will throw a <code>NotConnectedException</code>. + */ + virtual void SAL_CALL closeOutput( ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); +}; + +} // namespace comphelper + +#endif //_COMPHELPER_SEQSTREAM_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/sequence.hxx b/comphelper/inc/comphelper/sequence.hxx new file mode 100644 index 000000000000..125668172fb1 --- /dev/null +++ b/comphelper/inc/comphelper/sequence.hxx @@ -0,0 +1,387 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_SEQUENCE_HXX_ +#define _COMPHELPER_SEQUENCE_HXX_ + +#ifndef INCLUDED_ALGORITHM +#include <algorithm> // copy algorithm +#define INCLUDED_ALGORITHM +#endif +#include <com/sun/star/uno/Sequence.hxx> +#include <osl/diagnose.h> +#include "comphelper/comphelperdllapi.h" + +#include <vector> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + namespace staruno = ::com::sun::star::uno; + + //------------------------------------------------------------------------- + /** search the given string within the given sequence, return the positions where it was found. + if _bOnlyFirst is sal_True, only the first occurrence will be returned. + */ + COMPHELPER_DLLPUBLIC staruno::Sequence<sal_Int16> findValue(const staruno::Sequence< ::rtl::OUString >& _rList, const ::rtl::OUString& _rValue, sal_Bool _bOnlyFirst = sal_False); + + /** Checks if the name exists + * + * \param Value The value to search for. + * \param _aList The list in which to search for the value. + * \return <TRUE/> if the value can be found, otherwise <FALSE/>. + */ + COMPHELPER_DLLPUBLIC sal_Bool existsValue(const ::rtl::OUString& Value,const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _aList); + + + //------------------------------------------------------------------------- + namespace internal + { + template <class T> + void implCopySequence(const T* _pSource, T*& _pDest, sal_Int32 _nSourceLen) + { + for (sal_Int32 i=0; i<_nSourceLen; ++i, ++_pSource, ++_pDest) + *_pDest = *_pSource; + } + } + //------------------------------------------------------------------------- + /// concat two sequences + template <class T> + staruno::Sequence<T> concatSequences(const staruno::Sequence<T>& _rLeft, const staruno::Sequence<T>& _rRight) + { + sal_Int32 nLeft(_rLeft.getLength()), nRight(_rRight.getLength()); + const T* pLeft = _rLeft.getConstArray(); + const T* pRight = _rRight.getConstArray(); + + sal_Int32 nReturnLen(nLeft + nRight); + staruno::Sequence<T> aReturn(nReturnLen); + T* pReturn = aReturn.getArray(); + + internal::implCopySequence(pLeft, pReturn, nLeft); + internal::implCopySequence(pRight, pReturn, nRight); + + return aReturn; + } + + //------------------------------------------------------------------------- + /// concat three sequences + template <class T> + staruno::Sequence<T> concatSequences(const staruno::Sequence<T>& _rLeft, const staruno::Sequence<T>& _rMiddle, const staruno::Sequence<T>& _rRight) + { + sal_Int32 nLeft(_rLeft.getLength()), nMiddle(_rMiddle.getLength()), nRight(_rRight.getLength()); + const T* pLeft = _rLeft.getConstArray(); + const T* pMiddle = _rMiddle.getConstArray(); + const T* pRight = _rRight.getConstArray(); + + sal_Int32 nReturnLen(nLeft + nMiddle + nRight); + staruno::Sequence<T> aReturn(nReturnLen); + T* pReturn = aReturn.getArray(); + + internal::implCopySequence(pLeft, pReturn, nLeft); + internal::implCopySequence(pMiddle, pReturn, nMiddle); + internal::implCopySequence(pRight, pReturn, nRight); + + return aReturn; + } + + //------------------------------------------------------------------------- + /// remove a specified element from a sequences + template<class T> + void removeElementAt(staruno::Sequence<T>& _rSeq, sal_Int32 _nPos) + { + sal_uInt32 nLength = _rSeq.getLength(); + + OSL_ENSURE(0 <= _nPos && (sal_uInt32)_nPos < nLength, "invalid index"); + + for (sal_uInt32 i = (sal_uInt32)_nPos + 1; i < nLength; ++i) + { + _rSeq[i-1] = _rSeq[i]; + } + + _rSeq.realloc(nLength-1); + } + + //===================================================================== + //= iterating through sequences + //===================================================================== + class SAL_NO_VTABLE IIterator + { + public: + virtual sal_Bool hasMoreElements() const = 0; + virtual ::com::sun::star::uno::Any nextElement() = 0; + }; + /** a helper class for iterating through a sequence + */ + template <class TYPE> + class OSequenceIterator : public IIterator + { + const TYPE* m_pElements; + sal_Int32 m_nLen; + const TYPE* m_pCurrent; + + public: + /** contrcuct a sequence iterator from a sequence + */ + OSequenceIterator(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq); + /** contrcuct a sequence iterator from a Any containing a sequence + */ + OSequenceIterator(const ::com::sun::star::uno::Any& _rSequenceAny); + + virtual sal_Bool hasMoreElements() const; + virtual ::com::sun::star::uno::Any nextElement(); + + protected: + void construct(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq); + }; + + //--------------------------------------------------------------------- + template <class TYPE> + OSequenceIterator<TYPE>::OSequenceIterator(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq) + :m_pElements(NULL) + ,m_nLen(0) + ,m_pCurrent(NULL) + { + construct(_rSeq); + } + + //--------------------------------------------------------------------- + template <class TYPE> + OSequenceIterator<TYPE>::OSequenceIterator(const ::com::sun::star::uno::Any& _rSequenceAny) + :m_pElements(NULL) + ,m_nLen(0) + ,m_pCurrent(NULL) + { + ::com::sun::star::uno::Sequence< TYPE > aContainer; + sal_Bool bSuccess = _rSequenceAny >>= aContainer; + OSL_ENSURE(bSuccess, "OSequenceIterator::OSequenceIterator: invalid Any!"); + (void)bSuccess; + construct(aContainer); + } + + //--------------------------------------------------------------------- + template <class TYPE> + void OSequenceIterator<TYPE>::construct(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq) + { + m_pElements = _rSeq.getConstArray(); + m_nLen = _rSeq.getLength(); + m_pCurrent = m_pElements; + } + + //--------------------------------------------------------------------- + template <class TYPE> + sal_Bool OSequenceIterator<TYPE>::hasMoreElements() const + { + return m_pCurrent - m_pElements < m_nLen; + } + + //--------------------------------------------------------------------- + template <class TYPE> + ::com::sun::star::uno::Any OSequenceIterator<TYPE>::nextElement() + { + return ::com::sun::star::uno::makeAny(*m_pCurrent++); + } + + //------------------------------------------------------------------------- + /** Copy from a plain C/C++ array into a Sequence. + + @tpl SrcType + Array element type. Must be assignable to DstType + + @tpl DstType + Sequence element type. Must be assignable from SrcType + + @param i_pArray + Valid pointer to at least num elements of type SrcType + + @param nNum + Number of array elements to copy + + @return the resulting Sequence + + @attention when copying from e.g. a double array to a + Sequence<int>, no proper rounding will be performed, but the + values will be truncated. There's currently no measure to + prevent or detect precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + ::com::sun::star::uno::Sequence< DstType > arrayToSequence( const SrcType* i_pArray, sal_Int32 nNum ) + { + ::com::sun::star::uno::Sequence< DstType > result( nNum ); + ::std::copy( i_pArray, i_pArray+nNum, result.getArray() ); + return result; + } + + //------------------------------------------------------------------------- + /** Copy from a Sequence into a plain C/C++ array + + @tpl SrcType + Sequence element type. Must be assignable to DstType + + @tpl DstType + Array element type. Must be assignable from SrcType + + @param io_pArray + Valid pointer to at least i_Sequence.getLength() elements of + type DstType + + @param i_Sequence + Reference to a Sequence of SrcType elements + + @return a pointer to the array + + @attention when copying from e.g. a Sequence<double> to an int + array, no proper rounding will be performed, but the values + will be truncated. There's currently no measure to prevent or + detect precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + DstType* sequenceToArray( DstType* io_pArray, const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence ) + { + ::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), io_pArray ); + return io_pArray; + } + + //------------------------------------------------------------------------- + /** Copy from a container into a Sequence + + @tpl SrcType + Container type. This type must fulfill the STL container + concept, in particular, the size(), begin() and end() methods + must be available and have the usual semantics. + + @tpl DstType + Sequence element type. Must be assignable from SrcType's + elements + + @param i_Container + Reference to the input contain with elements of type SrcType + + @return the generated Sequence + + @attention this function always performs a copy. Furthermore, + when copying from e.g. a vector<double> to a Sequence<int>, no + proper rounding will be performed, but the values will be + truncated. There's currently no measure to prevent or detect + precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + ::com::sun::star::uno::Sequence< DstType > containerToSequence( const SrcType& i_Container ) + { + ::com::sun::star::uno::Sequence< DstType > result( i_Container.size() ); + ::std::copy( i_Container.begin(), i_Container.end(), result.getArray() ); + return result; + } + + template <typename T> + inline ::com::sun::star::uno::Sequence<T> containerToSequence( + ::std::vector<T> const& v ) + { + return ::com::sun::star::uno::Sequence<T>( + v.empty() ? 0 : &v[0], static_cast<sal_Int32>(v.size()) ); + } + + //------------------------------------------------------------------------- + /** Copy from a Sequence into a container + + @tpl SrcType + Sequence element type. Must be assignable to SrcType's + elements + + @tpl DstType + Container type. This type must fulfill the STL container and + sequence concepts, in particular, the begin(), end() and the + unary constructor DstType(int) methods must be available and + have the usual semantics. + + @param i_Sequence + Reference to a Sequence of SrcType elements + + @return the generated container + + @attention this function always performs a copy. Furthermore, + when copying from e.g. a Sequence<double> to a vector<int>, no + proper rounding will be performed, but the values will be + truncated. There's currently no measure to prevent or detect + precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + DstType sequenceToContainer( const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence ) + { + DstType result( i_Sequence.getLength() ); + ::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), result.begin() ); + return result; + } + //------------------------------------------------------------------------- + /** Copy from a Sequence into an existing container + + This potentially saves a needless extra copy operation over + the whole container, as it passes the target object by + reference. + + @tpl SrcType + Sequence element type. Must be assignable to SrcType's + elements + + @tpl DstType + Container type. This type must fulfill the STL container and + sequence concepts, in particular, the begin(), end() and + resize(int) methods must be available and have the usual + semantics. + + @param o_Output + Reference to the target container + + @param i_Sequence + Reference to a Sequence of SrcType elements + + @return a non-const reference to the given container + + @attention this function always performs a copy. Furthermore, + when copying from e.g. a Sequence<double> to a vector<int>, no + proper rounding will be performed, but the values will be + truncated. There's currently no measure to prevent or detect + precision loss, overflow or truncation. + */ + template < typename DstType, typename SrcType > + DstType& sequenceToContainer( DstType& o_Output, const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence ) + { + o_Output.resize( i_Sequence.getLength() ); + ::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), o_Output.begin() ); + return o_Output; + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +#endif // _COMPHELPER_SEQUENCE_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/sequenceashashmap.hxx b/comphelper/inc/comphelper/sequenceashashmap.hxx new file mode 100644 index 000000000000..e809d6a78f78 --- /dev/null +++ b/comphelper/inc/comphelper/sequenceashashmap.hxx @@ -0,0 +1,382 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_SEQUENCEASHASHMAP_HXX_ +#define _COMPHELPER_SEQUENCEASHASHMAP_HXX_ + +//_______________________________________________ +// includes + +#include <boost/unordered_map.hpp> + +#ifndef INCLUDED_ALGORITHM +#include <algorithm> +#define INCLUDED_ALGORITHM +#endif +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/NamedValue.hpp> + +#include <com/sun/star/beans/IllegalTypeException.hpp> +#include "comphelper/comphelperdllapi.h" + +// see method dbg_dumpToFile() below! +#if OSL_DEBUG_LEVEL > 1 + #ifndef _RTL_USTRBUF_HXX_ + #include <rtl/ustrbuf.hxx> + #endif + + #include <stdio.h> +#endif + +//_______________________________________________ +// namespace + +namespace comphelper{ + +//_______________________________________________ +// definitions + +/** @short Implements a stl hash map on top of some + specialized sequence from type PropertyValue + or NamedValue. + + @descr That provides the possibility to modify + such name sequences very easy ... + */ + +struct SequenceAsHashMapBase : public ::boost::unordered_map< + ::rtl::OUString , + ::com::sun::star::uno::Any , + ::rtl::OUStringHash , + ::std::equal_to< ::rtl::OUString > > +{ +}; + +class COMPHELPER_DLLPUBLIC SequenceAsHashMap : public SequenceAsHashMapBase +{ + //------------------------------------------- + public: + + //--------------------------------------- + /** @short creates an empty hash map. + */ + SequenceAsHashMap(); + + //--------------------------------------- + /** @see operator<<(const ::com::sun::star::uno::Any&) + */ + SequenceAsHashMap(const ::com::sun::star::uno::Any& aSource); + + //--------------------------------------- + /** @see operator<<(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >&) + */ + SequenceAsHashMap(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& lSource); + + //--------------------------------------- + /** @see operator<<(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >&) + */ + SequenceAsHashMap(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lSource); + + //--------------------------------------- + /** @see operator<<(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >&) + */ + SequenceAsHashMap(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& lSource); + + //--------------------------------------- + /** @short not realy used but maybe usefull :-) + */ + ~SequenceAsHashMap(); + + //--------------------------------------- + /** @short fill this map from the given + any, which of course must contain + a suitable sequence of element types + "css.beans.PropertyValue" or "css.beans.NamedValue". + + @attention If the given Any is an empty one + (if its set to VOID), no exception + is thrown. In such case this instance will + be created as an empty one too! + + @param aSource + contains the new items for this map. + + @throw An <type scope="com::sun::star::beans">IllegalTypeException</type> + is thrown, if the given any does not contain a suitable sequence ... + but not if its a VOID Any! + */ + void operator<<(const ::com::sun::star::uno::Any& aSource); + + //--------------------------------------- + /** @short fill this map from the given + sequence, where every Any must contain + an item from type "css.beans.PropertyValue" + "css.beans.NamedValue". + + @param lSource + contains the new items for this map. + + @throw An <type scope="com::sun::star::beans">IllegalTypeException</type> + is thrown, if the given any sequence + uses wrong types for its items. VOID Any will be ignored! + */ + void operator<<(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& lSource); + + //--------------------------------------- + /** @short fill this map from the given + PropertyValue sequence. + + @param lSource + contains the new items for this map. + */ + void operator<<(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lSource); + + //--------------------------------------- + /** @short fill this map from the given + NamedValue sequence. + + @param lSource + contains the new items for this map. + */ + void operator<<(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& lSource); + + //--------------------------------------- + /** @short converts this map instance to an + PropertyValue sequence. + + @param lDestination + target sequence for converting. + */ + void operator>>(::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lDestination) const; + + //--------------------------------------- + /** @short converts this map instance to an + NamedValue sequence. + + @param lDestination + target sequence for converting. + */ + void operator>>(::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& lDestination) const; + + //--------------------------------------- + /** @short return this map instance as an + Any, which can be + used in const environments only. + + @descr Its made const to prevent using of the + return value directly as an in/out parameter! + usage: myMethod(stlDequeAdapter.getAsAnyList()); + + @param bAsPropertyValue + switch between using of PropertyValue or NamedValue as + value type. + + @return A const Any, which + contains all items of this map. + */ + const ::com::sun::star::uno::Any getAsConstAny(::sal_Bool bAsPropertyValue) const; + + //--------------------------------------- + /** @short return this map instance as a + sequence< Any >, which can be + used in const environments only. + + @descr Its made const to prevent using of the + return value directly as an in/out parameter! + usage: myMethod(stlDequeAdapter.getAsAnyList()); + + @param bAsPropertyValue + switch between using of PropertyValue or NamedValue as + value type. + + @return A const sequence which elements of Any, which + contains all items of this map. + */ + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > getAsConstAnyList(::sal_Bool bAsPropertyValue) const; + + //--------------------------------------- + /** @short return this map instance to as a + NamedValue sequence, which can be + used in const environments only. + + @descr Its made const to prevent using of the + return value directly as an in/out parameter! + usage: myMethod(stlDequeAdapter.getAsNamedValueList()); + + @return A const sequence of type NamedValue, which + contains all items of this map. + */ + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getAsConstNamedValueList() const; + + //--------------------------------------- + /** @short return this map instance to as a + PropertyValue sequence, which can be + used in const environments only. + + @descr Its made const to prevent using of the + return value directly as an in/out parameter! + usage: myMethod(stlDequeAdapter.getAsPropertyValueList()); + + @return A const sequence of type PropertyValue, which + contains all items of this map. + */ + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > getAsConstPropertyValueList() const; + + //--------------------------------------- + /** @short check if the specified item exists + and return its (unpacked!) value or it returns the + specified default value otherwhise. + + @descr If a value should be extracted only in case + the requsted property exists realy (without creating + of new items as it the index operator of a + has_map does!) this method can be used. + + @param sKey + key name of the item. + + @param aDefault + the default value, which is returned + if the specified item could not + be found. + + @return The (unpacked!) value of the specified property or + the given default value otherwhise. + + @attention "unpacked" means the Any content of every iterator->second! + */ + template< class TValueType > + TValueType getUnpackedValueOrDefault(const ::rtl::OUString& sKey , + const TValueType& aDefault) const + { + const_iterator pIt = find(sKey); + if (pIt == end()) + return aDefault; + + TValueType aValue = TValueType(); + if (!(pIt->second >>= aValue)) + return aDefault; + + return aValue; + } + + //--------------------------------------- + /** @short creates a new item with the specified + name and value only in case such item name + does not already exist. + + @descr To check if the property already exists only + her name is used for compare. Its value isnt + checked! + + @param sKey + key name of the property. + + @param aValue + the new (unpacked!) value. + Note: This value will be transformed to an Any + internaly, because only Any values can be + part of a PropertyValue or NamedValue structure. + + @return TRUE if this property was added as new item; + FALSE if it already exists. + */ + template< class TValueType > + sal_Bool createItemIfMissing(const ::rtl::OUString& sKey , + const TValueType& aValue) + { + if (find(sKey) == end()) + { + (*this)[sKey] = ::com::sun::star::uno::makeAny(aValue); + return sal_True; + } + + return sal_False; + } + + //--------------------------------------- + /** @short check if all items of given map + exists in these called map also. + + @descr Every item of the given map must exists + with same name and value inside these map. + But these map can contain additional items + which are not part of the search-map. + + @param rCheck + the map containing all items for checking. + + @return + TRUE if all items of Rcheck could be found + in these map; FALSE otherwise. + */ + sal_Bool match(const SequenceAsHashMap& rCheck) const; + + //--------------------------------------- + /** @short merge all values from the given map into + this one. + + @descr Existing items will be overwritten ... + missing items will be created new ... + but non specified items will stay alive ! + + @param rSource + the map containing all items for the update. + */ + void update(const SequenceAsHashMap& rSource); + + //--------------------------------------- + /** @short can be used to generate a file dump of + the current content of this instance. + + @descr Because the content of STL container + cant be analyzed easy, such dump function + seem to be usefull. + Of course its available in debug versions + only. + + @param pFileName + a system file name. + (doesnt matter if relativ or absolute) + + @param pComment + used to mark the dump inside the same log file. + Can be usefull to analyze changes of this + hash map due to the parts of an operation. + */ + #if OSL_DEBUG_LEVEL > 1 + void dbg_dumpToFile(const char* pFileName, const char* pComment) const; + #endif +}; + +} // namespace comphelper + +#endif // _COMPHELPER_SEQUENCEASHASHMAP_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/sequenceasvector.hxx b/comphelper/inc/comphelper/sequenceasvector.hxx new file mode 100644 index 000000000000..909893a88b5d --- /dev/null +++ b/comphelper/inc/comphelper/sequenceasvector.hxx @@ -0,0 +1,263 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_SEQUENCEASVECTOR_HXX_ +#define _COMPHELPER_SEQUENCEASVECTOR_HXX_ + +//_______________________________________________ +// includes + +#include <vector> +#include <algorithm> +#include <com/sun/star/uno/Sequence.hxx> + +#include <com/sun/star/beans/IllegalTypeException.hpp> + +//_______________________________________________ +// namespace + +namespace comphelper{ + +//_______________________________________________ +// definitions + +/** @short Implements a stl vector on top of any + uno sequence. + + @descr That provides the possibility to modify + sequences very easy ... + Of course this can be usefull only, if + count of modifications is high, so copying + of the sequence make sense! + */ +template< class TElementType > +class SequenceAsVector : public ::std::vector< TElementType > +{ + //------------------------------------------- + // types + + public: + + //--------------------------------------- + /** @short When inheriting from a template using typename is generally required when using + types from the base! */ + typedef typename ::std::vector< TElementType >::const_iterator const_iterator; + + //--------------------------------------- + /** @short When inheriting from a template using typename is generally required when using + types from the base! */ + typedef typename ::std::vector< TElementType >::iterator iterator; + + //------------------------------------------- + // interface + public: + + //--------------------------------------- + /** @short default ctor, to create an empty list. + */ + SequenceAsVector() + {} + + //--------------------------------------- + /** @short default dtor + */ + ~SequenceAsVector() + {} + + //--------------------------------------- + /** @short creates a new vector with the given length. + + @param nLength + the number of elements for the new vector. + */ + explicit SequenceAsVector(sal_Int32 nLength) : + ::std::vector< TElementType >( static_cast< size_t >( nLength ) ) + { + } + + //--------------------------------------- + /** @short creates a new deque from the given uno sequence. + + @param lSource + contains the new items for this deque. + */ + SequenceAsVector(const ::com::sun::star::uno::Sequence< TElementType >& lSource) + { + (*this) << lSource; + } + + //--------------------------------------- + /** @short creates a new instance from the given Any, which + of course must contain a valid sequence using the + right element type for every item. + + @attention If the given Any is an empty one + (if its set to VOID), no exception + is thrown. In such case this instance will + be created as an empty one too! + + @param aSource + this any must contain a suitable sequence. :-) + + @throw A <type scope="com::sun::star::beans">IllegalTypeException</type> + if an unsupported element inside this Any + is given. An empty Any reset this instance! + */ + SequenceAsVector(const ::com::sun::star::uno::Any& aSource) + { + (*this) << aSource; + } + + //--------------------------------------- + /** @short fill this instance from the given uno sequence. + + @param lSource + contains the new items for this deque. + */ + void operator<<(const ::com::sun::star::uno::Sequence< TElementType >& lSource) + { + this->clear(); + + sal_Int32 c = lSource.getLength(); + const TElementType* pSource = lSource.getConstArray(); + + for (sal_Int32 i=0; i<c; ++i) + this->push_back(pSource[i]); + } + + //--------------------------------------- + /** @short fill this instance from the given Any, which + of course must contain a valid sequence using the + right element type for every item. + + @attention If the given Any is an empty one + (if its set to VOID), no exception + is thrown. In such case this instance will + be created as an empty one too! + + @param aSource + this any must contain a suitable sequence. :-) + + @throw A <type scope="com::sun::star::beans">IllegalTypeException</type> + if an unsupported element inside this Any + is given. An empty Any reset this instance! + */ + void operator<<(const ::com::sun::star::uno::Any& aSource) + { + // An empty Any reset this instance! + if (!aSource.hasValue()) + { + this->clear(); + return; + } + + ::com::sun::star::uno::Sequence< TElementType > lSource; + if (!(aSource >>= lSource)) + throw ::com::sun::star::beans::IllegalTypeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SequenceAsVector operator<<(Any) was called with an unsupported Any type.")), + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >()); + + (*this) << lSource; + } + + //--------------------------------------- + /** @short converts this instance to an uno sequence. + + @param lDestination + target sequence for converting. + */ + void operator>>(::com::sun::star::uno::Sequence< TElementType >& lDestination) const + { + sal_Int32 c = (sal_Int32)this->size(); + lDestination.realloc(c); + TElementType* pDestination = lDestination.getArray(); + + sal_Int32 i = 0; + for (typename std::vector<TElementType>::const_iterator pThis = this->begin(); + pThis != this->end() ; + ++pThis ) + { + pDestination[i] = *pThis; + ++i; + } + } + + //--------------------------------------- + /** @short converts this instance to an uno any + which contains a suitable sequence + of items of this stl struct. + + @param aDestination + target any for converting. + */ + void operator>>(::com::sun::star::uno::Any& aDestination) const + { + sal_Int32 c = (sal_Int32)this->size(); + ::com::sun::star::uno::Sequence< TElementType > lDestination(c); + TElementType* pDestination = lDestination.getArray(); + + sal_Int32 i = 0; + for (typename std::vector<TElementType>::const_iterator pThis = this->begin(); + pThis != this->end() ; + ++pThis ) + { + pDestination[i] = *pThis; + ++i; + } + + aDestination <<= lDestination; + } + + //--------------------------------------- + /** @short converts this deque to a suitable uno + sequence which contains all items. + + @attention It return a const sequence to prevent + the outside code against using of this + return value as [in/]out parameter for + direct function calls! + Of course it can be casted to non const + ... but then its a problem of the outside + code :-) + + @return A (const!) sequence, which contains all items of + this deque. + */ + const ::com::sun::star::uno::Sequence< TElementType > getAsConstList() const + { + ::com::sun::star::uno::Sequence< TElementType > lDestination; + (*this) >> lDestination; + return lDestination; + } +}; + +} // namespace comphelper + +#endif // _COMPHELPER_SEQUENCEASVECTOR_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/servicedecl.hxx b/comphelper/inc/comphelper/servicedecl.hxx new file mode 100644 index 000000000000..c5ab4b79f5f7 --- /dev/null +++ b/comphelper/inc/comphelper/servicedecl.hxx @@ -0,0 +1,419 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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(COMPHELPER_SERVICEDECL_HXX_INCLUDED) +#define COMPHELPER_SERVICEDECL_HXX_INCLUDED + +#include <comphelper/comphelperdllapi.h> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <uno/environment.h> +#include <boost/utility.hpp> +#include <boost/function.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/repetition.hpp> +#include <boost/preprocessor/seq/enum.hpp> + +namespace comphelper { +namespace service_decl { + +class ServiceDecl; + +namespace detail { +namespace css = ::com::sun::star; +typedef ::boost::function3< + css::uno::Reference<css::uno::XInterface> /* return */, + ServiceDecl const&, + css::uno::Sequence<css::uno::Any> const&, + css::uno::Reference<css::uno::XComponentContext> const&> CreateFuncF; +} + +/** Class to declare a service implementation. There is no need to implement + lang::XServiceInfo nor lang::XInitialization anymore. + The declaration can be done in various ways, the (simplest) form is + + <pre> + class MyClass : public cppu::WeakImplHelper2<XInterface1, XInterface2> { + public: + MyClass( uno::Reference<uno::XComponentContext> const& xContext ) + [...] + }; + [...] + namespace sdecl = comphelper::service_decl; + sdecl::ServiceDecl const myDecl( + sdecl::class_<MyClass>(), + "my.unique.implementation.name", + "MyServiceSpec1;MyServiceSpec2" ); + </pre> + + If the service demands initialization by arguments, the implementation + class has to define a constructor taking both arguments and component + context: + + <pre> + class MyClass : public cppu::WeakImplHelper2<XInterface1, XInterface2> { + public: + MyClass( uno::Sequence<uno::Any> const& args, + uno::Reference<uno:XComponentContext> const& xContext ) + [...] + }; + [...] + namespace sdecl = comphelper::service_decl; + sdecl::ServiceDecl const myDecl( + sdecl::class_<MyClass, sdecl::with_args<true> >(), + "my.unique.implementation.name", + "MyServiceSpec1;MyServiceSpec2" ); + </pre> + + Additionally, there is the possibility to process some code after creation, + e.g. to add the newly created object as a listener or perform aggregation + (C++-UNO only): + + <pre> + uno::Reference<uno::XInterface> somePostProcCode( MyClass * p ); + [...] + namespace sdecl = comphelper::service_decl; + sdecl::ServiceDecl const myDecl( + sdecl::class_<MyClass, ... >(&somePostProcCode), + "my.unique.implementation.name", + "MyServiceSpec1;MyServiceSpec2" ); + </pre> + + In the latter case, somePostProcCode gets the yet unacquired "raw" pointer. +*/ +class COMPHELPER_DLLPUBLIC ServiceDecl : private ::boost::noncopyable +{ +public: + /** Ctor for multiple supported service names. + + @param implClass implementation class description + @param pImplName implementation name + @param pSupportedServiceNames supported service names + @param cDelim delimiter for supported service names + */ + template <typename ImplClassT> + ServiceDecl( ImplClassT const& implClass, + char const* pImplName, + char const* pSupportedServiceNames, char cDelim = ';' ) + : m_createFunc(implClass.m_createFunc), + m_pImplName(pImplName), + m_pServiceNames(pSupportedServiceNames), + m_cDelim(cDelim) {} + + /// @internal gets called by component_getFactoryHelper() + void * getFactory( sal_Char const* pImplName ) const; + + /// @return supported service names + ::com::sun::star::uno::Sequence< ::rtl::OUString> + getSupportedServiceNames() const; + + /// @return whether name is in set of supported service names + bool supportsService( ::rtl::OUString const& name ) const; + + /// @return implementation name + ::rtl::OUString getImplementationName() const; + +private: + class Factory; + friend class Factory; + + detail::CreateFuncF const m_createFunc; + char const* const m_pImplName; + char const* const m_pServiceNames; + char const m_cDelim; +}; + +/** To specify whether the implementation class expects arguments + (uno::Sequence<uno::Any>). +*/ +template <bool> struct with_args; + +/// @internal +namespace detail { +template <typename ImplT> +class OwnServiceImpl + : public ImplT, + private ::boost::noncopyable +{ + typedef ImplT BaseT; + +public: + OwnServiceImpl( + ServiceDecl const& rServiceDecl, + css::uno::Sequence<css::uno::Any> const& args, + css::uno::Reference<css::uno::XComponentContext> const& xContext ) + :BaseT(args, xContext), m_rServiceDecl(rServiceDecl) {} + OwnServiceImpl( + ServiceDecl const& rServiceDecl, + css::uno::Reference<css::uno::XComponentContext> const& xContext ) + : BaseT(xContext), m_rServiceDecl(rServiceDecl) {} + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException) { + return m_rServiceDecl.getImplementationName(); + } + virtual sal_Bool SAL_CALL supportsService( ::rtl::OUString const& name ) + throw (css::uno::RuntimeException) { + return m_rServiceDecl.supportsService(name); + } + virtual css::uno::Sequence< ::rtl::OUString> + SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException) { + return m_rServiceDecl.getSupportedServiceNames(); + } + +private: + ServiceDecl const& m_rServiceDecl; +}; + +template <typename ImplT> +class ServiceImpl : public OwnServiceImpl< ::cppu::ImplInheritanceHelper1<ImplT,css::lang::XServiceInfo> > +{ +typedef OwnServiceImpl< ::cppu::ImplInheritanceHelper1<ImplT,css::lang::XServiceInfo> > ServiceImpl_BASE; +public: + ServiceImpl( + ServiceDecl const& rServiceDecl, + css::uno::Sequence<css::uno::Any> const& args, + css::uno::Reference<css::uno::XComponentContext> const& xContext ) + : ServiceImpl_BASE(rServiceDecl, args, xContext) {} + ServiceImpl( + ServiceDecl const& rServiceDecl, + css::uno::Reference<css::uno::XComponentContext> const& xContext ) + : ServiceImpl_BASE(rServiceDecl, xContext) {} +}; + +template <typename ServiceImplT> +struct PostProcessDefault { + css::uno::Reference<css::uno::XInterface> + operator()( ServiceImplT * p ) const { + return static_cast<css::lang::XServiceInfo *>(p); + } +}; + +template <typename ImplT, typename PostProcessFuncT, typename WithArgsT> +struct CreateFunc; + +template <typename ImplT, typename PostProcessFuncT> +struct CreateFunc<ImplT, PostProcessFuncT, with_args<false> > { + PostProcessFuncT const m_postProcessFunc; + explicit CreateFunc( PostProcessFuncT const& postProcessFunc ) + : m_postProcessFunc(postProcessFunc) {} + + css::uno::Reference<css::uno::XInterface> + operator()( ServiceDecl const& rServiceDecl, + css::uno::Sequence<css::uno::Any> const&, + css::uno::Reference<css::uno::XComponentContext> + const& xContext ) const + { + return m_postProcessFunc( + new ImplT( rServiceDecl, xContext ) ); + } +}; + +template <typename ImplT, typename PostProcessFuncT> +struct CreateFunc<ImplT, PostProcessFuncT, with_args<true> > { + PostProcessFuncT const m_postProcessFunc; + explicit CreateFunc( PostProcessFuncT const& postProcessFunc ) + : m_postProcessFunc(postProcessFunc) {} + + css::uno::Reference<css::uno::XInterface> + operator()( ServiceDecl const& rServiceDecl, + css::uno::Sequence<css::uno::Any> const& args, + css::uno::Reference<css::uno::XComponentContext> + const& xContext ) const + { + return m_postProcessFunc( + new ImplT( rServiceDecl, args, xContext ) ); + } +}; + +} // namespace detail + +/** Defines a service implementation class. + + @tpl ImplT_ service implementation class + @WithArgsT whether the implementation class ctor expects arguments + (uno::Sequence<uno::Any>, uno::Reference<uno::XComponentContext>) + or just (uno::Reference<uno::XComponentContext>) +*/ +template <typename ImplT_, typename WithArgsT = with_args<false> > +struct serviceimpl_base { + typedef ImplT_ ImplT; + + detail::CreateFuncF const m_createFunc; + + typedef detail::PostProcessDefault<ImplT> PostProcessDefaultT; + + /** Default ctor. Implementation class without args, expecting + component context as single argument. + */ + serviceimpl_base() : m_createFunc( + detail::CreateFunc<ImplT, PostProcessDefaultT, WithArgsT>( + PostProcessDefaultT() ) ) {} + + /** Ctor to pass a post processing function/functor. + + @tpl PostProcessDefaultT let your compiler deduce this + @param postProcessFunc function/functor that gets the yet unacquired + ImplT_ pointer returning a + uno::Reference<uno::XInterface> + */ + template <typename PostProcessFuncT> + explicit serviceimpl_base( PostProcessFuncT const& postProcessFunc ) + : m_createFunc( detail::CreateFunc<ImplT, PostProcessFuncT, WithArgsT>( + postProcessFunc ) ) {} +}; + +template <typename ImplT_, typename WithArgsT = with_args<false> > +struct class_ : public serviceimpl_base< detail::ServiceImpl<ImplT_>, WithArgsT > +{ + typedef serviceimpl_base< detail::ServiceImpl<ImplT_>, WithArgsT > baseT; + /** Default ctor. Implementation class without args, expecting + component context as single argument. + */ + class_() : baseT() {} + template <typename PostProcessFuncT> + /** Ctor to pass a post processing function/functor. + + @tpl PostProcessDefaultT let your compiler deduce this + @param postProcessFunc function/functor that gets the yet unacquired + ImplT_ pointer returning a + uno::Reference<uno::XInterface> + */ + explicit class_( PostProcessFuncT const& postProcessFunc ) : baseT( postProcessFunc ) {} +}; + +// +// component_... helpers with arbitrary service declarations: +// + +#define COMPHELPER_SERVICEDECL_getFactory(z_, n_, unused_) \ + if (pRet == 0) \ + pRet = BOOST_PP_CAT(s, n_).getFactory(pImplName); + +/** The following preprocessor repetitions generate functions like + + <pre> + inline void * component_getFactoryHelper( + sal_Char const* pImplName, + ::com::sun::star::lang::XMultiServiceFactory *, + ::com::sun::star::registry::XRegistryKey * xRegistryKey, + ServiceDecl const& s0, ServiceDecl const& s1, ... ); + </pre> + + which call on the passed service declarations. + + The maximum number of service declarations can be set by defining + COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS; its default is 8. +*/ +#define COMPHELPER_SERVICEDECL_make(z_, n_, unused_) \ +inline void * component_getFactoryHelper( \ + sal_Char const* pImplName, \ + ::com::sun::star::lang::XMultiServiceFactory *, \ + ::com::sun::star::registry::XRegistryKey *, \ + BOOST_PP_ENUM_PARAMS(n_, ServiceDecl const& s) ) \ +{ \ + void * pRet = 0; \ + BOOST_PP_REPEAT(n_, COMPHELPER_SERVICEDECL_getFactory, ~) \ + return pRet; \ +} + +#if ! defined(COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS) +#define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 8 +#endif + +BOOST_PP_REPEAT_FROM_TO(1, COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS, + COMPHELPER_SERVICEDECL_make, ~) + +#undef COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS +#undef COMPHELPER_SERVICEDECL_make +#undef COMPHELPER_SERVICEDECL_getFactory + +} // namespace service_decl +} // namespace comphelper + +/** The following preprocessor macro generates the C access functions, + that are used to initialize and register the components of a + shared library object. + + If you have, say, written a lib that contains three distinct + components, each with its own ServiceDecl object, you might want + to employ the following code: + + <pre> + // must reside outside _any_ namespace + COMPHELPER_SERVICEDECL_EXPORTS3(yourServiceDecl1, + yourServiceDecl2, + yourServiceDecl3); + </pre> + + For your convenience, the COMPHELPER_SERVICEDECL_EXPORTS<N> macro + comes pre-defined up to N=8, if you should need more arguments, + call COMPHELPER_SERVICEDECL_make_exports directly, like this: + + <pre> + // must reside outside _any_ namespace + COMPHELPER_SERVICEDECL_make_exports((yourServiceDecl1)(yourServiceDecl2)...(yourServiceDeclN)); + </pre> + + Note the missing colons between the bracketed arguments. + */ +#define COMPHELPER_SERVICEDECL_make_exports(varargs_ ) \ +extern "C" \ +{ \ + SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( sal_Char const* pImplName, \ + ::com::sun::star::lang::XMultiServiceFactory* pServiceManager, \ + ::com::sun::star::registry::XRegistryKey* pRegistryKey ) \ + { \ + return component_getFactoryHelper( pImplName, pServiceManager, \ + pRegistryKey, \ + BOOST_PP_SEQ_ENUM(varargs_) ); \ + } \ +} + +#define COMPHELPER_SERVICEDECL_EXPORTS1(comp0_) \ + COMPHELPER_SERVICEDECL_make_exports((comp0_)) +#define COMPHELPER_SERVICEDECL_EXPORTS2(comp0_,comp1_) \ + COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)) +#define COMPHELPER_SERVICEDECL_EXPORTS3(comp0_,comp1_,comp2_) \ + COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)) +#define COMPHELPER_SERVICEDECL_EXPORTS4(comp0_,comp1_,comp2_,comp3_) \ + COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)) +#define COMPHELPER_SERVICEDECL_EXPORTS5(comp0_,comp1_,comp2_,comp3_,comp4_) \ + COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)) +#define COMPHELPER_SERVICEDECL_EXPORTS6(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_) \ + COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)) +#define COMPHELPER_SERVICEDECL_EXPORTS7(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_) \ + COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_)) +#define COMPHELPER_SERVICEDECL_EXPORTS8(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_,comp7_) \ + COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_)(comp7_)) + +#endif // ! defined(COMPHELPER_SERVICEDECL_HXX_INCLUDED) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/servicehelper.hxx b/comphelper/inc/comphelper/servicehelper.hxx new file mode 100644 index 000000000000..0a095e1b987a --- /dev/null +++ b/comphelper/inc/comphelper/servicehelper.hxx @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_SERVICEHELPER_HXX_ +#define _COMPHELPER_SERVICEHELPER_HXX_ + +#include <rtl/uuid.h> +#include <rtl/instance.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +class UnoTunnelIdInit +{ +private: + ::com::sun::star::uno::Sequence< sal_Int8 > m_aSeq; +public: + UnoTunnelIdInit() : m_aSeq(16) + { + rtl_createUuid( (sal_uInt8*)m_aSeq.getArray(), 0, sal_True ); + } + const ::com::sun::star::uno::Sequence< sal_Int8 >& getSeq() const { return m_aSeq; } +}; + +/** the UNO3_GETIMPLEMENTATION_* macros implement a static helper function + that gives access to your implementation for a given interface reference, + if possible. + + Example: + MyClass* pClass = MyClass::getImplementation( xRef ); + + Usage: + Put a UNO3_GETIMPLEMENTATION_DECL( classname ) inside your class + definitian and UNO3_GETIMPLEMENTATION_IMPL( classname ) inside + your cxx file. Your class must inherit ::com::sun::star::uno::XUnoTunnel + and export it with queryInterface. Implementation of XUnoTunnel is + done by this macro. +*/ +#define UNO3_GETIMPLEMENTATION_DECL( classname ) \ + static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId() throw(); \ + static classname* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xInt ); \ + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException); + +#define UNO3_GETIMPLEMENTATION_BASE_IMPL( classname ) \ +namespace \ +{ \ + class the##classname##UnoTunnelId : public rtl::Static< UnoTunnelIdInit, the##classname##UnoTunnelId> {}; \ +} \ +const ::com::sun::star::uno::Sequence< sal_Int8 > & classname::getUnoTunnelId() throw() \ +{ \ + return the##classname##UnoTunnelId::get().getSeq(); \ +} \ +\ +classname* classname::getImplementation( const uno::Reference< uno::XInterface >& xInt ) \ +{ \ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xInt, ::com::sun::star::uno::UNO_QUERY ); \ + if( xUT.is() ) \ + return reinterpret_cast<classname*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething( classname::getUnoTunnelId() ))); \ + else \ + return NULL; \ +} + +#define UNO3_GETIMPLEMENTATION_IMPL( classname )\ +UNO3_GETIMPLEMENTATION_BASE_IMPL(classname)\ +sal_Int64 SAL_CALL classname::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException) \ +{ \ + if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), \ + rId.getConstArray(), 16 ) ) \ + { \ + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); \ + } \ + return 0; \ +} + +#define UNO3_GETIMPLEMENTATION2_IMPL( classname, baseclass )\ +UNO3_GETIMPLEMENTATION_BASE_IMPL(classname)\ +sal_Int64 SAL_CALL classname::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException) \ +{ \ + if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), \ + rId.getConstArray(), 16 ) ) \ + { \ + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); \ + } \ + else \ + { \ + return baseclass::getSomething( rId ); \ + } \ +} + + +#endif // _COMPHELPER_SERVICEHELPER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/serviceinfohelper.hxx b/comphelper/inc/comphelper/serviceinfohelper.hxx new file mode 100644 index 000000000000..29ffe3bd9907 --- /dev/null +++ b/comphelper/inc/comphelper/serviceinfohelper.hxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef COMPHELPER_SERVICEINFOHELPER_HXX +#define COMPHELPER_SERVICEINFOHELPER_HXX + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper { + +/** this class provides a basic helper for classes suporting the XServiceInfo Interface. + * + * you can overload the <code>getSupprotedServiceNames</code> to implement a XServiceInfo. + * you can use the static helper methods to combine your services with that of parent + * or aggregatet classes. + */ +class COMPHELPER_DLLPUBLIC ServiceInfoHelper : public ::com::sun::star::lang::XServiceInfo +{ +public: + // 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); + + // helper + static ::com::sun::star::uno::Sequence< ::rtl::OUString > concatSequences( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rSeq1, + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rSeq2 ) throw(); + static void addToSequence( ::com::sun::star::uno::Sequence< ::rtl::OUString >& rSeq, sal_uInt16 nServices, /* sal_Char* */... ) throw(); + static sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& SupportedServices ) throw(); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/sharedmutex.hxx b/comphelper/inc/comphelper/sharedmutex.hxx new file mode 100644 index 000000000000..a1984121fc50 --- /dev/null +++ b/comphelper/inc/comphelper/sharedmutex.hxx @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_SHAREDMUTEX_HXX +#define COMPHELPER_SHAREDMUTEX_HXX + +#include "comphelper/comphelperdllapi.h" + +#include <osl/mutex.hxx> + +#include <boost/shared_ptr.hpp> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //============================================================ + //= SharedMutex + //============================================================ + class COMPHELPER_DLLPUBLIC SharedMutex + { + public: + SharedMutex(); + SharedMutex( const SharedMutex& ); + SharedMutex& operator=( const SharedMutex& ); + ~SharedMutex() + { + } + + inline ::osl::Mutex& getMutex() { return *m_pMutexImpl; } + inline operator ::osl::Mutex& () { return *m_pMutexImpl; } + + private: + ::boost::shared_ptr< ::osl::Mutex > m_pMutexImpl; + }; + + //============================================================ + //= SharedMutexBase + //============================================================ + /** sometimes, it's necessary to have an initialized ::osl::Mutex to pass + to some ctor call of your base class. In this case, you can't hold the + SharedMutex as member, but you need to move it into another base class, + which is initialized before the mutex-requiring class is. + */ + class COMPHELPER_DLLPUBLIC SharedMutexBase + { + protected: + SharedMutexBase() + { + } + ~SharedMutexBase() + { + } + + protected: + ::osl::Mutex& getMutex() const { return m_aMutex; } + SharedMutex& getSharedMutex() const { return m_aMutex; } + + private: + mutable SharedMutex m_aMutex; + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_SHAREDMUTEX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/stillreadwriteinteraction.hxx b/comphelper/inc/comphelper/stillreadwriteinteraction.hxx new file mode 100644 index 000000000000..5ad07f201f1a --- /dev/null +++ b/comphelper/inc/comphelper/stillreadwriteinteraction.hxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General 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 _COMPHELPER_STILLREADWRITEINTERACTION_HXX_ +#define _COMPHELPER_STRILLREADWRITEINTERACTION_HXX_ + +//_______________________________________________ +// includes +#include <ucbhelper/interceptedinteraction.hxx> + +#include <com/sun/star/task/XInteractionHandler.hpp> + +#include <ucbhelper/interceptedinteraction.hxx> +#include "comphelper/comphelperdllapi.h" + +//_______________________________________________ +// namespace + +namespace comphelper{ +class COMPHELPER_DLLPUBLIC StillReadWriteInteraction : public ::ucbhelper::InterceptedInteraction +{ +private: + static const sal_Int32 HANDLE_INTERACTIVEIOEXCEPTION = 0; + static const sal_Int32 HANDLE_UNSUPPORTEDDATASINKEXCEPTION = 1; + + sal_Bool m_bUsed; + sal_Bool m_bHandledByMySelf; + sal_Bool m_bHandledByInternalHandler; + +public: + StillReadWriteInteraction(const com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler >& xHandler); + + void resetInterceptions(); + void resetErrorStates(); + sal_Bool wasWriteError(); + +private: + virtual ucbhelper::InterceptedInteraction::EInterceptionState intercepted(const ::ucbhelper::InterceptedInteraction::InterceptedRequest& aRequest, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest); + +}; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/stl_types.hxx b/comphelper/inc/comphelper/stl_types.hxx new file mode 100644 index 000000000000..79c4a17de291 --- /dev/null +++ b/comphelper/inc/comphelper/stl_types.hxx @@ -0,0 +1,274 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_STLTYPES_HXX_ +#define _COMPHELPER_STLTYPES_HXX_ + +#include <vector> +#include <map> + +#include <stack> +#include <set> + +#ifdef _MSC_VER +# ifndef _USE_MATH_DEFINES +# define _USE_MATH_DEFINES // needed by Visual C++ for math constants +# endif +#endif + +#include <math.h> // prevent conflict between exception and std::exception +#include <functional> + + +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> + +//... namespace comphelper ................................................ +namespace comphelper +{ +//......................................................................... + +//======================================================================== +// comparisation functions + +//------------------------------------------------------------------------ + struct UStringLess : public ::std::binary_function< ::rtl::OUString, ::rtl::OUString, bool> +{ + bool operator() (const ::rtl::OUString& x, const ::rtl::OUString& y) const { return x < y ? true : false;} // construct prevents a MSVC6 warning +}; +//------------------------------------------------------------------------ +struct UStringMixLess : public ::std::binary_function< ::rtl::OUString, ::rtl::OUString, bool> +{ + bool m_bCaseSensitive; +public: + UStringMixLess(bool bCaseSensitive = true):m_bCaseSensitive(bCaseSensitive){} + bool operator() (const ::rtl::OUString& x, const ::rtl::OUString& y) const + { + if (m_bCaseSensitive) + return rtl_ustr_compare(x.getStr(), y.getStr()) < 0 ? true : false; + else + return rtl_ustr_compareIgnoreAsciiCase(x.getStr(), y.getStr()) < 0 ? true : false; + } + + bool isCaseSensitive() const {return m_bCaseSensitive;} +}; +//------------------------------------------------------------------------ +struct UStringEqual +{ + sal_Bool operator() (const ::rtl::OUString& lhs, const ::rtl::OUString& rhs) const { return lhs.equals( rhs );} +}; + +//------------------------------------------------------------------------ +struct UStringIEqual +{ + sal_Bool operator() (const ::rtl::OUString& lhs, const ::rtl::OUString& rhs) const { return lhs.equalsIgnoreAsciiCase( rhs );} +}; + +//------------------------------------------------------------------------ +class UStringMixEqual +{ + sal_Bool m_bCaseSensitive; + +public: + UStringMixEqual(sal_Bool bCaseSensitive = sal_True):m_bCaseSensitive(bCaseSensitive){} + sal_Bool operator() (const ::rtl::OUString& lhs, const ::rtl::OUString& rhs) const + { + return m_bCaseSensitive ? lhs.equals( rhs ) : lhs.equalsIgnoreAsciiCase( rhs ); + } + sal_Bool isCaseSensitive() const {return m_bCaseSensitive;} +}; +//------------------------------------------------------------------------ +class TStringMixEqualFunctor : public ::std::binary_function< ::rtl::OUString,::rtl::OUString,bool> +{ + sal_Bool m_bCaseSensitive; + +public: + TStringMixEqualFunctor(sal_Bool bCaseSensitive = sal_True) + :m_bCaseSensitive(bCaseSensitive) + {} + bool operator() (const ::rtl::OUString& lhs, const ::rtl::OUString& rhs) const + { + return !!(m_bCaseSensitive ? lhs.equals( rhs ) : lhs.equalsIgnoreAsciiCase( rhs )); + } + sal_Bool isCaseSensitive() const {return m_bCaseSensitive;} +}; +//------------------------------------------------------------------------ +class TPropertyValueEqualFunctor : public ::std::binary_function< ::com::sun::star::beans::PropertyValue,::rtl::OUString,bool> +{ +public: + TPropertyValueEqualFunctor() + {} + bool operator() (const ::com::sun::star::beans::PropertyValue& lhs, const ::rtl::OUString& rhs) const + { + return !!(lhs.Name == rhs); + } +}; +//------------------------------------------------------------------------ +class UStringMixHash +{ + sal_Bool m_bCaseSensitive; + +public: + UStringMixHash(sal_Bool bCaseSensitive = sal_True):m_bCaseSensitive(bCaseSensitive){} + size_t operator() (const ::rtl::OUString& rStr) const + { + return m_bCaseSensitive ? rStr.hashCode() : rStr.toAsciiUpperCase().hashCode(); + } + sal_Bool isCaseSensitive() const {return m_bCaseSensitive;} +}; + +//===================================================================== +//= OInterfaceCompare +//===================================================================== +/** is stl-compliant structure for comparing Reference< <iface> > instances +*/ +template < class IAFCE > +struct OInterfaceCompare + :public ::std::binary_function < ::com::sun::star::uno::Reference< IAFCE > + , ::com::sun::star::uno::Reference< IAFCE > + , bool + > +{ + bool operator() (const ::com::sun::star::uno::Reference< IAFCE >& lhs, const ::com::sun::star::uno::Reference< IAFCE >& rhs) const + { + return lhs.get() < rhs.get(); + // this does not make any sense if you see the semantics of the pointer returned by get: + // It's a pointer to a point in memory where an interface implementation lies. + // But for our purpose (provide a reliable less-operator which can be used with the STL), this is + // sufficient .... + } +}; + +template <class _Tp, class _Arg> +class mem_fun1_t : public ::std::binary_function<_Tp*,_Arg,void> +{ + typedef void (_Tp::*_fun_type)(_Arg); +public: + explicit mem_fun1_t(_fun_type __pf) : _M_f(__pf) {} + void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } +private: + _fun_type _M_f; +}; + +template <class _Tp, class _Arg> +inline mem_fun1_t<_Tp,_Arg> mem_fun(void (_Tp::*__f)(_Arg)) +{ + return mem_fun1_t<_Tp,_Arg>(__f); +} + +//......................................................................... +/** output iterator that appends OUStrings into an OUStringBuffer. + */ +class OUStringBufferAppender : + public ::std::iterator< ::std::output_iterator_tag, void, void, void, void> +{ +public: + typedef OUStringBufferAppender Self; + typedef ::std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void reference; + typedef void pointer; + typedef size_t difference_type; + + OUStringBufferAppender(::rtl::OUStringBuffer & i_rBuffer) + : m_rBuffer(i_rBuffer) { } + Self & operator=(::rtl::OUString const & i_rStr) + { + m_rBuffer.append( i_rStr ); + return *this; + } + Self & operator*() { return *this; } // so operator= works + Self & operator++() { return *this; } + Self & operator++(int) { return *this; } + +private: + ::rtl::OUStringBuffer & m_rBuffer; +}; + +//......................................................................... +/** algorithm similar to std::copy, but inserts a separator between elements. + */ +template< typename ForwardIter, typename OutputIter, typename T > +OutputIter intersperse( + ForwardIter start, ForwardIter end, OutputIter out, T const & separator) +{ + if (start != end) { + *out = *start; + ++start; + ++out; + } + + while (start != end) { + *out = separator; + ++out; + *out = *start; + ++start; + ++out; + } + + return out; +} + +//......................................................................... +} +//... namespace comphelper ................................................ + +//================================================================== +// consistently defining stl-types +//================================================================== + +#define DECLARE_STL_ITERATORS(classname) \ + typedef classname::iterator classname##Iterator; \ + typedef classname::const_iterator Const##classname##Iterator \ + +#define DECLARE_STL_MAP(keytype, valuetype, comparefct, classname) \ + typedef std::map< keytype, valuetype, comparefct > classname; \ + DECLARE_STL_ITERATORS(classname) \ + +#define DECLARE_STL_STDKEY_MAP(keytype, valuetype, classname) \ + DECLARE_STL_MAP(keytype, valuetype, std::less< keytype >, classname) \ + +#define DECLARE_STL_VECTOR(valuetyp, classname) \ + typedef std::vector< valuetyp > classname; \ + DECLARE_STL_ITERATORS(classname) \ + +#define DECLARE_STL_USTRINGACCESS_MAP(valuetype, classname) \ + DECLARE_STL_MAP(::rtl::OUString, valuetype, ::comphelper::UStringLess, classname) \ + +#define DECLARE_STL_STDKEY_SET(valuetype, classname) \ + typedef ::std::set< valuetype > classname; \ + DECLARE_STL_ITERATORS(classname) \ + +#define DECLARE_STL_SET(valuetype, comparefct, classname) \ + typedef ::std::set< valuetype, comparefct > classname; \ + DECLARE_STL_ITERATORS(classname) \ + +#endif // _COMPHELPER_STLTYPES_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/stlunosequence.hxx b/comphelper/inc/comphelper/stlunosequence.hxx new file mode 100644 index 000000000000..454de6400c32 --- /dev/null +++ b/comphelper/inc/comphelper/stlunosequence.hxx @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_STLUNOITERATOR_HXX +#define _COMPHELPER_STLUNOITERATOR_HXX + +#include <com/sun/star/uno/Sequence.hxx> +#include <sal/types.h> + + +namespace comphelper +{ + /** + @short stl-container-like access to an existing ::com::sun::star::uno::Sequence + @descr These template functions allows using an existing + ::com::sun::star::uno::Sequence using stl algorithms. They provides + standard-compliant mutable random access iterators. Because random access + iterators are the most generic iterators defined by the stl, any stl algorithm + can be applied to the Sequence (excluding algorithms requiring output + iterators). + <p> + Example: (creating a ::std::list from a ::com::sun::star::uno::Sequence) + <code> + ::com::sun::star::uno::Sequence<sal_Int32> aSeq(10); + ::std::list stl_list(stl_begin(aSeq), stl_end(aSeq)); + </code> + <p> + Example: (sorting ::com::sun::star::uno::Sequence inplace) + <code> + ::com::sun::star::uno::Sequence<sal_Int32> aSeq(10); + ::std::sort(stl_begin(aSeq), stl_seq.end(aSeq)); + </code> + <p> + Example: (counting occurrences of 4711 in a ::com::sun::star::uno::Sequence) + <code> + ::com::sun::star::uno::Sequence<sal_Int32> aSeq(10); + sal_Int32 count = 0; + ::std::count(stl_begin(aSeq), stl_end(aSeq), 4711, count); + </code> + <p> + + @see http://www.sgi.com/tech/stl/Container.html + @see http://www.sgi.com/tech/stl/Sequence.html + @see http://www.sgi.com/tech/stl/RandomAccessIterator.html + */ + + template <typename V> + V* stl_begin(::com::sun::star::uno::Sequence<V>& rSeq) + { return rSeq.getArray(); } + + template <typename V> + V* stl_end(::com::sun::star::uno::Sequence<V>& rSeq) + { return rSeq.getArray() + rSeq.getLength(); } + + template <typename V> + const V* stl_begin(const ::com::sun::star::uno::Sequence<V>& rSeq) + { return rSeq.getConstArray(); } + + template <typename V> + const V* stl_end(const ::com::sun::star::uno::Sequence<V>& rSeq) + { return rSeq.getConstArray() + rSeq.getLength(); } +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/storagehelper.hxx b/comphelper/inc/comphelper/storagehelper.hxx new file mode 100644 index 000000000000..078bfb81c885 --- /dev/null +++ b/comphelper/inc/comphelper/storagehelper.hxx @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_STORAGEHELPER_HXX +#define _COMPHELPER_STORAGEHELPER_HXX + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XStream.hpp> +#include "comphelper/comphelperdllapi.h" + + +#define PACKAGE_STORAGE_FORMAT_STRING ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PackageFormat" ) ) +#define ZIP_STORAGE_FORMAT_STRING ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ZipFormat" ) ) +#define OFOPXML_STORAGE_FORMAT_STRING ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OFOPXMLFormat" ) ) + +#define PACKAGE_ENCRYPTIONDATA_SHA256UTF8 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PackageSHA256UTF8EncryptionKey" ) ) +#define PACKAGE_ENCRYPTIONDATA_SHA1UTF8 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PackageSHA1UTF8EncryptionKey" ) ) +#define PACKAGE_ENCRYPTIONDATA_SHA1MS1252 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PackageSHA1MS1252EncryptionKey" ) ) + +namespace comphelper { + +class COMPHELPER_DLLPUBLIC OStorageHelper +{ +public: + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > + GetStorageFactory( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSF + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ) + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > + GetFileSystemStorageFactory( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSF + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ) + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > + GetTemporaryStorage( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ) + throw ( ::com::sun::star::uno::Exception ); + + /// this one will only return Storage + static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > + GetStorageFromURL( + const ::rtl::OUString& aURL, + sal_Int32 nStorageMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ) + throw ( ::com::sun::star::uno::Exception ); + + /// this one will return either Storage or FileSystemStorage + static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > + GetStorageFromURL2( + const ::rtl::OUString& aURL, + sal_Int32 nStorageMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ) + + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > + GetStorageFromInputStream( + const ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream >& xStream, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ) + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > + GetStorageFromStream( + const ::com::sun::star::uno::Reference < ::com::sun::star::io::XStream >& xStream, + sal_Int32 nStorageMode = ::com::sun::star::embed::ElementModes::READWRITE, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ) + throw ( ::com::sun::star::uno::Exception ); + + static void CopyInputToOutput( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInput, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput ) + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > + GetInputStreamFromURL( + const ::rtl::OUString& aURL, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ) + throw ( ::com::sun::star::uno::Exception ); + + static void SetCommonStorageEncryptionData( + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aEncryptionData ) + throw ( ::com::sun::star::uno::Exception ); + + // the following method supports only storages of OOo formats + static sal_Int32 GetXStorageFormat( + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage ) + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > + GetStorageOfFormatFromURL( + const ::rtl::OUString& aFormat, + const ::rtl::OUString& aURL, + sal_Int32 nStorageMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >(), + sal_Bool bRepairStorage = sal_False ) + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > + GetStorageOfFormatFromInputStream( + const ::rtl::OUString& aFormat, + const ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream >& xStream, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >(), + sal_Bool bRepairStorage = sal_False ) + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > + GetStorageOfFormatFromStream( + const ::rtl::OUString& aFormat, + const ::com::sun::star::uno::Reference < ::com::sun::star::io::XStream >& xStream, + sal_Int32 nStorageMode = ::com::sun::star::embed::ElementModes::READWRITE, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >(), + sal_Bool bRepairStorage = sal_False ) + throw ( ::com::sun::star::uno::Exception ); + + static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + CreatePackageEncryptionData( + const ::rtl::OUString& aPassword, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSF + = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ); + + static sal_Bool IsValidZipEntryFileName( const ::rtl::OUString& aName, sal_Bool bSlashAllowed ); + static sal_Bool IsValidZipEntryFileName( const sal_Unicode *pChar, sal_Int32 nLength, sal_Bool bSlashAllowed ); + + static sal_Bool PathHasSegment( const ::rtl::OUString& aPath, const ::rtl::OUString& aSegment ); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/streamsection.hxx b/comphelper/inc/comphelper/streamsection.hxx new file mode 100644 index 000000000000..fb1758135e9e --- /dev/null +++ b/comphelper/inc/comphelper/streamsection.hxx @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_STREAMSECTION_HXX_ +#define _COMPHELPER_STREAMSECTION_HXX_ + +#include <com/sun/star/io/XMarkableStream.hpp> +#include <com/sun/star/io/XDataInputStream.hpp> +#include <com/sun/star/io/XDataOutputStream.hpp> +#include "comphelper/comphelperdllapi.h" + +namespace comphelper +{ + + namespace stario = ::com::sun::star::io; + namespace staruno = ::com::sun::star::uno; + +/** implements handling for compatibly reading/writing data from/into an input/output stream. + data written in a block secured by this class should be readable by older versions which + use the same mechanism. + + @author Frank Schoenheit + @since 00/26/05 +*/ + +class COMPHELPER_DLLPUBLIC OStreamSection +{ + staruno::Reference< stario::XMarkableStream > m_xMarkStream; + staruno::Reference< stario::XDataInputStream > m_xInStream; + staruno::Reference< stario::XDataOutputStream > m_xOutStream; + + sal_Int32 m_nBlockStart; + sal_Int32 m_nBlockLen; + +public: + /** starts reading of a "skippable" section of data within the given input stream<BR> + @param _rxInput the stream to read from. Must support the + <type scope="com::sun::star::io">XMarkableStream</type> interface + */ + OStreamSection(const staruno::Reference< stario::XDataInputStream >& _rxInput); + + /** starts writing of a "skippable" section of data into the given output stream + @param _rxOutput the stream the stream to write to. Must support the + <type scope="com::sun::star::io">XMarkableStream</type> interface + @param _nPresumedLength estimation for the length of the upcoming section. If greater 0, this + value will be written as section length and corrected (in the dtor) only if + needed. If you know how much bytes you are about to write, you may + want to use this param, saving some stream operations this way. + */ + OStreamSection(const staruno::Reference< stario::XDataOutputStream >& _rxOutput, sal_Int32 _nPresumedLength = 0); + + /** dtor. <BR>If constructed for writing, the section "opened" by this object will be "closed".<BR> + If constructed for reading, any remaining bytes 'til the end of the section will be skipped. + */ + ~OStreamSection(); + /** + return the number of bytes which are still available + */ + sal_Int32 available(); +}; + +} // namespace comphelper + +#endif // _COMPHELPER_STREAMSECTION_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/string.hxx b/comphelper/inc/comphelper/string.hxx new file mode 100644 index 000000000000..3e74ca452aaa --- /dev/null +++ b/comphelper/inc/comphelper/string.hxx @@ -0,0 +1,295 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_STRING_HXX +#define INCLUDED_COMPHELPER_STRING_HXX + +#include "sal/config.h" + +#include <cstddef> +#include "comphelper/comphelperdllapi.h" +#include "sal/types.h" +#include <com/sun/star/uno/Sequence.hxx> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/i18n/XCollator.hpp> +#include <com/sun/star/i18n/XBreakIterator.hpp> + +namespace rtl { class OUString; } + +// rtl::OUString helper functions that are not widespread or mature enough to +// go into the stable URE API: +namespace comphelper { namespace string { + +/** + Replace the first occurrence of a substring with another string. + + @param source + The source string, in which the search will take place. + + @param from + The ASCII substring to search for. Must point to at least fromLength ASCII + characters. + + @param fromLength + The length of the from substring. Must not be negative. + + @param to + The string to use as replacement. + + @param beginAt + The index at which to begin the search. Must be between zero and the length + of source, inclusive. + + @param replacedAt + If non-null, receives the starting index at which the replacement took place + or -1 if from was not found. + + @return + The resulting string, in which the replacement has taken place. +*/ +COMPHELPER_DLLPUBLIC rtl::OUString searchAndReplaceAsciiL( + rtl::OUString const & source, char const * from, sal_Int32 fromLength, + rtl::OUString const & to, sal_Int32 beginAt = 0, + sal_Int32 * replacedAt = NULL); + +/** replaces, in the given source string, all occurrences of a given ASCII pattern + with another ASCII pattern +*/ +COMPHELPER_DLLPUBLIC ::rtl::OUString searchAndReplaceAllAsciiWithAscii( + const ::rtl::OUString& source, const sal_Char* from, const sal_Char* to, + const sal_Int32 beginAt = 0 ); + +/** does an in-place replacement of the first occurrence of a sub string with + another string + + @param source + the string to search and replace in. + @param asciiPattern + the ASCII sub string to search for. Must point to a 0-terminated string. + @param replace + The string to use as replacement. + @param beginAt + The index at which to begin the search. Must be between zero and the length + of source, inclusive. + + @param replacedAt + If non-null, receives the starting index at which the replacement took place + or -1 if from was not found. + + @return + a reference to <code>source</code> +*/ +COMPHELPER_DLLPUBLIC ::rtl::OUString& + searchAndReplaceAsciiI( ::rtl::OUString & source, sal_Char const * asciiPattern, + ::rtl::OUString const & replace, sal_Int32 beginAt = 0, + sal_Int32 * replacedAt = NULL ); + +/** Replaces each substring of this OString that matches the search OString + with the specified replacement OString + + @param rIn The input OString + @param rSearch The substring to be replaced + @param rReplace The replacement substring + + @return The resulting OString + */ +COMPHELPER_DLLPUBLIC rtl::OString replace(const rtl::OString &rIn, + const rtl::OString &rSearch, const rtl::OString &rReplace); + +/** Replaces each substring of this OUString that matches the search OUString + with the specified replacement OUString + + @param rIn The input OUString + @param rSearch The substring to be replaced + @param rReplace The replacement substring + + @return The resulting OUString + */ +COMPHELPER_DLLPUBLIC rtl::OUString replace(const rtl::OUString &rIn, + const rtl::OUString &rSearch, const rtl::OUString &rReplace); + +/** Returns a token in the OString + + @param token the number of the token to return + @param cTok the character which seperate the tokens. + @return the token if token is negative or doesn't exist an empty token + is returned +*/ +COMPHELPER_DLLPUBLIC inline rtl::OString getToken(const rtl::OString &rIn, + sal_Int32 nToken, sal_Char cTok) SAL_THROW(()) +{ + sal_Int32 nIndex = 0; + return rIn.getToken(nToken, cTok, nIndex); +} + +/** Returns a token in the OUString + + @param token the number of the token to return + @param cTok the character which seperate the tokens. + @return the token if token is negative or doesn't exist an empty token + is returned +*/ +COMPHELPER_DLLPUBLIC inline rtl::OUString getToken(const rtl::OUString &rIn, + sal_Int32 nToken, sal_Unicode cTok) SAL_THROW(()) +{ + sal_Int32 nIndex = 0; + return rIn.getToken(nToken, cTok, nIndex); +} + +/** + Match against a substring appearing in another string. + + The result is true if and only if the second string appears as a substring + of the first string, at the given position. + This function can't be used for language specific comparison. + + @param rStr The string that pMatch will be compared to. + @param pMatch The substring rStr is to be compared against + @param nMatchLen The length of pMatch + @param fromIndex The index to start the comparion from. + The index must be greater or equal than 0 + and less or equal as the string length. + @return sal_True if pMatch match with the characters in the string + at the given position; + sal_False, otherwise. +*/ +COMPHELPER_DLLPUBLIC inline sal_Bool matchL(const rtl::OString& rStr, const char *pMatch, sal_Int32 nMatchLen, sal_Int32 fromIndex = 0) SAL_THROW(()) +{ + return rtl_str_shortenedCompare_WithLength( rStr.pData->buffer+fromIndex, + rStr.pData->length-fromIndex, pMatch, nMatchLen, nMatchLen ) == 0; +} + +/** Convert a sequence of strings to a single comma separated string. + + Note that no escaping of commas or anything fancy is done. + + @param i_rSeq A list of strings to be concatenated. + + @return A single string containing the concatenation of the given + list, interspersed with the string ", ". + */ +COMPHELPER_DLLPUBLIC ::rtl::OUString convertCommaSeparated( + ::com::sun::star::uno::Sequence< ::rtl::OUString > const & i_rSeq); + +/** Convert a decimal string to a number. + + The string must be base-10, no sign but can contain any + codepoint listed in the "Number, Decimal Digit" Unicode + category. + + No verification is made about the validity of the string, + passing string not containing decimal digit code points + gives unspecified results + + If your string is guaranteed to contain only ASCII digit + use rtl::OUString::toInt32 instead. + + @param str The string to convert containing only decimal + digit codepoints. + + @return The value of the string as an int32. + */ +COMPHELPER_DLLPUBLIC sal_uInt32 decimalStringToNumber( + ::rtl::OUString const & str ); + +/** Convert a single comma separated string to a sequence of strings. + + Note that no escaping of commas or anything fancy is done. + + @param i_rString A string containing comma-separated words. + + @return A sequence of strings resulting from splitting the given + string at ',' tokens and stripping whitespace. + */ +COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Sequence< ::rtl::OUString > + convertCommaSeparated( ::rtl::OUString const & i_rString ); + +/** + Compares two strings using natural order. + + For non digit characters, the comparison use the same algorithm as + rtl_str_compare. When a number is encountered during the comparison, + natural order is used. Thus, Heading 10 will be considered as greater + than Heading 2. Numerical comparison is done using decimal representation. + + Beware that "MyString 001" and "MyString 1" will be considered as equal + since leading 0 are meaningless. + + @param str the object to be compared. + @return 0 - if both strings are equal + < 0 - if this string is less than the string argument + > 0 - if this string is greater than the string argument +*/ +COMPHELPER_DLLPUBLIC sal_Int32 compareNatural( const ::rtl::OUString &rLHS, const ::rtl::OUString &rRHS, + const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > &rCollator, + const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > &rBI, + const ::com::sun::star::lang::Locale &rLocale ); + +class COMPHELPER_DLLPUBLIC NaturalStringSorter +{ +private: + ::com::sun::star::lang::Locale m_aLocale; + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > m_xCollator; + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > m_xBI; +public: + NaturalStringSorter( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > &rContext, + const ::com::sun::star::lang::Locale &rLocale); + sal_Int32 compare(const rtl::OUString &rLHS, const rtl::OUString &rRHS) const + { + return compareNatural(rLHS, rRHS, m_xCollator, m_xBI, m_aLocale); + } + const ::com::sun::star::lang::Locale& getLocale() const { return m_aLocale; } +}; + +/** Determine if an OString contains solely ascii numeric digits + + @param rString An OString + + @return false if string contains any characters outside + the ascii '0'-'9' range + true otherwise, including for empty string + */ +COMPHELPER_DLLPUBLIC bool isAsciiDecimalString(const rtl::OString &rString); + +/** Determine if an OUString contains solely ascii numeric digits + + @param rString An OUString + + @return false if string contains any characters outside + the ascii '0'-'9' range + true otherwise, including for empty string + */ +COMPHELPER_DLLPUBLIC bool isAsciiDecimalString(const rtl::OUString &rString); + +} } + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/synchronousdispatch.hxx b/comphelper/inc/comphelper/synchronousdispatch.hxx new file mode 100644 index 000000000000..4bd0375086b6 --- /dev/null +++ b/comphelper/inc/comphelper/synchronousdispatch.hxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_SYNCHRONOUSDISPATCH_HXX +#define _COMPHELPER_SYNCHRONOUSDISPATCH_HXX + +#include "comphelper/comphelperdllapi.h" + +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/Sequence.hxx" + +#include "com/sun/star/beans/PropertyValue.hpp" + +namespace com { namespace sun { namespace star { + namespace uno { + class XInterface; } + namespace lang { + class XComponent; } +} } } + +namespace rtl { class OUString; } + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //==================================================================== + //= SynchronousDispatch + //==================================================================== + /** a helper class for working with the dispatch interface replacing + loadComponentFromURL + */ + class SynchronousDispatch + { + public: + static COMPHELPER_DLLPUBLIC com::sun::star::uno::Reference< com::sun::star::lang::XComponent > dispatch( + const com::sun::star::uno::Reference< com::sun::star::uno::XInterface > &xStartPoint, + const rtl::OUString &sURL, + const rtl::OUString &sTarget, + const sal_Int32 nFlags, + const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > &lArguments ); + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // _COMPHELPER_SYNCHRONOUSDISPATCH_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/types.hxx b/comphelper/inc/comphelper/types.hxx new file mode 100644 index 000000000000..dfa1565c4493 --- /dev/null +++ b/comphelper/inc/comphelper/types.hxx @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_TYPES_HXX_ +#define _COMPHELPER_TYPES_HXX_ + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include "comphelper/comphelperdllapi.h" +#include "cppu/unotype.hxx" + +namespace com { namespace sun { namespace star { namespace awt { + struct FontDescriptor; +} } } } + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + namespace staruno = ::com::sun::star::uno; + namespace starawt = ::com::sun::star::awt; + namespace starlang = ::com::sun::star::lang; + + typedef staruno::Reference< staruno::XInterface > InterfaceRef; + typedef staruno::Sequence< ::rtl::OUString > StringSequence; + + //------------------------------------------------------------------------- + /** compare the two given Anys + The comparison is deep, means if one of the Any's contains an Any which contains an Any ..., this is resolved <br/> + Other types recognized currently : FontDescriptor, ::com::sun::star::util::Date/Tim/DateTime, staruno::Sequence<sal_Int8> + */ + COMPHELPER_DLLPUBLIC sal_Bool compare(const staruno::Any& rLeft, const staruno::Any& rRight); + + //------------------------------------------------------------------------- + /** compare two FontDescriptor's + */ + COMPHELPER_DLLPUBLIC sal_Bool operator ==(const starawt::FontDescriptor& _rLeft, const starawt::FontDescriptor& _rRight); + inline sal_Bool operator !=(const starawt::FontDescriptor& _rLeft, const starawt::FontDescriptor& _rRight) + { + return !(_rLeft == _rRight); + } + + //------------------------------------------------------------------------- + /// returns sal_True if objects of the types given are "compatible" + COMPHELPER_DLLPUBLIC sal_Bool isAssignableFrom(const staruno::Type& _rAssignable, const staruno::Type& _rFrom); + + //------------------------------------------------------------------------- + /** just a small shortcut ... + check if a type you have at hand at runtime is equal to another type you have at compile time + if all our compiler would accept function calls with explicit template arguments (like + isA<classFoo>(runtimeType)), we wouldn't need the second parameter. But unfortunally at + least the current solaris compiler doesn't allow this .... + So this function is nearly senseless .... + */ + template <class TYPE> + sal_Bool isA(const staruno::Type& _rType, TYPE* pDummy) + { + return _rType.equals(cppu::getTypeFavourUnsigned(pDummy)); + } + + //------------------------------------------------------------------------- + /** check if a type you have at hand at runtime is equal to another type you have at compile time + same comment as for the other isA .... + */ + template <class TYPE> + sal_Bool isA(const staruno::Any& _rVal, TYPE* pDummy) + { + return _rVal.getValueType().equals( + cppu::getTypeFavourUnsigned(pDummy)); + } + + //------------------------------------------------------------------------- + /** check if a type you have at hand at runtime is equal to another type you have at compile time + */ + template <class TYPE> + sal_Bool isAReference(const staruno::Any& _rVal, TYPE*) + { + return _rVal.getValueType().equals( + cppu::getTypeFavourUnsigned( + static_cast<staruno::Reference<TYPE>*>(NULL))); + } + + //------------------------------------------------------------------------- + /** ask the given object for an XComponent interface and dispose on it + */ + template <class TYPE> + void disposeComponent(staruno::Reference<TYPE>& _rxComp) + { + staruno::Reference<starlang::XComponent> xComp(_rxComp, staruno::UNO_QUERY); + if (xComp.is()) + { + xComp->dispose(); + _rxComp = NULL; + } + } + //------------------------------------------------------------------------- + template <class TYPE> + sal_Bool getImplementation(TYPE*& _pObject, const staruno::Reference< staruno::XInterface >& _rxIFace) + { + _pObject = NULL; + staruno::Reference< starlang::XUnoTunnel > xTunnel(_rxIFace, staruno::UNO_QUERY); + if (xTunnel.is()) + _pObject = reinterpret_cast< TYPE* >(xTunnel->getSomething(TYPE::getUnoTunnelImplementationId())); + + return (_pObject != NULL); + } + + + //------------------------------------------------------------------------- + /** get a com::sun::star::awt::FontDescriptor that is fully initialized with + the XXX_DONTKNOW enum values (which isn't the case if you instantiate it + via the default constructor) + */ + COMPHELPER_DLLPUBLIC starawt::FontDescriptor getDefaultFont(); + + /** examine a sequence for the <type scope="com.sun.star.uno">Type</type> of it's elements. + */ + COMPHELPER_DLLPUBLIC staruno::Type getSequenceElementType(const staruno::Type& _rSequenceType); + +//========================================================================= +//= replacement of the former UsrAny.getXXX methods + + // may be used if you need the return value just as temporary, else it's may be too inefficient .... + + // no, we don't use templates here. This would lead to a lot of implicit uses of the conversion methods, + // which would be difficult to trace ... + + COMPHELPER_DLLPUBLIC sal_Int32 getINT32(const staruno::Any& _rAny); + COMPHELPER_DLLPUBLIC sal_Int16 getINT16(const staruno::Any& _rAny); + COMPHELPER_DLLPUBLIC double getDouble(const staruno::Any& _rAny); + COMPHELPER_DLLPUBLIC float getFloat(const staruno::Any& _rAny); + COMPHELPER_DLLPUBLIC ::rtl::OUString getString(const staruno::Any& _rAny); + COMPHELPER_DLLPUBLIC sal_Bool getBOOL(const staruno::Any& _rAny); + + COMPHELPER_DLLPUBLIC sal_Int32 getEnumAsINT32(const staruno::Any& _rAny) throw(starlang::IllegalArgumentException); + +//= replacement of some former UsrAny.setXXX methods - can be used with rvalues + inline void setBOOL(staruno::Any& _rAny, sal_Bool _b) + { _rAny.setValue(&_b, ::getBooleanCppuType()); } + +//= extension of ::cppu::makeAny() + inline staruno::Any makeBoolAny(sal_Bool _b) + { return staruno::Any(&_b, ::getBooleanCppuType()); } + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_TYPES_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/uieventslogger.hxx b/comphelper/inc/comphelper/uieventslogger.hxx new file mode 100644 index 000000000000..40e9a68ad1cf --- /dev/null +++ b/comphelper/inc/comphelper/uieventslogger.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_UIEVENTSLOGGER_HXX +#define _COMPHELPER_UIEVENTSLOGGER_HXX + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/util/URL.hpp> +#include <comphelper/comphelperdllapi.h> +#include <rtl/ustring.hxx> + + +namespace comphelper +{ + // this class is part of the OOo Improvement Program Core + class COMPHELPER_DLLPUBLIC UiEventsLogger + { + public: + static sal_Bool isEnabled(); + static sal_Int32 getSessionLogEventCount(); + static void appendDispatchOrigin( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& args, const ::rtl::OUString& originapp, const ::rtl::OUString& originwidget); + static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue> purgeDispatchOrigin(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& args); + static void logDispatch(const ::com::sun::star::util::URL& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& args); + static void logVcl(const ::rtl::OUString& parent_id, sal_Int32 window_type, const ::rtl::OUString& id, const ::rtl::OUString& method, const ::rtl::OUString& param); + static void logVcl(const ::rtl::OUString& parent_id, sal_Int32 window_type, const ::rtl::OUString& id, const ::rtl::OUString& method, sal_Int32 param); + static void logVcl(const ::rtl::OUString& parent_id, sal_Int32 window_type, const ::rtl::OUString& id, const ::rtl::OUString& method); + static void disposing(); + static void reinit(); + virtual ~UiEventsLogger() {} + }; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/uno3.hxx b/comphelper/inc/comphelper/uno3.hxx new file mode 100644 index 000000000000..2a199905857e --- /dev/null +++ b/comphelper/inc/comphelper/uno3.hxx @@ -0,0 +1,284 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_UNO3_HXX_ +#define _COMPHELPER_UNO3_HXX_ + +#include <osl/interlck.h> +#include <rtl/instance.hxx> +#include <comphelper/types.hxx> +#include <com/sun/star/uno/XAggregation.hpp> +#include <comphelper/sequence.hxx> +#include <cppuhelper/typeprovider.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +//========================================================================= + + /// manipulate ref counts without calling acquire/release + inline oslInterlockedCount increment(oslInterlockedCount& _counter) { return osl_incrementInterlockedCount(&_counter); } + inline oslInterlockedCount decrement(oslInterlockedCount& _counter) { return osl_decrementInterlockedCount(&_counter); } + +//========================================================================= + + /** used for declaring UNO3-Defaults, i.e. acquire/release + */ + #define DECLARE_UNO3_DEFAULTS(classname, baseclass) \ + virtual void SAL_CALL acquire() throw() { baseclass::acquire(); } \ + virtual void SAL_CALL release() throw() { baseclass::release(); } \ + void SAL_CALL PUT_SEMICOLON_AT_THE_END() + + /** used for declaring UNO3-Defaults, i.e. acquire/release if you want to forward all queryInterfaces to the base class, + (e.g. if you overload queryAggregation) + */ + #define DECLARE_UNO3_AGG_DEFAULTS(classname, baseclass) \ + virtual void SAL_CALL acquire() throw() { baseclass::acquire(); } \ + virtual void SAL_CALL release() throw() { baseclass::release(); } \ + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type& _rType) throw (::com::sun::star::uno::RuntimeException) \ + { return baseclass::queryInterface(_rType); } \ + void SAL_CALL PUT_SEMICOLON_AT_THE_END() + + /** Use this macro to forward XComponent methods to base class + + When using the ::cppu::WeakComponentImplHelper base classes to + implement a UNO interface, a problem occurs when the interface + itself already derives from XComponent (like e.g. awt::XWindow + or awt::XControl): ::cppu::WeakComponentImplHelper is then + still abstract. Using this macro in the most derived class + definition provides overrides for the XComponent methods, + forwarding them to the given baseclass. + + @param classname + Name of the class this macro is issued within + + @param baseclass + Name of the baseclass that should have the XInterface methods + forwarded to - that's usually the WeakComponentImplHelperN base + + @param implhelper + Name of the baseclass that should have the XComponent methods + forwarded to - in the case of the WeakComponentImplHelper, + that would be ::cppu::WeakComponentImplHelperBase + */ + #define DECLARE_UNO3_XCOMPONENT_DEFAULTS(classname, baseclass, implhelper) \ + virtual void SAL_CALL acquire() throw() { baseclass::acquire(); } \ + virtual void SAL_CALL release() throw() { baseclass::release(); } \ + virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException) \ + { \ + implhelper::dispose(); \ + } \ + virtual void SAL_CALL addEventListener( \ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > const & xListener ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + implhelper::addEventListener(xListener); \ + } \ + virtual void SAL_CALL removeEventListener( \ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > const & xListener ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + implhelper::removeEventListener(xListener); \ + } \ + void SAL_CALL PUT_SEMICOLON_AT_THE_END() + + + /** Use this macro to forward XComponent methods to base class + + When using the ::cppu::WeakComponentImplHelper base classes to + implement a UNO interface, a problem occurs when the interface + itself already derives from XComponent (like e.g. awt::XWindow + or awt::XControl): ::cppu::WeakComponentImplHelper is then + still abstract. Using this macro in the most derived class + definition provides overrides for the XComponent methods, + forwarding them to the given baseclass. + + @param classname + Name of the class this macro is issued within + + @param baseclass + Name of the baseclass that should have the XInterface methods + forwarded to - that's usually the WeakComponentImplHelperN base + + @param implhelper + Name of the baseclass that should have the XComponent methods + forwarded to - in the case of the WeakComponentImplHelper, + that would be ::cppu::WeakComponentImplHelperBase + */ + #define DECLARE_UNO3_XCOMPONENT_AGG_DEFAULTS(classname, baseclass, implhelper) \ + virtual void SAL_CALL acquire() throw() { baseclass::acquire(); } \ + virtual void SAL_CALL release() throw() { baseclass::release(); } \ + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type& _rType) throw (::com::sun::star::uno::RuntimeException) \ + { return baseclass::queryInterface(_rType); } \ + virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException) \ + { \ + implhelper::dispose(); \ + } \ + virtual void SAL_CALL addEventListener( \ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > const & xListener ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + implhelper::addEventListener(xListener); \ + } \ + virtual void SAL_CALL removeEventListener( \ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > const & xListener ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + implhelper::removeEventListener(xListener); \ + } \ + void SAL_CALL PUT_SEMICOLON_AT_THE_END() + + + //===================================================================== + //= deriving from multiple XInterface-derived classes + //===================================================================== + //= forwarding/merging XInterface funtionality + //===================================================================== + #define DECLARE_XINTERFACE( ) \ + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException); \ + virtual void SAL_CALL acquire() throw(); \ + virtual void SAL_CALL release() throw(); + + #define IMPLEMENT_FORWARD_REFCOUNT( classname, refcountbase ) \ + void SAL_CALL classname::acquire() throw() { refcountbase::acquire(); } \ + void SAL_CALL classname::release() throw() { refcountbase::release(); } + + #define IMPLEMENT_FORWARD_XINTERFACE2( classname, refcountbase, baseclass2 ) \ + IMPLEMENT_FORWARD_REFCOUNT( classname, refcountbase ) \ + ::com::sun::star::uno::Any SAL_CALL classname::queryInterface( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + ::com::sun::star::uno::Any aReturn = refcountbase::queryInterface( _rType ); \ + if ( !aReturn.hasValue() ) \ + aReturn = baseclass2::queryInterface( _rType ); \ + return aReturn; \ + } + + #define IMPLEMENT_FORWARD_XINTERFACE3( classname, refcountbase, baseclass2, baseclass3 ) \ + IMPLEMENT_FORWARD_REFCOUNT( classname, refcountbase ) \ + ::com::sun::star::uno::Any SAL_CALL classname::queryInterface( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + ::com::sun::star::uno::Any aReturn = refcountbase::queryInterface( _rType ); \ + if ( !aReturn.hasValue() ) \ + { \ + aReturn = baseclass2::queryInterface( _rType ); \ + if ( !aReturn.hasValue() ) \ + aReturn = baseclass3::queryInterface( _rType ); \ + } \ + return aReturn; \ + } + + //===================================================================== + //= forwarding/merging XTypeProvider funtionality + //===================================================================== + #define DECLARE_XTYPEPROVIDER( ) \ + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw (::com::sun::star::uno::RuntimeException); \ + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (::com::sun::star::uno::RuntimeException); + + #define IMPLEMENT_GET_IMPLEMENTATION_ID( classname ) \ + namespace \ + { \ + class the##classname##ImplementationId : public rtl::Static< ::cppu::OImplementationId, the##classname##ImplementationId> {}; \ + } \ + ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL classname::getImplementationId( ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + return the##classname##ImplementationId::get().getImplementationId(); \ + } + + #define IMPLEMENT_FORWARD_XTYPEPROVIDER2( classname, baseclass1, baseclass2 ) \ + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL classname::getTypes( ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + return ::comphelper::concatSequences( \ + baseclass1::getTypes(), \ + baseclass2::getTypes() \ + ); \ + } \ + \ + IMPLEMENT_GET_IMPLEMENTATION_ID( classname ) + + #define IMPLEMENT_FORWARD_XTYPEPROVIDER3( classname, baseclass1, baseclass2, baseclass3 ) \ + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL classname::getTypes( ) throw (::com::sun::star::uno::RuntimeException) \ + { \ + return ::comphelper::concatSequences( \ + baseclass1::getTypes(), \ + baseclass2::getTypes(), \ + baseclass3::getTypes() \ + ); \ + } \ + \ + IMPLEMENT_GET_IMPLEMENTATION_ID( classname ) + +//========================================================================= + + /** ask for an iface of an aggregated object + usage:<br/> + Reference<XFoo> xFoo;<br/> + if (query_aggregation(xAggregatedObject, xFoo))<br/> + .... + */ + template <class iface> + sal_Bool query_aggregation(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation >& _rxAggregate, ::com::sun::star::uno::Reference<iface>& _rxOut) + { + _rxOut = static_cast<iface*>(NULL); + if (_rxAggregate.is()) + { + ::com::sun::star::uno::Any aCheck = _rxAggregate->queryAggregation( + iface::static_type()); + if (aCheck.hasValue()) + _rxOut = *(::com::sun::star::uno::Reference<iface>*)aCheck.getValue(); + } + return _rxOut.is(); + } + + /** ask for an iface of an object + usage:<br/> + Reference<XFoo> xFoo;<br/> + if (query_interface(xAnything, xFoo))<br/> + .... + */ + template <class iface> + sal_Bool query_interface(const InterfaceRef& _rxObject, ::com::sun::star::uno::Reference<iface>& _rxOut) + { + _rxOut = static_cast<iface*>(NULL); + if (_rxObject.is()) + { + ::com::sun::star::uno::Any aCheck = _rxObject->queryInterface( + iface::static_type()); + if(aCheck.hasValue()) + { + _rxOut = *(::com::sun::star::uno::Reference<iface>*)aCheck.getValue(); + return _rxOut.is(); + } + } + return sal_False; + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif // _COMPHELPER_UNO3_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/unwrapargs.hxx b/comphelper/inc/comphelper/unwrapargs.hxx new file mode 100644 index 000000000000..94dfb2263f2d --- /dev/null +++ b/comphelper/inc/comphelper/unwrapargs.hxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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(COMPHELPER_UNWRAPARGS_HXX_INCLUDED) +#define COMPHELPER_UNWRAPARGS_HXX_INCLUDED + +#if ! defined(_RTL_USTRBUF_HXX_) +#include "rtl/ustrbuf.hxx" +#endif +#include "com/sun/star/uno/Sequence.hxx" +#if ! defined(_COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_) +#include "com/sun/star/lang/IllegalArgumentException.hpp" +#endif +#include "boost/optional.hpp" +#include "boost/preprocessor/cat.hpp" +#include "boost/preprocessor/repetition.hpp" +#include "boost/preprocessor/arithmetic/add.hpp" +#include "cppu/unotype.hxx" + +namespace comphelper { + +// +// generating helper functions to unwrap the service's argument sequence: +// + +/// @internal +namespace detail { + +template <typename T> +inline void extract( + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> const& seq, + sal_Int32 nArg, T & v, + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> + const& xErrorContext ) +{ + if (nArg >= seq.getLength()) { + throw ::com::sun::star::lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "No such argument available!") ), + xErrorContext, static_cast<sal_Int16>(nArg) ); + } + if (! (seq[nArg] >>= v)) { + ::rtl::OUStringBuffer buf; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Cannot extract ANY { ") ); + buf.append( seq[nArg].getValueType().getTypeName() ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" } to ") ); + buf.append( ::cppu::UnoType<T>::get().getTypeName() ); + buf.append( static_cast<sal_Unicode>('!') ); + throw ::com::sun::star::lang::IllegalArgumentException( + buf.makeStringAndClear(), xErrorContext, + static_cast<sal_Int16>(nArg) ); + } +} + +template <typename T> +inline void extract( + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> const& seq, + sal_Int32 nArg, ::boost::optional<T> & v, + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> + const& xErrorContext ) +{ + if (nArg < seq.getLength()) { + T t; + extract( seq, nArg, t, xErrorContext ); + v.reset( t ); + } +} + +} // namespace detail + +#define COMPHELPER_UNWRAPARGS_extract(z_, n_, unused_) \ + detail::extract( seq, n_, BOOST_PP_CAT(v, n_), xErrorContext ); +#define COMPHELPER_UNWRAPARGS_args(z_, n_, unused_) \ + BOOST_PP_CAT(T, n_) & BOOST_PP_CAT(v, n_) + +/** The following preprocessor repetitions generate functions like + + <pre> + template <typename T0, typename T1, ...> + inline void unwrapArgs( + uno::Sequence<uno::Any> const& seq, + T0 & v0, T1 & v1, ..., + css::uno::Reference<css::uno::XInterface> const& xErrorContext = + css::uno::Reference<css::uno::XInterface>() ); + </pre> + (full namespace qualification ::com::sun::star has been omitted + for brevity) + + which unwraps the passed sequence's elements, assigning them to the + referenced values. Specify optional arguments as boost::optional<T>. + If the length of the sequence is greater than the count of arguments, + then the latter sequence elements are ignored. + If too few arguments are given in the sequence and a missing argument is + no boost::optional<T>, then an lang::IllegalArgumentException is thrown + with the specified xErrorContext (defaults to null-ref). + + The maximum number of service declarations can be set by defining + COMPHELPER_UNWRAPARGS_MAX_ARGS; its default is 12. +*/ +#define COMPHELPER_UNWRAPARGS_make(z_, n_, unused_) \ +template < BOOST_PP_ENUM_PARAMS( BOOST_PP_ADD(n_, 1), typename T) > \ +inline void unwrapArgs( \ + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > const& seq, \ + BOOST_PP_ENUM(BOOST_PP_ADD(n_, 1), COMPHELPER_UNWRAPARGS_args, ~), \ + ::com::sun::star::uno::Reference< \ + ::com::sun::star::uno::XInterface> const& xErrorContext = \ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>() ) \ +{ \ + BOOST_PP_REPEAT(BOOST_PP_ADD(n_, 1), COMPHELPER_UNWRAPARGS_extract, ~) \ +} + +#if ! defined(COMPHELPER_UNWRAPARGS_MAX_ARGS) +#define COMPHELPER_UNWRAPARGS_MAX_ARGS 12 +#endif + +BOOST_PP_REPEAT(COMPHELPER_UNWRAPARGS_MAX_ARGS, COMPHELPER_UNWRAPARGS_make, ~) + +#undef COMPHELPER_UNWRAPARGS_MAX_ARGS +#undef COMPHELPER_UNWRAPARGS_make +#undef COMPHELPER_UNWRAPARGS_args +#undef COMPHELPER_UNWRAPARGS_extract + +} // namespace comphelper + +#endif // ! defined(COMPHELPER_UNWRAPARGS_HXX_INCLUDED) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/weak.hxx b/comphelper/inc/comphelper/weak.hxx new file mode 100644 index 000000000000..5f3f8b14432a --- /dev/null +++ b/comphelper/inc/comphelper/weak.hxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 _COMPHELPER_WEAK_HXX_ +#define _COMPHELPER_WEAK_HXX_ + +#include "comphelper/comphelperdllapi.h" + +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <cppuhelper/weak.hxx> + +namespace comphelper +{ +/** Base class to implement an UNO object supporting types and weak references, i.e. the object can be held + weakly (by a ::com::sun::star::uno::WeakReference). + This implementation copes with reference counting. Upon last release(), the virtual dtor + is called. + + In addition to the features from cppu::OWeakObject, derivations from this class can + also used as a base class for ::cppu::ImplInheritanceHelper? +*/ +class COMPHELPER_DLLPUBLIC OWeakTypeObject : public ::cppu::OWeakObject, public ::com::sun::star::lang::XTypeProvider +{ +public: + OWeakTypeObject(); + virtual ~OWeakTypeObject(); + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getImplementationId( ) throw (::com::sun::star::uno::RuntimeException); + +}; + +} + +#endif + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/weakbag.hxx b/comphelper/inc/comphelper/weakbag.hxx new file mode 100644 index 000000000000..2d6fdfaed89e --- /dev/null +++ b/comphelper/inc/comphelper/weakbag.hxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_COMPHELPER_WEAKBAG_HXX +#define INCLUDED_COMPHELPER_WEAKBAG_HXX + +#include "sal/config.h" + +#include <list> +#include "com/sun/star/uno/Reference.hxx" +#include "cppuhelper/weakref.hxx" +#include "osl/diagnose.h" + +namespace comphelper { + +/** + A bag of UNO weak references. +*/ +template< typename T > class WeakBag { +public: + /** + Add a new weak reference. + + The implementation keeps the amount of memory consumed linear in the + number of living references added, not linear in the number of total + references added. + + @param e + a non-null reference. + */ + void add(com::sun::star::uno::Reference< T > const & e) { + OSL_ASSERT(e.is()); + for (typename WeakReferenceList::iterator i(m_list.begin()); i != m_list.end();) { + if (com::sun::star::uno::Reference< T >(*i).is()) { + ++i; + } else { + i = m_list.erase(i); + } + } + m_list.push_back(com::sun::star::uno::WeakReference< T >(e)); + } + + /** + Remove a living reference. + + @return + a living reference, or null if there are none. + */ + com::sun::star::uno::Reference< T > remove() { + while (!m_list.empty()) { + com::sun::star::uno::Reference< T > r(m_list.front()); + m_list.pop_front(); + if (r.is()) { + return r; + } + } + return com::sun::star::uno::Reference< T >(); + } + +private: + typedef std::list< com::sun::star::uno::WeakReference< T > > WeakReferenceList; + + WeakReferenceList m_list; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/comphelper/weakeventlistener.hxx b/comphelper/inc/comphelper/weakeventlistener.hxx new file mode 100644 index 000000000000..c4cc42bc4052 --- /dev/null +++ b/comphelper/inc/comphelper/weakeventlistener.hxx @@ -0,0 +1,191 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_WEAKEVENTLISTENER_HXX +#define COMPHELPER_WEAKEVENTLISTENER_HXX + +#include <cppuhelper/compbase1.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/uno/XWeak.hpp> +#include <cppuhelper/weakref.hxx> +#include <comphelper/broadcasthelper.hxx> +#include "comphelper/comphelperdllapi.h" + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //===================================================================== + //= OWeakListenerAdapterBase + //===================================================================== + /** (the base for) an adapter which allows to add as listener to a foreign component, without + being held hard. + + <p>The idea is that this adapter is added as listener to a foreign component, which usually + holds it's listener hard. The adapter itself knows the real listener as weak reference, + thus not affecting it's life time.</p> + */ + class OWeakListenerAdapterBase : public OBaseMutex + { + private: + ::com::sun::star::uno::WeakReference< ::com::sun::star::uno::XInterface > + m_aListener; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + m_xBroadcaster; + + protected: + inline ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + getListener( ) const + { + return m_aListener.get(); + } + + inline const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& + getBroadcaster( ) const + { + return m_xBroadcaster; + } + + inline void resetListener( ) + { + m_aListener.clear(); + } + + + protected: + inline OWeakListenerAdapterBase( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XWeak >& _rxListener, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxBroadcaster + ) + :m_aListener ( _rxListener ) + ,m_xBroadcaster ( _rxBroadcaster ) + { + } + + protected: + virtual ~OWeakListenerAdapterBase(); + }; + + + //===================================================================== + //= OWeakListenerAdapter + //===================================================================== + template< class BROADCASTER, class LISTENER > + /** yet another base for weak listener adapters, this time with some type safety + + <p>Note that derived classes need to overwrite all virtual methods of their interface + except XEventListener::disposing, and forward it to their master listener.</p> + + <p>Addtionally, derived classes need to add themself as listener to the broadcaster, + as this can't be done in a generic way</p> + */ + class OWeakListenerAdapter + :public ::cppu::WeakComponentImplHelper1 < LISTENER > + ,public OWeakListenerAdapterBase + { + protected: + /** ctor + <p>Note that derived classes still need to add themself as listener to the broadcaster, + as this can't be done in a generic way</p> + */ + OWeakListenerAdapter( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XWeak >& _rxListener, + const ::com::sun::star::uno::Reference< BROADCASTER >& _rxBroadcaster + ); + + protected: + inline ::com::sun::star::uno::Reference< LISTENER > getListener( ) const + { + return ::com::sun::star::uno::Reference< LISTENER >( OWeakListenerAdapterBase::getListener(), ::com::sun::star::uno::UNO_QUERY ); + } + + // XEventListener overridables + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + + protected: + // OComponentHelper overridables + // to be overridden, again - the derived class should revoke the listener from the broadcaster + virtual void SAL_CALL disposing( ) = 0; + }; + + //===================================================================== + //= OWeakEventListenerAdapter + //===================================================================== + typedef OWeakListenerAdapter < ::com::sun::star::lang::XComponent + , ::com::sun::star::lang::XEventListener + > OWeakEventListenerAdapter_Base; + /** the most simple listener adapter: for XEventListeners at XComponents + */ + class COMPHELPER_DLLPUBLIC OWeakEventListenerAdapter : public OWeakEventListenerAdapter_Base + { + public: + OWeakEventListenerAdapter( + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XWeak > _rxListener, + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > _rxBroadcaster + ); + + // nothing to do except an own ctor - the forwarding of the "disposing" is already done + // in the base class + + protected: + using OWeakEventListenerAdapter_Base::disposing; + virtual void SAL_CALL disposing( ); + }; + + //===================================================================== + //= OWeakListenerAdapter + //===================================================================== + //--------------------------------------------------------------------- + template< class BROADCASTER, class LISTENER > + OWeakListenerAdapter< BROADCASTER, LISTENER >::OWeakListenerAdapter( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XWeak >& _rxListener, + const ::com::sun::star::uno::Reference< BROADCASTER >& _rxBroadcaster + ) + : ::cppu::WeakComponentImplHelper1< LISTENER >( m_aMutex ) + , OWeakListenerAdapterBase( _rxListener, _rxBroadcaster ) + { + } + + //--------------------------------------------------------------------- + template< class BROADCASTER, class LISTENER > + void SAL_CALL OWeakListenerAdapter< BROADCASTER, LISTENER >::disposing( const ::com::sun::star::lang::EventObject& _rSource ) throw (::com::sun::star::uno::RuntimeException) + { + ::com::sun::star::uno::Reference< LISTENER > xListener( getListener() ); + if ( xListener.is() ) + xListener->disposing( _rSource ); + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + +#endif// COMPHELPER_WEAKEVENTLISTENER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/pch/precompiled_comphelper.cxx b/comphelper/inc/pch/precompiled_comphelper.cxx new file mode 100644 index 000000000000..ad6e1ab9b5ac --- /dev/null +++ b/comphelper/inc/pch/precompiled_comphelper.cxx @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/inc/pch/precompiled_comphelper.hxx b/comphelper/inc/pch/precompiled_comphelper.hxx new file mode 100644 index 000000000000..7fcb7d048fe2 --- /dev/null +++ b/comphelper/inc/pch/precompiled_comphelper.hxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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:34.253143 + +#ifdef PRECOMPILED_HEADERS +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/prj/build.lst b/comphelper/prj/build.lst new file mode 100644 index 000000000000..7dde46c47c7e --- /dev/null +++ b/comphelper/prj/build.lst @@ -0,0 +1,2 @@ +ph comphelper : cppuhelper ucbhelper offapi salhelper LIBXSLT:libxslt NULL +ch comphelper\prj nmake - all ch_all NULL diff --git a/comphelper/prj/d.lst b/comphelper/prj/d.lst new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/comphelper/prj/d.lst diff --git a/comphelper/prj/makefile.mk b/comphelper/prj/makefile.mk new file mode 100644 index 000000000000..ffd9fb276d8a --- /dev/null +++ b/comphelper/prj/makefile.mk @@ -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. +# +#************************************************************************* + +PRJ=.. +TARGET=prj + +.INCLUDE : settings.mk + +.IF "$(VERBOSE)"!="" +VERBOSEFLAG := +.ELSE +VERBOSEFLAG := -s +.ENDIF + +all: + cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(GMAKE_MODULE_PARALLELISM) $(gb_MAKETARGET) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog diff --git a/comphelper/qa/complex/comphelper/Map.java b/comphelper/qa/complex/comphelper/Map.java new file mode 100644 index 000000000000..5571eadb7e6e --- /dev/null +++ b/comphelper/qa/complex/comphelper/Map.java @@ -0,0 +1,553 @@ +/* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 complex.comphelper; + +import com.sun.star.beans.IllegalTypeException; +import com.sun.star.beans.Pair; +import com.sun.star.container.ContainerEvent; +import com.sun.star.container.XContainer; +import com.sun.star.container.XContainerListener; +import com.sun.star.container.XElementAccess; +import com.sun.star.container.XEnumerableMap; +import com.sun.star.container.XEnumeration; +import com.sun.star.container.XIdentifierAccess; +import com.sun.star.container.XMap; +import com.sun.star.container.XSet; +import com.sun.star.form.XFormComponent; +// import com.sun.star.lang.DisposedException; +import com.sun.star.lang.EventObject; +import com.sun.star.lang.Locale; +// import com.sun.star.lang.NoSupportException; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.uno.Any; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.Type; +import com.sun.star.uno.TypeClass; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XInterface; +import java.util.HashSet; +import java.util.Set; + +// import org.junit.After; +import org.junit.AfterClass; +// import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openoffice.test.OfficeConnection; +import static org.junit.Assert.*; + +/** complex test case for the css.container.Map implementation + * + * @author frank.schoenheit@sun.com + */ +public class Map /* extends complexlib.ComplexTestCase */ +{ +// @Override +// public String[] getTestMethodNames() +// { +// return new String[] { +// "testSimpleKeyTypes", +// "testComplexKeyTypes", +// "testValueTypes", +// "testEnumerations", +// "testSpecialValues" +// }; +// } + +// public static String getShortTestDescription() +// { +// return "tests the css.container.Map implementation from comphelper/source/misc/map.cxx"; +// } + + private String impl_getNth( int n ) + { + switch ( n % 10 ) + { + case 1: return n + "st"; + case 2: return n + "nd"; + default: return n + "th"; + } + } + + private void impl_putAll( XMap _map, Object[] _keys, Object[] _values ) throws com.sun.star.uno.Exception + { + for ( int i=0; i<_keys.length; ++i ) + { + _map.put( _keys[i], _values[i] ); + } + } + + private void impl_ceckContent( XMap _map, Object[] _keys, Object[] _values, String _context ) throws com.sun.star.uno.Exception + { + for ( int i=0; i<_keys.length; ++i ) + { + assertTrue( _context + ": " + impl_getNth(i) + " key (" + _keys[i].toString() + ") not found in map", + _map.containsKey( _keys[i] ) ); + assertTrue( _context + ": " + impl_getNth(i) + " value (" + _values[i].toString() + ") not found in map", + _map.containsValue( _values[i] ) ); + assertEquals( _context + ": wrong value for " + impl_getNth(i) + " key (" + _keys[i] + ")", + _values[i], _map.get( _keys[i] ) ); + } + } + + @SuppressWarnings("unchecked") + private void impl_checkMappings( Object[] _keys, Object[] _values, String _context ) throws com.sun.star.uno.Exception + { + System.out.println( "checking mapping " + _context + "..." ); + + Type keyType = AnyConverter.getType( _keys[0] ); + Type valueType = AnyConverter.getType( _values[0] ); + + // create a map for the given types + XMap map = com.sun.star.container.EnumerableMap.create( connection.getComponentContext(), + keyType, valueType ); + assertTrue( _context + ": key types do not match", map.getKeyType().equals( keyType ) ); + assertTrue( _context + ": value types do not match", map.getValueType().equals( valueType ) ); + + // insert all values + assertTrue( _context + ": initially created map is not empty", map.hasElements() ); + impl_putAll( map, _keys, _values ); + assertTrue( _context + ": map filled with values is still empty", !map.hasElements() ); + // and verify them + impl_ceckContent( map, _keys, _values, _context ); + + // remove all values + for ( int i=_keys.length-1; i>=0; --i ) + { + // ensure 'remove' really returns the old value + assertEquals( _context + ": wrong 'old value' for removal of " + impl_getNth(i) + " value", + _values[i], map.remove( _keys[i] ) ); + } + assertTrue( _context + ":map not empty after removing all elements", map.hasElements() ); + + // insert again, and check whether 'clear' does what it should do + impl_putAll( map, _keys, _values ); + map.clear(); + assertTrue( _context + ": 'clear' does not empty the map", map.hasElements() ); + + // try the constructor which creates an immutable version + Pair< ?, ? >[] initialMappings = new Pair< ?, ? >[ _keys.length ]; + for ( int i=0; i<_keys.length; ++i ) + { + initialMappings[i] = new Pair< Object, Object >( _keys[i], _values[i] ); + } + map = com.sun.star.container.EnumerableMap.createImmutable( + connection.getComponentContext(), keyType, valueType, (Pair< Object, Object >[])initialMappings ); + impl_ceckContent( map, _keys, _values, _context ); + + // check the thing is actually immutable + //? assureException( map, "clear", new Object[] {}, NoSupportException.class ); + //? assureException( map, "remove", new Class[] { Object.class }, new Object[] { _keys[0] }, NoSupportException.class ); + //? assureException( map, "put", new Class[] { Object.class, Object.class }, new Object[] { _keys[0], _values[0] }, NoSupportException.class ); + } + + @Test public void testSimpleKeyTypes() throws com.sun.star.uno.Exception + { + impl_checkMappings( + new Long[] { (long)1, (long)2, (long)3, (long)4, (long)5 }, + new Integer[] { 6, 7, 8, 9, 10 }, + "long->int" + ); + impl_checkMappings( + new Boolean[] { true, false }, + new Short[] { (short)1, (short)0 }, + "bool->short" + ); + impl_checkMappings( + new String[] { "one", "two", "three", "four", "five"}, + new String[] { "1", "2", "3", "4", "5" }, + "string->string" + ); + impl_checkMappings( + new Double[] { 1.2, 3.4, 5.6, 7.8, 9.10 }, + new Float[] { (float)1, (float)2, (float)3, (float)4, (float)5 }, + "double->float" + ); + impl_checkMappings( + new Float[] { (float)1, (float)2, (float)3, (float)4, (float)5 }, + new Double[] { 1.2, 3.4, 5.6, 7.8, 9.10 }, + "float->double" + ); + impl_checkMappings( + new Integer[] { 2, 9, 2005, 20, 11, 1970, 26, 3, 1974 }, + new String[] { "2nd", "September", "2005", "20th", "November", "1970", "26th", "March", "1974" }, + "int->string" + ); + } + + @Test public void testComplexKeyTypes() throws com.sun.star.uno.Exception + { + Type intType = new Type( Integer.class ); + Type longType = new Type( Long.class ); + Type msfType = new Type ( XMultiServiceFactory.class ); + // .................................................................... + // css.uno.Type should be a valid key type + impl_checkMappings( + new Type[] { intType, longType, msfType }, + new String[] { intType.getTypeName(), longType.getTypeName(), msfType.getTypeName() }, + "type->string" + ); + + // .................................................................... + // any UNO interface type should be a valid key type. + // Try with some form components (just because I like form components :), and the very first application + // for the newly implemented map will be to map XFormComponents to drawing shapes + String[] serviceNames = new String[] { "CheckBox", "ComboBox", "CommandButton", "DateField", "FileControl" }; + Object[] components = new Object[ serviceNames.length ]; + for ( int i=0; i<serviceNames.length; ++i ) + { + components[i] = getMSF().createInstance( "com.sun.star.form.component." + serviceNames[i] ); + } + // "normalize" the first component, so it has the property type + Type formComponentType = new Type( XFormComponent.class ); + components[0] = UnoRuntime.queryInterface( formComponentType.getZClass(), components[0] ); + impl_checkMappings( components, serviceNames, "XFormComponent->string" ); + + // .................................................................... + // any UNO enum type should be a valid key type + impl_checkMappings( + new TypeClass[] { intType.getTypeClass(), longType.getTypeClass(), msfType.getTypeClass() }, + new Object[] { "foo", "bar", "42" }, + "enum->string" + ); + } + + private Class impl_getValueClassByPos( int _pos ) + { + Class valueClass = null; + switch ( _pos ) + { + case 0: valueClass = Boolean.class; break; + case 1: valueClass = Short.class; break; + case 2: valueClass = Integer.class; break; + case 3: valueClass = Long.class; break; + case 4: valueClass = XInterface.class; break; + case 5: valueClass = XSet.class; break; + case 6: valueClass = XContainer.class; break; + case 7: valueClass = XIdentifierAccess.class; break; + case 8: valueClass = XElementAccess.class; break; + case 9: valueClass = com.sun.star.uno.Exception.class; break; + case 10: valueClass = com.sun.star.uno.RuntimeException.class; break; + case 11: valueClass = EventObject.class; break; + case 12: valueClass = ContainerEvent.class; break; + case 13: valueClass = Object.class; break; + default: + fail( "internal error: wrong position for getValueClass" ); + } + return valueClass; + } + + @SuppressWarnings("unchecked") + private Object impl_getSomeValueByTypePos( int _pos ) + { + Object someValue = null; + switch ( _pos ) + { + case 0: someValue = new Boolean( false ); break; + case 1: someValue = new Short( (short)0 ); break; + case 2: someValue = new Integer( 0 ); break; + case 3: someValue = new Long( 0 ); break; + case 4: someValue = UnoRuntime.queryInterface( XInterface.class, new DummyInterface() ); break; + case 5: someValue = UnoRuntime.queryInterface( XSet.class, new DummySet() ); break; + case 6: someValue = UnoRuntime.queryInterface( XContainer.class, new DummyContainer() ); break; + case 7: someValue = UnoRuntime.queryInterface( XIdentifierAccess.class, new DummyIdentifierAccess() ); break; + case 8: someValue = UnoRuntime.queryInterface( XElementAccess.class, new DummyElementAccess() ); break; + case 9: someValue = new com.sun.star.uno.Exception(); break; + case 10: someValue = new com.sun.star.uno.RuntimeException(); break; + case 11: someValue = new EventObject(); break; + case 12: someValue = new ContainerEvent(); break; + case 13: someValue = new Locale(); break; // just use *any* value which does not conflict with the others + default: + fail( "internal error: wrong position for getSomeValue" ); + } + return someValue; + } + + private class DummyInterface implements XInterface + { + }; + + private class DummySet implements XSet + { + public boolean has( Object arg0 ) { throw new UnsupportedOperationException( "Not implemented." ); } + public void insert( Object arg0 ) { throw new UnsupportedOperationException( "Not implemented." ); } + public void remove( Object arg0 ) { throw new UnsupportedOperationException( "Not implemented." ); } + public XEnumeration createEnumeration() { throw new UnsupportedOperationException( "Not implemented." ); } + public Type getElementType() { throw new UnsupportedOperationException( "Not implemented." ); } + public boolean hasElements() { throw new UnsupportedOperationException( "Not implemented." ); } + }; + + private class DummyContainer implements XContainer + { + public void addContainerListener( XContainerListener arg0 ) { throw new UnsupportedOperationException( "Not implemented." ); } + public void removeContainerListener( XContainerListener arg0 ) { throw new UnsupportedOperationException( "Not implemented." ); } + }; + + private class DummyIdentifierAccess implements XIdentifierAccess + { + public Object getByIdentifier( int arg0 ) { throw new UnsupportedOperationException( "Not implemented." ); } + public int[] getIdentifiers() { throw new UnsupportedOperationException( "Not implemented." ); } + public Type getElementType() { throw new UnsupportedOperationException( "Not implemented." ); } + public boolean hasElements() { throw new UnsupportedOperationException( "Not implemented." ); } + }; + + private class DummyElementAccess implements XElementAccess + { + public Type getElementType() { throw new UnsupportedOperationException( "Not implemented." ); } + public boolean hasElements() { throw new UnsupportedOperationException( "Not implemented." ); } + }; + + @Test public void testValueTypes() throws com.sun.star.uno.Exception + { + final Integer key = new Integer(1); + + // type compatibility matrix: rows are the value types used to create the map, + // columns are the value types fed into the map. A value "1" means the respective type + // should be accepted. + Integer[][] typeCompatibility = new Integer[][] { + /* boolean */ new Integer[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* short */ new Integer[] { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* int */ new Integer[] { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* long */ new Integer[] { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* XInterface */ new Integer[] { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, + /* XSet */ new Integer[] { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* XContainer */ new Integer[] { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, + /* XIdentifierAccess */ new Integer[] { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + /* XElementAccess */ new Integer[] { 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0 }, + /* Exception */ new Integer[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, + /* RuntimeException */ new Integer[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + /* EventObject */ new Integer[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, + /* ContainerEvent */ new Integer[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, + /* any */ new Integer[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + }; + // several asects are checked with this compatibility matrix: + // - if a map's value type is a scalar type, or a string, then nothing but this + // type should be accepted + // - if a map's value type is an interface type, then values should be accepted if + // they contain a derived interface, or the interrface itself, or if they can be + // queried for this interface (actually, the latter rule is not tested with the + // above matrix) + // - if a map's value type is a struct or exception, then values should be accepted + // if they are of the given type, or of a derived type. + // - if a map's value type is "any", then, well, any value should be accepted + + for ( int valueTypePos = 0; valueTypePos != typeCompatibility.length; ++valueTypePos ) + { + XMap map = com.sun.star.container.EnumerableMap.create( connection.getComponentContext(), + new Type( Integer.class ), new Type( impl_getValueClassByPos( valueTypePos ) ) ); + + for ( int checkTypePos = 0; checkTypePos != typeCompatibility[valueTypePos].length; ++checkTypePos ) + { + Object value = impl_getSomeValueByTypePos( checkTypePos ); + if ( typeCompatibility[valueTypePos][checkTypePos] != 0 ) + { + // expected to succeed +//? assureException( +//? "(" + valueTypePos + "," + checkTypePos + ") putting an " + +//? AnyConverter.getType( value ).getTypeName() + ", where " + +//? map.getValueType().getTypeName() + " is expected, should succeed", +//? map, "put", new Class[] { Object.class, Object.class }, new Object[] { key, value }, +//? null ); + } + else + { + // expected to fail +//? assureException( +//? "(" + valueTypePos + "," + checkTypePos + ") putting an " + +//? AnyConverter.getType( value ).getTypeName() + ", where " + +//? map.getValueType().getTypeName() + " is expected, should not succeed", +//? map, "put", new Class[] { Object.class, Object.class }, new Object[] { key, value }, +//? IllegalTypeException.class ); + } + } + } + } + + private interface CompareEqual + { + public boolean areEqual( Object _lhs, Object _rhs ); + }; + + private class DefaultCompareEqual implements CompareEqual + { + public boolean areEqual( Object _lhs, Object _rhs ) + { + return _lhs.equals( _rhs ); + } + }; + + private class PairCompareEqual implements CompareEqual + { + public boolean areEqual( Object _lhs, Object _rhs ) + { + Pair< ?, ? > lhs = (Pair< ?, ? >)_lhs; + Pair< ?, ? > rhs = (Pair< ?, ? >)_rhs; + return lhs.First.equals( rhs.First ) && lhs.Second.equals( rhs.Second ); + } + }; + + @SuppressWarnings("unchecked") + private void impl_verifyEnumerationContent( XEnumeration _enum, final Object[] _expectedElements, final String _context ) + throws com.sun.star.uno.Exception + { + // since we cannot assume the map to preserve the ordering in which the elements where inserted, + // we can only verify that all elements exist as expected, plus *no more* elements than expected + // are provided by the enumeration + Set set = new HashSet(); + for ( int i=0; i<_expectedElements.length; ++i ) + { + set.add( i ); + } + + CompareEqual comparator = _expectedElements[0].getClass().equals( Pair.class ) + ? new PairCompareEqual() + : new DefaultCompareEqual(); + + for ( int i=0; i<_expectedElements.length; ++i ) + { + assertTrue( _context + ": too few elements in the enumeration (still " + ( _expectedElements.length - i ) + " to go)", + _enum.hasMoreElements() ); + + Object nextElement = _enum.nextElement(); + if ( nextElement.getClass().equals( Any.class ) ) + { + nextElement = ((Any)nextElement).getObject(); + } + + int foundPos = -1; + for ( int j=0; j<_expectedElements.length; ++j ) + { + if ( comparator.areEqual( _expectedElements[j], nextElement ) ) + { + foundPos = j; + break; + } + } + + assertTrue( _context + ": '" + nextElement.toString() + "' is not expected in the enumeration", + set.contains( foundPos ) ); + set.remove( foundPos ); + } + assertTrue( _context + ": too many elements returned by the enumeration", set.isEmpty() ); + } + + @Test public void testEnumerations() throws com.sun.star.uno.Exception + { + // fill a map + final String[] keys = new String[] { "This", "is", "an", "enumeration", "test" }; + final String[] values = new String[] { "for", "the", "map", "implementation", "." }; + XEnumerableMap map = com.sun.star.container.EnumerableMap.create( connection.getComponentContext(), new Type( String.class ), new Type( String.class ) ); + impl_putAll( map, keys, values ); + + final Pair< ?, ? >[] paired = new Pair< ?, ? >[ keys.length ]; + for ( int i=0; i<keys.length; ++i ) + { + paired[i] = new Pair< Object, Object >( keys[i], values[i] ); + } + + // create non-isolated enumerators, and check their content + XEnumeration enumerateKeys = map.createKeyEnumeration( false ); + XEnumeration enumerateValues = map.createValueEnumeration( false ); + XEnumeration enumerateAll = map.createElementEnumeration( false ); + impl_verifyEnumerationContent( enumerateKeys, keys, "key enumeration" ); + impl_verifyEnumerationContent( enumerateValues, values, "value enumeration" ); + impl_verifyEnumerationContent( enumerateAll, paired, "content enumeration" ); + + // all enumerators above have been created as non-isolated iterators, so they're expected to die when + // the underlying map changes + map.remove( keys[0] ); +//? assureException( enumerateKeys, "hasMoreElements", new Object[] {}, DisposedException.class ); +//? assureException( enumerateValues, "hasMoreElements", new Object[] {}, DisposedException.class ); +//? assureException( enumerateAll, "hasMoreElements", new Object[] {}, DisposedException.class ); + + // now try with isolated iterators + map.put( keys[0], values[0] ); + enumerateKeys = map.createKeyEnumeration( true ); + enumerateValues = map.createValueEnumeration( true ); + enumerateAll = map.createElementEnumeration( true ); + map.put( "additional", "value" ); + impl_verifyEnumerationContent( enumerateKeys, keys, "key enumeration" ); + impl_verifyEnumerationContent( enumerateValues, values, "value enumeration" ); + impl_verifyEnumerationContent( enumerateAll, paired, "content enumeration" ); + } + + @Test public void testSpecialValues() throws com.sun.star.uno.Exception + { + final Double[] keys = new Double[] { new Double( 0 ), Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }; + final Double[] values = new Double[] { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, new Double( 0 ) }; + + XEnumerableMap map = com.sun.star.container.EnumerableMap.create( connection.getComponentContext(), new Type( Double.class ), new Type( Double.class ) ); + impl_putAll( map, keys, values ); + + assertTrue( "containsKey( Double.+INF failed", map.containsKey( Double.POSITIVE_INFINITY ) ); + assertTrue( "containsKey( Double.-INF failed", map.containsKey( Double.NEGATIVE_INFINITY ) ); + assertTrue( "containsKey( 0 ) failed", map.containsKey( new Double( 0 ) ) ); + + assertTrue( "containsValue( Double.+INF ) failed", map.containsValue( Double.POSITIVE_INFINITY ) ); + assertTrue( "containsValue( Double.-INF ) failed", map.containsValue( Double.NEGATIVE_INFINITY ) ); + assertTrue( "containsValue( 0 ) failed", map.containsValue( new Double( 0 ) ) ); + + // put and containsKey should reject Double.NaN as key +//? assureException( "Double.NaN should not be allowed as key in a call to 'put'", map, "put", +//? new Class[] { Object.class, Object.class }, new Object[] { Double.NaN, new Double( 0 ) }, +//? com.sun.star.lang.IllegalArgumentException.class ); +//? assureException( "Double.NaN should not be allowed as key in a call to 'containsKey'", map, "containsKey", +//? new Class[] { Object.class }, new Object[] { Double.NaN }, +//? com.sun.star.lang.IllegalArgumentException.class ); + + // ditto for put and containsValue +//? assureException( "Double.NaN should not be allowed as value in a call to 'put'", map, "put", +//? new Class[] { Object.class, Object.class }, new Object[] { new Double( 0 ), Double.NaN }, +//? com.sun.star.lang.IllegalArgumentException.class ); +//? assureException( "Double.NaN should not be allowed as key in a call to 'containsValue'", map, "containsValue", +//? new Class[] { Object.class }, new Object[] { Double.NaN }, +//? com.sun.star.lang.IllegalArgumentException.class ); + } + + + private XMultiServiceFactory getMSF() + { + final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager()); + return xMSF1; + } + + // setup and close connections + @BeforeClass public static void setUpConnection() throws Exception { + System.out.println("setUpConnection()"); + connection.setUp(); + } + + @AfterClass public static void tearDownConnection() + throws InterruptedException, com.sun.star.uno.Exception + { + System.out.println("tearDownConnection()"); + connection.tearDown(); + } + + private static final OfficeConnection connection = new OfficeConnection(); +} diff --git a/comphelper/qa/complex/comphelper/SequenceOutputStreamUnitTest.java b/comphelper/qa/complex/comphelper/SequenceOutputStreamUnitTest.java new file mode 100644 index 000000000000..d6683e64bc83 --- /dev/null +++ b/comphelper/qa/complex/comphelper/SequenceOutputStreamUnitTest.java @@ -0,0 +1,188 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 complex.comphelper; + +// import complexlib.ComplexTestCase; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.uno.UnoRuntime; + +import com.sun.star.io.XSequenceOutputStream; +import com.sun.star.io.XSeekableInputStream; + +import java.util.Random; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openoffice.test.OfficeConnection; +import static org.junit.Assert.*; + +/* Document. + */ + +class TestHelper +{ + // LogWriter m_aLogWriter; + String m_sTestPrefix; + + /** Creates a new instance of TestHelper + * @param sTestPrefix + */ + public TestHelper ( String sTestPrefix ) { + m_sTestPrefix = sTestPrefix; + } + + public void Error ( String sError ) { + System.out.println ( m_sTestPrefix + "Error: " + sError ); + } + + public void Message ( String sMessage ) { + System.out.println ( m_sTestPrefix + sMessage ); + } +} + +public class SequenceOutputStreamUnitTest /* extends ComplexTestCase*/ { + private XMultiServiceFactory m_xMSF = null; + + TestHelper m_aTestHelper = null; + +// public String[] getTestMethodNames() { +// return new String[] { +// "ExecuteTest01"}; +// } + +// public String getTestObjectName () { +// return "SequenceOutputStreamUnitTest"; +// } + +// public static String getShortTestDescription() { +// return "tests the SequenceOutput/InputStream implementations"; +// } + + @Before public void before() { + try { + m_xMSF = getMSF(); + m_aTestHelper = new TestHelper ( "Test01: "); + } catch (Exception e) { + fail ("Cannot create service factory!"); + } + if (m_xMSF==null) { + fail ("Cannot create service factory!"); + } + } + + @After public void after() { + m_xMSF = null; + } + +// @Test public void ExecuteTest01() { +// Test01 aTest = new Test01 (m_xMSF); +// assertTrue( "Test01 failed!", aTest.test() ); +// } + + @Test public void test () { + try { + final int nBytesCnt = 20; + + //create SequenceOutputStream + Object oSequenceOutputStream = m_xMSF.createInstance ( + "com.sun.star.io.SequenceOutputStream" ); + XSequenceOutputStream xSeqOutStream = + UnoRuntime.queryInterface ( + XSequenceOutputStream.class, oSequenceOutputStream ); + m_aTestHelper.Message ( "SequenceOutputStream created." ); + + //write something to the stream + byte pBytesOriginal[] = new byte [nBytesCnt]; + Random oRandom = new Random(); + oRandom.nextBytes (pBytesOriginal); + xSeqOutStream.writeBytes (pBytesOriginal); + byte pBytesWritten[] = xSeqOutStream.getWrittenBytes (); + m_aTestHelper.Message ( "SeuenceOutputStream filled." ); + + //create SequenceInputstream + Object pArgs[] = new Object[1]; + pArgs[0] = pBytesWritten; + Object oSequenceInputStream = m_xMSF.createInstanceWithArguments ( + "com.sun.star.io.SequenceInputStream", pArgs ); + XSeekableInputStream xSeekableInStream = + UnoRuntime.queryInterface ( + XSeekableInputStream.class, oSequenceInputStream ); + m_aTestHelper.Message ( "SequenceInputStream created." ); + + //read from the stream + byte pBytesRead[][] = new byte [1][nBytesCnt]; + xSeekableInStream.readBytes ( pBytesRead, pBytesRead[0].length + 1 ); + m_aTestHelper.Message ( "Read from SequenceInputStream." ); + + //close the streams + xSeqOutStream.closeOutput (); + xSeekableInStream.closeInput (); + m_aTestHelper.Message ( "Both streams closed." ); + + //compare the original, written and read arrys + for ( int i = 0; i < nBytesCnt; ++i ) { + if ( pBytesOriginal[i] != pBytesWritten[i] ) { + m_aTestHelper.Error ( "Written array not identical to " + + "original array. Position: " + i ); + return /* false */; + } else if ( pBytesOriginal[i] != pBytesRead[0][i] ) { + m_aTestHelper.Error ( "Read array not identical to original " + + "array. Position: " + i ); + return /* false */; + } + } + m_aTestHelper.Message ( "All data correct." ); + } catch ( Exception e ) { + m_aTestHelper.Error ( "Exception: " + e ); + return /* false */; + } + return /* true */; + } + + private XMultiServiceFactory getMSF() + { + final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager()); + return xMSF1; + } + + // setup and close connections + @BeforeClass public static void setUpConnection() throws Exception { + System.out.println("setUpConnection()"); + connection.setUp(); + } + + @AfterClass public static void tearDownConnection() + throws InterruptedException, com.sun.star.uno.Exception + { + System.out.println("tearDownConnection()"); + connection.tearDown(); + } + + private static final OfficeConnection connection = new OfficeConnection(); +}
\ No newline at end of file diff --git a/comphelper/qa/complex/comphelper_all.sce b/comphelper/qa/complex/comphelper_all.sce new file mode 100644 index 000000000000..63e5276f00ed --- /dev/null +++ b/comphelper/qa/complex/comphelper_all.sce @@ -0,0 +1,2 @@ +-o complex.comphelper.SequenceOutputStreamUnitTest +-o complex.comphelper.Map diff --git a/comphelper/qa/string/test_string.cxx b/comphelper/qa/string/test_string.cxx new file mode 100644 index 000000000000..4ac96dccc5f7 --- /dev/null +++ b/comphelper/qa/string/test_string.cxx @@ -0,0 +1,357 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "sal/cppunit.h" + +#include <comphelper/string.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/i18n/CharType.hpp> + +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" + +namespace { + +class TestString: public CppUnit::TestFixture +{ +public: + void testSearchAndReplaceAsciiL(); + void testNatural(); + void testReplace(); + void testToken(); + void testDecimalStringToNumber(); + + CPPUNIT_TEST_SUITE(TestString); + CPPUNIT_TEST(testSearchAndReplaceAsciiL); + CPPUNIT_TEST(testNatural); + CPPUNIT_TEST(testReplace); + CPPUNIT_TEST(testToken); + CPPUNIT_TEST(testDecimalStringToNumber); + CPPUNIT_TEST_SUITE_END(); +}; + +void TestString::testSearchAndReplaceAsciiL() +{ + rtl::OUString s1(RTL_CONSTASCII_USTRINGPARAM("foobarbar")); + sal_Int32 n1; + rtl::OUString s2( + comphelper::string::searchAndReplaceAsciiL( + s1, RTL_CONSTASCII_STRINGPARAM("bar"), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("baaz")), 0, &n1)); + CPPUNIT_ASSERT( + s2 == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foobaazbar"))); + CPPUNIT_ASSERT(n1 == 3); + sal_Int32 n2; + rtl::OUString s3( + comphelper::string::searchAndReplaceAsciiL( + s2, RTL_CONSTASCII_STRINGPARAM("bar"), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bz")), + n1 + RTL_CONSTASCII_LENGTH("baaz"), &n2)); + CPPUNIT_ASSERT( + s3 == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foobaazbz"))); + CPPUNIT_ASSERT(n2 == 7); + sal_Int32 n3; + rtl::OUString s4( + comphelper::string::searchAndReplaceAsciiL( + s3, RTL_CONSTASCII_STRINGPARAM("bar"), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("baz")), + n2 + RTL_CONSTASCII_LENGTH("bz"), &n3)); + CPPUNIT_ASSERT(s4 == s3); + CPPUNIT_ASSERT(n3 == -1); +} + +void TestString::testDecimalStringToNumber() +{ + rtl::OUString s1(RTL_CONSTASCII_USTRINGPARAM("1234")); + CPPUNIT_ASSERT_EQUAL((sal_uInt32)1234, comphelper::string::decimalStringToNumber(s1)); + s1 += rtl::OUString(static_cast<sal_Unicode>(0x07C6)); + CPPUNIT_ASSERT_EQUAL((sal_uInt32)12346, comphelper::string::decimalStringToNumber(s1)); + // Codepoints on 2 16bits words + sal_uInt32 utf16String[] = { 0x1D7FE /* 8 */, 0x1D7F7 /* 1 */}; + s1 = rtl::OUString(utf16String, 2); + CPPUNIT_ASSERT_EQUAL((sal_uInt32)81, comphelper::string::decimalStringToNumber(s1)); +} + +using namespace ::com::sun::star; + +class testCollator : public cppu::WeakImplHelper1< i18n::XCollator > +{ +public: + virtual sal_Int32 SAL_CALL compareSubstring( + const rtl::OUString& str1, sal_Int32 off1, sal_Int32 len1, + const rtl::OUString& str2, sal_Int32 off2, sal_Int32 len2) throw(uno::RuntimeException) + { + return str1.copy(off1, len1).compareTo(str2.copy(off2, len2)); + } + virtual sal_Int32 SAL_CALL compareString( + const rtl::OUString& str1, + const rtl::OUString& str2) throw(uno::RuntimeException) + { + return str1.compareTo(str2); + } + virtual sal_Int32 SAL_CALL loadDefaultCollator(const lang::Locale&, sal_Int32) + throw(uno::RuntimeException) {return 0;} + virtual sal_Int32 SAL_CALL loadCollatorAlgorithm(const rtl::OUString&, + const lang::Locale&, sal_Int32) throw(uno::RuntimeException) {return 0;} + virtual void SAL_CALL loadCollatorAlgorithmWithEndUserOption(const rtl::OUString&, + const lang::Locale&, const uno::Sequence< sal_Int32 >&) throw(uno::RuntimeException) {} + virtual uno::Sequence< rtl::OUString > SAL_CALL listCollatorAlgorithms(const lang::Locale&) + throw(uno::RuntimeException) + { + return uno::Sequence< rtl::OUString >(); + } + virtual uno::Sequence< sal_Int32 > SAL_CALL listCollatorOptions(const rtl::OUString&) + throw(uno::RuntimeException) + { + return uno::Sequence< sal_Int32 >(); + } +}; + +#define IS_DIGIT(CHAR) (((CHAR) >= 48) && ((CHAR <= 57))) + +class testBreakIterator : public cppu::WeakImplHelper1< i18n::XBreakIterator > +{ +public: + virtual sal_Int32 SAL_CALL nextCharacters( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int16, sal_Int32, sal_Int32& ) + throw(uno::RuntimeException) {return -1;} + virtual sal_Int32 SAL_CALL previousCharacters( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int16, sal_Int32, sal_Int32& ) + throw(uno::RuntimeException) {return -1;} + + virtual i18n::Boundary SAL_CALL previousWord( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int16) throw(uno::RuntimeException) + { return i18n::Boundary(); } + virtual i18n::Boundary SAL_CALL nextWord( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int16) throw(uno::RuntimeException) + { return i18n::Boundary(); } + virtual i18n::Boundary SAL_CALL getWordBoundary( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int16, sal_Bool ) + throw(uno::RuntimeException) + { return i18n::Boundary(); } + + virtual sal_Bool SAL_CALL isBeginWord( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int16 ) throw(uno::RuntimeException) + { return false; } + virtual sal_Bool SAL_CALL isEndWord( const rtl::OUString&, sal_Int32, + const lang::Locale& , sal_Int16 ) throw(uno::RuntimeException) + { return false; } + virtual sal_Int16 SAL_CALL getWordType( const rtl::OUString&, sal_Int32, + const lang::Locale& ) throw(uno::RuntimeException) + { return 0; } + + virtual sal_Int32 SAL_CALL beginOfSentence( const rtl::OUString&, sal_Int32, + const lang::Locale& ) throw(uno::RuntimeException) + { return 0; } + virtual sal_Int32 SAL_CALL endOfSentence( const rtl::OUString& rText, sal_Int32, + const lang::Locale& ) throw(uno::RuntimeException) + { return rText.getLength(); } + + virtual i18n::LineBreakResults SAL_CALL getLineBreak( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int32, + const i18n::LineBreakHyphenationOptions&, + const i18n::LineBreakUserOptions&) + throw(uno::RuntimeException) + { + return i18n::LineBreakResults(); + } + + virtual sal_Int16 SAL_CALL getScriptType( const rtl::OUString&, sal_Int32 ) + throw(uno::RuntimeException) { return -1; } + virtual sal_Int32 SAL_CALL beginOfScript( const rtl::OUString&, sal_Int32, + sal_Int16 ) throw(uno::RuntimeException) { return -1; } + virtual sal_Int32 SAL_CALL endOfScript( const rtl::OUString&, sal_Int32, + sal_Int16 ) throw(uno::RuntimeException) { return -1; } + virtual sal_Int32 SAL_CALL previousScript( const rtl::OUString&, sal_Int32, + sal_Int16 ) throw(uno::RuntimeException) { return -1; } + virtual sal_Int32 SAL_CALL nextScript( const rtl::OUString&, sal_Int32, + sal_Int16 ) throw(uno::RuntimeException) { return -1; } + + virtual sal_Int32 SAL_CALL beginOfCharBlock( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int16 ) throw(uno::RuntimeException) { return -1; } + virtual sal_Int32 SAL_CALL endOfCharBlock( const rtl::OUString& rText, sal_Int32 nStartPos, + const lang::Locale&, sal_Int16 CharType ) throw(uno::RuntimeException) + { + const sal_Unicode *pStr = rText.getStr()+nStartPos; + for (sal_Int32 nI = nStartPos; nI < rText.getLength(); ++nI) + { + if (CharType == i18n::CharType::DECIMAL_DIGIT_NUMBER && !IS_DIGIT(*pStr)) + return nI; + else if (CharType != i18n::CharType::DECIMAL_DIGIT_NUMBER && IS_DIGIT(*pStr)) + return nI; + ++pStr; + } + return -1; + } + virtual sal_Int32 SAL_CALL previousCharBlock( const rtl::OUString&, sal_Int32, + const lang::Locale&, sal_Int16 ) throw(uno::RuntimeException) { return -1; } + virtual sal_Int32 SAL_CALL nextCharBlock( const rtl::OUString& rText, sal_Int32 nStartPos, + const lang::Locale&, sal_Int16 CharType ) throw(uno::RuntimeException) + { + const sal_Unicode *pStr = rText.getStr()+nStartPos; + for (sal_Int32 nI = nStartPos; nI < rText.getLength(); ++nI) + { + if (CharType == i18n::CharType::DECIMAL_DIGIT_NUMBER && IS_DIGIT(*pStr)) + return nI; + else if (CharType != i18n::CharType::DECIMAL_DIGIT_NUMBER && !IS_DIGIT(*pStr)) + return nI; + ++pStr; + } + return -1; + } +}; + +void TestString::testNatural() +{ + using namespace comphelper::string; + + uno::Reference< i18n::XCollator > xCollator(new testCollator); + uno::Reference< i18n::XBreakIterator > xBI(new testBreakIterator); + +// --- Some generic tests to ensure we do not alter original behavior +// outside what we want + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("ABC"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("ABC"))), xCollator, xBI, lang::Locale()) == 0 + ); + // Case sensitivity + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("ABC"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("abc"))), xCollator, xBI, lang::Locale()) < 0 + ); + // Reverse + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("abc"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("ABC"))), xCollator, xBI, lang::Locale()) > 0 + ); + // First shorter + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("alongstring"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("alongerstring"))), xCollator, xBI, lang::Locale()) > 0 + ); + // Second shorter + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("alongerstring"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("alongstring"))), xCollator, xBI, lang::Locale()) < 0 + ); +// -- Here we go on natural order, each one is followed by classic compare and the reverse comparison + // That's why we originally made the patch + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("Heading 9"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("Heading 10"))), xCollator, xBI, lang::Locale()) < 0 + ); + // Original behavior + CPPUNIT_ASSERT( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("Heading 9"))).compareTo(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("Heading 10")))) > 0 + ); + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("Heading 10"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("Heading 9"))), xCollator, xBI, lang::Locale()) > 0 + ); + // Harder + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("July, the 4th"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("July, the 10th"))), xCollator, xBI, lang::Locale()) < 0 + ); + CPPUNIT_ASSERT( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("July, the 4th"))).compareTo(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("July, the 10th")))) > 0 + ); + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("July, the 10th"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("July, the 4th"))), xCollator, xBI, lang::Locale()) > 0 + ); + // Hardest + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("abc08"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("abc010"))), xCollator, xBI, lang::Locale()) < 0 + ); + CPPUNIT_ASSERT( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("abc08"))).compareTo(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("abc010")))) > 0 + ); + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("abc010"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("abc08"))), xCollator, xBI, lang::Locale()) > 0 + ); + CPPUNIT_ASSERT( + compareNatural(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("apple10apple"))), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(("apple10apple"))), xCollator, xBI, lang::Locale()) == 0 + ); +} + +void TestString::testReplace() +{ + ::rtl::OString aIn(RTL_CONSTASCII_STRINGPARAM("aaa")); + ::rtl::OString aOut; + + aOut = ::comphelper::string::replace(aIn, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("aa")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("b"))); + CPPUNIT_ASSERT(aOut.equalsL(RTL_CONSTASCII_STRINGPARAM("ba"))); + + aOut = ::comphelper::string::replace(aIn, + rtl::OString(), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("whatever"))); + CPPUNIT_ASSERT(aOut.equalsL(RTL_CONSTASCII_STRINGPARAM("aaa"))); + + aOut = ::comphelper::string::replace(aIn, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("aaa")), + rtl::OString()); + CPPUNIT_ASSERT(aOut.isEmpty()); + + aIn = rtl::OString(RTL_CONSTASCII_STRINGPARAM("aaa foo aaa foo bbb")); + + aOut = ::comphelper::string::replace(aIn, + rtl::OString(RTL_CONSTASCII_STRINGPARAM("foo")), + rtl::OString(RTL_CONSTASCII_STRINGPARAM("bar"))); + CPPUNIT_ASSERT(aOut.equalsL( + RTL_CONSTASCII_STRINGPARAM("aaa bar aaa bar bbb"))); + + aOut = ::comphelper::string::replace(aIn, + rtl::OString(' '), + rtl::OString()); + CPPUNIT_ASSERT(aOut.equalsL( + RTL_CONSTASCII_STRINGPARAM("aaafooaaafoobbb"))); +} + +void TestString::testToken() +{ + ::rtl::OString aIn(RTL_CONSTASCII_STRINGPARAM("10.11.12")); + ::rtl::OString aOut; + + aOut = ::comphelper::string::getToken(aIn, -1, '.'); + CPPUNIT_ASSERT(aOut.isEmpty()); + + aOut = ::comphelper::string::getToken(aIn, 0, '.'); + CPPUNIT_ASSERT(aOut.equalsL(RTL_CONSTASCII_STRINGPARAM("10"))); + + aOut = ::comphelper::string::getToken(aIn, 1, '.'); + CPPUNIT_ASSERT(aOut.equalsL(RTL_CONSTASCII_STRINGPARAM("11"))); + + aOut = ::comphelper::string::getToken(aIn, 2, '.'); + CPPUNIT_ASSERT(aOut.equalsL(RTL_CONSTASCII_STRINGPARAM("12"))); + + aOut = ::comphelper::string::getToken(aIn, 3, '.'); + CPPUNIT_ASSERT(aOut.isEmpty()); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(TestString); + +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/qa/version.map b/comphelper/qa/version.map new file mode 100644 index 000000000000..5e95a1532f8a --- /dev/null +++ b/comphelper/qa/version.map @@ -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. +# +#************************************************************************* + +UDK_3_0_0 { + global: + cppunitTestPlugIn; + local: + *; +}; diff --git a/comphelper/qa/weakbag/makefile.mk b/comphelper/qa/weakbag/makefile.mk new file mode 100644 index 000000000000..fdba94838a56 --- /dev/null +++ b/comphelper/qa/weakbag/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 := comphelper +TARGET := qa_weakbag + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk +.INCLUDE : $(PRJ)$/version.mk + +CFLAGSCXX += $(CPPUNIT_CFLAGS) + +DLLPRE = # no leading "lib" on .so files + +INCPRE += $(MISC)$/$(TARGET)$/inc + +SHL1TARGET = $(TARGET)_weakbag +SHL1OBJS = $(SLO)$/test_weakbag.obj $(SLO)$/test_weakbag_noadditional.obj +SHL1STDLIBS = $(CPPUHELPERLIB) $(CPPULIB) $(CPPUNITLIB) $(SALLIB) $(COMPHELPERLIB) +SHL1VERSIONMAP = ..$/version.map +SHL1IMPLIB = i$(SHL1TARGET) +DEF1NAME = $(SHL1TARGET) + +SLOFILES = $(SHL1OBJS) + +.INCLUDE: target.mk +.INCLUDE: _cppunit.mk diff --git a/comphelper/qa/weakbag/test_weakbag.cxx b/comphelper/qa/weakbag/test_weakbag.cxx new file mode 100644 index 000000000000..84767f0ede0e --- /dev/null +++ b/comphelper/qa/weakbag/test_weakbag.cxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "sal/config.h" + +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/XInterface.hpp" +#include "comphelper/weakbag.hxx" +#include "cppuhelper/weak.hxx" + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> + +namespace { + +namespace css = com::sun::star; + +class Test: public CppUnit::TestFixture { +public: + void test() { + css::uno::Reference< css::uno::XInterface > ref1(new cppu::OWeakObject); + css::uno::Reference< css::uno::XInterface > ref2(new cppu::OWeakObject); + css::uno::Reference< css::uno::XInterface > ref3(new cppu::OWeakObject); + comphelper::WeakBag< css::uno::XInterface > bag; + bag.add(ref1); + bag.add(ref1); + bag.add(ref2); + bag.add(ref2); + ref1.clear(); + bag.add(ref3); + ref3.clear(); + CPPUNIT_ASSERT_MESSAGE("remove first ref2", bag.remove() == ref2); + CPPUNIT_ASSERT_MESSAGE("remove second ref2", bag.remove() == ref2); + CPPUNIT_ASSERT_MESSAGE("remove first null", !bag.remove().is()); + CPPUNIT_ASSERT_MESSAGE("remove second null", !bag.remove().is()); + } + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(test); + CPPUNIT_TEST_SUITE_END(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/qa/weakbag/test_weakbag_noadditional.cxx b/comphelper/qa/weakbag/test_weakbag_noadditional.cxx new file mode 100644 index 000000000000..9f3bfe5061ab --- /dev/null +++ b/comphelper/qa/weakbag/test_weakbag_noadditional.cxx @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 <cppunit/plugin/TestPlugIn.h> + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/compare/AnyCompareFactory.cxx b/comphelper/source/compare/AnyCompareFactory.cxx new file mode 100644 index 000000000000..074d3a5ffc3a --- /dev/null +++ b/comphelper/source/compare/AnyCompareFactory.cxx @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +#include <com/sun/star/ucb/XAnyCompareFactory.hpp> +#include <com/sun/star/i18n/XCollator.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <comphelper/stl_types.hxx> +#include <map> + + +using namespace com::sun::star::uno; +using namespace com::sun::star::ucb; +using namespace com::sun::star::lang; +using namespace com::sun::star::i18n; + +using ::rtl::OUString; + +//============================================================================= + +class AnyCompare : public ::cppu::WeakImplHelper1< XAnyCompare > +{ + Reference< XCollator > m_rCollator; + +public: + AnyCompare( Reference< XComponentContext > xContext, const Locale& rLocale ) throw() + { + Reference< XMultiComponentFactory > xFactory = xContext->getServiceManager(); + if ( xFactory.is() ) + { + m_rCollator = Reference< XCollator >( + xFactory->createInstanceWithContext( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.Collator" )), xContext ), + UNO_QUERY ); + m_rCollator->loadDefaultCollator( rLocale, + 0 ); //??? + } + + } + + virtual sal_Int16 SAL_CALL compare( const Any& any1, const Any& any2 ) throw(RuntimeException); +}; + +//============================================================================= + +class AnyCompareFactory : public cppu::WeakImplHelper3< XAnyCompareFactory, XInitialization, XServiceInfo > +{ + Reference< XAnyCompare > m_rAnyCompare; + Reference< XComponentContext > m_rContext; + Locale m_Locale; + +public: + AnyCompareFactory( Reference< XComponentContext > xContext ) : m_rContext( xContext ) + {} + + // XAnyCompareFactory + virtual Reference< XAnyCompare > SAL_CALL createAnyCompareByName ( const OUString& aPropertyName ) throw(::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) + throw ( Exception, RuntimeException ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException); + + // XServiceInfo - static versions (used for component registration) + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static Reference< XInterface > SAL_CALL Create( const Reference< XComponentContext >& ); +}; + +//=========================================================================================== + +sal_Int16 SAL_CALL AnyCompare::compare( const Any& any1, const Any& any2 ) throw(::com::sun::star::uno::RuntimeException) +{ + sal_Int16 aResult = 0; + + if( m_rCollator.is() ) + { + OUString aStr1; + OUString aStr2; + + any1 >>= aStr1; + any2 >>= aStr2; + + aResult = ( sal_Int16 )m_rCollator->compareString( aStr1, aStr2 ); + } + + return aResult; +} + +//=========================================================================================== + +Reference< XAnyCompare > SAL_CALL AnyCompareFactory::createAnyCompareByName( const OUString& aPropertyName ) throw(::com::sun::star::uno::RuntimeException) +{ + // for now only OUString properties compare is implemented + // so no check for the property name is done + + if( aPropertyName.equals( OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" )) ) ) + return m_rAnyCompare; + + return Reference< XAnyCompare >(); +} + +void SAL_CALL AnyCompareFactory::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException ) +{ + if( aArguments.getLength() ) + { + if( aArguments[0] >>= m_Locale ) + { + m_rAnyCompare = new AnyCompare( m_rContext, m_Locale ); + return; + } + } + +} + +OUString SAL_CALL AnyCompareFactory::getImplementationName( ) throw( RuntimeException ) +{ + return getImplementationName_static(); +} + +OUString SAL_CALL AnyCompareFactory::getImplementationName_static( ) +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AnyCompareFactory" ) ); +} + +sal_Bool SAL_CALL AnyCompareFactory::supportsService( const OUString& ServiceName ) throw(RuntimeException) +{ + rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.AnyCompareFactory" ) ); + return aServiceName == ServiceName; +} + +Sequence< OUString > SAL_CALL AnyCompareFactory::getSupportedServiceNames( ) throw(RuntimeException) +{ + return getSupportedServiceNames_static(); +} + +Sequence< OUString > SAL_CALL AnyCompareFactory::getSupportedServiceNames_static( ) +{ + const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.AnyCompareFactory" ) ); + const Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +Reference< XInterface > SAL_CALL AnyCompareFactory::Create( + const Reference< XComponentContext >& rxContext ) +{ + return (cppu::OWeakObject*)new AnyCompareFactory( rxContext ); +} + +void createRegistryInfo_AnyCompareFactory() +{ + static ::comphelper::module::OAutoRegistration< AnyCompareFactory > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/container/IndexedPropertyValuesContainer.cxx b/comphelper/source/container/IndexedPropertyValuesContainer.cxx new file mode 100644 index 000000000000..4608f9115bcb --- /dev/null +++ b/comphelper/source/container/IndexedPropertyValuesContainer.cxx @@ -0,0 +1,271 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + + +#include <vector> + +using namespace com::sun::star; + +typedef std::vector < uno::Sequence< beans::PropertyValue > > IndexedPropertyValues; + +class IndexedPropertyValuesContainer : public cppu::WeakImplHelper2< container::XIndexContainer, lang::XServiceInfo > +{ +public: + IndexedPropertyValuesContainer() throw(); + virtual ~IndexedPropertyValuesContainer() throw(); + + // XIndexContainer + virtual void SAL_CALL insertByIndex( sal_Int32 nIndex, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeByIndex( sal_Int32 nIndex ) + throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XIndexReplace + virtual void SAL_CALL replaceByIndex( sal_Int32 nIndex, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) + throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XElementAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements( ) + throw(::com::sun::star::uno::RuntimeException); + + //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); + + // XServiceInfo - static versions (used for component registration) + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static uno::Reference< uno::XInterface > SAL_CALL Create( const uno::Reference< uno::XComponentContext >& ); + +private: + IndexedPropertyValues maProperties; +}; + +IndexedPropertyValuesContainer::IndexedPropertyValuesContainer() throw() +{ +} + +IndexedPropertyValuesContainer::~IndexedPropertyValuesContainer() throw() +{ +} + +// XIndexContainer +void SAL_CALL IndexedPropertyValuesContainer::insertByIndex( sal_Int32 nIndex, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + sal_Int32 nSize(maProperties.size()); + if ((nSize >= nIndex) && (nIndex >= 0)) + { + uno::Sequence<beans::PropertyValue> aProps; + if (!(aElement >>= aProps)) + throw lang::IllegalArgumentException(); + if (nSize == nIndex) + maProperties.push_back(aProps); + else + { + IndexedPropertyValues::iterator aItr; + if ((nIndex * 2) < nSize) + { + aItr = maProperties.begin(); + sal_Int32 i(0); + while(i < nIndex) + { + ++i; + ++aItr; + } + } + else + { + aItr = maProperties.end(); + sal_Int32 i(nSize - 1); + while(i > nIndex) + { + --i; + --aItr; + } + } + maProperties.insert(aItr, aProps); + } + } + else + throw lang::IndexOutOfBoundsException(); +} + +void SAL_CALL IndexedPropertyValuesContainer::removeByIndex( sal_Int32 nIndex ) + throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + sal_Int32 nSize(maProperties.size()); + if ((nIndex < nSize) && (nIndex >= 0)) + { + IndexedPropertyValues::iterator aItr; + if ((nIndex * 2) < nSize) + { + aItr = maProperties.begin(); + sal_Int32 i(0); + while(i < nIndex) + { + ++i; + ++aItr; + } + } + else + { + aItr = maProperties.end(); + sal_Int32 i(nSize - 1); + while(i > nIndex) + { + --i; + --aItr; + } + } + maProperties.erase(aItr); + } + else + throw lang::IndexOutOfBoundsException(); +} + +// XIndexReplace +void SAL_CALL IndexedPropertyValuesContainer::replaceByIndex( sal_Int32 nIndex, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + sal_Int32 nSize(maProperties.size()); + if ((nIndex < nSize) && (nIndex >= 0)) + { + uno::Sequence<beans::PropertyValue> aProps; + if (!(aElement >>= aProps)) + throw lang::IllegalArgumentException(); + maProperties[nIndex] = aProps; + } + else + throw lang::IndexOutOfBoundsException(); +} + +// XIndexAccess +sal_Int32 SAL_CALL IndexedPropertyValuesContainer::getCount( ) + throw(::com::sun::star::uno::RuntimeException) +{ + return maProperties.size(); +} + +::com::sun::star::uno::Any SAL_CALL IndexedPropertyValuesContainer::getByIndex( sal_Int32 nIndex ) + throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + sal_Int32 nSize(maProperties.size()); + if (!((nIndex < nSize) && (nIndex >= 0))) + throw lang::IndexOutOfBoundsException(); + + uno::Any aAny; + aAny <<= maProperties[nIndex]; + return aAny; +} + +// XElementAccess +::com::sun::star::uno::Type SAL_CALL IndexedPropertyValuesContainer::getElementType( ) + throw(::com::sun::star::uno::RuntimeException) +{ + return ::getCppuType((uno::Sequence<beans::PropertyValue> *)0); +} + +sal_Bool SAL_CALL IndexedPropertyValuesContainer::hasElements( ) + throw(::com::sun::star::uno::RuntimeException) +{ + return !maProperties.empty(); +} + +//XServiceInfo +::rtl::OUString SAL_CALL IndexedPropertyValuesContainer::getImplementationName( ) throw(::com::sun::star::uno::RuntimeException) +{ + return getImplementationName_static(); +} + +::rtl::OUString SAL_CALL IndexedPropertyValuesContainer::getImplementationName_static( ) +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IndexedPropertyValuesContainer" ) ); +} + +sal_Bool SAL_CALL IndexedPropertyValuesContainer::supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException) +{ + rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.IndexedPropertyValues" ) ); + return aServiceName == ServiceName; +} + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL IndexedPropertyValuesContainer::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException) +{ + return getSupportedServiceNames_static(); +} + + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL IndexedPropertyValuesContainer::getSupportedServiceNames_static( ) +{ + const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.IndexedPropertyValues" ) ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + + +uno::Reference< uno::XInterface > SAL_CALL IndexedPropertyValuesContainer::Create( + const uno::Reference< uno::XComponentContext >&) +{ + return (cppu::OWeakObject*)new IndexedPropertyValuesContainer(); +} + +void createRegistryInfo_IndexedPropertyValuesContainer() +{ + static ::comphelper::module::OAutoRegistration< IndexedPropertyValuesContainer > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/container/NamedPropertyValuesContainer.cxx b/comphelper/source/container/NamedPropertyValuesContainer.cxx new file mode 100644 index 000000000000..329e6211c6ea --- /dev/null +++ b/comphelper/source/container/NamedPropertyValuesContainer.cxx @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <comphelper/stl_types.hxx> + + +#include <map> + + +using namespace com::sun::star; + +DECLARE_STL_USTRINGACCESS_MAP( uno::Sequence<beans::PropertyValue>, NamedPropertyValues ); + +class NamedPropertyValuesContainer : public cppu::WeakImplHelper2< container::XNameContainer, lang::XServiceInfo > +{ +public: + NamedPropertyValuesContainer() throw(); + virtual ~NamedPropertyValuesContainer() throw(); + + // XNameContainer + virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XNameReplace + virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XNameAccess + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::uno::RuntimeException); + + // XElementAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements( ) + throw(::com::sun::star::uno::RuntimeException); + + //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); + + // XServiceInfo - static versions (used for component registration) + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static uno::Reference< uno::XInterface > SAL_CALL Create( const uno::Reference< uno::XComponentContext >& ); + +private: + NamedPropertyValues maProperties; +}; + +NamedPropertyValuesContainer::NamedPropertyValuesContainer() throw() +{ +} + +NamedPropertyValuesContainer::~NamedPropertyValuesContainer() throw() +{ +} + +// XNameContainer +void SAL_CALL NamedPropertyValuesContainer::insertByName( const rtl::OUString& aName, const uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + if( maProperties.find( aName ) != maProperties.end() ) + throw container::ElementExistException(); + + uno::Sequence<beans::PropertyValue> aProps; + if( !(aElement >>= aProps ) ) + throw lang::IllegalArgumentException(); + + maProperties.insert( NamedPropertyValues::value_type(aName ,aProps) ); +} + +void SAL_CALL NamedPropertyValuesContainer::removeByName( const ::rtl::OUString& Name ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + NamedPropertyValues::iterator aIter = maProperties.find( Name ); + if( aIter == maProperties.end() ) + throw container::NoSuchElementException(); + + maProperties.erase( aIter ); +} + +// XNameReplace +void SAL_CALL NamedPropertyValuesContainer::replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + NamedPropertyValues::iterator aIter = maProperties.find( aName ); + if( aIter == maProperties.end() ) + throw container::NoSuchElementException(); + + uno::Sequence<beans::PropertyValue> aProps; + if( !(aElement >>= aProps) ) + throw lang::IllegalArgumentException(); + + (*aIter).second = aProps; +} + +// XNameAccess +::com::sun::star::uno::Any SAL_CALL NamedPropertyValuesContainer::getByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + NamedPropertyValues::iterator aIter = maProperties.find( aName ); + if( aIter == maProperties.end() ) + throw container::NoSuchElementException(); + + uno::Any aElement; + + aElement <<= (*aIter).second; + + return aElement; +} + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL NamedPropertyValuesContainer::getElementNames( ) + throw(::com::sun::star::uno::RuntimeException) +{ + NamedPropertyValues::iterator aIter = maProperties.begin(); + const NamedPropertyValues::iterator aEnd = maProperties.end(); + + uno::Sequence< rtl::OUString > aNames( maProperties.size() ); + rtl::OUString* pNames = aNames.getArray(); + + while( aIter != aEnd ) + { + *pNames++ = (*aIter++).first; + } + + return aNames; +} + +sal_Bool SAL_CALL NamedPropertyValuesContainer::hasByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::uno::RuntimeException) +{ + NamedPropertyValues::iterator aIter = maProperties.find( aName ); + return aIter != maProperties.end(); +} + +// XElementAccess +::com::sun::star::uno::Type SAL_CALL NamedPropertyValuesContainer::getElementType( ) + throw(::com::sun::star::uno::RuntimeException) +{ + return ::getCppuType((uno::Sequence<beans::PropertyValue> *)0); +} + +sal_Bool SAL_CALL NamedPropertyValuesContainer::hasElements( ) + throw(::com::sun::star::uno::RuntimeException) +{ + return !maProperties.empty(); +} + +//XServiceInfo +::rtl::OUString SAL_CALL NamedPropertyValuesContainer::getImplementationName( ) throw(::com::sun::star::uno::RuntimeException) +{ + return getImplementationName_static(); +} + +::rtl::OUString SAL_CALL NamedPropertyValuesContainer::getImplementationName_static( ) +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NamedPropertyValuesContainer" ) ); +} + +sal_Bool SAL_CALL NamedPropertyValuesContainer::supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException) +{ + rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.NamedPropertyValues" ) ); + return aServiceName == ServiceName; +} + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL NamedPropertyValuesContainer::getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException) +{ + return getSupportedServiceNames_static(); +} + + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL NamedPropertyValuesContainer::getSupportedServiceNames_static( ) +{ + const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.NamedPropertyValues" ) ); + const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +uno::Reference< uno::XInterface > SAL_CALL NamedPropertyValuesContainer::Create( + const uno::Reference< uno::XComponentContext >&) +{ + return (cppu::OWeakObject*)new NamedPropertyValuesContainer(); +} + +void createRegistryInfo_NamedPropertyValuesContainer() +{ + static ::comphelper::module::OAutoRegistration< NamedPropertyValuesContainer > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/container/container.cxx b/comphelper/source/container/container.cxx new file mode 100644 index 000000000000..ef99066c4bf5 --- /dev/null +++ b/comphelper/source/container/container.cxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <comphelper/container.hxx> +#include <osl/diagnose.h> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +//============================================================================== +IndexAccessIterator::IndexAccessIterator(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xStartingPoint) + :m_xStartingPoint(xStartingPoint) + ,m_xCurrentObject(NULL) +{ + OSL_ENSURE(m_xStartingPoint.is(), "IndexAccessIterator::IndexAccessIterator : no starting point !"); +} + +IndexAccessIterator::~IndexAccessIterator() {} + +//------------------------------------------------------------------------------ +::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> IndexAccessIterator::Next() +{ + sal_Bool bCheckingStartingPoint = !m_xCurrentObject.is(); + // ist die aktuelle Node der Anfangspunkt ? + sal_Bool bAlreadyCheckedCurrent = m_xCurrentObject.is(); + // habe ich die aktuelle Node schon mal mittels ShouldHandleElement testen ? + if (!m_xCurrentObject.is()) + m_xCurrentObject = m_xStartingPoint; + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xSearchLoop( m_xCurrentObject); + sal_Bool bHasMoreToSearch = sal_True; + sal_Bool bFoundSomething = sal_False; + while (!bFoundSomething && bHasMoreToSearch) + { + // pre-order-traversierung + if (!bAlreadyCheckedCurrent && ShouldHandleElement(xSearchLoop)) + { + m_xCurrentObject = xSearchLoop; + bFoundSomething = sal_True; + } + else + { + // zuerst absteigen, wenn moeglich + ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess> xContainerAccess(xSearchLoop, ::com::sun::star::uno::UNO_QUERY); + if (xContainerAccess.is() && xContainerAccess->getCount() && ShouldStepInto(xContainerAccess)) + { // zum ersten Child + ::com::sun::star::uno::Any aElement(xContainerAccess->getByIndex(0)); + xSearchLoop = *(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>*)aElement.getValue(); + bCheckingStartingPoint = sal_False; + + m_arrChildIndizies.push_back((sal_Int32)0); + } + else + { + // dann nach oben und nach rechts, wenn moeglich + while (m_arrChildIndizies.size() > 0) + { // (mein Stack ist nich leer, also kann ich noch nach oben gehen) + ::com::sun::star::uno::Reference< ::com::sun::star::container::XChild> xChild(xSearchLoop, ::com::sun::star::uno::UNO_QUERY); + OSL_ENSURE(xChild.is(), "IndexAccessIterator::Next : a content has no approriate interface !"); + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xParent( xChild->getParent()); + xContainerAccess = ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>(xParent, ::com::sun::star::uno::UNO_QUERY); + OSL_ENSURE(xContainerAccess.is(), "IndexAccessIterator::Next : a content has an invalid parent !"); + + // den Index, den SearchLoop in diesem Parent hatte, von meinem 'Stack' + sal_Int32 nOldSearchChildIndex = m_arrChildIndizies[m_arrChildIndizies.size() - 1]; + m_arrChildIndizies.pop_back(); + + if (nOldSearchChildIndex < xContainerAccess->getCount() - 1) + { // auf dieser Ebene geht es noch nach rechts + ++nOldSearchChildIndex; + // also das naechste Child + ::com::sun::star::uno::Any aElement(xContainerAccess->getByIndex(nOldSearchChildIndex)); + xSearchLoop = *(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>*) aElement.getValue(); + bCheckingStartingPoint = sal_False; + // und dessen Position auf den 'Stack' + m_arrChildIndizies.push_back((sal_Int32)nOldSearchChildIndex); + + break; + } + // hierher komme ich, wenn es auf der aktuellen Ebene nicht nach rechts geht, dann mache ich eine darueber weiter + xSearchLoop = xParent; + bCheckingStartingPoint = sal_False; + } + + if ((m_arrChildIndizies.size() == 0) && !bCheckingStartingPoint) + { // das ist genau dann der Fall, wenn ich keinen rechten Nachbarn fuer irgendeinen der direkten Vorfahren des + // urspruenglichen xSearchLoop gefunden habe + bHasMoreToSearch = sal_False; + } + } + + if (bHasMoreToSearch) + { // ich habe in xSearchLoop jetzt ein Interface eines 'Knotens' meines 'Baumes', den ich noch abtesten kann + if (ShouldHandleElement(xSearchLoop)) + { + m_xCurrentObject = xSearchLoop; + bFoundSomething = sal_True; + } + else + if (bCheckingStartingPoint) + // ich bin noch am Anfang, konnte nicht absteigen, und habe an diesem Anfang nix gefunden -> nix mehr zu tun + bHasMoreToSearch = sal_False; + bAlreadyCheckedCurrent = sal_True; + } + } + } + + if (!bFoundSomething) + { + OSL_ENSURE(m_arrChildIndizies.size() == 0, "IndexAccessIterator::Next : items left on stack ! how this ?"); + Invalidate(); + } + + return m_xCurrentObject; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/container/containermultiplexer.cxx b/comphelper/source/container/containermultiplexer.cxx new file mode 100644 index 000000000000..21c72fbbead1 --- /dev/null +++ b/comphelper/source/container/containermultiplexer.cxx @@ -0,0 +1,205 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "comphelper/containermultiplexer.hxx" +#include "comphelper/uno3.hxx" +#include <osl/diagnose.h> +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::container; + + //===================================================================== + //= OContainerListener + //===================================================================== + //--------------------------------------------------------------------- + OContainerListener::OContainerListener(::osl::Mutex& _rMutex) + :m_pAdapter(NULL) + ,m_rMutex(_rMutex) + { + } + + //--------------------------------------------------------------------- + OContainerListener::~OContainerListener() + { + if (m_pAdapter) + { + m_pAdapter->dispose(); + m_pAdapter = NULL; + } + } + + //--------------------------------------------------------------------- + void OContainerListener::_elementInserted( const ContainerEvent& /*_rEvent*/ ) throw(RuntimeException) + { + } + + //--------------------------------------------------------------------- + void OContainerListener::_elementRemoved( const ContainerEvent& ) throw(RuntimeException) + { + } + + //--------------------------------------------------------------------- + void OContainerListener::_elementReplaced( const ContainerEvent& /*_rEvent*/ ) throw(RuntimeException) + { + } + + //--------------------------------------------------------------------- + void OContainerListener::_disposing(const EventObject& ) throw( RuntimeException) + { + } + + //------------------------------------------------------------------ + void OContainerListener::setAdapter(OContainerListenerAdapter* pAdapter) + { + if (m_pAdapter) + { + ::osl::MutexGuard aGuard(m_rMutex); + m_pAdapter->release(); + m_pAdapter = NULL; + } + + if (pAdapter) + { + ::osl::MutexGuard aGuard(m_rMutex); + m_pAdapter = pAdapter; + m_pAdapter->acquire(); + } + } + + //===================================================================== + //= OContainerListenerAdapter + //===================================================================== + //--------------------------------------------------------------------- + OContainerListenerAdapter::OContainerListenerAdapter(OContainerListener* _pListener, + const Reference< XContainer >& _rxContainer) + :m_xContainer(_rxContainer) + ,m_pListener(_pListener) + ,m_nLockCount(0) + { + if (m_pListener) + m_pListener->setAdapter(this); + + ::comphelper::increment(m_refCount); + try + { + m_xContainer->addContainerListener(this); + } + catch(const Exception&) + { + OSL_FAIL("Exceptiopn caught!"); + } + ::comphelper::decrement(m_refCount); + } + + //--------------------------------------------------------------------- + OContainerListenerAdapter::~OContainerListenerAdapter() + { + } + + //------------------------------------------------------------------ + void OContainerListenerAdapter::lock() + { + ++m_nLockCount; + } + + //------------------------------------------------------------------ + void OContainerListenerAdapter::unlock() + { + --m_nLockCount; + } + + //------------------------------------------------------------------ + void OContainerListenerAdapter::dispose() + { + if (m_xContainer.is()) + { + try + { + Reference< XContainerListener > xPreventDelete(this); + m_xContainer->removeContainerListener(xPreventDelete); + m_pListener->setAdapter(NULL); + } + catch(const Exception&) + { + OSL_FAIL("Exception caught!"); + } + m_xContainer = NULL; + m_pListener = NULL; + } + } + + //------------------------------------------------------------------ + void SAL_CALL OContainerListenerAdapter::disposing( const EventObject& _rSource) throw(RuntimeException) + { + if (m_pListener) + { + // tell the listener + if (!locked()) + m_pListener->_disposing(_rSource); + // disconnect the listener + if ( m_pListener ) + m_pListener->setAdapter(NULL); + } + + m_xContainer = NULL; + m_pListener = NULL; + } + + //------------------------------------------------------------------ + void SAL_CALL OContainerListenerAdapter::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException) + { + if (m_pListener && !locked()) + m_pListener->_elementInserted(_rEvent); + } + + //------------------------------------------------------------------ + void SAL_CALL OContainerListenerAdapter::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException) + { + if (m_pListener && !locked()) + m_pListener->_elementRemoved(_rEvent); + } + + //------------------------------------------------------------------ + void SAL_CALL OContainerListenerAdapter::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException) + { + if (m_pListener && !locked()) + m_pListener->_elementReplaced(_rEvent); + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/container/embeddedobjectcontainer.cxx b/comphelper/source/container/embeddedobjectcontainer.cxx new file mode 100644 index 000000000000..9f84b7afa053 --- /dev/null +++ b/comphelper/source/container/embeddedobjectcontainer.cxx @@ -0,0 +1,1666 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/embed/XEmbedObjectCreator.hpp> +#include <com/sun/star/embed/XLinkCreator.hpp> +#include <com/sun/star/embed/XEmbedPersist.hpp> +#include <com/sun/star/embed/XLinkageSupport.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/embed/XOptimizedStorage.hpp> +#include <com/sun/star/embed/EntryInitModes.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/embed/EmbedStates.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/embed/EmbedMisc.hpp> + +#include <comphelper/seqstream.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/storagehelper.hxx> +#include <comphelper/embeddedobjectcontainer.hxx> +#include <comphelper/sequence.hxx> +#include <cppuhelper/weakref.hxx> +#include <boost/unordered_map.hpp> +#include <algorithm> + +#include <rtl/logfile.hxx> + +using namespace ::com::sun::star; + +namespace comphelper +{ + +struct hashObjectName_Impl +{ + size_t operator()(const ::rtl::OUString Str) const + { + return (size_t)Str.hashCode(); + } +}; + +struct eqObjectName_Impl +{ + sal_Bool operator()(const ::rtl::OUString Str1, const ::rtl::OUString Str2) const + { + return ( Str1 == Str2 ); + } +}; + +typedef boost::unordered_map +< + ::rtl::OUString, + ::com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >, + hashObjectName_Impl, + eqObjectName_Impl +> +EmbeddedObjectContainerNameMap; + +struct EmbedImpl +{ + // TODO/LATER: remove objects from temp. Container storage when object is disposed + EmbeddedObjectContainerNameMap maObjectContainer; + uno::Reference < embed::XStorage > mxStorage; + EmbeddedObjectContainer* mpTempObjectContainer; + uno::Reference < embed::XStorage > mxImageStorage; + uno::WeakReference < uno::XInterface > m_xModel; + //EmbeddedObjectContainerNameMap maTempObjectContainer; + //uno::Reference < embed::XStorage > mxTempStorage; + sal_Bool bOwnsStorage; + + const uno::Reference < embed::XStorage >& GetReplacements(); +}; + +const uno::Reference < embed::XStorage >& EmbedImpl::GetReplacements() +{ + if ( !mxImageStorage.is() ) + { + try + { + mxImageStorage = mxStorage->openStorageElement( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectReplacements")), embed::ElementModes::READWRITE ); + } + catch ( uno::Exception& ) + { + mxImageStorage = mxStorage->openStorageElement( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectReplacements")), embed::ElementModes::READ ); + } + } + + if ( !mxImageStorage.is() ) + throw io::IOException(); + + return mxImageStorage; +} + +EmbeddedObjectContainer::EmbeddedObjectContainer() +{ + pImpl = new EmbedImpl; + pImpl->mxStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); + pImpl->bOwnsStorage = sal_True; + pImpl->mpTempObjectContainer = 0; +} + +EmbeddedObjectContainer::EmbeddedObjectContainer( const uno::Reference < embed::XStorage >& rStor ) +{ + pImpl = new EmbedImpl; + pImpl->mxStorage = rStor; + pImpl->bOwnsStorage = sal_False; + pImpl->mpTempObjectContainer = 0; +} + +EmbeddedObjectContainer::EmbeddedObjectContainer( const uno::Reference < embed::XStorage >& rStor, const uno::Reference < uno::XInterface >& xModel ) +{ + pImpl = new EmbedImpl; + pImpl->mxStorage = rStor; + pImpl->bOwnsStorage = sal_False; + pImpl->mpTempObjectContainer = 0; + pImpl->m_xModel = xModel; +} + +void EmbeddedObjectContainer::SwitchPersistence( const uno::Reference < embed::XStorage >& rStor ) +{ + ReleaseImageSubStorage(); + + if ( pImpl->bOwnsStorage ) + pImpl->mxStorage->dispose(); + + pImpl->mxStorage = rStor; + pImpl->bOwnsStorage = sal_False; +} + +sal_Bool EmbeddedObjectContainer::CommitImageSubStorage() +{ + if ( pImpl->mxImageStorage.is() ) + { + try + { + sal_Bool bReadOnlyMode = sal_True; + uno::Reference < beans::XPropertySet > xSet(pImpl->mxImageStorage,uno::UNO_QUERY); + if ( xSet.is() ) + { + // get the open mode from the parent storage + sal_Int32 nMode = 0; + uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenMode")) ); + if ( aAny >>= nMode ) + bReadOnlyMode = !(nMode & embed::ElementModes::WRITE ); + } // if ( xSet.is() ) + if ( !bReadOnlyMode ) + { + uno::Reference< embed::XTransactedObject > xTransact( pImpl->mxImageStorage, uno::UNO_QUERY_THROW ); + xTransact->commit(); + } + } + catch( uno::Exception& ) + { + return sal_False; + } + } + + return sal_True; +} + +void EmbeddedObjectContainer::ReleaseImageSubStorage() +{ + CommitImageSubStorage(); + + if ( pImpl->mxImageStorage.is() ) + { + try + { + pImpl->mxImageStorage->dispose(); + pImpl->mxImageStorage = uno::Reference< embed::XStorage >(); + } + catch( uno::Exception& ) + { + OSL_FAIL( "Problems releasing image substorage!\n" ); + } + } +} + +EmbeddedObjectContainer::~EmbeddedObjectContainer() +{ + ReleaseImageSubStorage(); + + if ( pImpl->bOwnsStorage ) + pImpl->mxStorage->dispose(); + + delete pImpl->mpTempObjectContainer; + delete pImpl; +} + +void EmbeddedObjectContainer::CloseEmbeddedObjects() +{ + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); + while ( aIt != pImpl->maObjectContainer.end() ) + { + uno::Reference < util::XCloseable > xClose( (*aIt).second, uno::UNO_QUERY ); + if ( xClose.is() ) + { + try + { + xClose->close( sal_True ); + } + catch ( uno::Exception& ) + { + } + } + + aIt++; + } +} + +::rtl::OUString EmbeddedObjectContainer::CreateUniqueObjectName() +{ + ::rtl::OUString aPersistName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Object ") ); + ::rtl::OUString aStr; + sal_Int32 i=1; + do + { + aStr = aPersistName; + aStr += ::rtl::OUString::valueOf( i++ ); + } + while( HasEmbeddedObject( aStr ) ); + // TODO/LATER: should we consider deleted objects? + + return aStr; +} + +uno::Sequence < ::rtl::OUString > EmbeddedObjectContainer::GetObjectNames() +{ + uno::Sequence < ::rtl::OUString > aSeq( pImpl->maObjectContainer.size() ); + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); + sal_Int32 nIdx=0; + while ( aIt != pImpl->maObjectContainer.end() ) + aSeq[nIdx++] = (*aIt++).first; + return aSeq; +} + +sal_Bool EmbeddedObjectContainer::HasEmbeddedObjects() +{ + return pImpl->maObjectContainer.size() != 0; +} + +sal_Bool EmbeddedObjectContainer::HasEmbeddedObject( const ::rtl::OUString& rName ) +{ + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); + if ( aIt == pImpl->maObjectContainer.end() ) + { + uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); + return xAccess->hasByName(rName); + } + else + return sal_True; +} + +sal_Bool EmbeddedObjectContainer::HasEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj ) +{ + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); + while ( aIt != pImpl->maObjectContainer.end() ) + { + if ( (*aIt).second == xObj ) + return sal_True; + else + aIt++; + } + + return sal_False; +} + +sal_Bool EmbeddedObjectContainer::HasInstantiatedEmbeddedObject( const ::rtl::OUString& rName ) +{ + // allows to detect whether the object was already instantiated + // currently the filter instantiate it on loading, so this method allows + // to avoid objects pointing to the same persistence + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); + return ( aIt != pImpl->maObjectContainer.end() ); +} + +::rtl::OUString EmbeddedObjectContainer::GetEmbeddedObjectName( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj ) +{ + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); + while ( aIt != pImpl->maObjectContainer.end() ) + { + if ( (*aIt).second == xObj ) + return (*aIt).first; + else + aIt++; + } + + OSL_FAIL( "Unknown object!" ); + return ::rtl::OUString(); +} + +uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::GetEmbeddedObject( const ::rtl::OUString& rName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetEmbeddedObject" ); + + OSL_ENSURE( rName.getLength(), "Empty object name!"); + + uno::Reference < embed::XEmbeddedObject > xObj; + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); + +#if OSL_DEBUG_LEVEL > 1 + uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); + uno::Sequence< ::rtl::OUString> aSeq = xAccess->getElementNames(); + const ::rtl::OUString* pIter = aSeq.getConstArray(); + const ::rtl::OUString* pEnd = pIter + aSeq.getLength(); + for(;pIter != pEnd;++pIter) + { + (void)*pIter; + } + OSL_ENSURE( aIt != pImpl->maObjectContainer.end() || xAccess->hasByName(rName), "Could not return object!" ); +#endif + + // check if object was already created + if ( aIt != pImpl->maObjectContainer.end() ) + xObj = (*aIt).second; + else + xObj = Get_Impl( rName, uno::Reference < embed::XEmbeddedObject >() ); + + return xObj; +} + +uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::Get_Impl( const ::rtl::OUString& rName, const uno::Reference < embed::XEmbeddedObject >& xCopy ) +{ + uno::Reference < embed::XEmbeddedObject > xObj; + try + { + // create the object from the storage + uno::Reference < beans::XPropertySet > xSet( pImpl->mxStorage, uno::UNO_QUERY ); + sal_Bool bReadOnlyMode = sal_True; + if ( xSet.is() ) + { + // get the open mode from the parent storage + sal_Int32 nMode = 0; + uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenMode")) ); + if ( aAny >>= nMode ) + bReadOnlyMode = !(nMode & embed::ElementModes::WRITE ); + } + + // object was not added until now - should happen only by calling this method from "inside" + //TODO/LATER: it would be good to detect an error when an object should be created already, but isn't (not an "inside" call) + uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY ); + uno::Sequence< beans::PropertyValue > aObjDescr( xCopy.is() ? 2 : 1 ); + aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); + aObjDescr[0].Value <<= pImpl->m_xModel.get(); + if ( xCopy.is() ) + { + aObjDescr[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CloneFrom" ) ); + aObjDescr[1].Value <<= xCopy; + } + + uno::Sequence< beans::PropertyValue > aMediaDescr( 1 ); + aMediaDescr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")); + aMediaDescr[0].Value <<= bReadOnlyMode; + xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitFromEntry( + pImpl->mxStorage, rName, + aMediaDescr, aObjDescr ), uno::UNO_QUERY ); + + // insert object into my list + AddEmbeddedObject( xObj, rName ); + } + catch ( uno::Exception& ) + { + } + + return xObj; +} + +uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CreateEmbeddedObject( const uno::Sequence < sal_Int8 >& rClassId, + const uno::Sequence < beans::PropertyValue >& rArgs, ::rtl::OUString& rNewName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CreateEmbeddedObject" ); + + if ( !rNewName.getLength() ) + rNewName = CreateUniqueObjectName(); + + OSL_ENSURE( !HasEmbeddedObject(rNewName), "Object to create already exists!"); + + // create object from classid by inserting it into storage + uno::Reference < embed::XEmbeddedObject > xObj; + try + { + uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY ); + + uno::Sequence< beans::PropertyValue > aObjDescr( rArgs.getLength() + 1 ); + aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); + aObjDescr[0].Value <<= pImpl->m_xModel.get(); + ::std::copy( rArgs.getConstArray(), rArgs.getConstArray() + rArgs.getLength(), aObjDescr.getArray() + 1 ); + xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitNew( + rClassId, ::rtl::OUString(), pImpl->mxStorage, rNewName, + aObjDescr ), uno::UNO_QUERY ); + + AddEmbeddedObject( xObj, rNewName ); + + OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED, + "A freshly create object should be running always!\n" ); + } + catch ( uno::Exception& ) + { + } + + return xObj; +} + +uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CreateEmbeddedObject( const uno::Sequence < sal_Int8 >& rClassId, ::rtl::OUString& rNewName ) +{ + return CreateEmbeddedObject( rClassId, uno::Sequence < beans::PropertyValue >(), rNewName ); +} + +void EmbeddedObjectContainer::AddEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, const ::rtl::OUString& rName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::AddEmbeddedObject" ); + +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE( rName.getLength(), "Added object doesn't have a name!"); + uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); + uno::Reference < embed::XEmbedPersist > xEmb( xObj, uno::UNO_QUERY ); + uno::Reference < embed::XLinkageSupport > xLink( xEmb, uno::UNO_QUERY ); + // if the object has a persistance and the object is not a link than it must have persistence entry in the storage + OSL_ENSURE( !( xEmb.is() && ( !xLink.is() || !xLink->isLink() ) ) || xAccess->hasByName(rName), + "Added element not in storage!" ); +#endif + + // remember object - it needs to be in storage already + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); + OSL_ENSURE( aIt == pImpl->maObjectContainer.end(), "Element already inserted!" ); + pImpl->maObjectContainer[ rName ] = xObj; + uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY ); + if ( xChild.is() && xChild->getParent() != pImpl->m_xModel.get() ) + xChild->setParent( pImpl->m_xModel.get() ); + + // look for object in temorary container + if ( pImpl->mpTempObjectContainer ) + { + aIt = pImpl->mpTempObjectContainer->pImpl->maObjectContainer.begin(); + while ( aIt != pImpl->mpTempObjectContainer->pImpl->maObjectContainer.end() ) + { + if ( (*aIt).second == xObj ) + { + // copy replacement image from temporary container (if there is any) + ::rtl::OUString aTempName = (*aIt).first; + ::rtl::OUString aMediaType; + uno::Reference < io::XInputStream > xStream = pImpl->mpTempObjectContainer->GetGraphicStream( xObj, &aMediaType ); + if ( xStream.is() ) + { + InsertGraphicStream( xStream, rName, aMediaType ); + xStream = 0; + pImpl->mpTempObjectContainer->RemoveGraphicStream( aTempName ); + } + + // remove object from storage of temporary container + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + if ( xPersist.is() ) + { + try + { + pImpl->mpTempObjectContainer->pImpl->mxStorage->removeElement( aTempName ); + } + catch ( uno::Exception& ) + { + } + } + + // temp. container needs to forget the object + pImpl->mpTempObjectContainer->pImpl->maObjectContainer.erase( aIt ); + break; + } + else + aIt++; + } + } +} + +sal_Bool EmbeddedObjectContainer::StoreEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName, sal_Bool bCopy ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::StoreEmbeddedObject" ); + + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + if ( !rName.getLength() ) + rName = CreateUniqueObjectName(); + +#if OSL_DEBUG_LEVEL > 1 + uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); + OSL_ENSURE( !xPersist.is() || !xAccess->hasByName(rName), "Inserting element already present in storage!" ); + OSL_ENSURE( xPersist.is() || xObj->getCurrentState() == embed::EmbedStates::RUNNING, "Non persistent object inserted!"); +#endif + + // insert objects' storage into the container storage (if object has one) + try + { + if ( xPersist.is() ) + { + uno::Sequence < beans::PropertyValue > aSeq; + if ( bCopy ) + xPersist->storeToEntry( pImpl->mxStorage, rName, aSeq, aSeq ); + else + { + //TODO/LATER: possible optimisation, don't store immediately + //xPersist->setPersistentEntry( pImpl->mxStorage, rName, embed::EntryInitModes::ENTRY_NO_INIT, aSeq, aSeq ); + xPersist->storeAsEntry( pImpl->mxStorage, rName, aSeq, aSeq ); + xPersist->saveCompleted( sal_True ); + } + } + } + catch ( uno::Exception& ) + { + // TODO/LATER: better error recovery should keep storage intact + return sal_False; + } + + return sal_True; +} + +sal_Bool EmbeddedObjectContainer::InsertEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( Object )" ); + // store it into the container storage + if ( StoreEmbeddedObject( xObj, rName, sal_False ) ) + { + // remember object + AddEmbeddedObject( xObj, rName ); + return sal_True; + } + else + return sal_False; +} + +uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedObject( const uno::Reference < io::XInputStream >& xStm, ::rtl::OUString& rNewName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( InputStream )" ); + + if ( !rNewName.getLength() ) + rNewName = CreateUniqueObjectName(); + + // store it into the container storage + sal_Bool bIsStorage = sal_False; + try + { + // first try storage persistence + uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm ); + + // storage was created from stream successfully + bIsStorage = sal_True; + + uno::Reference < embed::XStorage > xNewStore = pImpl->mxStorage->openStorageElement( rNewName, embed::ElementModes::READWRITE ); + xStore->copyToStorage( xNewStore ); + } + catch ( uno::Exception& ) + { + if ( bIsStorage ) + // it is storage persistence, but opening of new substorage or copying to it failed + return uno::Reference < embed::XEmbeddedObject >(); + + // stream didn't contain a storage, now try stream persistence + try + { + uno::Reference < io::XStream > xNewStream = pImpl->mxStorage->openStreamElement( rNewName, embed::ElementModes::READWRITE ); + ::comphelper::OStorageHelper::CopyInputToOutput( xStm, xNewStream->getOutputStream() ); + + // No mediatype is provided so the default for OLE objects value is used + // it is correct so for now, but what if somebody introduces a new stream based embedded object? + // Probably introducing of such an object must be restricted ( a storage must be used! ). + uno::Reference< beans::XPropertySet > xProps( xNewStream, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), + uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) ); + } + catch ( uno::Exception& ) + { + // complete disaster! + return uno::Reference < embed::XEmbeddedObject >(); + } + } + + // stream was copied into the container storage in either way, now try to open something form it + uno::Reference < embed::XEmbeddedObject > xRet = GetEmbeddedObject( rNewName ); + try + { + if ( !xRet.is() ) + // no object could be created, so withdraw insertion + pImpl->mxStorage->removeElement( rNewName ); + } + catch ( uno::Exception& ) + { + } + + return xRet; +} + +uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedObject( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& aMedium, ::rtl::OUString& rNewName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( MediaDescriptor )" ); + + if ( !rNewName.getLength() ) + rNewName = CreateUniqueObjectName(); + + uno::Reference < embed::XEmbeddedObject > xObj; + try + { + uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY ); + uno::Sequence< beans::PropertyValue > aObjDescr( 1 ); + aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); + aObjDescr[0].Value <<= pImpl->m_xModel.get(); + xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitFromMediaDescriptor( + pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY ); + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + + OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED, + "A freshly create object should be running always!\n" ); + + // possible optimization: store later! + if ( xPersist.is()) + xPersist->storeOwn(); + + AddEmbeddedObject( xObj, rNewName ); + } + catch ( uno::Exception& ) + { + } + + return xObj; +} + +uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedLink( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& aMedium, ::rtl::OUString& rNewName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedLink" ); + + if ( !rNewName.getLength() ) + rNewName = CreateUniqueObjectName(); + + uno::Reference < embed::XEmbeddedObject > xObj; + try + { + uno::Reference < embed::XLinkCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY ); + uno::Sequence< beans::PropertyValue > aObjDescr( 1 ); + aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); + aObjDescr[0].Value <<= pImpl->m_xModel.get(); + xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceLink( + pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY ); + + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + + OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED, + "A freshly create object should be running always!\n" ); + + // possible optimization: store later! + if ( xPersist.is()) + xPersist->storeOwn(); + + AddEmbeddedObject( xObj, rNewName ); + } + catch ( uno::Exception& ) + { + } + + return xObj; +} + +sal_Bool EmbeddedObjectContainer::TryToCopyGraphReplacement( EmbeddedObjectContainer& rSrc, + const ::rtl::OUString& aOrigName, + const ::rtl::OUString& aTargetName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::TryToCopyGraphReplacement" ); + + sal_Bool bResult = sal_False; + + if ( ( &rSrc != this || !aOrigName.equals( aTargetName ) ) && aOrigName.getLength() && aTargetName.getLength() ) + { + ::rtl::OUString aMediaType; + uno::Reference < io::XInputStream > xGrStream = rSrc.GetGraphicStream( aOrigName, &aMediaType ); + if ( xGrStream.is() ) + bResult = InsertGraphicStream( xGrStream, aTargetName, aMediaType ); + } + + return bResult; +} + +sal_Bool EmbeddedObjectContainer::CopyEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CopyEmbeddedObject" ); + + OSL_FAIL( "This method is depricated! Use EmbeddedObjectContainer::CopyAndGetEmbeddedObject() to copy object!\n" ); + + // get the object name before(!) it is assigned to a new storage + ::rtl::OUString aOrigName; + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + if ( xPersist.is() ) + aOrigName = xPersist->getEntryName(); + + if ( !rName.getLength() ) + rName = CreateUniqueObjectName(); + + if ( StoreEmbeddedObject( xObj, rName, sal_True ) ) + { + TryToCopyGraphReplacement( rSrc, aOrigName, rName ); + return sal_True; + } + + return sal_False; +} + +uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CopyAndGetEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CopyAndGetEmbeddedObject" ); + + uno::Reference< embed::XEmbeddedObject > xResult; + + // TODO/LATER: For now only objects that implement XEmbedPersist have a replacement image, it might change in future + // do an incompatible change so that object name is provided in all the move and copy methods + ::rtl::OUString aOrigName; + try + { + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY_THROW ); + aOrigName = xPersist->getEntryName(); + } + catch( uno::Exception& ) + {} + + if ( !rName.getLength() ) + rName = CreateUniqueObjectName(); + + // objects without persistance are not really stored by the method + if ( xObj.is() && StoreEmbeddedObject( xObj, rName, sal_True ) ) + { + xResult = Get_Impl( rName, xObj); + if ( !xResult.is() ) + { + // this is a case when object has no real persistence + // in such cases a new object should be explicitly created and initialized with the data of the old one + try + { + uno::Reference< embed::XLinkageSupport > xOrigLinkage( xObj, uno::UNO_QUERY ); + if ( xOrigLinkage.is() && xOrigLinkage->isLink() ) + { + // this is a OOo link, it has no persistence + ::rtl::OUString aURL = xOrigLinkage->getLinkURL(); + if ( !aURL.getLength() ) + throw uno::RuntimeException(); + + // create new linked object from the URL the link is based on + uno::Reference < embed::XLinkCreator > xCreator( + ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator") ) ), + uno::UNO_QUERY_THROW ); + + uno::Sequence< beans::PropertyValue > aMediaDescr( 1 ); + aMediaDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + aMediaDescr[0].Value <<= aURL; + uno::Sequence< beans::PropertyValue > aObjDescr( 1 ); + aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); + aObjDescr[0].Value <<= pImpl->m_xModel.get(); + xResult = uno::Reference < embed::XEmbeddedObject >( + xCreator->createInstanceLink( + pImpl->mxStorage, + rName, + aMediaDescr, + aObjDescr ), + uno::UNO_QUERY_THROW ); + } + else + { + // the component is required for copying of this object + if ( xObj->getCurrentState() == embed::EmbedStates::LOADED ) + xObj->changeState( embed::EmbedStates::RUNNING ); + + // this must be an object based on properties, otherwise we can not copy it currently + uno::Reference< beans::XPropertySet > xOrigProps( xObj->getComponent(), uno::UNO_QUERY_THROW ); + + // use object class ID to create a new one and tranfer all the properties + uno::Reference < embed::XEmbedObjectCreator > xCreator( + ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator") ) ), + uno::UNO_QUERY_THROW ); + + uno::Sequence< beans::PropertyValue > aObjDescr( 1 ); + aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) ); + aObjDescr[0].Value <<= pImpl->m_xModel.get(); + xResult = uno::Reference < embed::XEmbeddedObject >( + xCreator->createInstanceInitNew( + xObj->getClassID(), + xObj->getClassName(), + pImpl->mxStorage, + rName, + aObjDescr ), + uno::UNO_QUERY_THROW ); + + if ( xResult->getCurrentState() == embed::EmbedStates::LOADED ) + xResult->changeState( embed::EmbedStates::RUNNING ); + + uno::Reference< beans::XPropertySet > xTargetProps( xResult->getComponent(), uno::UNO_QUERY_THROW ); + + // copy all the properties from xOrigProps to xTargetProps + uno::Reference< beans::XPropertySetInfo > xOrigInfo = xOrigProps->getPropertySetInfo(); + if ( !xOrigInfo.is() ) + throw uno::RuntimeException(); + + uno::Sequence< beans::Property > aPropertiesList = xOrigInfo->getProperties(); + for ( sal_Int32 nInd = 0; nInd < aPropertiesList.getLength(); nInd++ ) + { + try + { + xTargetProps->setPropertyValue( + aPropertiesList[nInd].Name, + xOrigProps->getPropertyValue( aPropertiesList[nInd].Name ) ); + } + catch( beans::PropertyVetoException& ) + { + // impossibility to copy readonly property is not treated as an error for now + // but the assertion is helpful to detect such scenarios and review them + OSL_FAIL( "Could not copy readonly property!\n" ); + } + } + } + + if ( xResult.is() ) + AddEmbeddedObject( xResult, rName ); + } + catch( uno::Exception& ) + { + if ( xResult.is() ) + { + try + { + xResult->close( sal_True ); + } + catch( uno::Exception& ) + {} + xResult = uno::Reference< embed::XEmbeddedObject >(); + } + } + } + } + + OSL_ENSURE( xResult.is(), "Can not copy embedded object that has no persistance!\n" ); + + if ( xResult.is() ) + { + // the object is successfully copied, try to copy graphical replacement + if ( aOrigName.getLength() ) + TryToCopyGraphReplacement( rSrc, aOrigName, rName ); + + // the object might need the size to be set + try + { + if ( xResult->getStatus( embed::Aspects::MSOLE_CONTENT ) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD ) + xResult->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, + xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) ); + } + catch( uno::Exception& ) + {} + } + + return xResult; +} + +sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::MoveEmbeddedObject( Object )" ); + + // get the object name before(!) it is assigned to a new storage + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + ::rtl::OUString aName; + if ( xPersist.is() ) + aName = xPersist->getEntryName(); + + // now move the object to the new container; the returned name is the new persist name in this container + sal_Bool bRet; + + try + { + bRet = InsertEmbeddedObject( xObj, rName ); + if ( bRet ) + TryToCopyGraphReplacement( rSrc, aName, rName ); + } + catch ( uno::Exception& e ) + { + (void)e; + OSL_FAIL( "Failed to insert embedded object into storage!" ); + bRet = sal_False; + } + + if ( bRet ) + { + // now remove the object from the former container + bRet = sal_False; + EmbeddedObjectContainerNameMap::iterator aIt = rSrc.pImpl->maObjectContainer.begin(); + while ( aIt != rSrc.pImpl->maObjectContainer.end() ) + { + if ( (*aIt).second == xObj ) + { + rSrc.pImpl->maObjectContainer.erase( aIt ); + bRet = sal_True; + break; + } + + aIt++; + } + + OSL_ENSURE( bRet, "Object not found for removal!" ); + if ( xPersist.is() ) + { + // now it's time to remove the storage from the container storage + try + { + if ( xPersist.is() ) + rSrc.pImpl->mxStorage->removeElement( aName ); + } + catch ( uno::Exception& ) + { + OSL_FAIL( "Failed to remove object from storage!" ); + bRet = sal_False; + } + } + + // rSrc.RemoveGraphicStream( aName ); + } + + return bRet; +} + +sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Name )" ); + + uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( rName ); + if ( xObj.is() ) + return RemoveEmbeddedObject( xObj, bClose ); + else + return sal_False; +} + +sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( const ::rtl::OUString& rName, EmbeddedObjectContainer& rCnt ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::MoveEmbeddedObject( Name )" ); + + // find object entry + EmbeddedObjectContainerNameMap::iterator aIt2 = rCnt.pImpl->maObjectContainer.find( rName ); + OSL_ENSURE( aIt2 == rCnt.pImpl->maObjectContainer.end(), "Object does already exist in target container!" ); + + if ( aIt2 != rCnt.pImpl->maObjectContainer.end() ) + return sal_False; + + uno::Reference < embed::XEmbeddedObject > xObj; + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName ); + if ( aIt != pImpl->maObjectContainer.end() ) + { + xObj = (*aIt).second; + try + { + if ( xObj.is() ) + { + // move object + ::rtl::OUString aName( rName ); + rCnt.InsertEmbeddedObject( xObj, aName ); + pImpl->maObjectContainer.erase( aIt ); + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + if ( xPersist.is() ) + pImpl->mxStorage->removeElement( rName ); + } + else + { + // copy storages; object *must* have persistence! + uno::Reference < embed::XStorage > xOld = pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READ ); + uno::Reference < embed::XStorage > xNew = rCnt.pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READWRITE ); + xOld->copyToStorage( xNew ); + } + + rCnt.TryToCopyGraphReplacement( *this, rName, rName ); + // RemoveGraphicStream( rName ); + + return sal_True; + } + catch ( uno::Exception& ) + { + OSL_FAIL("Could not move object!"); + return sal_False; + } + + } + else + OSL_FAIL("Unknown object!"); + return sal_False; +} + +sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Object )" ); + + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + ::rtl::OUString aName; + if ( xPersist.is() ) + aName = xPersist->getEntryName(); + +#if OSL_DEBUG_LEVEL > 1 + uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY ); + uno::Reference < embed::XLinkageSupport > xLink( xPersist, uno::UNO_QUERY ); + sal_Bool bIsNotEmbedded = !xPersist.is() || ( xLink.is() && xLink->isLink() ); + + // if the object has a persistance and the object is not a link than it must have persistence entry in the storage + OSL_ENSURE( bIsNotEmbedded || xAccess->hasByName(aName), "Removing element not present in storage!" ); +#endif + + // try to close it if permitted + if ( bClose ) + { + uno::Reference < ::util::XCloseable > xClose( xObj, uno::UNO_QUERY ); + try + { + xClose->close( sal_True ); + } + catch ( util::CloseVetoException& ) + { + bClose = sal_False; + } + } + + if ( !bClose ) + { + // somebody still needs the object, so we must assign a temporary persistence + try + { + if ( xPersist.is() ) + { + /* + //TODO/LATER: needs storage handling! Why not letting the object do it?! + if ( !pImpl->mxTempStorage.is() ) + pImpl->mxTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); + uno::Sequence < beans::PropertyValue > aSeq; + + ::rtl::OUString aTmpPersistName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Object ") ); + aTmpPersistName += ::rtl::OUString::valueOf( (sal_Int32) pImpl->maTempObjectContainer.size() ); + + xPersist->storeAsEntry( pImpl->mxTempStorage, aTmpPersistName, aSeq, aSeq ); + xPersist->saveCompleted( sal_True ); + + pImpl->maTempObjectContainer[ aTmpPersistName ] = uno::Reference < embed::XEmbeddedObject >(); + */ + + if ( !pImpl->mpTempObjectContainer ) + { + pImpl->mpTempObjectContainer = new EmbeddedObjectContainer(); + try + { + // TODO/LATER: in future probably the temporary container will have two storages ( of two formats ) + // the media type will be provided with object insertion + ::rtl::OUString aOrigStorMediaType; + uno::Reference< beans::XPropertySet > xStorProps( pImpl->mxStorage, uno::UNO_QUERY_THROW ); + static const ::rtl::OUString s_sMediaType(RTL_CONSTASCII_USTRINGPARAM("MediaType")); + xStorProps->getPropertyValue( s_sMediaType ) >>= aOrigStorMediaType; + + OSL_ENSURE( aOrigStorMediaType.getLength(), "No valuable media type in the storage!\n" ); + + uno::Reference< beans::XPropertySet > xTargetStorProps( + pImpl->mpTempObjectContainer->pImpl->mxStorage, + uno::UNO_QUERY_THROW ); + xTargetStorProps->setPropertyValue( s_sMediaType,uno::makeAny( aOrigStorMediaType ) ); + } + catch( uno::Exception& ) + { + OSL_FAIL( "Can not set the new media type to a storage!\n" ); + } + } + + ::rtl::OUString aTempName, aMediaType; + pImpl->mpTempObjectContainer->InsertEmbeddedObject( xObj, aTempName ); + + uno::Reference < io::XInputStream > xStream = GetGraphicStream( xObj, &aMediaType ); + if ( xStream.is() ) + pImpl->mpTempObjectContainer->InsertGraphicStream( xStream, aTempName, aMediaType ); + + // object is stored, so at least it can be set to loaded state + xObj->changeState( embed::EmbedStates::LOADED ); + } + else + // objects without persistence need to stay in running state if they shall not be closed + xObj->changeState( embed::EmbedStates::RUNNING ); + } + catch ( uno::Exception& ) + { + return sal_False; + } + } + + sal_Bool bFound = sal_False; + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); + while ( aIt != pImpl->maObjectContainer.end() ) + { + if ( (*aIt).second == xObj ) + { + pImpl->maObjectContainer.erase( aIt ); + bFound = sal_True; + uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY ); + if ( xChild.is() ) + xChild->setParent( uno::Reference < uno::XInterface >() ); + break; + } + + aIt++; + } + + OSL_ENSURE( bFound, "Object not found for removal!" ); + (void)bFound; + if ( xPersist.is() ) + { + // remove replacement image (if there is one) + RemoveGraphicStream( aName ); + + // now it's time to remove the storage from the container storage + try + { +#if OSL_DEBUG_LEVEL > 1 + // if the object has a persistance and the object is not a link than it must have persistence entry in storage + OSL_ENSURE( bIsNotEmbedded || pImpl->mxStorage->hasByName( aName ), "The object has no persistence entry in the storage!" ); +#endif + if ( xPersist.is() && pImpl->mxStorage->hasByName( aName ) ) + pImpl->mxStorage->removeElement( aName ); + } + catch ( uno::Exception& ) + { + OSL_FAIL( "Failed to remove object from storage!" ); + return sal_False; + } + } + + return sal_True; +} + +sal_Bool EmbeddedObjectContainer::CloseEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CloseEmbeddedObject" ); + + // disconnect the object from the container and close it if possible + + sal_Bool bFound = sal_False; + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); + while ( aIt != pImpl->maObjectContainer.end() ) + { + if ( (*aIt).second == xObj ) + { + pImpl->maObjectContainer.erase( aIt ); + bFound = sal_True; + break; + } + + aIt++; + } + + if ( bFound ) + { + uno::Reference < ::util::XCloseable > xClose( xObj, uno::UNO_QUERY ); + try + { + xClose->close( sal_True ); + } + catch ( uno::Exception& ) + { + // it is no problem if the object is already closed + // TODO/LATER: what if the object can not be closed? + } + } + + return bFound; +} + +uno::Reference < io::XInputStream > EmbeddedObjectContainer::GetGraphicStream( const ::rtl::OUString& aName, rtl::OUString* pMediaType ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetGraphicStream( Name )" ); + + uno::Reference < io::XInputStream > xStream; + + OSL_ENSURE( aName.getLength(), "Retrieving graphic for unknown object!" ); + if ( aName.getLength() ) + { + try + { + uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements(); + uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( aName, embed::ElementModes::READ ); + xStream = xGraphicStream->getInputStream(); + if ( pMediaType ) + { + uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY ); + if ( xSet.is() ) + { + uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")) ); + aAny >>= *pMediaType; + } + } + } + catch ( uno::Exception& ) + { + } + } + + return xStream; +} + +uno::Reference < io::XInputStream > EmbeddedObjectContainer::GetGraphicStream( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, rtl::OUString* pMediaType ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetGraphicStream( Object )" ); + + // get the object name + ::rtl::OUString aName; + EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin(); + while ( aIt != pImpl->maObjectContainer.end() ) + { + if ( (*aIt).second == xObj ) + { + aName = (*aIt).first; + break; + } + + aIt++; + } + + // try to load it from the container storage + return GetGraphicStream( aName, pMediaType ); +} + +sal_Bool EmbeddedObjectContainer::InsertGraphicStream( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertGraphicStream" ); + + try + { + uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements(); + + // store it into the subfolder + uno::Reference < io::XOutputStream > xOutStream; + uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( rObjectName, + embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); + xOutStream = xGraphicStream->getOutputStream(); + ::comphelper::OStorageHelper::CopyInputToOutput( rStream, xOutStream ); + xOutStream->flush(); + + uno::Reference< beans::XPropertySet > xPropSet( xGraphicStream, uno::UNO_QUERY ); + if ( !xPropSet.is() ) + throw uno::RuntimeException(); + + xPropSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption")), + uno::makeAny( (sal_Bool)sal_True ) ); + uno::Any aAny; + aAny <<= rMediaType; + xPropSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), aAny ); + + xPropSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), + uno::makeAny( (sal_Bool)sal_True ) ); + } + catch( uno::Exception& ) + { + return sal_False; + } + + return sal_True; +} + +sal_Bool EmbeddedObjectContainer::InsertGraphicStreamDirectly( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertGraphicStreamDirectly" ); + + try + { + uno::Reference < embed::XStorage > xReplacement = pImpl->GetReplacements(); + uno::Reference < embed::XOptimizedStorage > xOptRepl( xReplacement, uno::UNO_QUERY_THROW ); + + // store it into the subfolder + uno::Sequence< beans::PropertyValue > aProps( 3 ); + aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); + aProps[0].Value <<= rMediaType; + aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ); + aProps[1].Value <<= (sal_Bool)sal_True; + aProps[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ); + aProps[2].Value <<= (sal_Bool)sal_True; + + if ( xReplacement->hasByName( rObjectName ) ) + xReplacement->removeElement( rObjectName ); + + xOptRepl->insertStreamElementDirect( rObjectName, rStream, aProps ); + } + catch( uno::Exception& ) + { + return sal_False; + } + + return sal_True; +} + + +sal_Bool EmbeddedObjectContainer::RemoveGraphicStream( const ::rtl::OUString& rObjectName ) +{ + RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveGraphicStream" ); + + try + { + uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements(); + xReplacements->removeElement( rObjectName ); + } + catch( uno::Exception& ) + { + return sal_False; + } + + return sal_True; +} +namespace { + void InsertStreamIntoPicturesStorage_Impl( const uno::Reference< embed::XStorage >& xDocStor, + const uno::Reference< io::XInputStream >& xInStream, + const ::rtl::OUString& aStreamName ) + { + OSL_ENSURE( aStreamName.getLength() && xInStream.is() && xDocStor.is(), "Misuse of the method!\n" ); + + try + { + uno::Reference< embed::XStorage > xPictures = xDocStor->openStorageElement( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ), + embed::ElementModes::READWRITE ); + uno::Reference< io::XStream > xObjReplStr = xPictures->openStreamElement( + aStreamName, + embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); + uno::Reference< io::XOutputStream > xOutStream( + xObjReplStr->getInputStream(), uno::UNO_QUERY_THROW ); + + ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xOutStream ); + xOutStream->closeOutput(); + + uno::Reference< embed::XTransactedObject > xTransact( xPictures, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); + } + catch( uno::Exception& ) + { + OSL_FAIL( "The pictures storage is not available!\n" ); + } + } + +} +// ----------------------------------------------------------------------------- +sal_Bool EmbeddedObjectContainer::StoreAsChildren(sal_Bool _bOasisFormat,sal_Bool _bCreateEmbedded,const uno::Reference < embed::XStorage >& _xStorage) +{ + sal_Bool bResult = sal_False; + try + { + comphelper::EmbeddedObjectContainer aCnt( _xStorage ); + const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames(); + const ::rtl::OUString* pIter = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pIter + aNames.getLength(); + for(;pIter != pEnd;++pIter) + { + uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter ); + OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" ); + if ( xObj.is() ) + { + sal_Bool bSwitchBackToLoaded = sal_False; + uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY ); + + uno::Reference < io::XInputStream > xStream; + ::rtl::OUString aMediaType; + + sal_Int32 nCurState = xObj->getCurrentState(); + if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING ) + { + // means that the object is not active + // copy replacement image from old to new container + xStream = GetGraphicStream( xObj, &aMediaType ); + } + + if ( !xStream.is() ) + { + // the image must be regenerated + // TODO/LATER: another aspect could be used + if ( xObj->getCurrentState() == embed::EmbedStates::LOADED ) + bSwitchBackToLoaded = sal_True; + + xStream = GetGraphicReplacementStream( + embed::Aspects::MSOLE_CONTENT, + xObj, + &aMediaType ); + } + + if ( _bOasisFormat || (xLink.is() && xLink->isLink()) ) + { + if ( xStream.is() ) + { + if ( _bOasisFormat ) + { + // if it is an embedded object or the optimized inserting fails the normal inserting should be done + if ( _bCreateEmbedded + || !aCnt.InsertGraphicStreamDirectly( xStream, *pIter, aMediaType ) ) + aCnt.InsertGraphicStream( xStream, *pIter, aMediaType ); + } + else + { + // it is a linked object exported into SO7 format + InsertStreamIntoPicturesStorage_Impl( _xStorage, xStream, *pIter ); + } + } + } + + uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + if ( xPersist.is() ) + { + uno::Sequence< beans::PropertyValue > aArgs( _bOasisFormat ? 2 : 3 ); + aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StoreVisualReplacement" ) ); + aArgs[0].Value <<= (sal_Bool)( !_bOasisFormat ); + + // if it is an embedded object or the optimized inserting fails the normal inserting should be done + aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanTryOptimization" ) ); + aArgs[1].Value <<= !_bCreateEmbedded; + if ( !_bOasisFormat ) + { + // if object has no cached replacement it will use this one + aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualReplacement" ) ); + aArgs[2].Value <<= xStream; + } + + xPersist->storeAsEntry( _xStorage, + xPersist->getEntryName(), + uno::Sequence< beans::PropertyValue >(), + aArgs ); + } + + if ( bSwitchBackToLoaded ) + // switch back to loaded state; that way we have a minimum cache confusion + xObj->changeState( embed::EmbedStates::LOADED ); + } + } + + bResult = aCnt.CommitImageSubStorage(); + + } + catch ( uno::Exception& ) + { + // TODO/LATER: error handling + bResult = sal_False; + } + + // the old SO6 format does not store graphical replacements + if ( !_bOasisFormat && bResult ) + { + try + { + // the substorage still can not be locked by the embedded object conteiner + ::rtl::OUString aObjReplElement( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) ); + if ( _xStorage->hasByName( aObjReplElement ) && _xStorage->isStorageElement( aObjReplElement ) ) + _xStorage->removeElement( aObjReplElement ); + } + catch ( uno::Exception& ) + { + // TODO/LATER: error handling; + bResult = sal_False; + } + } + return bResult; +} +// ----------------------------------------------------------------------------- +sal_Bool EmbeddedObjectContainer::StoreChildren(sal_Bool _bOasisFormat,sal_Bool _bObjectsOnly) +{ + sal_Bool bResult = sal_True; + const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames(); + const ::rtl::OUString* pIter = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pIter + aNames.getLength(); + for(;pIter != pEnd;++pIter) + { + uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter ); + OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" ); + if ( xObj.is() ) + { + sal_Int32 nCurState = xObj->getCurrentState(); + if ( _bOasisFormat && nCurState != embed::EmbedStates::LOADED && nCurState != embed::EmbedStates::RUNNING ) + { + // means that the object is active + // the image must be regenerated + ::rtl::OUString aMediaType; + + // TODO/LATER: another aspect could be used + uno::Reference < io::XInputStream > xStream = + GetGraphicReplacementStream( + embed::Aspects::MSOLE_CONTENT, + xObj, + &aMediaType ); + if ( xStream.is() ) + { + if ( !InsertGraphicStreamDirectly( xStream, *pIter, aMediaType ) ) + InsertGraphicStream( xStream, *pIter, aMediaType ); + } + } + + // TODO/LATER: currently the object by default does not cache replacement image + // that means that if somebody loads SO7 document and store its objects using + // this method the images might be lost. + // Currently this method is only used on storing to alien formats, that means + // that SO7 documents storing does not use it, and all other filters are + // based on OASIS format. But if it changes the method must be fixed. The fix + // must be done only on demand since it can affect performance. + + uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + if ( xPersist.is() ) + { + try + { + //TODO/LATER: only storing if changed! + xPersist->storeOwn(); + } + catch( uno::Exception& ) + { + // TODO/LATER: error handling + bResult = sal_False; + break; + } + } + + if ( !_bOasisFormat && !_bObjectsOnly ) + { + // copy replacement images for linked objects + try + { + uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY ); + if ( xLink.is() && xLink->isLink() ) + { + ::rtl::OUString aMediaType; + uno::Reference < io::XInputStream > xInStream = GetGraphicStream( xObj, &aMediaType ); + if ( xInStream.is() ) + InsertStreamIntoPicturesStorage_Impl( pImpl->mxStorage, xInStream, *pIter ); + } + } + catch( uno::Exception& ) + { + } + } + } + } + + if ( bResult && _bOasisFormat ) + bResult = CommitImageSubStorage(); + + if ( bResult && !_bObjectsOnly ) + { + try + { + ReleaseImageSubStorage(); + ::rtl::OUString aObjReplElement( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) ); + if ( !_bOasisFormat && pImpl->mxStorage->hasByName( aObjReplElement ) && pImpl->mxStorage->isStorageElement( aObjReplElement ) ) + pImpl->mxStorage->removeElement( aObjReplElement ); + } + catch( uno::Exception& ) + { + // TODO/LATER: error handling + bResult = sal_False; + } + } + return bResult; +} +// ----------------------------------------------------------------------------- +uno::Reference< io::XInputStream > EmbeddedObjectContainer::GetGraphicReplacementStream( + sal_Int64 nViewAspect, + const uno::Reference< embed::XEmbeddedObject >& xObj, + ::rtl::OUString* pMediaType ) +{ + uno::Reference< io::XInputStream > xInStream; + if ( xObj.is() ) + { + try + { + // retrieving of the visual representation can switch object to running state + embed::VisualRepresentation aRep = xObj->getPreferredVisualRepresentation( nViewAspect ); + if ( pMediaType ) + *pMediaType = aRep.Flavor.MimeType; + + uno::Sequence < sal_Int8 > aSeq; + aRep.Data >>= aSeq; + xInStream = new ::comphelper::SequenceInputStream( aSeq ); + } + catch ( uno::Exception& ) + { + } + } + + return xInStream; +} +// ----------------------------------------------------------------------------- +sal_Bool EmbeddedObjectContainer::SetPersistentEntries(const uno::Reference< embed::XStorage >& _xStorage,bool _bClearModifedFlag) +{ + sal_Bool bError = sal_False; + const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames(); + const ::rtl::OUString* pIter = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pIter + aNames.getLength(); + for(;pIter != pEnd;++pIter) + { + uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter ); + OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" ); + if ( xObj.is() ) + { + uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + if ( xPersist.is() ) + { + try + { + xPersist->setPersistentEntry( _xStorage, + *pIter, + embed::EntryInitModes::NO_INIT, + uno::Sequence< beans::PropertyValue >(), + uno::Sequence< beans::PropertyValue >() ); + + } + catch( uno::Exception& ) + { + // TODO/LATER: error handling + bError = sal_True; + break; + } + } + if ( _bClearModifedFlag ) + { + // if this method is used as part of SaveCompleted the object must stay unmodified after execution + try + { + uno::Reference< util::XModifiable > xModif( xObj->getComponent(), uno::UNO_QUERY_THROW ); + if ( xModif->isModified() ) + xModif->setModified( sal_False ); + } + catch( uno::Exception& ) + { + } + } + } + } + return bError; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/container/enumerablemap.cxx b/comphelper/source/container/enumerablemap.cxx new file mode 100644 index 000000000000..10727897b5a3 --- /dev/null +++ b/comphelper/source/container/enumerablemap.cxx @@ -0,0 +1,810 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" +#include "comphelper/anytostring.hxx" +#include "comphelper/anycompare.hxx" +#include "comphelper/componentbase.hxx" +#include "comphelper/componentcontext.hxx" +#include "comphelper/extract.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/container/XEnumerableMap.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/ucb/AlreadyInitializedException.hpp> +#include <com/sun/star/beans/Pair.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +/** === end UNO includes === **/ + +#include <cppuhelper/compbase3.hxx> +#include <cppuhelper/implbase1.hxx> +#include <rtl/math.hxx> +#include <rtl/ustrbuf.hxx> +#include <typelib/typedescription.hxx> + +#include <map> +#include <boost/shared_ptr.hpp> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::container::XEnumerableMap; + using ::com::sun::star::lang::NoSupportException; + using ::com::sun::star::beans::IllegalTypeException; + using ::com::sun::star::container::NoSuchElementException; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::lang::XInitialization; + using ::com::sun::star::ucb::AlreadyInitializedException; + using ::com::sun::star::beans::Pair; + using ::com::sun::star::uno::TypeClass; + using ::com::sun::star::uno::TypeClass_VOID; + using ::com::sun::star::uno::TypeClass_UNKNOWN; + using ::com::sun::star::uno::TypeClass_ANY; + using ::com::sun::star::uno::TypeClass_EXCEPTION; + using ::com::sun::star::uno::TypeClass_STRUCT; + using ::com::sun::star::uno::TypeClass_UNION; + using ::com::sun::star::uno::TypeClass_FLOAT; + using ::com::sun::star::uno::TypeClass_DOUBLE; + using ::com::sun::star::uno::TypeClass_INTERFACE; + using ::com::sun::star::lang::XServiceInfo; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::container::XEnumeration; + using ::com::sun::star::uno::TypeDescription; + using ::com::sun::star::lang::WrappedTargetException; + using ::com::sun::star::lang::DisposedException; + /** === end UNO using === **/ + + //==================================================================== + //= MapData + //==================================================================== + class IMapModificationListener; + typedef ::std::vector< IMapModificationListener* > MapListeners; + + typedef ::std::map< Any, Any, LessPredicateAdapter > KeyedValues; + struct MapData + { + Type m_aKeyType; + Type m_aValueType; + ::std::auto_ptr< KeyedValues > m_pValues; + ::boost::shared_ptr< IKeyPredicateLess > m_pKeyCompare; + bool m_bMutable; + MapListeners m_aModListeners; + + MapData() + :m_bMutable( true ) + { + } + + MapData( const MapData& _source ) + :m_aKeyType( _source.m_aKeyType ) + ,m_aValueType( _source.m_aValueType ) + ,m_pValues( new KeyedValues( *_source.m_pValues ) ) + ,m_pKeyCompare( _source.m_pKeyCompare ) + ,m_bMutable( false ) + ,m_aModListeners() + { + } + private: + MapData& operator=( const MapData& _source ); // not implemented + }; + + //==================================================================== + //= IMapModificationListener + //==================================================================== + /** implemented by components who want to be notified of modifications in the MapData they work with + */ + class SAL_NO_VTABLE IMapModificationListener + { + public: + /// called when the map was modified + virtual void mapModified() = 0; + virtual ~IMapModificationListener() + { + } + }; + + //==================================================================== + //= MapData helpers + //==================================================================== + //-------------------------------------------------------------------- + static void lcl_registerMapModificationListener( MapData& _mapData, IMapModificationListener& _listener ) + { + #if OSL_DEBUG_LEVEL > 0 + for ( MapListeners::const_iterator lookup = _mapData.m_aModListeners.begin(); + lookup != _mapData.m_aModListeners.end(); + ++lookup + ) + { + OSL_ENSURE( *lookup != &_listener, "lcl_registerMapModificationListener: this listener is already registered!" ); + } + #endif + _mapData.m_aModListeners.push_back( &_listener ); + } + + //-------------------------------------------------------------------- + static void lcl_revokeMapModificationListener( MapData& _mapData, IMapModificationListener& _listener ) + { + for ( MapListeners::iterator lookup = _mapData.m_aModListeners.begin(); + lookup != _mapData.m_aModListeners.end(); + ++lookup + ) + { + if ( *lookup == &_listener ) + { + _mapData.m_aModListeners.erase( lookup ); + return; + } + } + OSL_FAIL( "lcl_revokeMapModificationListener: the listener is not registered!" ); + } + + //-------------------------------------------------------------------- + static void lcl_notifyMapDataListeners_nothrow( const MapData& _mapData ) + { + for ( MapListeners::const_iterator loop = _mapData.m_aModListeners.begin(); + loop != _mapData.m_aModListeners.end(); + ++loop + ) + { + (*loop)->mapModified(); + } + } + + //==================================================================== + //= EnumerableMap + //==================================================================== + typedef ::cppu::WeakAggComponentImplHelper3 < XInitialization + , XEnumerableMap + , XServiceInfo + > Map_IFace; + + class COMPHELPER_DLLPRIVATE EnumerableMap :public Map_IFace + ,public ComponentBase + { + protected: + EnumerableMap( const ComponentContext& _rContext ); + virtual ~EnumerableMap(); + + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException); + + // XEnumerableMap + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createKeyEnumeration( ::sal_Bool _Isolated ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createValueEnumeration( ::sal_Bool _Isolated ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createElementEnumeration( ::sal_Bool _Isolated ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + + // XMap + virtual Type SAL_CALL getKeyType() throw (RuntimeException); + virtual Type SAL_CALL getValueType() throw (RuntimeException); + virtual void SAL_CALL clear( ) throw (NoSupportException, RuntimeException); + virtual ::sal_Bool SAL_CALL containsKey( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException); + virtual ::sal_Bool SAL_CALL containsValue( const Any& _value ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException); + virtual Any SAL_CALL get( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException); + virtual Any SAL_CALL put( const Any& _key, const Any& _value ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, RuntimeException); + virtual Any SAL_CALL remove( const Any& _key ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException); + + // XElementAccess (base of XMap) + virtual Type SAL_CALL getElementType() throw (RuntimeException); + virtual ::sal_Bool SAL_CALL hasElements() throw (RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + + public: + // XServiceInfo, static version (used for component registration) + static ::rtl::OUString SAL_CALL getImplementationName_static( ); + static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static( ); + static Reference< XInterface > SAL_CALL Create( const Reference< XComponentContext >& ); + + private: + void impl_initValues_throw( const Sequence< Pair< Any, Any > >& _initialValues ); + + /// throws a IllegalTypeException if the given value is not compatible with our ValueType + void impl_checkValue_throw( const Any& _value ) const; + void impl_checkKey_throw( const Any& _key ) const; + void impl_checkNaN_throw( const Any& _keyOrValue, const Type& _keyOrValueType ) const; + void impl_checkMutable_throw() const; + + private: + ::osl::Mutex m_aMutex; + ComponentContext m_aContext; + MapData m_aData; + + ::std::vector< ::com::sun::star::uno::WeakReference< XInterface > > + m_aDependentComponents; + }; + + //==================================================================== + //= EnumerationType + //==================================================================== + enum EnumerationType + { + eKeys, eValues, eBoth + }; + + //==================================================================== + //= MapEnumerator + //==================================================================== + class MapEnumerator : public IMapModificationListener + { + public: + MapEnumerator( ::cppu::OWeakObject& _rParent, MapData& _mapData, const EnumerationType _type ) + :m_rParent( _rParent ) + ,m_rMapData( _mapData ) + ,m_eType( _type ) + ,m_mapPos( _mapData.m_pValues->begin() ) + ,m_disposed( false ) + { + lcl_registerMapModificationListener( m_rMapData, *this ); + } + + virtual ~MapEnumerator() + { + dispose(); + } + + void dispose() + { + if ( !m_disposed ) + { + lcl_revokeMapModificationListener( m_rMapData, *this ); + m_disposed = true; + } + } + + // XEnumeration equivalents + ::sal_Bool hasMoreElements(); + Any nextElement(); + + // IMapModificationListener + virtual void mapModified(); + + private: + ::cppu::OWeakObject& m_rParent; + MapData& m_rMapData; + const EnumerationType m_eType; + KeyedValues::const_iterator m_mapPos; + bool m_disposed; + + private: + MapEnumerator(); // not implemented + MapEnumerator( const MapEnumerator& ); // not implemented + MapEnumerator& operator=( const MapEnumerator& ); // not implemented + }; + + //==================================================================== + //= MapEnumeration + //==================================================================== + typedef ::cppu::WeakImplHelper1 < XEnumeration + > MapEnumeration_Base; + class MapEnumeration :public ComponentBase + ,public MapEnumeration_Base + { + public: + MapEnumeration( ::cppu::OWeakObject& _parentMap, MapData& _mapData, ::cppu::OBroadcastHelper& _rBHelper, + const EnumerationType _type, const bool _isolated ) + :ComponentBase( _rBHelper, ComponentBase::NoInitializationNeeded() ) + ,m_xKeepMapAlive( _parentMap ) + ,m_pMapDataCopy( _isolated ? new MapData( _mapData ) : NULL ) + ,m_aEnumerator( *this, _isolated ? *m_pMapDataCopy : _mapData, _type ) + { + } + + // XEnumeration + virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (RuntimeException); + virtual Any SAL_CALL nextElement( ) throw (NoSuchElementException, WrappedTargetException, RuntimeException); + + protected: + virtual ~MapEnumeration() + { + acquire(); + { + ::osl::MutexGuard aGuard( getMutex() ); + m_aEnumerator.dispose(); + m_pMapDataCopy.reset(); + } + } + + private: + // sicne we share our mutex with the main map, we need to keep it alive as long as we live + Reference< XInterface > m_xKeepMapAlive; + ::std::auto_ptr< MapData > m_pMapDataCopy; + MapEnumerator m_aEnumerator; + }; + + //==================================================================== + //= EnumerableMap + //==================================================================== + //-------------------------------------------------------------------- + EnumerableMap::EnumerableMap( const ComponentContext& _rContext ) + :Map_IFace( m_aMutex ) + ,ComponentBase( Map_IFace::rBHelper ) + ,m_aContext( _rContext ) + { + } + + //-------------------------------------------------------------------- + EnumerableMap::~EnumerableMap() + { + if ( !impl_isDisposed() ) + { + acquire(); + dispose(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL EnumerableMap::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException) + { + ComponentMethodGuard aGuard( *this, ComponentMethodGuard::WithoutInit ); + if ( impl_isInitialized_nothrow() ) + throw AlreadyInitializedException(); + + sal_Int32 nArgumentCount = _arguments.getLength(); + if ( ( nArgumentCount != 2 ) && ( nArgumentCount != 3 ) ) + throw IllegalArgumentException(); + + Type aKeyType, aValueType; + if ( !( _arguments[0] >>= aKeyType ) ) + throw IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Type expected.")), *this, 1 ); + if ( !( _arguments[1] >>= aValueType ) ) + throw IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Type expected.")), *this, 2 ); + + Sequence< Pair< Any, Any > > aInitialValues; + bool bMutable = true; + if ( nArgumentCount == 3 ) + { + if ( !( _arguments[2] >>= aInitialValues ) ) + throw IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[]com.sun.star.beans.Pair<any,any> expected.")), *this, 2 ); + bMutable = false; + } + + // for the value, anything is allowed, except VOID + if ( ( aValueType.getTypeClass() == TypeClass_VOID ) || ( aValueType.getTypeClass() == TypeClass_UNKNOWN ) ) + throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported value type." ) ), *this ); + + // create the comparator for the KeyType, and throw if the type is not supported + ::std::auto_ptr< IKeyPredicateLess > pComparator( getStandardLessPredicate( aKeyType, NULL ) ); + if ( !pComparator.get() ) + throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported key type." ) ), *this ); + + // init members + m_aData.m_aKeyType = aKeyType; + m_aData.m_aValueType = aValueType; + m_aData.m_pKeyCompare = pComparator; + m_aData.m_pValues.reset( new KeyedValues( *m_aData.m_pKeyCompare ) ); + m_aData.m_bMutable = bMutable; + + if ( aInitialValues.getLength() ) + impl_initValues_throw( aInitialValues ); + + setInitialized(); + } + + //-------------------------------------------------------------------- + void EnumerableMap::impl_initValues_throw( const Sequence< Pair< Any, Any > >& _initialValues ) + { + OSL_PRECOND( m_aData.m_pValues.get() && m_aData.m_pValues->empty(), "EnumerableMap::impl_initValues_throw: illegal call!" ); + if ( !m_aData.m_pValues.get() || !m_aData.m_pValues->empty() ) + throw RuntimeException(); + + const Pair< Any, Any >* mapping = _initialValues.getConstArray(); + const Pair< Any, Any >* mappingEnd = mapping + _initialValues.getLength(); + Any normalizedValue; + for ( ; mapping != mappingEnd; ++mapping ) + { + impl_checkValue_throw( mapping->Second ); + (*m_aData.m_pValues)[ mapping->First ] = mapping->Second; + } + } + + //-------------------------------------------------------------------- + void EnumerableMap::impl_checkValue_throw( const Any& _value ) const + { + if ( !_value.hasValue() ) + // nothing to do, NULL values are always allowed, regardless of the ValueType + return; + + TypeClass eAllowedTypeClass = m_aData.m_aValueType.getTypeClass(); + bool bValid = false; + + switch ( eAllowedTypeClass ) + { + default: + bValid = ( _value.getValueTypeClass() == eAllowedTypeClass ); + break; + case TypeClass_ANY: + bValid = true; + break; + case TypeClass_INTERFACE: + { + // special treatment: _value might contain the proper type, but the interface + // might actually be NULL. Which is still valid ... + if ( m_aData.m_aValueType.isAssignableFrom( _value.getValueType() ) ) + // this also catches the special case where XFoo is our value type, + // and _value contains a NULL-reference to XFoo, or a derived type + bValid = true; + else + { + Reference< XInterface > xValue( _value, UNO_QUERY ); + Any aTypedValue; + if ( xValue.is() ) + // XInterface is not-NULL, but is X(ValueType) not-NULL, too? + xValue.set( xValue->queryInterface( m_aData.m_aValueType ), UNO_QUERY ); + bValid = xValue.is(); + } + } + break; + case TypeClass_EXCEPTION: + case TypeClass_STRUCT: + case TypeClass_UNION: + { + // values are accepted if and only if their type equals, or is derived from, our value type + + if ( _value.getValueTypeClass() != eAllowedTypeClass ) + bValid = false; + else + { + const TypeDescription aValueTypeDesc( _value.getValueType() ); + const TypeDescription aRequiredTypeDesc( m_aData.m_aValueType ); + + const _typelib_CompoundTypeDescription* pValueCompoundTypeDesc = + reinterpret_cast< const _typelib_CompoundTypeDescription* >( aValueTypeDesc.get() ); + + while ( pValueCompoundTypeDesc ) + { + if ( typelib_typedescription_equals( &pValueCompoundTypeDesc->aBase, aRequiredTypeDesc.get() ) ) + break; + pValueCompoundTypeDesc = pValueCompoundTypeDesc->pBaseTypeDescription; + } + bValid = ( pValueCompoundTypeDesc != NULL ); + } + } + break; + } + + if ( !bValid ) + { + ::rtl::OUStringBuffer aMessage; + aMessage.appendAscii( "Incompatible value type. Found '" ); + aMessage.append( _value.getValueTypeName() ); + aMessage.appendAscii( "', where '" ); + aMessage.append( m_aData.m_aValueType.getTypeName() ); + aMessage.appendAscii( "' (or compatible type) is expected." ); + throw IllegalTypeException( aMessage.makeStringAndClear(), *const_cast< EnumerableMap* >( this ) ); + } + + impl_checkNaN_throw( _value, m_aData.m_aValueType ); + } + + //-------------------------------------------------------------------- + void EnumerableMap::impl_checkNaN_throw( const Any& _keyOrValue, const Type& _keyOrValueType ) const + { + if ( ( _keyOrValueType.getTypeClass() == TypeClass_DOUBLE ) + || ( _keyOrValueType.getTypeClass() == TypeClass_FLOAT ) + ) + { + double nValue(0); + if ( _keyOrValue >>= nValue ) + if ( ::rtl::math::isNan( nValue ) ) + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NaN (not-a-number) not supported by this implementation." ) ), + *const_cast< EnumerableMap* >( this ), 0 ); + // (note that the case of _key not containing a float/double value is handled in the + // respective IKeyPredicateLess implementation, so there's no need to handle this here.) + } + } + + //-------------------------------------------------------------------- + void EnumerableMap::impl_checkKey_throw( const Any& _key ) const + { + if ( !_key.hasValue() ) + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NULL keys not supported by this implementation." ) ), + *const_cast< EnumerableMap* >( this ), 0 ); + + impl_checkNaN_throw( _key, m_aData.m_aKeyType ); + } + + //-------------------------------------------------------------------- + void EnumerableMap::impl_checkMutable_throw() const + { + if ( !m_aData.m_bMutable ) + throw NoSupportException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The map is immutable." ) ), + *const_cast< EnumerableMap* >( this ) ); + } + + //-------------------------------------------------------------------- + Reference< XEnumeration > SAL_CALL EnumerableMap::createKeyEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eKeys, _Isolated ); + } + + //-------------------------------------------------------------------- + Reference< XEnumeration > SAL_CALL EnumerableMap::createValueEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eValues, _Isolated ); + } + + //-------------------------------------------------------------------- + Reference< XEnumeration > SAL_CALL EnumerableMap::createElementEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eBoth, _Isolated ); + } + + //-------------------------------------------------------------------- + Type SAL_CALL EnumerableMap::getKeyType() throw (RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + return m_aData.m_aKeyType; + } + + //-------------------------------------------------------------------- + Type SAL_CALL EnumerableMap::getValueType() throw (RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + return m_aData.m_aValueType; + } + + //-------------------------------------------------------------------- + void SAL_CALL EnumerableMap::clear( ) throw (NoSupportException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + impl_checkMutable_throw(); + + m_aData.m_pValues->clear(); + + lcl_notifyMapDataListeners_nothrow( m_aData ); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL EnumerableMap::containsKey( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + impl_checkKey_throw( _key ); + + KeyedValues::const_iterator pos = m_aData.m_pValues->find( _key ); + return ( pos != m_aData.m_pValues->end() ); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL EnumerableMap::containsValue( const Any& _value ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + impl_checkValue_throw( _value ); + + for ( KeyedValues::const_iterator mapping = m_aData.m_pValues->begin(); + mapping != m_aData.m_pValues->end(); + ++mapping + ) + { + if ( mapping->second == _value ) + return sal_True; + } + return sal_False; + } + + //-------------------------------------------------------------------- + Any SAL_CALL EnumerableMap::get( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + impl_checkKey_throw( _key ); + + KeyedValues::const_iterator pos = m_aData.m_pValues->find( _key ); + if ( pos == m_aData.m_pValues->end() ) + throw NoSuchElementException( anyToString( _key ), *this ); + + return pos->second; + } + + //-------------------------------------------------------------------- + Any SAL_CALL EnumerableMap::put( const Any& _key, const Any& _value ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + impl_checkMutable_throw(); + impl_checkKey_throw( _key ); + impl_checkValue_throw( _value ); + + Any previousValue; + + KeyedValues::iterator pos = m_aData.m_pValues->find( _key ); + if ( pos != m_aData.m_pValues->end() ) + { + previousValue = pos->second; + pos->second = _value; + } + else + { + (*m_aData.m_pValues)[ _key ] = _value; + } + + lcl_notifyMapDataListeners_nothrow( m_aData ); + + return previousValue; + } + + //-------------------------------------------------------------------- + Any SAL_CALL EnumerableMap::remove( const Any& _key ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + impl_checkMutable_throw(); + impl_checkKey_throw( _key ); + + Any previousValue; + + KeyedValues::iterator pos = m_aData.m_pValues->find( _key ); + if ( pos != m_aData.m_pValues->end() ) + { + previousValue = pos->second; + m_aData.m_pValues->erase( pos ); + } + + lcl_notifyMapDataListeners_nothrow( m_aData ); + + return previousValue; + } + + //-------------------------------------------------------------------- + Type SAL_CALL EnumerableMap::getElementType() throw (RuntimeException) + { + return ::cppu::UnoType< Pair< Any, Any > >::get(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL EnumerableMap::hasElements() throw (RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + return m_aData.m_pValues->empty(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL EnumerableMap::getImplementationName( ) throw (RuntimeException) + { + return getImplementationName_static(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL EnumerableMap::supportsService( const ::rtl::OUString& _serviceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aServices( getSupportedServiceNames() ); + for ( sal_Int32 i=0; i<aServices.getLength(); ++i ) + if ( _serviceName == aServices[i] ) + return sal_True; + return sal_False; + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL EnumerableMap::getSupportedServiceNames( ) throw (RuntimeException) + { + return getSupportedServiceNames_static(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL EnumerableMap::getImplementationName_static( ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.comphelper.EnumerableMap" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL EnumerableMap::getSupportedServiceNames_static( ) + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.container.EnumerableMap" ) ); + return aServiceNames; + } + + //-------------------------------------------------------------------- + Reference< XInterface > SAL_CALL EnumerableMap::Create( const Reference< XComponentContext >& _context ) + { + return *new EnumerableMap( ComponentContext( _context ) ); + } + + //==================================================================== + //= MapEnumerator + //==================================================================== + //-------------------------------------------------------------------- + ::sal_Bool MapEnumerator::hasMoreElements() + { + if ( m_disposed ) + throw DisposedException( ::rtl::OUString(), m_rParent ); + return m_mapPos != m_rMapData.m_pValues->end(); + } + + //-------------------------------------------------------------------- + Any MapEnumerator::nextElement() + { + if ( m_disposed ) + throw DisposedException( ::rtl::OUString(), m_rParent ); + if ( m_mapPos == m_rMapData.m_pValues->end() ) + throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No more elements." ) ), m_rParent ); + + Any aNextElement; + switch ( m_eType ) + { + case eKeys: aNextElement = m_mapPos->first; break; + case eValues: aNextElement = m_mapPos->second; break; + case eBoth: aNextElement <<= Pair< Any, Any >( m_mapPos->first, m_mapPos->second ); break; + } + ++m_mapPos; + return aNextElement; + } + + //-------------------------------------------------------------------- + void MapEnumerator::mapModified() + { + m_disposed = true; + } + + //==================================================================== + //= MapEnumeration - implementation + //==================================================================== + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL MapEnumeration::hasMoreElements( ) throw (RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + return m_aEnumerator.hasMoreElements(); + } + + //-------------------------------------------------------------------- + Any SAL_CALL MapEnumeration::nextElement( ) throw (NoSuchElementException, WrappedTargetException, RuntimeException) + { + ComponentMethodGuard aGuard( *this ); + return m_aEnumerator.nextElement(); + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +void createRegistryInfo_Map() +{ + ::comphelper::module::OAutoRegistration< ::comphelper::EnumerableMap > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/container/enumhelper.cxx b/comphelper/source/container/enumhelper.cxx new file mode 100644 index 000000000000..e688c50ab4a6 --- /dev/null +++ b/comphelper/source/container/enumhelper.cxx @@ -0,0 +1,299 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/enumhelper.hxx> +#include <com/sun/star/lang/XComponent.hpp> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +//================================================================== +//= OEnumerationByName +//================================================================== +//------------------------------------------------------------------------------ +OEnumerationByName::OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess>& _rxAccess) + :m_aNames(_rxAccess->getElementNames()) + ,m_nPos(0) + ,m_xAccess(_rxAccess) + ,m_bListening(sal_False) +{ + impl_startDisposeListening(); +} + +//------------------------------------------------------------------------------ +OEnumerationByName::OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess>& _rxAccess, + const staruno::Sequence< ::rtl::OUString >& _aNames ) + :m_aNames(_aNames) + ,m_nPos(0) + ,m_xAccess(_rxAccess) + ,m_bListening(sal_False) +{ + impl_startDisposeListening(); +} + +//------------------------------------------------------------------------------ +OEnumerationByName::~OEnumerationByName() +{ + impl_stopDisposeListening(); +} + +//------------------------------------------------------------------------------ +sal_Bool SAL_CALL OEnumerationByName::hasMoreElements( ) throw(staruno::RuntimeException) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + if (m_xAccess.is() && m_aNames.getLength() > m_nPos) + return sal_True; + + if (m_xAccess.is()) + { + impl_stopDisposeListening(); + m_xAccess.clear(); + } + + return sal_False; +} + +//------------------------------------------------------------------------------ +staruno::Any SAL_CALL OEnumerationByName::nextElement( ) + throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + staruno::Any aRes; + if (m_xAccess.is() && m_nPos < m_aNames.getLength()) + aRes = m_xAccess->getByName(m_aNames.getConstArray()[m_nPos++]); + + if (m_xAccess.is() && m_nPos >= m_aNames.getLength()) + { + impl_stopDisposeListening(); + m_xAccess.clear(); + } + + if (!aRes.hasValue()) // es gibt kein Element mehr + throw starcontainer::NoSuchElementException(); + + return aRes; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OEnumerationByName::disposing(const starlang::EventObject& aEvent) + throw(staruno::RuntimeException) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + if (aEvent.Source == m_xAccess) + m_xAccess.clear(); +} + +//------------------------------------------------------------------------------ +void OEnumerationByName::impl_startDisposeListening() +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + if (m_bListening) + return; + + ++m_refCount; + staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY); + if (xDisposable.is()) + { + xDisposable->addEventListener(this); + m_bListening = sal_True; + } + --m_refCount; +} + +//------------------------------------------------------------------------------ +void OEnumerationByName::impl_stopDisposeListening() +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + if (!m_bListening) + return; + + ++m_refCount; + staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY); + if (xDisposable.is()) + { + xDisposable->removeEventListener(this); + m_bListening = sal_False; + } + --m_refCount; +} + +//================================================================== +//= OEnumerationByIndex +//================================================================== +//------------------------------------------------------------------------------ +OEnumerationByIndex::OEnumerationByIndex(const staruno::Reference< starcontainer::XIndexAccess >& _rxAccess) + :m_nPos(0) + ,m_xAccess(_rxAccess) + ,m_bListening(sal_False) +{ + impl_startDisposeListening(); +} + +//------------------------------------------------------------------------------ +OEnumerationByIndex::~OEnumerationByIndex() +{ + impl_stopDisposeListening(); +} + +//------------------------------------------------------------------------------ +sal_Bool SAL_CALL OEnumerationByIndex::hasMoreElements( ) throw(staruno::RuntimeException) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + if (m_xAccess.is() && m_xAccess->getCount() > m_nPos) + return sal_True; + + if (m_xAccess.is()) + { + impl_stopDisposeListening(); + m_xAccess.clear(); + } + + return sal_False; +} + +//------------------------------------------------------------------------------ +staruno::Any SAL_CALL OEnumerationByIndex::nextElement( ) + throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + staruno::Any aRes; + if (m_xAccess.is()) + { + aRes = m_xAccess->getByIndex(m_nPos++); + if (m_nPos >= m_xAccess->getCount()) + { + impl_stopDisposeListening(); + m_xAccess.clear(); + } + } + + if (!aRes.hasValue()) // es gibt kein Element mehr + throw starcontainer::NoSuchElementException(); + return aRes; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OEnumerationByIndex::disposing(const starlang::EventObject& aEvent) + throw(staruno::RuntimeException) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + if (aEvent.Source == m_xAccess) + m_xAccess.clear(); +} + +//------------------------------------------------------------------------------ +void OEnumerationByIndex::impl_startDisposeListening() +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + if (m_bListening) + return; + + ++m_refCount; + staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY); + if (xDisposable.is()) + { + xDisposable->addEventListener(this); + m_bListening = sal_True; + } + --m_refCount; +} + +//------------------------------------------------------------------------------ +void OEnumerationByIndex::impl_stopDisposeListening() +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + if (!m_bListening) + return; + + ++m_refCount; + staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY); + if (xDisposable.is()) + { + xDisposable->removeEventListener(this); + m_bListening = sal_False; + } + --m_refCount; +} + +//================================================================== +//= OAnyEnumeration +//================================================================== + +//------------------------------------------------------------------------------ +OAnyEnumeration::OAnyEnumeration(const staruno::Sequence< staruno::Any >& lItems) + :m_nPos(0) + ,m_lItems(lItems) +{ +} + +//------------------------------------------------------------------------------ +OAnyEnumeration::~OAnyEnumeration() +{ +} + +//------------------------------------------------------------------------------ +sal_Bool SAL_CALL OAnyEnumeration::hasMoreElements( ) throw(staruno::RuntimeException) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + return (m_lItems.getLength() > m_nPos); +} + +//------------------------------------------------------------------------------ +staruno::Any SAL_CALL OAnyEnumeration::nextElement( ) + throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException) +{ + if ( ! hasMoreElements()) + throw starcontainer::NoSuchElementException(); + + ::osl::ResettableMutexGuard aLock(m_aLock); + sal_Int32 nPos = m_nPos; + ++m_nPos; + return m_lItems[nPos]; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/container/namecontainer.cxx b/comphelper/source/container/namecontainer.cxx new file mode 100644 index 000000000000..48864d779326 --- /dev/null +++ b/comphelper/source/container/namecontainer.cxx @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/namecontainer.hxx> +#include <cppuhelper/implbase1.hxx> +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include <comphelper/stl_types.hxx> + +DECLARE_STL_USTRINGACCESS_MAP( ::com::sun::star::uno::Any, SvGenericNameContainerMapImpl ); + +namespace comphelper +{ + class NameContainerImpl + { + public: + osl::Mutex maMutex; + }; + + /** this is the base helper class for NameContainer thats also declared in this header. */ + class NameContainer : public ::cppu::WeakImplHelper1< ::com::sun::star::container::XNameContainer >, private NameContainerImpl + { + public: + NameContainer( ::com::sun::star::uno::Type aType ); + virtual ~NameContainer(); + + // XNameContainer + virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XNameReplace + virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XNameAccess + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::uno::RuntimeException); + + // XElementAccess + virtual sal_Bool SAL_CALL hasElements( ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) + throw(::com::sun::star::uno::RuntimeException); + + private: + SvGenericNameContainerMapImpl maProperties; + const ::com::sun::star::uno::Type maType; + }; +} + +using namespace ::comphelper; +using namespace ::osl; +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; + + +NameContainer::NameContainer( ::com::sun::star::uno::Type aType ) +: maType( aType ) +{ +} + +NameContainer::~NameContainer() +{ +} + +// XNameContainer +void SAL_CALL NameContainer::insertByName( const rtl::OUString& aName, const Any& aElement ) + throw(IllegalArgumentException, ElementExistException, + WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( maMutex ); + + if( maProperties.find( aName ) != maProperties.end() ) + throw ElementExistException(); + + if( aElement.getValueType() != maType ) + throw IllegalArgumentException(); + + maProperties.insert( SvGenericNameContainerMapImpl::value_type(aName,aElement)); +} + +void SAL_CALL NameContainer::removeByName( const ::rtl::OUString& Name ) + throw(NoSuchElementException, WrappedTargetException, + RuntimeException) +{ + MutexGuard aGuard( maMutex ); + + SvGenericNameContainerMapImpl::iterator aIter = maProperties.find( Name ); + if( aIter == maProperties.end() ) + throw NoSuchElementException(); + + maProperties.erase( aIter ); +} + +// XNameReplace + +void SAL_CALL NameContainer::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) + throw(IllegalArgumentException, NoSuchElementException, + WrappedTargetException, RuntimeException) +{ + MutexGuard aGuard( maMutex ); + + SvGenericNameContainerMapImpl::iterator aIter( maProperties.find( aName ) ); + if( aIter == maProperties.end() ) + throw NoSuchElementException(); + + if( aElement.getValueType() != maType ) + throw IllegalArgumentException(); + + (*aIter).second = aElement; +} + +// XNameAccess + +Any SAL_CALL NameContainer::getByName( const ::rtl::OUString& aName ) + throw(NoSuchElementException, WrappedTargetException, + RuntimeException) +{ + MutexGuard aGuard( maMutex ); + + SvGenericNameContainerMapImpl::iterator aIter = maProperties.find( aName ); + if( aIter == maProperties.end() ) + throw NoSuchElementException(); + + return (*aIter).second; +} + +Sequence< ::rtl::OUString > SAL_CALL NameContainer::getElementNames( ) + throw(RuntimeException) +{ + MutexGuard aGuard( maMutex ); + + SvGenericNameContainerMapImpl::iterator aIter = maProperties.begin(); + const SvGenericNameContainerMapImpl::iterator aEnd = maProperties.end(); + + Sequence< rtl::OUString > aNames( maProperties.size() ); + rtl::OUString* pNames = aNames.getArray(); + + while( aIter != aEnd ) + { + *pNames++ = (*aIter++).first; + } + + return aNames; +} + +sal_Bool SAL_CALL NameContainer::hasByName( const ::rtl::OUString& aName ) + throw(RuntimeException) +{ + MutexGuard aGuard( maMutex ); + + SvGenericNameContainerMapImpl::iterator aIter = maProperties.find( aName ); + return aIter != maProperties.end(); +} + +sal_Bool SAL_CALL NameContainer::hasElements( ) + throw(RuntimeException) +{ + MutexGuard aGuard( maMutex ); + + return !maProperties.empty(); +} + +Type SAL_CALL NameContainer::getElementType() + throw( RuntimeException ) +{ + return maType; +} + +Reference< XNameContainer > comphelper::NameContainer_createInstance( Type aType ) +{ + return (XNameContainer*) new NameContainer( aType ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/eventattachermgr/eventattachermgr.cxx b/comphelper/source/eventattachermgr/eventattachermgr.cxx new file mode 100644 index 000000000000..4db4e60b71d5 --- /dev/null +++ b/comphelper/source/eventattachermgr/eventattachermgr.cxx @@ -0,0 +1,911 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#if defined( UNX ) +#include <wchar.h> +#endif +#include <osl/mutex.hxx> +#include <osl/diagnose.h> +#include <comphelper/eventattachermgr.hxx> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/io/XObjectInputStream.hpp> +#include <com/sun/star/io/XPersistObject.hpp> +#include <com/sun/star/io/XObjectOutputStream.hpp> +#include <com/sun/star/io/XMarkableStream.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/reflection/XIdlClass.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/reflection/XIdlMethod.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/script/XEngineListener.hpp> +#include <com/sun/star/script/XEventAttacher2.hpp> +#include <com/sun/star/script/XEventAttacherManager.hpp> +#include <com/sun/star/script/XScriptListener.hpp> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> + +#include <deque> +#include <algorithm> +#include <functional> + +using namespace com::sun::star::uno; +using namespace com::sun::star::io; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::script; +using namespace com::sun::star::reflection; +using namespace cppu; +using namespace osl; + +using ::rtl::OUString; + +namespace comphelper +{ + +//----------------------------------------------------------------------------- +struct AttachedObject_Impl +{ + Reference< XInterface > xTarget; + Sequence< Reference< XEventListener > > aAttachedListenerSeq; + Any aHelper; + + bool operator<( const AttachedObject_Impl & ) const; + bool operator==( const AttachedObject_Impl & ) const; +}; + +struct AttacherIndex_Impl +{ + ::std::deque< ScriptEventDescriptor > aEventList; + ::std::deque< AttachedObject_Impl > aObjList; + + bool operator<( const AttacherIndex_Impl & ) const; + bool operator==( const AttacherIndex_Impl & ) const; +}; + +//----------------------------------------------------------------------------- +class ImplEventAttacherManager + : public WeakImplHelper2< XEventAttacherManager, XPersistObject > +{ + friend class AttacherAllListener_Impl; + ::std::deque< AttacherIndex_Impl > aIndex; + Mutex aLock; + // Container fuer die ScriptListener + OInterfaceContainerHelper aScriptListeners; + // EventAttacher-Instanz + Reference< XEventAttacher2 > xAttacher; + Reference< XMultiServiceFactory > mxSMgr; + Reference< XIdlReflection > mxCoreReflection; + Reference< XIntrospection > mxIntrospection; + Reference< XTypeConverter > xConverter; + sal_Int16 nVersion; +public: + ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection, + const Reference< XMultiServiceFactory > rSMgr ); + ~ImplEventAttacherManager(); + + // Methoden von XEventAttacherManager + virtual void SAL_CALL registerScriptEvent(sal_Int32 Index, const ScriptEventDescriptor& ScriptEvent) + throw( IllegalArgumentException, RuntimeException ); + virtual void SAL_CALL registerScriptEvents(sal_Int32 Index, const Sequence< ScriptEventDescriptor >& ScriptEvents) + throw( IllegalArgumentException, RuntimeException ); + virtual void SAL_CALL revokeScriptEvent(sal_Int32 Index, const OUString& ListenerType, const OUString& EventMethod, const OUString& removeListenerParam) + throw( IllegalArgumentException, RuntimeException ); + virtual void SAL_CALL revokeScriptEvents(sal_Int32 Index) + throw( IllegalArgumentException, RuntimeException ); + virtual void SAL_CALL insertEntry(sal_Int32 Index) + throw( IllegalArgumentException, RuntimeException ); + virtual void SAL_CALL removeEntry(sal_Int32 Index) + throw( IllegalArgumentException, RuntimeException ); + virtual Sequence< ScriptEventDescriptor > SAL_CALL getScriptEvents(sal_Int32 Index) + throw( IllegalArgumentException, RuntimeException ); + virtual void SAL_CALL attach(sal_Int32 Index, const Reference< XInterface >& Object, const Any& Helper) + throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException ); + virtual void SAL_CALL detach(sal_Int32 nIndex, const Reference< XInterface >& xObject) + throw( IllegalArgumentException, RuntimeException ); + virtual void SAL_CALL addScriptListener(const Reference< XScriptListener >& aListener) + throw( IllegalArgumentException, RuntimeException ); + virtual void SAL_CALL removeScriptListener(const Reference< XScriptListener >& Listener) + throw( IllegalArgumentException, RuntimeException ); + + // Methoden von XPersistObject + virtual OUString SAL_CALL getServiceName(void) throw( RuntimeException ); + virtual void SAL_CALL write(const Reference< XObjectOutputStream >& OutStream) throw( IOException, RuntimeException ); + virtual void SAL_CALL read(const Reference< XObjectInputStream >& InStream) throw( IOException, RuntimeException ); + +private: + Reference< XIdlReflection > getReflection() throw( Exception ); + + /** checks if <arg>_nIndex</arg> is a valid index, throws an <type>IllegalArgumentException</type> if not + @param _nIndex + the index to check + @return + the iterator pointing to the position indicated by the index + */ + ::std::deque<AttacherIndex_Impl>::iterator implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) ); +}; + +//======================================================================== +//======================================================================== +//======================================================================== + +// Implementation eines EventAttacher-bezogenen AllListeners, der +// nur einzelne Events an einen allgemeinen AllListener weiterleitet +class AttacherAllListener_Impl : public WeakImplHelper1< XAllListener > +{ + ImplEventAttacherManager* mpManager; + Reference< XEventAttacherManager > xManager; + OUString aScriptType; + OUString aScriptCode; + sal_Int16 nVersion; + + void convertToEventReturn( Any & rRet, const Type & rRetType ) + throw( CannotConvertException ); +public: + AttacherAllListener_Impl( ImplEventAttacherManager* pManager_, const OUString &rScriptType_, + const OUString & rScriptCode_ ); + + // Methoden von XAllListener + virtual void SAL_CALL firing(const AllEventObject& Event) throw( RuntimeException ); + virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw( InvocationTargetException, RuntimeException ); + + // Methoden von XEventListener + virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException ); +}; + +//======================================================================== +AttacherAllListener_Impl::AttacherAllListener_Impl +( + ImplEventAttacherManager* pManager_, + const OUString & rScriptType_, + const OUString & rScriptCode_ +) + : mpManager( pManager_ ) + , xManager( pManager_ ) + , aScriptType( rScriptType_ ) + , aScriptCode( rScriptCode_ ) + , nVersion( 2 ) +{ +} + + +//======================================================================== +// Methoden von XAllListener +void SAL_CALL AttacherAllListener_Impl::firing(const AllEventObject& Event) + throw( RuntimeException ) +{ + ScriptEvent aScriptEvent; + aScriptEvent.Source = (OWeakObject *)mpManager; // get correct XInterface + aScriptEvent.ListenerType = Event.ListenerType; + aScriptEvent.MethodName = Event.MethodName; + aScriptEvent.Arguments = Event.Arguments; + aScriptEvent.Helper = Event.Helper; + aScriptEvent.ScriptType = aScriptType; + aScriptEvent.ScriptCode = aScriptCode; + + // ueber alle Listener iterieren und Events senden + OInterfaceIteratorHelper aIt( mpManager->aScriptListeners ); + while( aIt.hasMoreElements() ) + ((XScriptListener *)aIt.next())->firing( aScriptEvent ); +} + +//======================================================================== +// Convert to the standard event return +void AttacherAllListener_Impl::convertToEventReturn( Any & rRet, const Type & rRetType ) + throw( CannotConvertException ) +{ + // no return value? Set to the specified values + if( rRet.getValueType().getTypeClass() == TypeClass_VOID ) + { + switch( rRetType.getTypeClass() ) + { + case TypeClass_INTERFACE: + { + rRet <<= Reference< XInterface >(); + } + break; + + case TypeClass_BOOLEAN: + rRet <<= sal_True; + break; + + case TypeClass_STRING: + rRet <<= OUString(); + break; + + case TypeClass_FLOAT: rRet <<= float(0); break; + case TypeClass_DOUBLE: rRet <<= double(0.0); break; + case TypeClass_BYTE: rRet <<= sal_uInt8(0); break; + case TypeClass_SHORT: rRet <<= sal_Int16( 0 ); break; + case TypeClass_LONG: rRet <<= sal_Int32( 0 ); break; + case TypeClass_UNSIGNED_SHORT: rRet <<= sal_uInt16( 0 ); break; + case TypeClass_UNSIGNED_LONG: rRet <<= sal_uInt32( 0 ); break; + + default: + OSL_ASSERT(false); + break; + } + } + else if( !rRet.getValueType().equals( rRetType ) ) + { + if( mpManager->xConverter.is() ) + rRet = mpManager->xConverter->convertTo( rRet, rRetType ); + else + throw CannotConvertException(); + } +} + +//======================================================================== +// Methoden von XAllListener +Any SAL_CALL AttacherAllListener_Impl::approveFiring( const AllEventObject& Event ) + throw( InvocationTargetException, RuntimeException ) +{ + ScriptEvent aScriptEvent; + aScriptEvent.Source = (OWeakObject *)mpManager; // get correct XInterface + aScriptEvent.ListenerType = Event.ListenerType; + aScriptEvent.MethodName = Event.MethodName; + aScriptEvent.Arguments = Event.Arguments; + aScriptEvent.Helper = Event.Helper; + aScriptEvent.ScriptType = aScriptType; + aScriptEvent.ScriptCode = aScriptCode; + + Any aRet; + // ueber alle Listener iterieren und Events senden + OInterfaceIteratorHelper aIt( mpManager->aScriptListeners ); + while( aIt.hasMoreElements() ) + { + aRet = ((XScriptListener *)aIt.next())->approveFiring( aScriptEvent ); + try + { + Reference< XIdlClass > xListenerType = mpManager->getReflection()-> + forName( Event.ListenerType.getTypeName() ); + Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName ); + if( xMeth.is() ) + { + Reference< XIdlClass > xRetType = xMeth->getReturnType(); + Type aRetType(xRetType->getTypeClass(), xRetType->getName()); + convertToEventReturn( aRet, aRetType ); + } + + switch( aRet.getValueType().getTypeClass() ) + { + case TypeClass_INTERFACE: + { + // Interface not null, return + Reference< XInterface > x; + aRet >>= x; + if( x.is() ) + return aRet; + } + break; + + case TypeClass_BOOLEAN: + // FALSE -> Return + if( !(*(sal_Bool*)aRet.getValue()) ) + return aRet; + break; + + case TypeClass_STRING: + // none empty string -> return + if( ((OUString*)aRet.getValue())->getLength() > 0 ) + return aRet; + break; + + // none zero number -> return + case TypeClass_FLOAT: if( *((float*)aRet.getValue()) ) return aRet; break; + case TypeClass_DOUBLE: if( *((double*)aRet.getValue()) ) return aRet; break; + case TypeClass_BYTE: if( *((sal_uInt8*)aRet.getValue()) ) return aRet; break; + case TypeClass_SHORT: if( *((sal_Int16*)aRet.getValue()) ) return aRet; break; + case TypeClass_LONG: if( *((sal_Int32*)aRet.getValue()) ) return aRet; break; + case TypeClass_UNSIGNED_SHORT: if( *((sal_uInt16*)aRet.getValue()) ) return aRet; break; + case TypeClass_UNSIGNED_LONG: if( *((sal_uInt32*)aRet.getValue()) ) return aRet; break; + + default: + OSL_ASSERT(false); + break; + } + } + catch( CannotConvertException& ) + { + // silent ignore conversions errors from a script call + Reference< XIdlClass > xListenerType = mpManager->getReflection()-> + forName( Event.ListenerType.getTypeName() ); + Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName ); + if( xMeth.is() ) + { + Reference< XIdlClass > xRetType = xMeth->getReturnType(); + Type aRetType(xRetType->getTypeClass(), xRetType->getName()); + aRet.clear(); + convertToEventReturn( aRet, aRetType ); + } + } + } + return aRet; +} + +//======================================================================== +// Methoden von XEventListener +void SAL_CALL AttacherAllListener_Impl::disposing(const EventObject& ) + throw( RuntimeException ) +{ + // It is up to the container to release the object +} + + +//======================================================================== +//======================================================================== +//======================================================================== + +// Create-Methode fuer EventAttacherManager +Reference< XEventAttacherManager > createEventAttacherManager( const Reference< XIntrospection > & rIntrospection, + const Reference< XMultiServiceFactory > & rSMgr ) + throw( Exception ) +{ + return new ImplEventAttacherManager( rIntrospection, rSMgr ); +} + +// Create-Methode fuer EventAttacherManager +Reference< XEventAttacherManager > createEventAttacherManager( const Reference< XMultiServiceFactory > & rSMgr ) + throw( Exception ) +{ + if ( rSMgr.is() ) + { + Reference< XInterface > xIFace( rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" )) ) ); + if ( xIFace.is() ) + { + Reference< XIntrospection > xIntrospection( xIFace, UNO_QUERY); + return new ImplEventAttacherManager( xIntrospection, rSMgr ); + } + } + + return Reference< XEventAttacherManager >(); +} + +//----------------------------------------------------------------------------- +ImplEventAttacherManager::ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection, + const Reference< XMultiServiceFactory > rSMgr ) + : aScriptListeners( aLock ) + , mxSMgr( rSMgr ) + , mxIntrospection( rIntrospection ) +{ + if ( rSMgr.is() ) + { + Reference< XInterface > xIFace( rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.EventAttacher" )) ) ); + if ( xIFace.is() ) + { + xAttacher = Reference< XEventAttacher2 >::query( xIFace ); + } + xIFace = rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" )) ); + if ( xIFace.is() ) + { + xConverter = Reference< XTypeConverter >::query( xIFace ); + } + } + + Reference< XInitialization > xInit( xAttacher, UNO_QUERY ); + if( xInit.is() ) + { + Sequence< Any > Arguments( 1 ); + Arguments[0] <<= rIntrospection; + xInit->initialize( Arguments ); + } +} + +//----------------------------------------------------------------------------- +ImplEventAttacherManager::~ImplEventAttacherManager() +{ +} + +Reference< XIdlReflection > ImplEventAttacherManager::getReflection() throw( Exception ) +{ + Guard< Mutex > aGuard( aLock ); + // Haben wir den Service schon? Sonst anlegen + if( !mxCoreReflection.is() ) + { + Reference< XInterface > xIFace( mxSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.CoreReflection" )) ) ); + mxCoreReflection = Reference< XIdlReflection >( xIFace, UNO_QUERY); + } + return mxCoreReflection; +} + + +//----------------------------------------------------------------------------- +::std::deque<AttacherIndex_Impl>::iterator ImplEventAttacherManager::implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) ) +{ + if (_nIndex < 0) + throw IllegalArgumentException(); + + ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin(); + for ( sal_Int32 i = 0; (i < _nIndex) && (aIt != aIndex.end()); ++i, ++aIt ) + ; + + if( aIt == aIndex.end() ) + throw IllegalArgumentException(); + + return aIt; +} + +namespace { + +class DetachObject : public std::unary_function<AttachedObject_Impl, void> +{ + ImplEventAttacherManager& mrMgr; + sal_Int32 mnIdx; +public: + DetachObject(ImplEventAttacherManager& rMgr, sal_Int32 nIdx) : + mrMgr(rMgr), mnIdx(nIdx) {} + + void operator() (AttachedObject_Impl& rObj) + { + mrMgr.detach(mnIdx, rObj.xTarget); + } +}; + +class AttachObject : public std::unary_function<AttachedObject_Impl, void> +{ + ImplEventAttacherManager& mrMgr; + sal_Int32 mnIdx; +public: + AttachObject(ImplEventAttacherManager& rMgr, sal_Int32 nIdx) : + mrMgr(rMgr), mnIdx(nIdx) {} + + void operator() (AttachedObject_Impl& rObj) + { + mrMgr.attach(mnIdx, rObj.xTarget, rObj.aHelper); + } +}; + +} + +//----------------------------------------------------------------------------- +//*** Methoden von XEventAttacherManager *** +void SAL_CALL ImplEventAttacherManager::registerScriptEvent +( + sal_Int32 nIndex, + const ScriptEventDescriptor& ScriptEvent +) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + + // Index pruefen und Array anpassen + ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); + + ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; + + ScriptEventDescriptor aEvt = ScriptEvent; + const sal_Unicode* pLastDot = aEvt.ListenerType.getStr(); + pLastDot += rtl_ustr_lastIndexOfChar( pLastDot, '.' ); + if( pLastDot ) + aEvt.ListenerType = pLastDot +1; + (*aIt).aEventList.push_back( aEvt ); + + // register new new Event + ::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.begin(); + ::std::deque< AttachedObject_Impl >::iterator aObjEnd = (*aIt).aObjList.end(); + while( aObjIt != aObjEnd ) + { + // resize + sal_Int32 nPos = (*aObjIt).aAttachedListenerSeq.getLength(); + (*aObjIt).aAttachedListenerSeq.realloc( nPos + 1 ); + Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray(); + + Reference< XAllListener > xAll = + new AttacherAllListener_Impl( this, ScriptEvent.ScriptType, ScriptEvent.ScriptCode ); + try + { + pArray[nPos] = xAttacher->attachSingleEventListener( (*aObjIt).xTarget, xAll, + (*aObjIt).aHelper, ScriptEvent.ListenerType, + ScriptEvent.AddListenerParam, ScriptEvent.EventMethod ); + } + catch( Exception& ) + { + } + + ++aObjIt; + } +} + +//----------------------------------------------------------------------------- +void SAL_CALL ImplEventAttacherManager::registerScriptEvents +( + sal_Int32 nIndex, + const Sequence< ScriptEventDescriptor >& ScriptEvents +) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + + // Index pruefen und Array anpassen + ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); + + ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; + ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex)); + + const ScriptEventDescriptor* pArray = ScriptEvents.getConstArray(); + sal_Int32 nLen = ScriptEvents.getLength(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + registerScriptEvent( nIndex, pArray[ i ] ); + + ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex)); +} + +//----------------------------------------------------------------------------- +void SAL_CALL ImplEventAttacherManager::revokeScriptEvent +( + sal_Int32 nIndex, + const OUString& ListenerType, + const OUString& EventMethod, + const OUString& ToRemoveListenerParam +) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + + ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); + + ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; + ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex)); + + OUString aLstType = ListenerType; + const sal_Unicode * pLastDot = aLstType.getStr(); + pLastDot += rtl_ustr_lastIndexOfChar( pLastDot, '.' ); + if( pLastDot ) + aLstType = pLastDot +1; + + ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = (*aIt).aEventList.begin(); + ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end(); + while( aEvtIt != aEvtEnd ) + { + if( aLstType == (*aEvtIt).ListenerType + && EventMethod == (*aEvtIt).EventMethod + && ToRemoveListenerParam == (*aEvtIt).AddListenerParam ) + { + (*aIt).aEventList.erase( aEvtIt ); + break; + } + + ++aEvtIt; + } + ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex)); +} + +//----------------------------------------------------------------------------- +void SAL_CALL ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex ) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); + + ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; + ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex)); + (*aIt).aEventList.clear(); + ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex)); +} + +//----------------------------------------------------------------------------- +void SAL_CALL ImplEventAttacherManager::insertEntry(sal_Int32 nIndex) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + if( nIndex < 0 ) + throw IllegalArgumentException(); + + if ( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() ) + aIndex.resize(nIndex+1); + + AttacherIndex_Impl aTmp; + aIndex.insert( aIndex.begin() + nIndex, aTmp ); +} + +//----------------------------------------------------------------------------- +void SAL_CALL ImplEventAttacherManager::removeEntry(sal_Int32 nIndex) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); + + ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; + ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex)); + aIndex.erase( aIt ); +} + +//----------------------------------------------------------------------------- +Sequence< ScriptEventDescriptor > SAL_CALL ImplEventAttacherManager::getScriptEvents(sal_Int32 nIndex) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); + + Sequence< ScriptEventDescriptor > aSeq( (*aIt).aEventList.size() ); + ScriptEventDescriptor * pArray = aSeq.getArray(); + + ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = (*aIt).aEventList.begin(); + ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end(); + sal_Int32 i = 0; + while( aEvtIt != aEvtEnd ) + { + pArray[i++] = *aEvtIt; + ++aEvtIt; + } + return aSeq; +} + +//----------------------------------------------------------------------------- +void SAL_CALL ImplEventAttacherManager::attach(sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any & Helper) + throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + if( nIndex < 0 || !xObject.is() ) + throw IllegalArgumentException(); + + if( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() ) + { + // alte Dateien lesen + if( nVersion == 1 ) + { + insertEntry( nIndex ); + attach( nIndex, xObject, Helper ); + return; + } + else + throw IllegalArgumentException(); + } + + ::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex; + + AttachedObject_Impl aTmp; + aTmp.xTarget = xObject; + aTmp.aHelper = Helper; + aCurrentPosition->aObjList.push_back( aTmp ); + + //::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.back(); + AttachedObject_Impl & rCurObj = aCurrentPosition->aObjList.back(); + rCurObj.aAttachedListenerSeq = Sequence< Reference< XEventListener > >( aCurrentPosition->aEventList.size() ); + + if (aCurrentPosition->aEventList.empty()) + return; + + Sequence<com::sun::star::script::EventListener> aEvents(aCurrentPosition->aEventList.size()); + std::deque<ScriptEventDescriptor>::iterator itr = aCurrentPosition->aEventList.begin(); + std::deque<ScriptEventDescriptor>::iterator itrEnd = aCurrentPosition->aEventList.end(); + ::com::sun::star::script::EventListener* p = aEvents.getArray(); + size_t i = 0; + for (; itr != itrEnd; ++itr) + { + com::sun::star::script::EventListener aListener; + aListener.AllListener = + new AttacherAllListener_Impl(this, itr->ScriptType, itr->ScriptCode); + aListener.Helper = rCurObj.aHelper; + aListener.ListenerType = itr->ListenerType; + aListener.EventMethod = itr->EventMethod; + aListener.AddListenerParam = itr->AddListenerParam; + p[i++] = aListener; + } + + try + { + rCurObj.aAttachedListenerSeq = + xAttacher->attachMultipleEventListeners(rCurObj.xTarget, aEvents); + } + catch (const Exception&) + { + // Fail gracefully. + } +} + +//----------------------------------------------------------------------------- +void SAL_CALL ImplEventAttacherManager::detach(sal_Int32 nIndex, const Reference< XInterface >& xObject) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + //return; + if( nIndex < 0 || static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() || !xObject.is() ) + throw IllegalArgumentException(); + + ::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex; + ::std::deque< AttachedObject_Impl >::iterator aObjIt = aCurrentPosition->aObjList.begin(); + ::std::deque< AttachedObject_Impl >::iterator aObjEnd = aCurrentPosition->aObjList.end(); + while( aObjIt != aObjEnd ) + { + if( (*aObjIt).xTarget == xObject ) + { + Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray(); + + ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = aCurrentPosition->aEventList.begin(); + ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = aCurrentPosition->aEventList.end(); + sal_Int32 i = 0; + while( aEvtIt != aEvtEnd ) + { + if( pArray[i].is() ) + { + try + { + xAttacher->removeListener( (*aObjIt).xTarget, (*aEvtIt).ListenerType, + (*aEvtIt).AddListenerParam, pArray[i] ); + } + catch( Exception& ) + { + } + } + i++; + ++aEvtIt; + } + aCurrentPosition->aObjList.erase( aObjIt ); + break; + } + ++aObjIt; + } +} + +void SAL_CALL ImplEventAttacherManager::addScriptListener(const Reference< XScriptListener >& aListener) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + aScriptListeners.addInterface( aListener ); +} + +void SAL_CALL ImplEventAttacherManager::removeScriptListener(const Reference< XScriptListener >& aListener) + throw( IllegalArgumentException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + aScriptListeners.removeInterface( aListener ); +} + + +// Methoden von XPersistObject +OUString SAL_CALL ImplEventAttacherManager::getServiceName(void) + throw( RuntimeException ) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.script.EventAttacherManager") ); +} + +void SAL_CALL ImplEventAttacherManager::write(const Reference< XObjectOutputStream >& OutStream) + throw( IOException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + // Ohne XMarkableStream laeuft nichts + Reference< XMarkableStream > xMarkStream( OutStream, UNO_QUERY ); + if( !xMarkStream.is() ) + return; + + // Version schreiben + OutStream->writeShort( 2 ); + + // Position fuer Laenge merken + sal_Int32 nObjLenMark = xMarkStream->createMark(); + OutStream->writeLong( 0L ); + + OutStream->writeLong( aIndex.size() ); + + // Sequences schreiben + ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin(); + ::std::deque<AttacherIndex_Impl>::iterator aEnd = aIndex.end(); + while( aIt != aEnd ) + { + // Laenge der Sequence und alle Descriptoren schreiben + OutStream->writeLong( (*aIt).aEventList.size() ); + ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = (*aIt).aEventList.begin(); + ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end(); + while( aEvtIt != aEvtEnd ) + { + const ScriptEventDescriptor& rDesc = (*aEvtIt); + OutStream->writeUTF( rDesc.ListenerType ); + OutStream->writeUTF( rDesc.EventMethod ); + OutStream->writeUTF( rDesc.AddListenerParam ); + OutStream->writeUTF( rDesc.ScriptType ); + OutStream->writeUTF( rDesc.ScriptCode ); + + ++aEvtIt; + } + ++aIt; + } + + // Die jetzt bekannte Laenge eintragen + sal_Int32 nObjLen = xMarkStream->offsetToMark( nObjLenMark ) -4; + xMarkStream->jumpToMark( nObjLenMark ); + OutStream->writeLong( nObjLen ); + xMarkStream->jumpToFurthest(); + xMarkStream->deleteMark( nObjLenMark ); +} + +void SAL_CALL ImplEventAttacherManager::read(const Reference< XObjectInputStream >& InStream) + throw( IOException, RuntimeException ) +{ + Guard< Mutex > aGuard( aLock ); + // Ohne XMarkableStream laeuft nichts + Reference< XMarkableStream > xMarkStream( InStream, UNO_QUERY ); + if( !xMarkStream.is() ) + return; + + // Version lesen + nVersion = InStream->readShort(); + + // Zunaechst kommen die Daten gemaess Version 1, + // muss auch bei hoeheren Versionen beibehalten werden + sal_Int32 nLen = InStream->readLong(); + + // Position fuer Vergleichszwecke + sal_Int32 nObjLenMark = xMarkStream->createMark(); + + // Anzahl der zu lesenden Sequences + sal_Int32 nItemCount = InStream->readLong(); + + for( sal_Int32 i = 0 ; i < nItemCount ; i++ ) + { + insertEntry( i ); + // Laenge der Sequence lesen + sal_Int32 nSeqLen = InStream->readLong(); + + // Sequence anlegen und Descriptoren lesen + Sequence< ScriptEventDescriptor > aSEDSeq( nSeqLen ); + ScriptEventDescriptor* pArray = aSEDSeq.getArray(); + for( sal_Int32 j = 0 ; j < nSeqLen ; j++ ) + { + ScriptEventDescriptor& rDesc = pArray[ j ]; + rDesc.ListenerType = InStream->readUTF(); + rDesc.EventMethod = InStream->readUTF(); + rDesc.AddListenerParam = InStream->readUTF(); + rDesc.ScriptType = InStream->readUTF(); + rDesc.ScriptCode = InStream->readUTF(); + } + registerScriptEvents( i, aSEDSeq ); + } + + // Haben wir die angegebene Laenge gelesen? + sal_Int32 nRealLen = xMarkStream->offsetToMark( nObjLenMark ); + if( nRealLen != nLen ) + { + // Nur wenn die StreamVersion > 1 ist und noch Daten folgen, kann das + // Ganze richtig sein. Sonst ist etwas voellig daneben gegangen. + if( nRealLen > nLen || nVersion == 1 ) + { + OSL_FAIL( "ImplEventAttacherManager::read(): Fatal Error, wrong object length" ); + } + else + { + // TODO: Pruefen, ob Zwischen-Speicherung der Daten sinnvoll sein koennte + + // Vorerst einfach nur Skippen + sal_Int32 nSkipCount = nLen - nRealLen; + InStream->skipBytes( nSkipCount ); + } + } + xMarkStream->jumpToFurthest(); + xMarkStream->deleteMark( nObjLenMark ); +} + +} // namesapce comphelper + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/inc/comphelper_module.hxx b/comphelper/source/inc/comphelper_module.hxx new file mode 100644 index 000000000000..dfa364df1983 --- /dev/null +++ b/comphelper/source/inc/comphelper_module.hxx @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_COMPHELPER_MODULE_HXX +#define COMPHELPER_COMPHELPER_MODULE_HXX + +#include "comphelper/componentmodule.hxx" + +//........................................................................ +namespace comphelper { namespace module +{ +//........................................................................ + + class ComphelperModule : public ::comphelper::OModule + { + friend struct ComphelperModuleCreator; + typedef ::comphelper::OModule BaseClass; + + public: + static ComphelperModule& getInstance(); + + private: + ComphelperModule(); + }; + + /* -------------------------------------------------------------------- */ + class ComphelperModuleClient : public ::comphelper::OModuleClient + { + private: + typedef ::comphelper::OModuleClient BaseClass; + + public: + ComphelperModuleClient() : BaseClass( ComphelperModule::getInstance() ) + { + } + }; + + /* -------------------------------------------------------------------- */ + template < class TYPE > + class OAutoRegistration : public ::comphelper::OAutoRegistration< TYPE > + { + private: + typedef ::comphelper::OAutoRegistration< TYPE > BaseClass; + + public: + OAutoRegistration() : BaseClass( ComphelperModule::getInstance() ) + { + } + }; + + /* -------------------------------------------------------------------- */ + template < class TYPE > + class OSingletonRegistration : public ::comphelper::OSingletonRegistration< TYPE > + { + private: + typedef ::comphelper::OSingletonRegistration< TYPE > BaseClass; + + public: + OSingletonRegistration() : BaseClass( ComphelperModule::getInstance() ) + { + } + }; + +//........................................................................ +} } // namespace comphelper::module +//........................................................................ + +#endif // COMPHELPER_COMPHELPER_MODULE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/SelectionMultiplex.cxx b/comphelper/source/misc/SelectionMultiplex.cxx new file mode 100644 index 000000000000..8ec3158c6789 --- /dev/null +++ b/comphelper/source/misc/SelectionMultiplex.cxx @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <comphelper/SelectionMultiplex.hxx> +#include <osl/diagnose.h> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::view; + +//======================================================================== +//= OSelectionChangeListener +//======================================================================== +//------------------------------------------------------------------------ +OSelectionChangeListener::~OSelectionChangeListener() +{ + if (m_pAdapter) + m_pAdapter->dispose(); +} + +//------------------------------------------------------------------ +void OSelectionChangeListener::_disposing(const EventObject&) throw( RuntimeException) +{ + // nothing to do here +} + +//------------------------------------------------------------------ +void OSelectionChangeListener::disposeAdapter() +{ + if ( m_pAdapter ) + m_pAdapter->dispose(); + + // will automatically set a new adapter + OSL_ENSURE( !m_pAdapter, "OSelectionChangeListener::disposeAdapter: what did dispose do?" ); +} + +//------------------------------------------------------------------ +void OSelectionChangeListener::setAdapter(OSelectionChangeMultiplexer* pAdapter) +{ + if (m_pAdapter) + { + ::osl::MutexGuard aGuard(m_rMutex); + m_pAdapter->release(); + m_pAdapter = NULL; + } + + if (pAdapter) + { + ::osl::MutexGuard aGuard(m_rMutex); + m_pAdapter = pAdapter; + m_pAdapter->acquire(); + } +} + +//======================================================================== +//= OSelectionChangeMultiplexer +//======================================================================== +//------------------------------------------------------------------ +OSelectionChangeMultiplexer::OSelectionChangeMultiplexer(OSelectionChangeListener* _pListener, const Reference< XSelectionSupplier>& _rxSet, sal_Bool _bAutoReleaseSet) + :m_xSet(_rxSet) + ,m_pListener(_pListener) + ,m_nLockCount(0) + ,m_bListening(sal_False) + ,m_bAutoSetRelease(_bAutoReleaseSet) +{ + m_pListener->setAdapter(this); + osl_incrementInterlockedCount(&m_refCount); + { + Reference< XSelectionChangeListener> xPreventDelete(this); + m_xSet->addSelectionChangeListener(xPreventDelete); + } + osl_decrementInterlockedCount(&m_refCount); +} + +//------------------------------------------------------------------ +OSelectionChangeMultiplexer::~OSelectionChangeMultiplexer() +{ +} + +//------------------------------------------------------------------ +void OSelectionChangeMultiplexer::lock() +{ + ++m_nLockCount; +} + +//------------------------------------------------------------------ +void OSelectionChangeMultiplexer::unlock() +{ + --m_nLockCount; +} + +//------------------------------------------------------------------ +void OSelectionChangeMultiplexer::dispose() +{ + if (m_bListening) + { + Reference< XSelectionChangeListener> xPreventDelete(this); + + m_xSet->removeSelectionChangeListener(xPreventDelete); + + m_pListener->setAdapter(NULL); + + m_pListener = NULL; + m_bListening = sal_False; + + if (m_bAutoSetRelease) + m_xSet = NULL; + } +} + +// XEventListener +//------------------------------------------------------------------ +void SAL_CALL OSelectionChangeMultiplexer::disposing( const EventObject& _rSource) throw( RuntimeException) +{ + if (m_pListener) + { + // tell the listener + if (!locked()) + m_pListener->_disposing(_rSource); + // disconnect the listener + if (m_pListener) // may have been reset whilest calling into _disposing + m_pListener->setAdapter(NULL); + } + + m_pListener = NULL; + m_bListening = sal_False; + + if (m_bAutoSetRelease) + m_xSet = NULL; +} + +// XSelectionChangeListener +//------------------------------------------------------------------ +void SAL_CALL OSelectionChangeMultiplexer::selectionChanged( const EventObject& _rEvent ) throw( RuntimeException) +{ + if (m_pListener && !locked()) + m_pListener->_selectionChanged(_rEvent); +} +//......................................................................... +} +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accessiblecomponenthelper.cxx b/comphelper/source/misc/accessiblecomponenthelper.cxx new file mode 100644 index 000000000000..8b6ebde6cc1c --- /dev/null +++ b/comphelper/source/misc/accessiblecomponenthelper.cxx @@ -0,0 +1,223 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/accessiblecomponenthelper.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::accessibility; + + //===================================================================== + //= OCommonAccessibleComponent + //===================================================================== + //--------------------------------------------------------------------- + OCommonAccessibleComponent::OCommonAccessibleComponent( ) + { + } + + //--------------------------------------------------------------------- + OCommonAccessibleComponent::OCommonAccessibleComponent( IMutex* _pExternalLock ) + :OAccessibleContextHelper( _pExternalLock ) + { + } + + //--------------------------------------------------------------------- + OCommonAccessibleComponent::~OCommonAccessibleComponent( ) + { + forgetExternalLock(); + // this ensures that the lock, which may be already destroyed as part of the derivee, + // is not used anymore + } + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL OCommonAccessibleComponent::containsPoint( const Point& _rPoint ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + Rectangle aBounds( implGetBounds() ); + return ( _rPoint.X >= 0 ) + && ( _rPoint.Y >= 0 ) + && ( _rPoint.X < aBounds.Width ) + && ( _rPoint.Y < aBounds.Height ); + } + + //-------------------------------------------------------------------- + Point SAL_CALL OCommonAccessibleComponent::getLocation( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + Rectangle aBounds( implGetBounds() ); + return Point( aBounds.X, aBounds.Y ); + } + + //-------------------------------------------------------------------- + Point SAL_CALL OCommonAccessibleComponent::getLocationOnScreen( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + Rectangle aBounds( implGetBounds() ); + + Point aScreenLoc( 0, 0 ); + + Reference< XAccessibleComponent > xParentComponent( implGetParentContext(), UNO_QUERY ); + OSL_ENSURE( xParentComponent.is(), "OCommonAccessibleComponent::getLocationOnScreen: no parent component!" ); + if ( xParentComponent.is() ) + { + Point aParentScreenLoc( xParentComponent->getLocationOnScreen() ); + Point aOwnRelativeLoc( getLocation() ); + aScreenLoc.X = aParentScreenLoc.X + aOwnRelativeLoc.X; + aScreenLoc.Y = aParentScreenLoc.Y + aOwnRelativeLoc.Y; + } + + return aScreenLoc; + } + + //-------------------------------------------------------------------- + Size SAL_CALL OCommonAccessibleComponent::getSize( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + Rectangle aBounds( implGetBounds() ); + return Size( aBounds.Width, aBounds.Height ); + } + + //-------------------------------------------------------------------- + Rectangle SAL_CALL OCommonAccessibleComponent::getBounds( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + return implGetBounds(); + } + + //===================================================================== + //= OAccessibleComponentHelper + //===================================================================== + //--------------------------------------------------------------------- + OAccessibleComponentHelper::OAccessibleComponentHelper( ) + { + } + + //--------------------------------------------------------------------- + OAccessibleComponentHelper::OAccessibleComponentHelper( IMutex* _pExternalLock ) + :OCommonAccessibleComponent( _pExternalLock ) + { + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleComponentHelper, OCommonAccessibleComponent, OAccessibleComponentHelper_Base ) + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleComponentHelper, OCommonAccessibleComponent, OAccessibleComponentHelper_Base ) + // (order matters: the first is the class name, the second is the class doing the ref counting) + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL OAccessibleComponentHelper::containsPoint( const Point& _rPoint ) throw (RuntimeException) + { + return OCommonAccessibleComponent::containsPoint( _rPoint ); + } + + //-------------------------------------------------------------------- + Point SAL_CALL OAccessibleComponentHelper::getLocation( ) throw (RuntimeException) + { + return OCommonAccessibleComponent::getLocation( ); + } + + //-------------------------------------------------------------------- + Point SAL_CALL OAccessibleComponentHelper::getLocationOnScreen( ) throw (RuntimeException) + { + return OCommonAccessibleComponent::getLocationOnScreen( ); + } + + //-------------------------------------------------------------------- + Size SAL_CALL OAccessibleComponentHelper::getSize( ) throw (RuntimeException) + { + return OCommonAccessibleComponent::getSize( ); + } + + //-------------------------------------------------------------------- + Rectangle SAL_CALL OAccessibleComponentHelper::getBounds( ) throw (RuntimeException) + { + return OCommonAccessibleComponent::getBounds( ); + } + + //===================================================================== + //= OAccessibleExtendedComponentHelper + //===================================================================== + //--------------------------------------------------------------------- + OAccessibleExtendedComponentHelper::OAccessibleExtendedComponentHelper( ) + { + } + + //--------------------------------------------------------------------- + OAccessibleExtendedComponentHelper::OAccessibleExtendedComponentHelper( IMutex* _pExternalLock ) + :OCommonAccessibleComponent( _pExternalLock ) + { + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleExtendedComponentHelper, OCommonAccessibleComponent, OAccessibleExtendedComponentHelper_Base ) + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleExtendedComponentHelper, OCommonAccessibleComponent, OAccessibleExtendedComponentHelper_Base ) + // (order matters: the first is the class name, the second is the class doing the ref counting) + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL OAccessibleExtendedComponentHelper::containsPoint( const Point& _rPoint ) throw (RuntimeException) + { + return OCommonAccessibleComponent::containsPoint( _rPoint ); + } + + //-------------------------------------------------------------------- + Point SAL_CALL OAccessibleExtendedComponentHelper::getLocation( ) throw (RuntimeException) + { + return OCommonAccessibleComponent::getLocation( ); + } + + //-------------------------------------------------------------------- + Point SAL_CALL OAccessibleExtendedComponentHelper::getLocationOnScreen( ) throw (RuntimeException) + { + return OCommonAccessibleComponent::getLocationOnScreen( ); + } + + //-------------------------------------------------------------------- + Size SAL_CALL OAccessibleExtendedComponentHelper::getSize( ) throw (RuntimeException) + { + return OCommonAccessibleComponent::getSize( ); + } + + //-------------------------------------------------------------------- + Rectangle SAL_CALL OAccessibleExtendedComponentHelper::getBounds( ) throw (RuntimeException) + { + return OCommonAccessibleComponent::getBounds( ); + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accessiblecontexthelper.cxx b/comphelper/source/misc/accessiblecontexthelper.cxx new file mode 100644 index 000000000000..fb89a0bf86a9 --- /dev/null +++ b/comphelper/source/misc/accessiblecontexthelper.cxx @@ -0,0 +1,358 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/accessiblecontexthelper.hxx> +#include <comphelper/accessibleeventbuffer.hxx> +#include <osl/diagnose.h> +#include <cppuhelper/weakref.hxx> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <comphelper/accessibleeventnotifier.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::accessibility; + + //===================================================================== + //= OContextHelper_Impl + //===================================================================== + /** implementation class for OAccessibleContextHelper. No own thread safety! + */ + class OContextHelper_Impl + { + private: + OAccessibleContextHelper* m_pAntiImpl; // the owning instance + IMutex* m_pExternalLock; // the optional additional external lock + + ::cppu::OInterfaceContainerHelper* m_pEventListeners; + WeakReference< XAccessible > m_aCreator; // the XAccessible which created our XAccessibleContext + + AccessibleEventNotifier::TClientId m_nClientId; + + public: + inline Reference< XAccessible > getCreator( ) const { return m_aCreator; } + inline void setCreator( const Reference< XAccessible >& _rAcc ); + + inline IMutex* getExternalLock( ) { return m_pExternalLock; } + inline void setExternalLock( IMutex* _pLock ) { m_pExternalLock = _pLock; } + + inline AccessibleEventNotifier::TClientId + getClientId() const { return m_nClientId; } + inline void setClientId( const AccessibleEventNotifier::TClientId _nId ) + { m_nClientId = _nId; } + + public: + OContextHelper_Impl( OAccessibleContextHelper* _pAntiImpl ) + :m_pAntiImpl( _pAntiImpl ) + ,m_pExternalLock( NULL ) + ,m_pEventListeners( NULL ) + ,m_nClientId( 0 ) + { + } + }; + + //--------------------------------------------------------------------- + inline void OContextHelper_Impl::setCreator( const Reference< XAccessible >& _rAcc ) + { + m_aCreator = _rAcc; + } + + //===================================================================== + //= OAccessibleContextHelper + //===================================================================== + //--------------------------------------------------------------------- + OAccessibleContextHelper::OAccessibleContextHelper( ) + :OAccessibleContextHelper_Base( GetMutex() ) + ,m_pImpl( NULL ) + { + m_pImpl = new OContextHelper_Impl( this ); + } + + //--------------------------------------------------------------------- + OAccessibleContextHelper::OAccessibleContextHelper( IMutex* _pExternalLock ) + :OAccessibleContextHelper_Base( GetMutex() ) + ,m_pImpl( NULL ) + { + m_pImpl = new OContextHelper_Impl( this ); + m_pImpl->setExternalLock( _pExternalLock ); + } + + //--------------------------------------------------------------------- + void OAccessibleContextHelper::forgetExternalLock() + { + m_pImpl->setExternalLock( NULL ); + } + + //--------------------------------------------------------------------- + OAccessibleContextHelper::~OAccessibleContextHelper( ) + { + forgetExternalLock(); + // this ensures that the lock, which may be already destroyed as part of the derivee, + // is not used anymore + + ensureDisposed(); + + delete m_pImpl; + m_pImpl = NULL; + } + + //--------------------------------------------------------------------- + IMutex* OAccessibleContextHelper::getExternalLock( ) + { + return m_pImpl->getExternalLock(); + } + + //--------------------------------------------------------------------- + void SAL_CALL OAccessibleContextHelper::disposing() + { + ::osl::ClearableMutexGuard aGuard( GetMutex() ); + + if ( m_pImpl->getClientId( ) ) + { + AccessibleEventNotifier::revokeClientNotifyDisposing( m_pImpl->getClientId( ), *this ); + m_pImpl->setClientId( 0 ); + } + } + + //--------------------------------------------------------------------- + void SAL_CALL OAccessibleContextHelper::addEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException) + { + OMutexGuard aGuard( getExternalLock() ); + // don't use the OContextEntryGuard - it will throw an exception if we're not alive + // anymore, while the most recent specification for XComponent states that we should + // silently ignore the call in such a situation + if ( !isAlive() ) + { + if ( _rxListener.is() ) + _rxListener->disposing( EventObject( *this ) ); + return; + } + + if ( _rxListener.is() ) + { + if ( !m_pImpl->getClientId( ) ) + m_pImpl->setClientId( AccessibleEventNotifier::registerClient( ) ); + + AccessibleEventNotifier::addEventListener( m_pImpl->getClientId( ), _rxListener ); + } + } + + //--------------------------------------------------------------------- + void SAL_CALL OAccessibleContextHelper::removeEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException) + { + OMutexGuard aGuard( getExternalLock() ); + // don't use the OContextEntryGuard - it will throw an exception if we're not alive + // anymore, while the most recent specification for XComponent states that we should + // silently ignore the call in such a situation + if ( !isAlive() ) + return; + + if ( _rxListener.is() ) + { + sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( m_pImpl->getClientId( ), _rxListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + AccessibleEventNotifier::revokeClient( m_pImpl->getClientId( ) ); + m_pImpl->setClientId( 0 ); + } + } + } + + //--------------------------------------------------------------------- + void SAL_CALL OAccessibleContextHelper::NotifyAccessibleEvent( const sal_Int16 _nEventId, + const Any& _rOldValue, const Any& _rNewValue ) + { + if ( !m_pImpl->getClientId( ) ) + // if we don't have a client id for the notifier, then we don't have listeners, then + // we don't need to notify anything + return; + + // build an event object + AccessibleEventObject aEvent; + aEvent.Source = *this; + aEvent.EventId = _nEventId; + aEvent.OldValue = _rOldValue; + aEvent.NewValue = _rNewValue; + + // let the notifier handle this event + AccessibleEventNotifier::addEvent( m_pImpl->getClientId( ), aEvent ); + } + + //--------------------------------------------------------------------- + void SAL_CALL OAccessibleContextHelper::BufferAccessibleEvent( const sal_Int16 _nEventId, + const Any& _rOldValue, const Any& _rNewValue, + AccessibleEventBuffer & _rBuffer ) + { + // TODO: this whole method (as well as the class AccessibleEventBuffer) should be removed + // The reasons why they have been introduces id that we needed to collect a set of events + // before notifying them alltogether (after releasing our mutex). With the other + // NotifyAccessibleEvent being asynchronous now, this should not be necessary anymore + // - clients could use the other version now. + + // copy our current listeners + Sequence< Reference< XInterface > > aListeners; + if ( m_pImpl->getClientId( ) ) + aListeners = AccessibleEventNotifier::getEventListeners( m_pImpl->getClientId( ) ); + + if ( aListeners.getLength() ) + { + AccessibleEventObject aEvent; + aEvent.Source = *this; + OSL_ENSURE( aEvent.Source.is(), "OAccessibleContextHelper::BufferAccessibleEvent: invalid creator!" ); + aEvent.EventId = _nEventId; + aEvent.OldValue = _rOldValue; + aEvent.NewValue = _rNewValue; + + _rBuffer.addEvent( aEvent, aListeners ); + } + } + + //--------------------------------------------------------------------- + sal_Bool OAccessibleContextHelper::isAlive() const + { + return !GetBroadcastHelper().bDisposed && !GetBroadcastHelper().bInDispose; + } + + //--------------------------------------------------------------------- + void OAccessibleContextHelper::ensureAlive() const SAL_THROW( ( DisposedException ) ) + { + if( !isAlive() ) + throw DisposedException(); + } + + //--------------------------------------------------------------------- + void OAccessibleContextHelper::ensureDisposed( ) + { + if ( !GetBroadcastHelper().bDisposed ) + { + OSL_ENSURE( 0 == m_refCount, "OAccessibleContextHelper::ensureDisposed: this method _has_ to be called from without your dtor only!" ); + acquire(); + dispose(); + } + } + + //--------------------------------------------------------------------- + void OAccessibleContextHelper::lateInit( const Reference< XAccessible >& _rxAccessible ) + { + m_pImpl->setCreator( _rxAccessible ); + } + + //--------------------------------------------------------------------- + Reference< XAccessible > OAccessibleContextHelper::getAccessibleCreator( ) const + { + return m_pImpl->getCreator(); + } + + //--------------------------------------------------------------------- + sal_Int32 SAL_CALL OAccessibleContextHelper::getAccessibleIndexInParent( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + // -1 for child not found/no parent (according to specification) + sal_Int32 nRet = -1; + + try + { + + Reference< XAccessibleContext > xParentContext( implGetParentContext() ); + + // iterate over parent's children and search for this object + if ( xParentContext.is() ) + { + // our own XAccessible for comparing with the children of our parent + Reference< XAccessible > xCreator( m_pImpl->getCreator() ); + + OSL_ENSURE( xCreator.is(), "OAccessibleContextHelper::getAccessibleIndexInParent: invalid creator!" ); + // two ideas why this could be NULL: + // * nobody called our late ctor (init), so we never had a creator at all -> bad + // * the creator is already dead. In this case, we should have been disposed, and + // never survived the above OContextEntryGuard. + // in all other situations the creator should be non-NULL + + if ( xCreator.is() ) + { + sal_Int32 nChildCount = xParentContext->getAccessibleChildCount(); + for ( sal_Int32 nChild = 0; ( nChild < nChildCount ) && ( -1 == nRet ); ++nChild ) + { + Reference< XAccessible > xChild( xParentContext->getAccessibleChild( nChild ) ); + if ( xChild.get() == xCreator.get() ) + nRet = nChild; + } + } + } + } + catch( const Exception& ) + { + OSL_FAIL( "OAccessibleContextHelper::getAccessibleIndexInParent: caught an exception!" ); + } + + return nRet; + } + + //--------------------------------------------------------------------- + Locale SAL_CALL OAccessibleContextHelper::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) + { + // simply ask the parent + Reference< XAccessible > xParent = getAccessibleParent(); + Reference< XAccessibleContext > xParentContext; + if ( xParent.is() ) + xParentContext = xParent->getAccessibleContext(); + + if ( !xParentContext.is() ) + throw IllegalAccessibleComponentStateException( ::rtl::OUString(), *this ); + + return xParentContext->getLocale(); + } + + //--------------------------------------------------------------------- + Reference< XAccessibleContext > OAccessibleContextHelper::implGetParentContext() SAL_THROW( ( RuntimeException ) ) + { + Reference< XAccessible > xParent = getAccessibleParent(); + Reference< XAccessibleContext > xParentContext; + if ( xParent.is() ) + xParentContext = xParent->getAccessibleContext(); + return xParentContext; + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accessibleeventbuffer.cxx b/comphelper/source/misc/accessibleeventbuffer.cxx new file mode 100644 index 000000000000..4137f91853f7 --- /dev/null +++ b/comphelper/source/misc/accessibleeventbuffer.cxx @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/accessibleeventbuffer.hxx" + +#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/accessibility/AccessibleEventObject.hpp" +#include "com/sun/star/accessibility/XAccessibleEventListener.hpp" +#include "osl/diagnose.h" +#include "rtl/textenc.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" + +namespace css = ::com::sun::star; + +using comphelper::AccessibleEventBuffer; + +struct AccessibleEventBuffer::Entry +{ + inline Entry(::css::accessibility::AccessibleEventObject const & rEvent, + ::css::uno::Sequence< ::css::uno::Reference< + ::css::uno::XInterface > > const & rListeners): + m_aEvent(rEvent), m_aListeners(rListeners) {} + + ::css::accessibility::AccessibleEventObject m_aEvent; + + ::css::uno::Sequence< + ::css::uno::Reference< ::css::uno::XInterface > > m_aListeners; +}; + +AccessibleEventBuffer::AccessibleEventBuffer() +{} + +AccessibleEventBuffer::AccessibleEventBuffer( + AccessibleEventBuffer const & rOther): + m_aEntries(rOther.m_aEntries) +{} + +AccessibleEventBuffer::~AccessibleEventBuffer() +{} + +AccessibleEventBuffer +AccessibleEventBuffer::operator =(AccessibleEventBuffer const & rOther) +{ + m_aEntries = rOther.m_aEntries; + return *this; +} + +void AccessibleEventBuffer::addEvent( + ::css::accessibility::AccessibleEventObject const & rEvent, + ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > + const & rListeners) +{ + m_aEntries.push_back(Entry(rEvent, rListeners)); +} + +void AccessibleEventBuffer::sendEvents() const +{ + for (Entries::const_iterator aIt(m_aEntries.begin()); + aIt != m_aEntries.end(); ++aIt) + for (::sal_Int32 i = 0; i < aIt->m_aListeners.getLength(); ++i) + { + ::css::uno::Reference< + ::css::accessibility::XAccessibleEventListener > xListener( + aIt->m_aListeners[i], ::css::uno::UNO_QUERY); + if (xListener.is()) + try + { + xListener->notifyEvent(aIt->m_aEvent); + } + catch (::css::uno::RuntimeException & rEx) + { + OSL_TRACE( + "comphelper::AccessibleEventBuffer::sendEvents:" + " caught %s\n", + ::rtl::OUStringToOString( + rEx.Message, RTL_TEXTENCODING_UTF8).getStr()); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accessibleeventnotifier.cxx b/comphelper/source/misc/accessibleeventnotifier.cxx new file mode 100644 index 000000000000..f03b1e78485a --- /dev/null +++ b/comphelper/source/misc/accessibleeventnotifier.cxx @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/accessibleeventnotifier.hxx> +#include <osl/diagnose.h> +#include <rtl/instance.hxx> +#include <comphelper/guarding.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::accessibility; +using namespace ::comphelper; + +//===================================================================== +//= AccessibleEventNotifier +//===================================================================== +//--------------------------------------------------------------------- +namespace +{ + struct lclMutex + : public rtl::Static< ::osl::Mutex, lclMutex > {}; + struct Clients + : public rtl::Static< AccessibleEventNotifier::ClientMap, Clients > {}; +} + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + //--------------------------------------------------------------------- + AccessibleEventNotifier::TClientId AccessibleEventNotifier::generateId() + { + TClientId nBiggestUsedId = 0; + TClientId nFreeId = 0; + + // look through all registered clients until we find a "gap" in the ids + + // Note that the following relies on the fact the elements in the map are traveled with + // ascending keys (aka client ids) + AccessibleEventNotifier::ClientMap &rClients = Clients::get(); + for ( ClientMap::const_iterator aLookup = rClients.begin(); + aLookup != rClients.end(); + ++aLookup + ) + { + TClientId nCurrent = aLookup->first; + OSL_ENSURE( nCurrent > nBiggestUsedId, "AccessibleEventNotifier::generateId: map is expected to be sorted ascending!" ); + + if ( nCurrent - nBiggestUsedId > 1 ) + { // found a "gap" + nFreeId = nBiggestUsedId + 1; + break; + } + + nBiggestUsedId = nCurrent; + } + + if ( !nFreeId ) + nFreeId = nBiggestUsedId + 1; + + OSL_ENSURE( rClients.end() == rClients.find( nFreeId ), + "AccessibleEventNotifier::generateId: algorithm broken!" ); + + return nFreeId; + } + + //--------------------------------------------------------------------- + AccessibleEventNotifier::TClientId AccessibleEventNotifier::registerClient( ) + { + ::osl::MutexGuard aGuard( lclMutex::get() ); + + // generate a new client id + TClientId nNewClientId = generateId( ); + + // the event listeners for the new client + EventListeners* pNewListeners = new EventListeners( lclMutex::get() ); + // note that we're using our own mutex here, so the listener containers for all + // our clients share this same mutex. + // this is a reminiscense to the days where the notifier was asynchronous. Today this is + // completely nonsense, and potentially slowing down the Office me thinks ... + + // add the client + Clients::get().insert( ClientMap::value_type( nNewClientId, pNewListeners ) ); + + // outta here + return nNewClientId; + } + + //--------------------------------------------------------------------- + sal_Bool AccessibleEventNotifier::implLookupClient( const TClientId _nClient, ClientMap::iterator& _rPos ) + { + // look up this client + AccessibleEventNotifier::ClientMap &rClients = Clients::get(); + _rPos = rClients.find( _nClient ); + OSL_ENSURE( rClients.end() != _rPos, "AccessibleEventNotifier::implLookupClient: invalid client id (did you register your client?)!" ); + + return ( rClients.end() != _rPos ); + } + + //--------------------------------------------------------------------- + void AccessibleEventNotifier::revokeClient( const TClientId _nClient ) + { + ::osl::MutexGuard aGuard( lclMutex::get() ); + + ClientMap::iterator aClientPos; + if ( !implLookupClient( _nClient, aClientPos ) ) + // already asserted in implLookupClient + return; + + // remove it from the clients map + delete aClientPos->second; + Clients::get().erase( aClientPos ); + } + + //--------------------------------------------------------------------- + void AccessibleEventNotifier::revokeClientNotifyDisposing( const TClientId _nClient, + const Reference< XInterface >& _rxEventSource ) SAL_THROW( ( ) ) + { + ::osl::MutexGuard aGuard( lclMutex::get() ); + + ClientMap::iterator aClientPos; + if ( !implLookupClient( _nClient, aClientPos ) ) + // already asserted in implLookupClient + return; + + // notify the "disposing" event for this client + EventObject aDisposalEvent; + aDisposalEvent.Source = _rxEventSource; + + // notify the listeners + EventListeners* pListeners = aClientPos->second; + + // we do not need the entry in the clients map anymore + // (do this before actually notifying, because some client implementations have re-entrance + // problems and call into revokeClient while we are notifying from hereing) + Clients::get().erase( aClientPos ); + + // now really do the notification + pListeners->disposeAndClear( aDisposalEvent ); + delete pListeners; + + } + + //--------------------------------------------------------------------- + sal_Int32 AccessibleEventNotifier::addEventListener( + const TClientId _nClient, const Reference< XAccessibleEventListener >& _rxListener ) SAL_THROW( ( ) ) + { + ::osl::MutexGuard aGuard( lclMutex::get() ); + + ClientMap::iterator aClientPos; + if ( !implLookupClient( _nClient, aClientPos ) ) + // already asserted in implLookupClient + return 0; + + if ( _rxListener.is() ) + aClientPos->second->addInterface( _rxListener ); + + return aClientPos->second->getLength(); + } + + //--------------------------------------------------------------------- + sal_Int32 AccessibleEventNotifier::removeEventListener( + const TClientId _nClient, const Reference< XAccessibleEventListener >& _rxListener ) SAL_THROW( ( ) ) + { + ::osl::MutexGuard aGuard( lclMutex::get() ); + + ClientMap::iterator aClientPos; + if ( !implLookupClient( _nClient, aClientPos ) ) + // already asserted in implLookupClient + return 0; + + if ( _rxListener.is() ) + aClientPos->second->removeInterface( _rxListener ); + + return aClientPos->second->getLength(); + } + + //--------------------------------------------------------------------- + Sequence< Reference< XInterface > > AccessibleEventNotifier::getEventListeners( const TClientId _nClient ) SAL_THROW( ( ) ) + { + Sequence< Reference< XInterface > > aListeners; + + ::osl::MutexGuard aGuard( lclMutex::get() ); + + ClientMap::iterator aClientPos; + if ( implLookupClient( _nClient, aClientPos ) ) + aListeners = aClientPos->second->getElements(); + + return aListeners; + } + + //--------------------------------------------------------------------- + void AccessibleEventNotifier::addEvent( const TClientId _nClient, const AccessibleEventObject& _rEvent ) SAL_THROW( ( ) ) + { + Sequence< Reference< XInterface > > aListeners; + + // --- <mutex lock> ------------------------------- + { + ::osl::MutexGuard aGuard( lclMutex::get() ); + + ClientMap::iterator aClientPos; + if ( !implLookupClient( _nClient, aClientPos ) ) + // already asserted in implLookupClient + return; + + // since we're synchronous, again, we want to notify immediately + aListeners = aClientPos->second->getElements(); + } + // --- </mutex lock> ------------------------------ + + // default handling: loop through all listeners, and notify them + const Reference< XInterface >* pListeners = aListeners.getConstArray(); + const Reference< XInterface >* pListenersEnd = pListeners + aListeners.getLength(); + while ( pListeners != pListenersEnd ) + { + try + { + static_cast< XAccessibleEventListener* >( pListeners->get() )->notifyEvent( _rEvent ); + } + catch( const Exception& ) + { + // no assertion, because a broken access remote bridge or something like this + // can cause this exception + } + ++pListeners; + } + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accessiblekeybindinghelper.cxx b/comphelper/source/misc/accessiblekeybindinghelper.cxx new file mode 100644 index 000000000000..ee98678f0b70 --- /dev/null +++ b/comphelper/source/misc/accessiblekeybindinghelper.cxx @@ -0,0 +1,117 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +// includes -------------------------------------------------------------- +#include <comphelper/accessiblekeybindinghelper.hxx> + + +//.............................................................................. +namespace comphelper +{ +//.............................................................................. + + using namespace ::com::sun::star; // MT 04/2003: was ::drafts::com::sun::star - otherwise to many changes + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::accessibility; + + //============================================================================== + // OAccessibleKeyBindingHelper + //============================================================================== + + OAccessibleKeyBindingHelper::OAccessibleKeyBindingHelper() + { + } + + // ----------------------------------------------------------------------------- + + OAccessibleKeyBindingHelper::OAccessibleKeyBindingHelper( const OAccessibleKeyBindingHelper& rHelper ) + : cppu::WeakImplHelper1<XAccessibleKeyBinding>( rHelper ) + , m_aKeyBindings( rHelper.m_aKeyBindings ) + { + } + + // ----------------------------------------------------------------------------- + + OAccessibleKeyBindingHelper::~OAccessibleKeyBindingHelper() + { + } + + // ----------------------------------------------------------------------------- + + void OAccessibleKeyBindingHelper::AddKeyBinding( const Sequence< awt::KeyStroke >& rKeyBinding ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + m_aKeyBindings.push_back( rKeyBinding ); + } + + // ----------------------------------------------------------------------------- + + void OAccessibleKeyBindingHelper::AddKeyBinding( const awt::KeyStroke& rKeyStroke ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + Sequence< awt::KeyStroke > aSeq(1); + aSeq[0] = rKeyStroke; + m_aKeyBindings.push_back( aSeq ); + } + + // ----------------------------------------------------------------------------- + // XAccessibleKeyBinding + // ----------------------------------------------------------------------------- + + sal_Int32 OAccessibleKeyBindingHelper::getAccessibleKeyBindingCount() throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + return m_aKeyBindings.size(); + } + + // ----------------------------------------------------------------------------- + + Sequence< awt::KeyStroke > OAccessibleKeyBindingHelper::getAccessibleKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( nIndex < 0 || nIndex >= (sal_Int32)m_aKeyBindings.size() ) + throw IndexOutOfBoundsException(); + + return m_aKeyBindings[nIndex]; + } + + // ----------------------------------------------------------------------------- + +//.............................................................................. +} // namespace comphelper +//.............................................................................. + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accessibleselectionhelper.cxx b/comphelper/source/misc/accessibleselectionhelper.cxx new file mode 100644 index 000000000000..e6aeac52eac4 --- /dev/null +++ b/comphelper/source/misc/accessibleselectionhelper.cxx @@ -0,0 +1,194 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/accessibleselectionhelper.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::accessibility; + + //===================================================================== + //= OCommonAccessibleSelection + //===================================================================== + //--------------------------------------------------------------------- + OCommonAccessibleSelection::OCommonAccessibleSelection( ) + { + } + + //-------------------------------------------------------------------- + void SAL_CALL OCommonAccessibleSelection::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + implSelect( nChildIndex, sal_True ); + } + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL OCommonAccessibleSelection::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + return( implIsSelected( nChildIndex ) ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OCommonAccessibleSelection::clearAccessibleSelection( ) throw (RuntimeException) + { + implSelect( ACCESSIBLE_SELECTION_CHILD_ALL, sal_False ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OCommonAccessibleSelection::selectAllAccessibleChildren( ) throw (RuntimeException) + { + implSelect( ACCESSIBLE_SELECTION_CHILD_ALL, sal_True ); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL OCommonAccessibleSelection::getSelectedAccessibleChildCount( ) throw (RuntimeException) + { + sal_Int32 nRet = 0; + Reference< XAccessibleContext > xParentContext( implGetAccessibleContext() ); + + OSL_ENSURE( xParentContext.is(), "OCommonAccessibleSelection::getSelectedAccessibleChildCount: no parent context!" ); + + if( xParentContext.is() ) + { + for( sal_Int32 i = 0, nChildCount = xParentContext->getAccessibleChildCount(); i < nChildCount; i++ ) + if( implIsSelected( i ) ) + ++nRet; + } + + return( nRet ); + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL OCommonAccessibleSelection::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + Reference< XAccessible > xRet; + Reference< XAccessibleContext > xParentContext( implGetAccessibleContext() ); + + OSL_ENSURE( xParentContext.is(), "OCommonAccessibleSelection::getSelectedAccessibleChildCount: no parent context!" ); + + if( xParentContext.is() ) + { + for( sal_Int32 i = 0, nChildCount = xParentContext->getAccessibleChildCount(), nPos = 0; ( i < nChildCount ) && !xRet.is(); i++ ) + if( implIsSelected( i ) && ( nPos++ == nSelectedChildIndex ) ) + xRet = xParentContext->getAccessibleChild( i ); + } + + return( xRet ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OCommonAccessibleSelection::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + implSelect( nSelectedChildIndex, sal_False ); + } + + //===================================================================== + //= OAccessibleSelectionHelper + //===================================================================== + //--------------------------------------------------------------------- + OAccessibleSelectionHelper::OAccessibleSelectionHelper( ) + { + } + + //-------------------------------------------------------------------- + OAccessibleSelectionHelper::OAccessibleSelectionHelper( IMutex* _pExternalLock ) : OAccessibleComponentHelper(_pExternalLock) + { + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleSelectionHelper, OAccessibleComponentHelper, OAccessibleSelectionHelper_Base ) + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleSelectionHelper, OAccessibleComponentHelper, OAccessibleSelectionHelper_Base ) + // (order matters: the first is the class name, the second is the class doing the ref counting) + + //-------------------------------------------------------------------- + Reference< XAccessibleContext > OAccessibleSelectionHelper::implGetAccessibleContext() throw ( RuntimeException ) + { + return( this ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleSelectionHelper::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + OCommonAccessibleSelection::selectAccessibleChild( nChildIndex ); + } + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL OAccessibleSelectionHelper::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + return( OCommonAccessibleSelection::isAccessibleChildSelected( nChildIndex ) ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleSelectionHelper::clearAccessibleSelection( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + OCommonAccessibleSelection::clearAccessibleSelection(); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleSelectionHelper::selectAllAccessibleChildren( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + OCommonAccessibleSelection::selectAllAccessibleChildren(); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL OAccessibleSelectionHelper::getSelectedAccessibleChildCount( ) throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + return( OCommonAccessibleSelection::getSelectedAccessibleChildCount() ); + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL OAccessibleSelectionHelper::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + return( OCommonAccessibleSelection::getSelectedAccessibleChild( nSelectedChildIndex ) ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleSelectionHelper::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + OCommonAccessibleSelection::deselectAccessibleChild( nSelectedChildIndex ); + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accessibletexthelper.cxx b/comphelper/source/misc/accessibletexthelper.cxx new file mode 100644 index 000000000000..d344192e7b46 --- /dev/null +++ b/comphelper/source/misc/accessibletexthelper.cxx @@ -0,0 +1,916 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +// includes -------------------------------------------------------------- +#include <comphelper/accessibletexthelper.hxx> +#include <com/sun/star/accessibility/AccessibleTextType.hpp> +#include <com/sun/star/i18n/CharacterIteratorMode.hpp> +#include <com/sun/star/i18n/WordType.hpp> +#include <com/sun/star/i18n/KCharacterType.hpp> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/accessibility/TextSegment.hpp> + +#include <algorithm> + +//.............................................................................. +namespace comphelper +{ +//.............................................................................. + + 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::accessibility; + + //============================================================================== + // OCommonAccessibleText + //============================================================================== + + OCommonAccessibleText::OCommonAccessibleText() + { + } + + // ----------------------------------------------------------------------------- + + OCommonAccessibleText::~OCommonAccessibleText() + { + } + + // ----------------------------------------------------------------------------- + + Reference < i18n::XBreakIterator > OCommonAccessibleText::implGetBreakIterator() + { + if ( !m_xBreakIter.is() ) + { + Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + if ( xMSF.is() ) + { + m_xBreakIter = Reference< i18n::XBreakIterator > + ( xMSF->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.BreakIterator" ) ) ), UNO_QUERY ); + } + } + + return m_xBreakIter; + } + + // ----------------------------------------------------------------------------- + + Reference < i18n::XCharacterClassification > OCommonAccessibleText::implGetCharacterClassification() + { + if ( !m_xCharClass.is() ) + { + Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + if ( xMSF.is() ) + { + m_xCharClass = Reference< i18n::XCharacterClassification > + ( xMSF->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.CharacterClassification" ) ) ), UNO_QUERY ); + } + } + + return m_xCharClass; + } + + // ----------------------------------------------------------------------------- + + sal_Bool OCommonAccessibleText::implIsValidBoundary( i18n::Boundary& rBoundary, sal_Int32 nLength ) + { + return ( rBoundary.startPos >= 0 ) && ( rBoundary.startPos < nLength ) && ( rBoundary.endPos >= 0 ) && ( rBoundary.endPos <= nLength ); + } + + // ----------------------------------------------------------------------------- + + sal_Bool OCommonAccessibleText::implIsValidIndex( sal_Int32 nIndex, sal_Int32 nLength ) + { + return ( nIndex >= 0 ) && ( nIndex < nLength ); + } + + // ----------------------------------------------------------------------------- + + sal_Bool OCommonAccessibleText::implIsValidRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex, sal_Int32 nLength ) + { + return ( nStartIndex >= 0 ) && ( nStartIndex <= nLength ) && ( nEndIndex >= 0 ) && ( nEndIndex <= nLength ); + } + + // ----------------------------------------------------------------------------- + + void OCommonAccessibleText::implGetGlyphBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex ) + { + ::rtl::OUString sText( implGetText() ); + + if ( implIsValidIndex( nIndex, sText.getLength() ) ) + { + Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator(); + if ( xBreakIter.is() ) + { + sal_Int32 nCount = 1; + sal_Int32 nDone; + sal_Int32 nStartIndex = xBreakIter->previousCharacters( sText, nIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone ); + if ( nDone != 0 ) + nStartIndex = xBreakIter->nextCharacters( sText, nStartIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone ); + sal_Int32 nEndIndex = xBreakIter->nextCharacters( sText, nStartIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone ); + if ( nDone != 0 ) + { + rBoundary.startPos = nStartIndex; + rBoundary.endPos = nEndIndex; + } + } + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } + } + + // ----------------------------------------------------------------------------- + + sal_Bool OCommonAccessibleText::implGetWordBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex ) + { + sal_Bool bWord = sal_False; + ::rtl::OUString sText( implGetText() ); + + if ( implIsValidIndex( nIndex, sText.getLength() ) ) + { + Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator(); + if ( xBreakIter.is() ) + { + rBoundary = xBreakIter->getWordBoundary( sText, nIndex, implGetLocale(), i18n::WordType::ANY_WORD, sal_True ); + + // it's a word, if the first character is an alpha-numeric character + Reference< i18n::XCharacterClassification > xCharClass = implGetCharacterClassification(); + if ( xCharClass.is() ) + { + sal_Int32 nType = xCharClass->getCharacterType( sText, rBoundary.startPos, implGetLocale() ); + if ( ( nType & ( i18n::KCharacterType::LETTER | i18n::KCharacterType::DIGIT ) ) != 0 ) + bWord = sal_True; + } + } + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } + + return bWord; + } + + // ----------------------------------------------------------------------------- + + void OCommonAccessibleText::implGetSentenceBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex ) + { + ::rtl::OUString sText( implGetText() ); + + if ( implIsValidIndex( nIndex, sText.getLength() ) ) + { + Locale aLocale = implGetLocale(); + Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator(); + if ( xBreakIter.is() ) + { + rBoundary.endPos = xBreakIter->endOfSentence( sText, nIndex, aLocale ); + rBoundary.startPos = xBreakIter->beginOfSentence( sText, rBoundary.endPos, aLocale ); + } + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } + } + + // ----------------------------------------------------------------------------- + + void OCommonAccessibleText::implGetParagraphBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex ) + { + ::rtl::OUString sText( implGetText() ); + + if ( implIsValidIndex( nIndex, sText.getLength() ) ) + { + rBoundary.startPos = 0; + rBoundary.endPos = sText.getLength(); + + sal_Int32 nFound = sText.lastIndexOf( (sal_Unicode)'\n', nIndex ); + if ( nFound != -1 ) + rBoundary.startPos = nFound + 1; + + nFound = sText.indexOf( (sal_Unicode)'\n', nIndex ); + if ( nFound != -1 ) + rBoundary.endPos = nFound + 1; + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } + } + + // ----------------------------------------------------------------------------- + + void OCommonAccessibleText::implGetLineBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex ) + { + ::rtl::OUString sText( implGetText() ); + sal_Int32 nLength = sText.getLength(); + + if ( implIsValidIndex( nIndex, nLength ) || nIndex == nLength ) + { + rBoundary.startPos = 0; + rBoundary.endPos = nLength; + } + else + { + rBoundary.startPos = nIndex; + rBoundary.endPos = nIndex; + } + } + + // ----------------------------------------------------------------------------- + + sal_Unicode OCommonAccessibleText::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::rtl::OUString sText( implGetText() ); + + if ( !implIsValidIndex( nIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + return sText.getStr()[nIndex]; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 OCommonAccessibleText::getCharacterCount() throw (RuntimeException) + { + return implGetText().getLength(); + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString OCommonAccessibleText::getSelectedText() throw (RuntimeException) + { + ::rtl::OUString sText; + sal_Int32 nStartIndex; + sal_Int32 nEndIndex; + + implGetSelection( nStartIndex, nEndIndex ); + + try + { + sText = getTextRange( nStartIndex, nEndIndex ); + } + catch ( IndexOutOfBoundsException& ) + { + } + + return sText; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 OCommonAccessibleText::getSelectionStart() throw (RuntimeException) + { + sal_Int32 nStartIndex; + sal_Int32 nEndIndex; + + implGetSelection( nStartIndex, nEndIndex ); + + return nStartIndex; + } + + // ----------------------------------------------------------------------------- + + sal_Int32 OCommonAccessibleText::getSelectionEnd() throw (RuntimeException) + { + sal_Int32 nStartIndex; + sal_Int32 nEndIndex; + + implGetSelection( nStartIndex, nEndIndex ); + + return nEndIndex; + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString OCommonAccessibleText::getText() throw (RuntimeException) + { + return implGetText(); + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString OCommonAccessibleText::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + ::rtl::OUString sText( implGetText() ); + + if ( !implIsValidRange( nStartIndex, nEndIndex, sText.getLength() ) ) + throw IndexOutOfBoundsException(); + + sal_Int32 nMinIndex = ::std::min( nStartIndex, nEndIndex ); + sal_Int32 nMaxIndex = ::std::max( nStartIndex, nEndIndex ); + + return sText.copy( nMinIndex, nMaxIndex - nMinIndex ); + } + + // ----------------------------------------------------------------------------- + + TextSegment OCommonAccessibleText::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException) + { + ::rtl::OUString sText( implGetText() ); + sal_Int32 nLength = sText.getLength(); + + if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength ) + throw IndexOutOfBoundsException(); + + i18n::Boundary aBoundary; + TextSegment aResult; + aResult.SegmentStart = -1; + aResult.SegmentEnd = -1; + + switch ( aTextType ) + { + case AccessibleTextType::CHARACTER: + { + if ( implIsValidIndex( nIndex, nLength ) ) + { + aResult.SegmentText = sText.copy( nIndex, 1 ); + aResult.SegmentStart = nIndex; + aResult.SegmentEnd = nIndex+1; + } + } + break; + case AccessibleTextType::GLYPH: + { + // get glyph at index + implGetGlyphBoundary( aBoundary, nIndex ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + break; + case AccessibleTextType::WORD: + { + // get word at index + sal_Bool bWord = implGetWordBoundary( aBoundary, nIndex ); + if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + break; + case AccessibleTextType::SENTENCE: + { + // get sentence at index + implGetSentenceBoundary( aBoundary, nIndex ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + break; + case AccessibleTextType::PARAGRAPH: + { + // get paragraph at index + implGetParagraphBoundary( aBoundary, nIndex ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + break; + case AccessibleTextType::LINE: + { + // get line at index + implGetLineBoundary( aBoundary, nIndex ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + break; + case AccessibleTextType::ATTRIBUTE_RUN: + { + // TODO: implGetAttributeRunBoundary() (incompatible!) + + aResult.SegmentText = sText; + aResult.SegmentStart = 0; + aResult.SegmentEnd = nLength; + } + break; + default: + { + // unknown text type + } + } + + return aResult; + } + + // ----------------------------------------------------------------------------- + + TextSegment OCommonAccessibleText::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException) + { + ::rtl::OUString sText( implGetText() ); + sal_Int32 nLength = sText.getLength(); + + if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength ) + throw IndexOutOfBoundsException(); + + i18n::Boundary aBoundary; + TextSegment aResult; + aResult.SegmentStart = -1; + aResult.SegmentEnd = -1; + + switch ( aTextType ) + { + case AccessibleTextType::CHARACTER: + { + if ( implIsValidIndex( nIndex - 1, nLength ) ) + { + aResult.SegmentText = sText.copy( nIndex - 1, 1 ); + aResult.SegmentStart = nIndex-1; + aResult.SegmentEnd = nIndex; + } + } + break; + case AccessibleTextType::GLYPH: + { + // get glyph at index + implGetGlyphBoundary( aBoundary, nIndex ); + // get previous glyph + if ( aBoundary.startPos > 0 ) + { + implGetGlyphBoundary( aBoundary, aBoundary.startPos - 1 ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + } + break; + case AccessibleTextType::WORD: + { + // get word at index + implGetWordBoundary( aBoundary, nIndex ); + // get previous word + sal_Bool bWord = sal_False; + while ( !bWord && aBoundary.startPos > 0 ) + bWord = implGetWordBoundary( aBoundary, aBoundary.startPos - 1 ); + if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + break; + case AccessibleTextType::SENTENCE: + { + // get sentence at index + implGetSentenceBoundary( aBoundary, nIndex ); + // get previous sentence + if ( aBoundary.startPos > 0 ) + { + implGetSentenceBoundary( aBoundary, aBoundary.startPos - 1 ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + } + break; + case AccessibleTextType::PARAGRAPH: + { + // get paragraph at index + implGetParagraphBoundary( aBoundary, nIndex ); + // get previous paragraph + if ( aBoundary.startPos > 0 ) + { + implGetParagraphBoundary( aBoundary, aBoundary.startPos - 1 ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + } + break; + case AccessibleTextType::LINE: + { + // get line at index + implGetLineBoundary( aBoundary, nIndex ); + // get previous line + if ( aBoundary.startPos > 0 ) + { + implGetLineBoundary( aBoundary, aBoundary.startPos - 1 ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + } + break; + case AccessibleTextType::ATTRIBUTE_RUN: + { + // TODO: implGetAttributeRunBoundary() (incompatible!) + } + break; + default: + { + // unknown text type + } + } + + return aResult; + } + + // ----------------------------------------------------------------------------- + + TextSegment OCommonAccessibleText::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException) + { + ::rtl::OUString sText( implGetText() ); + sal_Int32 nLength = sText.getLength(); + + if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength ) + throw IndexOutOfBoundsException(); + + i18n::Boundary aBoundary; + TextSegment aResult; + aResult.SegmentStart = -1; + aResult.SegmentEnd = -1; + + switch ( aTextType ) + { + case AccessibleTextType::CHARACTER: + { + if ( implIsValidIndex( nIndex + 1, nLength ) ) + { + aResult.SegmentText = sText.copy( nIndex + 1, 1 ); + aResult.SegmentStart = nIndex+1; + aResult.SegmentEnd = nIndex+2; + } + } + break; + case AccessibleTextType::GLYPH: + { + // get glyph at index + implGetGlyphBoundary( aBoundary, nIndex ); + // get next glyph + if ( aBoundary.endPos < nLength ) + { + implGetGlyphBoundary( aBoundary, aBoundary.endPos ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + } + break; + case AccessibleTextType::WORD: + { + // get word at index + implGetWordBoundary( aBoundary, nIndex ); + // get next word + sal_Bool bWord = sal_False; + while ( !bWord && aBoundary.endPos < nLength ) + bWord = implGetWordBoundary( aBoundary, aBoundary.endPos ); + if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + break; + case AccessibleTextType::SENTENCE: + { + // get sentence at index + implGetSentenceBoundary( aBoundary, nIndex ); + // get next sentence + sal_Int32 nEnd = aBoundary.endPos; + sal_Int32 nI = aBoundary.endPos; + sal_Bool bFound = sal_False; + while ( !bFound && ++nI < nLength ) + { + implGetSentenceBoundary( aBoundary, nI ); + bFound = ( aBoundary.endPos > nEnd ); + } + if ( bFound && implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + break; + case AccessibleTextType::PARAGRAPH: + { + // get paragraph at index + implGetParagraphBoundary( aBoundary, nIndex ); + // get next paragraph + if ( aBoundary.endPos < nLength ) + { + implGetParagraphBoundary( aBoundary, aBoundary.endPos ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + } + break; + case AccessibleTextType::LINE: + { + // get line at index + implGetLineBoundary( aBoundary, nIndex ); + // get next line + if ( aBoundary.endPos < nLength ) + { + implGetLineBoundary( aBoundary, aBoundary.endPos ); + if ( implIsValidBoundary( aBoundary, nLength ) ) + { + aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); + aResult.SegmentStart = aBoundary.startPos; + aResult.SegmentEnd = aBoundary.endPos; + } + } + } + break; + case AccessibleTextType::ATTRIBUTE_RUN: + { + // TODO: implGetAttributeRunBoundary() (incompatible!) + } + break; + default: + { + // unknown text type + } + } + + return aResult; + } + + // ----------------------------------------------------------------------------- + bool OCommonAccessibleText::implInitTextChangedEvent( + const rtl::OUString& rOldString, + const rtl::OUString& rNewString, + ::com::sun::star::uno::Any& rDeleted, + ::com::sun::star::uno::Any& rInserted) // throw() + { + sal_uInt32 nLenOld = rOldString.getLength(); + sal_uInt32 nLenNew = rNewString.getLength(); + + // equal + if ((0 == nLenOld) && (0 == nLenNew)) + return false; + + TextSegment aDeletedText; + TextSegment aInsertedText; + + aDeletedText.SegmentStart = -1; + aDeletedText.SegmentEnd = -1; + aInsertedText.SegmentStart = -1; + aInsertedText.SegmentEnd = -1; + + // insert only + if ((0 == nLenOld) && (nLenNew > 0)) + { + aInsertedText.SegmentStart = 0; + aInsertedText.SegmentEnd = nLenNew; + aInsertedText.SegmentText = rNewString.copy( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart ); + + rInserted <<= aInsertedText; + return true; + } + + // delete only + if ((nLenOld > 0) && (0 == nLenNew)) + { + aDeletedText.SegmentStart = 0; + aDeletedText.SegmentEnd = nLenOld; + aDeletedText.SegmentText = rOldString.copy( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart ); + + rDeleted <<= aDeletedText; + return true; + } + + const sal_Unicode* pFirstDiffOld = rOldString.getStr(); + const sal_Unicode* pLastDiffOld = rOldString.getStr() + nLenOld; + const sal_Unicode* pFirstDiffNew = rNewString.getStr(); + const sal_Unicode* pLastDiffNew = rNewString.getStr() + nLenNew; + + // find first difference + while ((*pFirstDiffOld == *pFirstDiffNew) && + (pFirstDiffOld < pLastDiffOld) && + (pFirstDiffNew < pLastDiffNew)) + { + pFirstDiffOld++; + pFirstDiffNew++; + } + + // equality test + if ((0 == *pFirstDiffOld) && (0 == *pFirstDiffNew)) + return false; + + // find last difference + while ( ( pLastDiffOld > pFirstDiffOld) && + ( pLastDiffNew > pFirstDiffNew) && + (pLastDiffOld[-1] == pLastDiffNew[-1])) + { + pLastDiffOld--; + pLastDiffNew--; + } + + if (pFirstDiffOld < pLastDiffOld) + { + aDeletedText.SegmentStart = pFirstDiffOld - rOldString.getStr(); + aDeletedText.SegmentEnd = pLastDiffOld - rOldString.getStr(); + aDeletedText.SegmentText = rOldString.copy( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart ); + + rDeleted <<= aDeletedText; + } + + if (pFirstDiffNew < pLastDiffNew) + { + aInsertedText.SegmentStart = pFirstDiffNew - rNewString.getStr(); + aInsertedText.SegmentEnd = pLastDiffNew - rNewString.getStr(); + aInsertedText.SegmentText = rNewString.copy( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart ); + + rInserted <<= aInsertedText; + } + return true; + } + + //============================================================================== + // OAccessibleTextHelper + //============================================================================== + + OAccessibleTextHelper::OAccessibleTextHelper() + { + } + + // ----------------------------------------------------------------------------- + + OAccessibleTextHelper::OAccessibleTextHelper( IMutex* _pExternalLock ) + :OAccessibleExtendedComponentHelper( _pExternalLock ) + { + } + + // ----------------------------------------------------------------------------- + // XInterface + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleTextHelper, OAccessibleExtendedComponentHelper, OAccessibleTextHelper_Base ) + + // ----------------------------------------------------------------------------- + // XTypeProvider + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleTextHelper, OAccessibleExtendedComponentHelper, OAccessibleTextHelper_Base ) + + // ----------------------------------------------------------------------------- + // XAccessibleText + // ----------------------------------------------------------------------------- + + sal_Unicode OAccessibleTextHelper::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getCharacter( nIndex ); + } + + // ----------------------------------------------------------------------------- + + sal_Int32 OAccessibleTextHelper::getCharacterCount() throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getCharacterCount(); + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString OAccessibleTextHelper::getSelectedText() throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getSelectedText(); + } + + // ----------------------------------------------------------------------------- + + sal_Int32 OAccessibleTextHelper::getSelectionStart() throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getSelectionStart(); + } + + // ----------------------------------------------------------------------------- + + sal_Int32 OAccessibleTextHelper::getSelectionEnd() throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getSelectionEnd(); + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString OAccessibleTextHelper::getText() throw (RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getText(); + } + + // ----------------------------------------------------------------------------- + + ::rtl::OUString OAccessibleTextHelper::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex ); + } + + // ----------------------------------------------------------------------------- + + TextSegment OAccessibleTextHelper::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); + } + + // ----------------------------------------------------------------------------- + + TextSegment OAccessibleTextHelper::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); + } + + // ----------------------------------------------------------------------------- + + TextSegment OAccessibleTextHelper::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException) + { + OExternalLockGuard aGuard( this ); + + return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); + } + + // ----------------------------------------------------------------------------- + +//.............................................................................. +} // namespace comphelper +//.............................................................................. + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accessiblewrapper.cxx b/comphelper/source/misc/accessiblewrapper.cxx new file mode 100644 index 000000000000..b9d26591f19f --- /dev/null +++ b/comphelper/source/misc/accessiblewrapper.cxx @@ -0,0 +1,683 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "comphelper/accessiblewrapper.hxx" +#include <com/sun/star/reflection/XProxyFactory.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> + +#include <algorithm> + +using namespace ::comphelper; +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +//............................................................................. +namespace comphelper +{ +//............................................................................. + + //========================================================================= + //= OWrappedAccessibleChildrenManager + //========================================================================= + //-------------------------------------------------------------------- + struct RemoveEventListener + : public ::std::unary_function< AccessibleMap::value_type, void > + { + private: + Reference< XEventListener > m_xListener; + + public: + RemoveEventListener( const Reference< XEventListener >& _rxListener ) + :m_xListener( _rxListener ) + { + } + + void operator()( const AccessibleMap::value_type& _rMapEntry ) const + { + Reference< XComponent > xComp( _rMapEntry.first, UNO_QUERY ); + if ( xComp.is() ) + xComp->removeEventListener( m_xListener ); + } + }; + + //-------------------------------------------------------------------- + struct DisposeMappedChild + : public ::std::unary_function< AccessibleMap::value_type, void > + { + void operator()( const AccessibleMap::value_type& _rMapEntry ) const + { + Reference< XComponent > xContextComponent; + if ( _rMapEntry.second.is() ) + xContextComponent = xContextComponent.query( _rMapEntry.second->getAccessibleContext() ); + if ( xContextComponent.is() ) + xContextComponent->dispose(); + } + }; + + //------------------------------------------------------------------------- + OWrappedAccessibleChildrenManager::OWrappedAccessibleChildrenManager( const Reference< XMultiServiceFactory >& _rxORB ) + :m_xORB( _rxORB ) + ,m_bTransientChildren( sal_True ) + { + } + + //------------------------------------------------------------------------- + OWrappedAccessibleChildrenManager::~OWrappedAccessibleChildrenManager( ) + { + } + + //------------------------------------------------------------------------- + void OWrappedAccessibleChildrenManager::setTransientChildren( sal_Bool _bSet ) + { + m_bTransientChildren = _bSet; + } + + //------------------------------------------------------------------------- + void OWrappedAccessibleChildrenManager::setOwningAccessible( const Reference< XAccessible >& _rxAcc ) + { + OSL_ENSURE( !m_aOwningAccessible.get().is(), "OWrappedAccessibleChildrenManager::setOwningAccessible: to be called only once!" ); + m_aOwningAccessible = WeakReference< XAccessible >( _rxAcc ); + } + + //------------------------------------------------------------------------- + void OWrappedAccessibleChildrenManager::removeFromCache( const Reference< XAccessible >& _rxKey ) + { + AccessibleMap::iterator aRemovedPos = m_aChildrenMap.find( _rxKey ); + if ( m_aChildrenMap.end() != aRemovedPos ) + { // it was cached + // remove ourself as event listener + RemoveEventListener aOperator( this ); + aOperator( *aRemovedPos ); + // and remove the entry from the map + m_aChildrenMap.erase( aRemovedPos ); + } + } + + //------------------------------------------------------------------------- + void OWrappedAccessibleChildrenManager::invalidateAll( ) + { + // remove as event listener from the map elements + ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), RemoveEventListener( this ) ); + // clear the map + AccessibleMap aMap; + m_aChildrenMap.swap( aMap ); + } + + //------------------------------------------------------------------------- + Reference< XAccessible > OWrappedAccessibleChildrenManager::getAccessibleWrapperFor( + const Reference< XAccessible >& _rxKey, sal_Bool _bCreate ) + { + Reference< XAccessible > xValue; + + if( !_rxKey.is() ) + { + // fprintf( stderr, "It was this path that was crashing stuff\n" ); + return xValue; + } + + // do we have this child in the cahce? + AccessibleMap::const_iterator aPos = m_aChildrenMap.find( _rxKey ); + if ( m_aChildrenMap.end() != aPos ) + { + xValue = aPos->second; + } + else if ( _bCreate ) + { // not found in the cache, and allowed to create + // -> new wrapper + xValue = new OAccessibleWrapper( m_xORB, _rxKey, (Reference< XAccessible >)m_aOwningAccessible ); + + // see if we do cache children + if ( !m_bTransientChildren ) + { + if (!m_aChildrenMap.insert( + AccessibleMap::value_type( _rxKey, xValue ) ).second) + { + OSL_FAIL( + "OWrappedAccessibleChildrenManager::" + "getAccessibleWrapperFor: element was already" + " inserted!" ); + } + + // listen for disposals of inner children - this may happen when the inner context + // is the owner for the inner children (it will dispose these children, and of course + // not our wrapper for these children) + Reference< XComponent > xComp( _rxKey, UNO_QUERY ); + if ( xComp.is() ) + xComp->addEventListener( this ); + } + } + + return xValue; + } + + //------------------------------------------------------------------------- + void OWrappedAccessibleChildrenManager::dispose() + { + // dispose our children + ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), RemoveEventListener( this ) ); + ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), DisposeMappedChild( ) ); + // clear our children + AccessibleMap aMap; + m_aChildrenMap.swap( aMap ); + } + + //-------------------------------------------------------------------- + void OWrappedAccessibleChildrenManager::implTranslateChildEventValue( const Any& _rInValue, Any& _rOutValue ) + { + _rOutValue.clear(); + Reference< XAccessible > xChild; + if ( _rInValue >>= xChild ) + _rOutValue <<= getAccessibleWrapperFor( xChild, sal_True ); + } + + //------------------------------------------------------------------------- + void OWrappedAccessibleChildrenManager::translateAccessibleEvent( const AccessibleEventObject& _rEvent, AccessibleEventObject& _rTranslatedEvent ) + { + // just in case we can't translate some of the values: + _rTranslatedEvent.NewValue = _rEvent.NewValue; + _rTranslatedEvent.OldValue = _rEvent.OldValue; + + switch ( _rEvent.EventId ) + { + case AccessibleEventId::CHILD: + case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED: + case AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED: + case AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED: + case AccessibleEventId::LABEL_FOR_RELATION_CHANGED: + case AccessibleEventId::LABELED_BY_RELATION_CHANGED: + case AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED: + case AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED: + // these are events where both the old and the new value contain child references + implTranslateChildEventValue( _rEvent.OldValue, _rTranslatedEvent.OldValue ); + implTranslateChildEventValue( _rEvent.NewValue, _rTranslatedEvent.NewValue ); + break; + + case AccessibleEventId::NAME_CHANGED: + case AccessibleEventId::DESCRIPTION_CHANGED: + case AccessibleEventId::ACTION_CHANGED: + case AccessibleEventId::STATE_CHANGED: + case AccessibleEventId::BOUNDRECT_CHANGED: + case AccessibleEventId::INVALIDATE_ALL_CHILDREN: + case AccessibleEventId::SELECTION_CHANGED: + case AccessibleEventId::VISIBLE_DATA_CHANGED: + case AccessibleEventId::VALUE_CHANGED: + case AccessibleEventId::MEMBER_OF_RELATION_CHANGED: + case AccessibleEventId::CARET_CHANGED: + case AccessibleEventId::TEXT_CHANGED: + case AccessibleEventId::HYPERTEXT_CHANGED: + case AccessibleEventId::TABLE_CAPTION_CHANGED: + case AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED: + case AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED: + case AccessibleEventId::TABLE_MODEL_CHANGED: + case AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED: + case AccessibleEventId::TABLE_ROW_HEADER_CHANGED: + case AccessibleEventId::TABLE_SUMMARY_CHANGED: + // #130798# + // these Ids are also missed: SUB_WINDOW_OF_RELATION_CHANGED & TEXT_ATTRIBUTE_CHANGED + case AccessibleEventId::TEXT_SELECTION_CHANGED: + // nothing to translate + break; + + default: + OSL_FAIL( "OWrappedAccessibleChildrenManager::translateAccessibleEvent: unknown (or unexpected) event id!" ); + break; + } + } + + //------------------------------------------------------------------------- + void OWrappedAccessibleChildrenManager::handleChildNotification( const AccessibleEventObject& _rEvent ) + { + if ( AccessibleEventId::INVALIDATE_ALL_CHILDREN == _rEvent.EventId ) + { // clear our child map + invalidateAll( ); + } + else if ( AccessibleEventId::CHILD == _rEvent.EventId ) + { + // check if the removed or replaced element is cached + Reference< XAccessible > xRemoved; + if ( _rEvent.OldValue >>= xRemoved ) + removeFromCache( xRemoved ); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OWrappedAccessibleChildrenManager::disposing( const EventObject& _rSource ) throw (RuntimeException) + { + // this should come from one of the inner XAccessible's of our children + Reference< XAccessible > xSource( _rSource.Source, UNO_QUERY ); + AccessibleMap::iterator aDisposedPos = m_aChildrenMap.find( xSource ); +#if OSL_DEBUG_LEVEL > 0 + if ( m_aChildrenMap.end() == aDisposedPos ) + { + OSL_FAIL( "OWrappedAccessibleChildrenManager::disposing: where did this come from?" ); + // helper for dignostics + Reference< XAccessible > xOwningAccessible( m_aOwningAccessible ); + Reference< XAccessibleContext > xContext; + try + { + if ( xOwningAccessible.is() ) + xContext = xOwningAccessible->getAccessibleContext(); + if ( xContext.is() ) + { + ::rtl::OUString sName = xContext->getAccessibleName(); + ::rtl::OUString sDescription = xContext->getAccessibleDescription(); +// sal_Int32 nPlaceYourBreakpointHere = 0; + } + } + catch( const Exception& /*e*/ ) + { + // silent this, it's only diagnostics which failed + } + } +#endif + if ( m_aChildrenMap.end() != aDisposedPos ) + { + m_aChildrenMap.erase( aDisposedPos ); + } + } + + //========================================================================= + //= OAccessibleWrapper (implementation) + //========================================================================= + //------------------------------------------------------------------------- + OAccessibleWrapper::OAccessibleWrapper( const Reference< XMultiServiceFactory >& _rxORB, + const Reference< XAccessible >& _rxInnerAccessible, const Reference< XAccessible >& _rxParentAccessible ) + :OAccessibleWrapper_Base( ) + ,OComponentProxyAggregation( _rxORB, Reference< XComponent >( _rxInnerAccessible, UNO_QUERY ) ) + ,m_xParentAccessible( _rxParentAccessible ) + ,m_xInnerAccessible( _rxInnerAccessible ) + { + } + + //-------------------------------------------------------------------- + OAccessibleWrapper::~OAccessibleWrapper( ) + { + if ( !m_rBHelper.bDisposed ) + { + acquire(); // to prevent duplicate dtor calls + dispose(); + } + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleWrapper, OComponentProxyAggregation, OAccessibleWrapper_Base ) + IMPLEMENT_FORWARD_REFCOUNT( OAccessibleWrapper, OComponentProxyAggregation ) + + //-------------------------------------------------------------------- + Any OAccessibleWrapper::queryInterface( const Type& _rType ) throw (RuntimeException) + { + // #111089# instead of the inner XAccessible the proxy XAccessible must be returned + Any aReturn = OAccessibleWrapper_Base::queryInterface( _rType ); + if ( !aReturn.hasValue() ) + aReturn = OComponentProxyAggregation::queryInterface( _rType ); + + return aReturn; + } + + //-------------------------------------------------------------------- + Reference< XAccessibleContext > OAccessibleWrapper::getContextNoCreate( ) const + { + return (Reference< XAccessibleContext >)m_aContext; + } + + //-------------------------------------------------------------------- + OAccessibleContextWrapper* OAccessibleWrapper::createAccessibleContext( const Reference< XAccessibleContext >& _rxInnerContext ) + { + return new OAccessibleContextWrapper( getORB(), _rxInnerContext, this, m_xParentAccessible ); + } + + //-------------------------------------------------------------------- + Reference< XAccessibleContext > SAL_CALL OAccessibleWrapper::getAccessibleContext( ) throw (RuntimeException) + { + // see if the context is still alive (we cache it) + Reference< XAccessibleContext > xContext = (Reference< XAccessibleContext >)m_aContext; + if ( !xContext.is() ) + { + // create a new context + Reference< XAccessibleContext > xInnerContext = m_xInnerAccessible->getAccessibleContext( ); + if ( xInnerContext.is() ) + { + xContext = createAccessibleContext( xInnerContext ); + // cache it + m_aContext = WeakReference< XAccessibleContext >( xContext ); + } + } + + return xContext; + } + + //========================================================================= + //= OAccessibleWrapper (implementation) + //========================================================================= + //------------------------------------------------------------------------- + OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper( + const Reference< XMultiServiceFactory >& _rxORB, + ::cppu::OBroadcastHelper& _rBHelper, + const Reference< XAccessibleContext >& _rxInnerAccessibleContext, + const Reference< XAccessible >& _rxOwningAccessible, + const Reference< XAccessible >& _rxParentAccessible ) + :OComponentProxyAggregationHelper( _rxORB, _rBHelper ) + ,m_xInnerContext( _rxInnerAccessibleContext ) + ,m_xOwningAccessible( _rxOwningAccessible ) + ,m_xParentAccessible( _rxParentAccessible ) + ,m_pChildMapper( NULL ) + { + // initialize the mapper for our children + m_pChildMapper = new OWrappedAccessibleChildrenManager( getORB() ); + m_pChildMapper->acquire(); + + // determine if we're allowed to cache children + Reference< XAccessibleStateSet > xStates( m_xInnerContext->getAccessibleStateSet( ) ); + OSL_ENSURE( xStates.is(), "OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper: no inner state set!" ); + m_pChildMapper->setTransientChildren( !xStates.is() || xStates->contains( AccessibleStateType::MANAGES_DESCENDANTS) ); + + m_pChildMapper->setOwningAccessible( m_xOwningAccessible ); + } + + //-------------------------------------------------------------------- + void OAccessibleContextWrapperHelper::aggregateProxy( oslInterlockedCount& _rRefCount, ::cppu::OWeakObject& _rDelegator ) + { + Reference< XComponent > xInnerComponent( m_xInnerContext, UNO_QUERY ); + OSL_ENSURE( xInnerComponent.is(), "OComponentProxyAggregation::aggregateProxy: accessible is no XComponent!" ); + if ( xInnerComponent.is() ) + componentAggregateProxyFor( xInnerComponent, _rRefCount, _rDelegator ); + + // add as event listener to the inner context, because we want to multiplex the AccessibleEvents + osl_incrementInterlockedCount( &_rRefCount ); + { + Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY ); + if ( xBroadcaster.is() ) + xBroadcaster->addEventListener( this ); + } + osl_decrementInterlockedCount( &_rRefCount ); + } + + //-------------------------------------------------------------------- + OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper( ) + { + OSL_ENSURE( m_rBHelper.bDisposed, "OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper: you should ensure (in your dtor) that the object is disposed!" ); + + m_pChildMapper->release(); + m_pChildMapper = NULL; + } + + //-------------------------------------------------------------------- + Any SAL_CALL OAccessibleContextWrapperHelper::queryInterface( const Type& _rType ) throw (RuntimeException) + { + Any aReturn = OComponentProxyAggregationHelper::queryInterface( _rType ); + if ( !aReturn.hasValue() ) + aReturn = OAccessibleContextWrapperHelper_Base::queryInterface( _rType ); + return aReturn; + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapperHelper, OComponentProxyAggregationHelper, OAccessibleContextWrapperHelper_Base ) + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL OAccessibleContextWrapperHelper::getAccessibleChildCount( ) throw (RuntimeException) + { + return m_xInnerContext->getAccessibleChildCount(); + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL OAccessibleContextWrapperHelper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) + { + // get the child of the wrapped component + Reference< XAccessible > xInnerChild = m_xInnerContext->getAccessibleChild( i ); + return m_pChildMapper->getAccessibleWrapperFor( xInnerChild ); + } + + //-------------------------------------------------------------------- + Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapperHelper::getAccessibleRelationSet( ) throw (RuntimeException) + { + return m_xInnerContext->getAccessibleRelationSet(); + // TODO: if this relation set would contain relations to siblings, we would normally need + // to wrap them, too .... + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleContextWrapperHelper::notifyEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException) + { +#if OSL_DEBUG_LEVEL > 0 + if ( AccessibleEventId::STATE_CHANGED == _rEvent.EventId ) + { + sal_Bool bChildTransienceChanged = sal_False; + sal_Int16 nChangeState = 0; + if ( _rEvent.OldValue >>= nChangeState ) + bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState; + if ( _rEvent.NewValue >>= nChangeState ) + bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState; + OSL_ENSURE( !bChildTransienceChanged, "OAccessibleContextWrapperHelper::notifyEvent: MANAGES_DESCENDANTS is not expected to change during runtime!" ); + // if this asserts, then we would need to update our m_bTransientChildren flag here, + // as well as (potentially) our child cache + } +#endif + AccessibleEventObject aTranslatedEvent( _rEvent ); + + { + ::osl::MutexGuard aGuard( m_rBHelper.rMutex ); + + // translate the event + queryInterface( ::getCppuType( static_cast< Reference< XInterface >* >( NULL ) ) ) >>= aTranslatedEvent.Source; + m_pChildMapper->translateAccessibleEvent( _rEvent, aTranslatedEvent ); + + // see if any of these notifications affect our child manager + m_pChildMapper->handleChildNotification( _rEvent ); + + if ( aTranslatedEvent.NewValue == m_xInner ) + aTranslatedEvent.NewValue = makeAny(aTranslatedEvent.Source); + if ( aTranslatedEvent.OldValue == m_xInner ) + aTranslatedEvent.OldValue = makeAny(aTranslatedEvent.Source); + } + + notifyTranslatedEvent( aTranslatedEvent ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleContextWrapperHelper::dispose() throw( RuntimeException ) + { + ::osl::MutexGuard aGuard( m_rBHelper.rMutex ); + + // stop multiplexing events + Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY ); + OSL_ENSURE( xBroadcaster.is(), "OAccessibleContextWrapperHelper::disposing(): inner context is no broadcaster!" ); + if ( xBroadcaster.is() ) + xBroadcaster->removeEventListener( this ); + + // dispose the child cache/map + m_pChildMapper->dispose(); + + // let the base class dispose the inner component + OComponentProxyAggregationHelper::dispose(); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleContextWrapperHelper::disposing( const EventObject& _rEvent ) throw (RuntimeException) + { + // simply disambiguate this + OComponentProxyAggregationHelper::disposing( _rEvent ); + } + + //==================================================================== + //= OAccessibleContextWrapper + //==================================================================== + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper ) + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper ) + + //-------------------------------------------------------------------- + OAccessibleContextWrapper::OAccessibleContextWrapper( const Reference< XMultiServiceFactory >& _rxORB, + const Reference< XAccessibleContext >& _rxInnerAccessibleContext, const Reference< XAccessible >& _rxOwningAccessible, + const Reference< XAccessible >& _rxParentAccessible ) + :OAccessibleContextWrapper_CBase( m_aMutex ) + ,OAccessibleContextWrapperHelper( _rxORB, rBHelper, _rxInnerAccessibleContext, _rxOwningAccessible, _rxParentAccessible ) + ,m_nNotifierClient( 0 ) + { + aggregateProxy( m_refCount, *this ); + } + + //-------------------------------------------------------------------- + OAccessibleContextWrapper::~OAccessibleContextWrapper() + { + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleChildCount( ) throw (RuntimeException) + { + return OAccessibleContextWrapperHelper::getAccessibleChildCount(); + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) + { + return OAccessibleContextWrapperHelper::getAccessibleChild( i ); + } + + //-------------------------------------------------------------------- + Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleParent( ) throw (RuntimeException) + { + return m_xParentAccessible; + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleIndexInParent( ) throw (RuntimeException) + { + return m_xInnerContext->getAccessibleIndexInParent(); + } + + //-------------------------------------------------------------------- + sal_Int16 SAL_CALL OAccessibleContextWrapper::getAccessibleRole( ) throw (RuntimeException) + { + return m_xInnerContext->getAccessibleRole(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL OAccessibleContextWrapper::getAccessibleDescription( ) throw (RuntimeException) + { + return m_xInnerContext->getAccessibleDescription(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL OAccessibleContextWrapper::getAccessibleName( ) throw (RuntimeException) + { + return m_xInnerContext->getAccessibleName(); + } + + //-------------------------------------------------------------------- + Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapper::getAccessibleRelationSet( ) throw (RuntimeException) + { + return OAccessibleContextWrapperHelper::getAccessibleRelationSet(); + } + + //-------------------------------------------------------------------- + Reference< XAccessibleStateSet > SAL_CALL OAccessibleContextWrapper::getAccessibleStateSet( ) throw (RuntimeException) + { + return m_xInnerContext->getAccessibleStateSet(); + } + + //-------------------------------------------------------------------- + Locale SAL_CALL OAccessibleContextWrapper::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) + { + return m_xInnerContext->getLocale(); + } + + //-------------------------------------------------------------------- + void OAccessibleContextWrapper::notifyTranslatedEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException) + { + if ( m_nNotifierClient ) + AccessibleEventNotifier::addEvent( m_nNotifierClient, _rEvent ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleContextWrapper::addEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_nNotifierClient ) + m_nNotifierClient = AccessibleEventNotifier::registerClient( ); + AccessibleEventNotifier::addEventListener( m_nNotifierClient, _rxListener ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleContextWrapper::removeEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_nNotifierClient ) + { + if ( 0 == AccessibleEventNotifier::removeEventListener( m_nNotifierClient, _rxListener ) ) + { + AccessibleEventNotifier::TClientId nId( m_nNotifierClient ); + m_nNotifierClient = 0; + AccessibleEventNotifier::revokeClient( nId ); + } + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleContextWrapper::disposing() throw (RuntimeException) + { + AccessibleEventNotifier::TClientId nClientId( 0 ); + + // --- <mutex lock> ----------------------------------------- + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // prepare notifying our AccessibleListeners + if ( m_nNotifierClient ) + { + nClientId = m_nNotifierClient; + m_nNotifierClient = 0; + } + } + // --- </mutex lock> ----------------------------------------- + + // let the base class do + OAccessibleContextWrapperHelper::dispose(); + + // notify the disposal + if ( nClientId ) + AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OAccessibleContextWrapper::dispose() throw( RuntimeException ) + { + // simply disambiguate + OComponentProxyAggregation_CBase::dispose(); + } + +//............................................................................. +} // namespace accessibility +//............................................................................. + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/accimplaccess.cxx b/comphelper/source/misc/accimplaccess.cxx new file mode 100644 index 000000000000..e06df35cde0c --- /dev/null +++ b/comphelper/source/misc/accimplaccess.cxx @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/accimplaccess.hxx> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <cppuhelper/typeprovider.hxx> + +#include <set> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +#define BITFIELDSIZE ( sizeof( sal_Int64 ) * 8 ) + // maximum number of bits we have in a sal_Int64 + + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::lang::XUnoTunnel; + using ::com::sun::star::accessibility::XAccessible; + using ::com::sun::star::accessibility::XAccessibleContext; + + //===================================================================== + //= OAccImpl_Impl + //===================================================================== + struct OAccImpl_Impl + { + Reference< XAccessible > m_xAccParent; + sal_Int64 m_nForeignControlledStates; + }; + + + //===================================================================== + //= OAccessibleImplementationAccess + //===================================================================== + //--------------------------------------------------------------------- + OAccessibleImplementationAccess::OAccessibleImplementationAccess( ) + :m_pImpl( new OAccImpl_Impl ) + { + } + + //--------------------------------------------------------------------- + OAccessibleImplementationAccess::~OAccessibleImplementationAccess( ) + { + delete m_pImpl; + m_pImpl = NULL; + } + + //--------------------------------------------------------------------- + Reference< XAccessible > OAccessibleImplementationAccess::implGetForeignControlledParent( ) const + { + return m_pImpl->m_xAccParent; + } + + //--------------------------------------------------------------------- + void OAccessibleImplementationAccess::setAccessibleParent( const Reference< XAccessible >& _rxAccParent ) + { + m_pImpl->m_xAccParent = _rxAccParent; + } + + //--------------------------------------------------------------------- + sal_Int64 OAccessibleImplementationAccess::implGetForeignControlledStates( ) const + { + return m_pImpl->m_nForeignControlledStates; + } + + //--------------------------------------------------------------------- + void OAccessibleImplementationAccess::setStateBit( const sal_Int16 _nState, const sal_Bool _bSet ) + { + OSL_ENSURE( _nState >= 0 && static_cast< sal_uInt16 >(_nState) < BITFIELDSIZE, "OAccessibleImplementationAccess::setStateBit: no more bits (shutting down the universe now)!" ); + + sal_uInt64 nBitMask( 1 ); + nBitMask <<= _nState; + if ( _bSet ) + m_pImpl->m_nForeignControlledStates |= nBitMask; + else + m_pImpl->m_nForeignControlledStates &= ~nBitMask; + } + + //--------------------------------------------------------------------- + sal_Bool OAccessibleImplementationAccess::setForeignControlledState( const Reference< XAccessibleContext >& _rxComponent, const sal_Int16 _nState, + const sal_Bool _bSet ) + { + OAccessibleImplementationAccess* pImplementation = getImplementation( _rxComponent ); + + if ( pImplementation ) + pImplementation->setStateBit( _nState, _bSet ); + + return ( NULL != pImplementation ); + } + + namespace { struct lcl_ImplId : public rtl::Static< ::cppu::OImplementationId, lcl_ImplId > {}; } + + //--------------------------------------------------------------------- + const Sequence< sal_Int8 > OAccessibleImplementationAccess::getUnoTunnelImplementationId() + { + ::cppu::OImplementationId &rID = lcl_ImplId::get(); + return rID.getImplementationId(); + } + + //--------------------------------------------------------------------- + sal_Int64 SAL_CALL OAccessibleImplementationAccess::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw (RuntimeException) + { + sal_Int64 nReturn( 0 ); + + if ( ( _rIdentifier.getLength() == 16 ) + && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), _rIdentifier.getConstArray(), 16 ) ) + ) + nReturn = reinterpret_cast< sal_Int64 >( this ); + + return nReturn; + } + + //--------------------------------------------------------------------- + OAccessibleImplementationAccess* OAccessibleImplementationAccess::getImplementation( const Reference< XAccessibleContext >& _rxComponent ) + { + OAccessibleImplementationAccess* pImplementation = NULL; + try + { + Reference< XUnoTunnel > xTunnel( _rxComponent, UNO_QUERY ); + if ( xTunnel.is() ) + { + pImplementation = reinterpret_cast< OAccessibleImplementationAccess* >( + xTunnel->getSomething( getUnoTunnelImplementationId() ) ); + } + } + catch( const Exception& ) + { + OSL_FAIL( "OAccessibleImplementationAccess::setAccessibleParent: caught an exception while retrieving the implementation!" ); + } + return pImplementation; + } + + //--------------------------------------------------------------------- + sal_Bool OAccessibleImplementationAccess::setAccessibleParent( + const Reference< XAccessibleContext >& _rxComponent, const Reference< XAccessible >& _rxNewParent ) + { + OAccessibleImplementationAccess* pImplementation = getImplementation( _rxComponent ); + + if ( pImplementation ) + pImplementation->setAccessibleParent( _rxNewParent ); + + return ( NULL != pImplementation ); + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/anycompare.cxx b/comphelper/source/misc/anycompare.cxx new file mode 100644 index 000000000000..a86174daf08e --- /dev/null +++ b/comphelper/source/misc/anycompare.cxx @@ -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 "precompiled_comphelper.hxx" + +#include "comphelper/anycompare.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +//...................................................................................................................... +namespace comphelper +{ +//...................................................................................................................... + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::uno::TypeClass_CHAR; + using ::com::sun::star::uno::TypeClass_BOOLEAN; + using ::com::sun::star::uno::TypeClass_BYTE; + using ::com::sun::star::uno::TypeClass_SHORT; + using ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT; + using ::com::sun::star::uno::TypeClass_LONG; + using ::com::sun::star::uno::TypeClass_UNSIGNED_LONG; + using ::com::sun::star::uno::TypeClass_HYPER; + using ::com::sun::star::uno::TypeClass_UNSIGNED_HYPER; + using ::com::sun::star::uno::TypeClass_FLOAT; + using ::com::sun::star::uno::TypeClass_DOUBLE; + using ::com::sun::star::uno::TypeClass_STRING; + using ::com::sun::star::uno::TypeClass_TYPE; + using ::com::sun::star::uno::TypeClass_ENUM; + using ::com::sun::star::uno::TypeClass_INTERFACE; + using ::com::sun::star::i18n::XCollator; + /** === end UNO using === **/ + + //------------------------------------------------------------------------------------------------------------------ + ::std::auto_ptr< IKeyPredicateLess > getStandardLessPredicate( Type const & i_type, Reference< XCollator > const & i_collator ) + { + ::std::auto_ptr< IKeyPredicateLess > pComparator; + switch ( i_type.getTypeClass() ) + { + case TypeClass_CHAR: + pComparator.reset( new ScalarPredicateLess< sal_Unicode >() ); + break; + case TypeClass_BOOLEAN: + pComparator.reset( new ScalarPredicateLess< sal_Bool >() ); + break; + case TypeClass_BYTE: + pComparator.reset( new ScalarPredicateLess< sal_Int8 >() ); + break; + case TypeClass_SHORT: + pComparator.reset( new ScalarPredicateLess< sal_Int16 >() ); + break; + case TypeClass_UNSIGNED_SHORT: + pComparator.reset( new ScalarPredicateLess< sal_uInt16 >() ); + break; + case TypeClass_LONG: + pComparator.reset( new ScalarPredicateLess< sal_Int32 >() ); + break; + case TypeClass_UNSIGNED_LONG: + pComparator.reset( new ScalarPredicateLess< sal_uInt32 >() ); + break; + case TypeClass_HYPER: + pComparator.reset( new ScalarPredicateLess< sal_Int64 >() ); + break; + case TypeClass_UNSIGNED_HYPER: + pComparator.reset( new ScalarPredicateLess< sal_uInt64 >() ); + break; + case TypeClass_FLOAT: + pComparator.reset( new ScalarPredicateLess< float >() ); + break; + case TypeClass_DOUBLE: + pComparator.reset( new ScalarPredicateLess< double >() ); + break; + case TypeClass_STRING: + if ( i_collator.is() ) + pComparator.reset( new StringCollationPredicateLess( i_collator ) ); + else + pComparator.reset( new StringPredicateLess() ); + break; + case TypeClass_TYPE: + pComparator.reset( new TypePredicateLess() ); + break; + case TypeClass_ENUM: + pComparator.reset( new EnumPredicateLess( i_type ) ); + break; + case TypeClass_INTERFACE: + pComparator.reset( new InterfacePredicateLess() ); + break; + default: + break; + } + return pComparator; + } + +//...................................................................................................................... +} // namespace comphelper +//...................................................................................................................... diff --git a/comphelper/source/misc/anytostring.cxx b/comphelper/source/misc/anytostring.cxx new file mode 100644 index 000000000000..bdb6d44d6e1f --- /dev/null +++ b/comphelper/source/misc/anytostring.cxx @@ -0,0 +1,337 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/anytostring.hxx" +#include "osl/diagnose.h" +#include "rtl/ustrbuf.hxx" +#include "typelib/typedescription.h" +#include "com/sun/star/lang/XServiceInfo.hpp" + +using namespace ::com::sun::star; + +namespace comphelper { +namespace { + +void appendTypeError( + rtl::OUStringBuffer & buf, typelib_TypeDescriptionReference * typeRef ) +{ + buf.appendAscii( + RTL_CONSTASCII_STRINGPARAM("<cannot get type description of type ") ); + buf.append( rtl::OUString::unacquired( &typeRef->pTypeName ) ); + buf.append( static_cast< sal_Unicode >('>') ); +} + +inline void appendChar( rtl::OUStringBuffer & buf, sal_Unicode c ) +{ + if (c < ' ' || c > '~') { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\X") ); + rtl::OUString const s( + rtl::OUString::valueOf( static_cast< sal_Int32 >(c), 16 ) ); + for ( sal_Int32 f = 4 - s.getLength(); f > 0; --f ) + buf.append( static_cast< sal_Unicode >('0') ); + buf.append( s ); + } + else { + buf.append( c ); + } +} + +//------------------------------------------------------------------------------ +void appendValue( rtl::OUStringBuffer & buf, + void const * val, typelib_TypeDescriptionReference * typeRef, + bool prependType ) +{ + if (typeRef->eTypeClass == typelib_TypeClass_VOID) { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("void") ); + return; + } + OSL_ASSERT( val != 0 ); + + if (prependType && + typeRef->eTypeClass != typelib_TypeClass_STRING && + typeRef->eTypeClass != typelib_TypeClass_CHAR && + typeRef->eTypeClass != typelib_TypeClass_BOOLEAN) + { + buf.append( static_cast< sal_Unicode >('(') ); + buf.append( rtl::OUString::unacquired( &typeRef->pTypeName ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(") ") ); + } + + switch (typeRef->eTypeClass) { + case typelib_TypeClass_INTERFACE: { + buf.append( static_cast<sal_Unicode>('@') ); + buf.append( reinterpret_cast< sal_Int64 >( + *static_cast< void * const * >(val) ), 16 ); + uno::Reference< lang::XServiceInfo > xServiceInfo( + *static_cast< uno::XInterface * const * >(val), + uno::UNO_QUERY ); + if (xServiceInfo.is()) { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( + " (ImplementationName = \"") ); + buf.append( xServiceInfo->getImplementationName() ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") ); + } + break; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); + typelib_TypeDescription * typeDescr = 0; + typelib_typedescriptionreference_getDescription( &typeDescr, typeRef ); + if (typeDescr == 0 || !typelib_typedescription_complete( &typeDescr )) { + appendTypeError( buf, typeRef ); + } + else { + typelib_CompoundTypeDescription * compType = + reinterpret_cast< typelib_CompoundTypeDescription * >( + typeDescr ); + sal_Int32 nDescr = compType->nMembers; + + if (compType->pBaseTypeDescription) { + appendValue( + buf, val, reinterpret_cast< + typelib_TypeDescription * >( + compType->pBaseTypeDescription)->pWeakRef, false ); + if (nDescr > 0) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); + } + + typelib_TypeDescriptionReference ** ppTypeRefs = + compType->ppTypeRefs; + sal_Int32 * memberOffsets = compType->pMemberOffsets; + rtl_uString ** ppMemberNames = compType->ppMemberNames; + + for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos ) + { + buf.append( ppMemberNames[ nPos ] ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") ); + typelib_TypeDescription * memberType = 0; + TYPELIB_DANGER_GET( &memberType, ppTypeRefs[ nPos ] ); + if (memberType == 0) { + appendTypeError( buf, ppTypeRefs[ nPos ] ); + } + else { + appendValue( buf, + static_cast< char const * >( + val ) + memberOffsets[ nPos ], + memberType->pWeakRef, true ); + TYPELIB_DANGER_RELEASE( memberType ); + } + if (nPos < (nDescr - 1)) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); + } + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); + if (typeDescr != 0) + typelib_typedescription_release( typeDescr ); + break; + } + case typelib_TypeClass_SEQUENCE: { + typelib_TypeDescription * typeDescr = 0; + TYPELIB_DANGER_GET( &typeDescr, typeRef ); + if (typeDescr == 0) { + appendTypeError( buf,typeRef ); + } + else { + typelib_TypeDescriptionReference * elementTypeRef = + reinterpret_cast< + typelib_IndirectTypeDescription * >(typeDescr)->pType; + typelib_TypeDescription * elementTypeDescr = 0; + TYPELIB_DANGER_GET( &elementTypeDescr, elementTypeRef ); + if (elementTypeDescr == 0) + { + appendTypeError( buf, elementTypeRef ); + } + else + { + sal_Int32 nElementSize = elementTypeDescr->nSize; + uno_Sequence * seq = + *static_cast< uno_Sequence * const * >(val); + sal_Int32 nElements = seq->nElements; + + if (nElements > 0) + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); + char const * pElements = seq->elements; + for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) + { + appendValue( + buf, pElements + (nElementSize * nPos), + elementTypeDescr->pWeakRef, false ); + if (nPos < (nElements - 1)) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); + } + else + { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") ); + } + TYPELIB_DANGER_RELEASE( elementTypeDescr ); + } + TYPELIB_DANGER_RELEASE( typeDescr ); + } + break; + } + case typelib_TypeClass_ANY: { + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") ); + uno_Any const * pAny = static_cast< uno_Any const * >(val); + appendValue( buf, pAny->pData, pAny->pType, true ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") ); + break; + } + case typelib_TypeClass_TYPE: + buf.append( (*reinterpret_cast< + typelib_TypeDescriptionReference * const * >(val) + )->pTypeName ); + break; + case typelib_TypeClass_STRING: { + buf.append( static_cast< sal_Unicode >('\"') ); + rtl::OUString const & str = rtl::OUString::unacquired( + static_cast< rtl_uString * const * >(val) ); + sal_Int32 len = str.getLength(); + for ( sal_Int32 pos = 0; pos < len; ++pos ) + { + sal_Unicode c = str[ pos ]; + if (c == '\"') + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\"") ); + else if (c == '\\') + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\\") ); + else + appendChar( buf, c ); + } + buf.append( static_cast< sal_Unicode >('\"') ); + break; + } + case typelib_TypeClass_ENUM: { + typelib_TypeDescription * typeDescr = 0; + typelib_typedescriptionreference_getDescription( &typeDescr, typeRef ); + if (typeDescr == 0 || !typelib_typedescription_complete( &typeDescr )) { + appendTypeError( buf, typeRef ); + } + else + { + sal_Int32 * pValues = + reinterpret_cast< typelib_EnumTypeDescription * >( + typeDescr )->pEnumValues; + sal_Int32 nPos = reinterpret_cast< typelib_EnumTypeDescription * >( + typeDescr )->nEnumValues; + while (nPos--) + { + if (pValues[ nPos ] == *static_cast< int const * >(val)) + break; + } + if (nPos >= 0) + { + buf.append( reinterpret_cast< typelib_EnumTypeDescription * >( + typeDescr )->ppEnumNames[ nPos ] ); + } + else + { + buf.appendAscii( + RTL_CONSTASCII_STRINGPARAM("?unknown enum value?") ); + } + } + if (typeDescr != 0) + typelib_typedescription_release( typeDescr ); + break; + } + case typelib_TypeClass_BOOLEAN: + if (*static_cast< sal_Bool const * >(val) != sal_False) + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") ); + else + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") ); + break; + case typelib_TypeClass_CHAR: { + buf.append( static_cast< sal_Unicode >('\'') ); + sal_Unicode c = *static_cast< sal_Unicode const * >(val); + if (c == '\'') + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\'") ); + else if (c == '\\') + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\\") ); + else + appendChar( buf, c ); + buf.append( static_cast< sal_Unicode >('\'') ); + break; + } + case typelib_TypeClass_FLOAT: + buf.append( *static_cast< float const * >(val) ); + break; + case typelib_TypeClass_DOUBLE: + buf.append( *static_cast< double const * >(val) ); + break; + case typelib_TypeClass_BYTE: + buf.append( static_cast< sal_Int32 >( + *static_cast< sal_Int8 const * >(val) ) ); + break; + case typelib_TypeClass_SHORT: + buf.append( static_cast< sal_Int32 >( + *static_cast< sal_Int16 const * >(val) ) ); + break; + case typelib_TypeClass_UNSIGNED_SHORT: + buf.append( static_cast< sal_Int32 >( + *static_cast< sal_uInt16 const * >(val) ) ); + break; + case typelib_TypeClass_LONG: + buf.append( *static_cast< sal_Int32 const * >(val) ); + break; + case typelib_TypeClass_UNSIGNED_LONG: + buf.append( static_cast< sal_Int64 >( + *static_cast< sal_uInt32 const * >(val) ) ); + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + buf.append( *static_cast< sal_Int64 const * >(val) ); + break; +// case typelib_TypeClass_UNION: +// case typelib_TypeClass_ARRAY: +// case typelib_TypeClass_UNKNOWN: +// case typelib_TypeClass_SERVICE: +// case typelib_TypeClass_MODULE: + default: + buf.append( static_cast< sal_Unicode >('?') ); + break; + } +} + +} // anon namespace + +//============================================================================== +rtl::OUString anyToString( uno::Any const & value ) +{ + rtl::OUStringBuffer buf; + appendValue( buf, value.getValue(), value.getValueTypeRef(), true ); + return buf.makeStringAndClear(); +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/asyncnotification.cxx b/comphelper/source/misc/asyncnotification.cxx new file mode 100644 index 000000000000..5697eb62b6b5 --- /dev/null +++ b/comphelper/source/misc/asyncnotification.cxx @@ -0,0 +1,283 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/asyncnotification.hxx> +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include <osl/conditn.hxx> +#include <comphelper/guarding.hxx> + +#include <deque> +#include <set> +#include <functional> +#include <algorithm> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //==================================================================== + //= AnyEvent + //==================================================================== + //-------------------------------------------------------------------- + AnyEvent::AnyEvent() + :m_refCount( 0 ) + { + } + + //-------------------------------------------------------------------- + AnyEvent::~AnyEvent() + { + } + + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL AnyEvent::acquire() + { + return osl_incrementInterlockedCount( &m_refCount ); + } + + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL AnyEvent::release() + { + if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) + { + delete this; + return 0; + } + return m_refCount; + } + + //==================================================================== + //= ProcessableEvent + //==================================================================== + struct ProcessableEvent + { + AnyEventRef aEvent; + ::rtl::Reference< IEventProcessor > xProcessor; + + ProcessableEvent( const AnyEventRef& _rEvent, const ::rtl::Reference< IEventProcessor >& _xProcessor ) + :aEvent( _rEvent ) + ,xProcessor( _xProcessor ) + { + } + + ProcessableEvent( const ProcessableEvent& _rRHS ) + :aEvent( _rRHS.aEvent ) + ,xProcessor( _rRHS.xProcessor ) + { + } + + ProcessableEvent& operator=( const ProcessableEvent& _rRHS ) + { + aEvent = _rRHS.aEvent; + xProcessor = _rRHS.xProcessor; + return *this; + } + }; + + //==================================================================== + typedef ::std::deque< ProcessableEvent > EventQueue; + + //==================================================================== + struct EqualProcessor : public ::std::unary_function< ProcessableEvent, bool > + { + const ::rtl::Reference< IEventProcessor >& rProcessor; + EqualProcessor( const ::rtl::Reference< IEventProcessor >& _rProcessor ) :rProcessor( _rProcessor ) { } + + bool operator()( const ProcessableEvent& _rEvent ) + { + return _rEvent.xProcessor.get() == rProcessor.get(); + } + }; + + //==================================================================== + //= EventNotifierImpl + //==================================================================== + struct EventNotifierImpl + { + ::osl::Mutex aMutex; + oslInterlockedCount m_refCount; + ::osl::Condition aPendingActions; + EventQueue aEvents; + ::std::set< ::rtl::Reference< IEventProcessor > > + m_aDeadProcessors; + + EventNotifierImpl() + :m_refCount( 0 ) + { + } + + private: + EventNotifierImpl( const EventNotifierImpl& ); // never implemented + EventNotifierImpl& operator=( const EventNotifierImpl& ); // never implemented + }; + + //==================================================================== + //= AsyncEventNotifier + //==================================================================== + //-------------------------------------------------------------------- + AsyncEventNotifier::AsyncEventNotifier() + :m_pImpl( new EventNotifierImpl ) + { + } + + //-------------------------------------------------------------------- + AsyncEventNotifier::~AsyncEventNotifier() + { + } + + //-------------------------------------------------------------------- + void AsyncEventNotifier::removeEventsForProcessor( const ::rtl::Reference< IEventProcessor >& _xProcessor ) + { + ::osl::MutexGuard aGuard( m_pImpl->aMutex ); + + // remove all events for this processor + ::std::remove_if( m_pImpl->aEvents.begin(), m_pImpl->aEvents.end(), EqualProcessor( _xProcessor ) ); + + // and just in case that an event for exactly this processor has just been + // popped from the queue, but not yet processed: remember it: + m_pImpl->m_aDeadProcessors.insert( _xProcessor ); + } + + //-------------------------------------------------------------------- + void SAL_CALL AsyncEventNotifier::terminate() + { + ::osl::MutexGuard aGuard( m_pImpl->aMutex ); + + // remember the termination request + AsyncEventNotifier_TBASE::terminate(); + + // awake the thread + m_pImpl->aPendingActions.set(); + } + + //-------------------------------------------------------------------- + void AsyncEventNotifier::addEvent( const AnyEventRef& _rEvent, const ::rtl::Reference< IEventProcessor >& _xProcessor ) + { + ::osl::MutexGuard aGuard( m_pImpl->aMutex ); + + OSL_TRACE( "AsyncEventNotifier(%p): adding %p\n", this, _rEvent.get() ); + // remember this event + m_pImpl->aEvents.push_back( ProcessableEvent( _rEvent, _xProcessor ) ); + + // awake the thread + m_pImpl->aPendingActions.set(); + } + + //-------------------------------------------------------------------- + void AsyncEventNotifier::run() + { + acquire(); + + // keep us alive, in case we're terminated in the mid of the following + ::rtl::Reference< AsyncEventNotifier > xKeepAlive( this ); + + do + { + AnyEventRef aNextEvent; + ::rtl::Reference< IEventProcessor > xNextProcessor; + + ::osl::ClearableMutexGuard aGuard( m_pImpl->aMutex ); + while ( m_pImpl->aEvents.size() > 0 ) + { + ProcessableEvent aEvent( m_pImpl->aEvents.front() ); + aNextEvent = aEvent.aEvent; + xNextProcessor = aEvent.xProcessor; + m_pImpl->aEvents.pop_front(); + + OSL_TRACE( "AsyncEventNotifier(%p): popping %p\n", this, aNextEvent.get() ); + + if ( !aNextEvent.get() ) + continue; + + // process the event, but only if it's processor did not die inbetween + ::std::set< ::rtl::Reference< IEventProcessor > >::iterator deadPos = m_pImpl->m_aDeadProcessors.find( xNextProcessor ); + if ( deadPos != m_pImpl->m_aDeadProcessors.end() ) + { + m_pImpl->m_aDeadProcessors.erase( xNextProcessor ); + xNextProcessor.clear(); + OSL_TRACE( "AsyncEventNotifier(%p): removing %p\n", this, aNextEvent.get() ); + } + + // if there was a termination request (->terminate), respect it + if ( !schedule() ) + return; + + { + ::comphelper::MutexRelease aReleaseOnce( m_pImpl->aMutex ); + if ( xNextProcessor.get() ) + xNextProcessor->processEvent( *aNextEvent.get() ); + } + } + + // if there was a termination request (->terminate), respect it + if ( !schedule() ) + return; + + // wait for new events to process + aGuard.clear(); + m_pImpl->aPendingActions.reset(); + m_pImpl->aPendingActions.wait(); + } + while ( sal_True ); + } + + //-------------------------------------------------------------------- + void SAL_CALL AsyncEventNotifier::onTerminated() + { + AsyncEventNotifier_TBASE::onTerminated(); + // when we were started (->run), we aquired ourself. Release this now + // that we were finally terminated + release(); + } + + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL AsyncEventNotifier::acquire() + { + return osl_incrementInterlockedCount( &m_pImpl->m_refCount ); + } + + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL AsyncEventNotifier::release() + { + if ( 0 == osl_decrementInterlockedCount( &m_pImpl->m_refCount ) ) + { + delete this; + return 0; + } + return m_pImpl->m_refCount; + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/comphelper_module.cxx b/comphelper/source/misc/comphelper_module.cxx new file mode 100644 index 000000000000..b2bdad6665cb --- /dev/null +++ b/comphelper/source/misc/comphelper_module.cxx @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +//........................................................................ +namespace comphelper { namespace module +{ +//........................................................................ + + struct ComphelperModuleCreator + { + ComphelperModule m_aComphelperModule; + }; + namespace + { + class theComphelperModuleInstance : public rtl::Static<ComphelperModuleCreator, theComphelperModuleInstance> {}; + } + + ComphelperModule::ComphelperModule() + :BaseClass() + { + } + + ComphelperModule& ComphelperModule::getInstance() + { + return theComphelperModuleInstance::get().m_aComphelperModule; + } + +//........................................................................ +} } // namespace comphelper::module +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/comphelper_services.cxx b/comphelper/source/misc/comphelper_services.cxx new file mode 100644 index 000000000000..27d06f4df84b --- /dev/null +++ b/comphelper/source/misc/comphelper_services.cxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +#include <rtl/instance.hxx> + +//-------------------------------------------------------------------- +extern void createRegistryInfo_OPropertyBag(); +extern void createRegistryInfo_SequenceOutputStream(); +extern void createRegistryInfo_SequenceInputStream(); +extern void createRegistryInfo_UNOMemoryStream(); +extern void createRegistryInfo_IndexedPropertyValuesContainer(); +extern void createRegistryInfo_NamedPropertyValuesContainer(); +extern void createRegistryInfo_AnyCompareFactory(); +extern void createRegistryInfo_OfficeInstallationDirectories(); +extern void createRegistryInfo_OInstanceLocker(); +extern void createRegistryInfo_Map(); +extern void createRegistryInfo_OSimpleLogRing(); +extern void createRegistryInfo_OOfficeRestartManager(); + +//........................................................................ +namespace comphelper { namespace module +{ +//........................................................................ + + namespace + { + class doInitialize + { + public: + doInitialize() + { + createRegistryInfo_OPropertyBag(); + createRegistryInfo_SequenceOutputStream(); + createRegistryInfo_SequenceInputStream(); + createRegistryInfo_UNOMemoryStream(); + createRegistryInfo_IndexedPropertyValuesContainer(); + createRegistryInfo_NamedPropertyValuesContainer(); + createRegistryInfo_AnyCompareFactory(); + createRegistryInfo_OfficeInstallationDirectories(); + createRegistryInfo_OInstanceLocker(); + createRegistryInfo_Map(); + createRegistryInfo_OSimpleLogRing(); + createRegistryInfo_OOfficeRestartManager(); + } + }; + + struct theInitializer : public rtl::Static< doInitialize, theInitializer > {}; + } + + static void initializeModule() + { + theInitializer::get(); + } + +//........................................................................ +} } // namespace comphelper::module +//........................................................................ + +extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL comphelp_component_getFactory( + const sal_Char* pImplementationName, void* pServiceManager, void* pRegistryKey ) +{ + ::comphelper::module::initializeModule(); + return ::comphelper::module::ComphelperModule::getInstance().getComponentFactory( pImplementationName, pServiceManager, pRegistryKey ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/componentbase.cxx b/comphelper/source/misc/componentbase.cxx new file mode 100644 index 000000000000..d6aa3c5fd50c --- /dev/null +++ b/comphelper/source/misc/componentbase.cxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/componentbase.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/NotInitializedException.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::lang::NotInitializedException; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + /** === end UNO using === **/ + + //==================================================================== + //= ComponentBase + //==================================================================== + //-------------------------------------------------------------------- + void ComponentBase::impl_checkDisposed_throw() const + { + if ( m_rBHelper.bDisposed ) + throw DisposedException( ::rtl::OUString(), getComponent() ); + } + + //-------------------------------------------------------------------- + void ComponentBase::impl_checkInitialized_throw() const + { + if ( !m_bInitialized ) + throw NotInitializedException( ::rtl::OUString(), getComponent() ); + } + + //-------------------------------------------------------------------- + Reference< XInterface > ComponentBase::getComponent() const + { + return NULL; + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/componentcontext.cxx b/comphelper/source/misc/componentcontext.cxx new file mode 100644 index 000000000000..86224687d9f4 --- /dev/null +++ b/comphelper/source/misc/componentcontext.cxx @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/componentcontext.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/NullPointerException.hpp> +#include <com/sun/star/lang/ServiceNotRegisteredException.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +/** === end UNO includes === **/ + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::lang::NullPointerException; + using ::com::sun::star::lang::ServiceNotRegisteredException; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::lang::XMultiServiceFactory; + using ::com::sun::star::beans::XPropertySet; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Sequence; + /** === end UNO using === **/ + + //==================================================================== + //= ComponentContext + //==================================================================== + //-------------------------------------------------------------------- + ComponentContext::ComponentContext( const Reference< XComponentContext >& _rxContext ) + :m_xContext( _rxContext ) + { + if ( m_xContext.is() ) + m_xORB = m_xContext->getServiceManager(); + if ( !m_xORB.is() ) + throw NullPointerException(); + } + + //------------------------------------------------------------------------ + ComponentContext::ComponentContext( const Reference< XMultiServiceFactory >& _rxLegacyFactory ) + { + if ( !_rxLegacyFactory.is() ) + throw NullPointerException(); + + try + { + Reference< XPropertySet > xFactoryProperties( _rxLegacyFactory, UNO_QUERY_THROW ); + m_xContext = Reference< XComponentContext >( + xFactoryProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ), + UNO_QUERY ); + } + catch( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + throw RuntimeException(); + } + + if ( m_xContext.is() ) + m_xORB = m_xContext->getServiceManager(); + if ( !m_xORB.is() ) + throw NullPointerException(); + } + + //------------------------------------------------------------------------ + Any ComponentContext::getContextValueByName( const ::rtl::OUString& _rName ) const + { + Any aReturn; + try + { + aReturn = m_xContext->getValueByName( _rName ); + } + catch( const Exception& ) + { + OSL_FAIL( "ComponentContext::getContextValueByName: caught an exception!" ); + } + return aReturn; + } + + //------------------------------------------------------------------------ + Reference< XInterface > ComponentContext::createComponent( const ::rtl::OUString& _rServiceName ) const + { + Reference< XInterface > xComponent( + m_xORB->createInstanceWithContext( _rServiceName, m_xContext ) + ); + if ( !xComponent.is() ) + throw ServiceNotRegisteredException( _rServiceName, NULL ); + return xComponent; + } + + //------------------------------------------------------------------------ + Reference< XInterface > ComponentContext::createComponentWithArguments( const ::rtl::OUString& _rServiceName, const Sequence< Any >& _rArguments ) const + { + Reference< XInterface > xComponent( + m_xORB->createInstanceWithArgumentsAndContext( _rServiceName, _rArguments, m_xContext ) + ); + if ( !xComponent.is() ) + throw ServiceNotRegisteredException( _rServiceName, NULL ); + return xComponent; + } + + //------------------------------------------------------------------------ + Reference< XInterface > ComponentContext::getSingleton( const ::rtl::OUString& _rInstanceName ) const + { + ::rtl::OUString sKey( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/" ) ) ); + sKey += _rInstanceName; + return Reference< XInterface >( getContextValueByName( sKey ), UNO_QUERY ); + } + + //------------------------------------------------------------------------ + Reference< XMultiServiceFactory > ComponentContext::getLegacyServiceFactory() const + { + return Reference< XMultiServiceFactory >( m_xORB, UNO_QUERY_THROW ); + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/componentmodule.cxx b/comphelper/source/misc/componentmodule.cxx new file mode 100644 index 000000000000..c42308c71508 --- /dev/null +++ b/comphelper/source/misc/componentmodule.cxx @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/componentmodule.hxx> + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ +#include <comphelper/sequence.hxx> +#include <osl/diagnose.h> + +#include <vector> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + using namespace ::cppu; + /** === being UNO using === **/ + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::lang::XMultiServiceFactory; + using ::com::sun::star::registry::XRegistryKey; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::XInterface; + /** === end UNO using === **/ + + typedef ::std::vector< ComponentDescription > ComponentDescriptions; + + //========================================================================= + //= OModuleImpl + //========================================================================= + /** implementation for <type>OModule</type>. not threadsafe, has to be guarded by it's owner + */ + class OModuleImpl + { + public: + ComponentDescriptions m_aRegisteredComponents; + + OModuleImpl(); + ~OModuleImpl(); + }; + + //------------------------------------------------------------------------- + OModuleImpl::OModuleImpl() + { + } + + //------------------------------------------------------------------------- + OModuleImpl::~OModuleImpl() + { + } + + //========================================================================= + //= OModule + //========================================================================= + //------------------------------------------------------------------------- + OModule::OModule() + :m_nClients( 0 ) + ,m_pImpl( new OModuleImpl ) + { + } + + OModule::~OModule() {} + + //------------------------------------------------------------------------- + void OModule::registerClient( OModule::ClientAccess ) + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( 1 == osl_incrementInterlockedCount( &m_nClients ) ) + onFirstClient(); + } + + //------------------------------------------------------------------------- + void OModule::revokeClient( OModule::ClientAccess ) + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( 0 == osl_decrementInterlockedCount( &m_nClients ) ) + onLastClient(); + } + + //-------------------------------------------------------------------------- + void OModule::onFirstClient() + { + } + + //-------------------------------------------------------------------------- + void OModule::onLastClient() + { + } + + //-------------------------------------------------------------------------- + void OModule::registerImplementation( const ComponentDescription& _rComp ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_pImpl ) + throw RuntimeException(); + + m_pImpl->m_aRegisteredComponents.push_back( _rComp ); + } + + //-------------------------------------------------------------------------- + void OModule::registerImplementation( const ::rtl::OUString& _rImplementationName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rServiceNames, + ::cppu::ComponentFactoryFunc _pCreateFunction, FactoryInstantiation _pFactoryFunction ) + { + ComponentDescription aComponent( _rImplementationName, _rServiceNames, ::rtl::OUString(), _pCreateFunction, _pFactoryFunction ); + registerImplementation( aComponent ); + } + + //-------------------------------------------------------------------------- + void* OModule::getComponentFactory( const sal_Char* _pImplementationName, void* _pServiceManager, void* /*_pRegistryKey*/ ) + { + Reference< XInterface > xFactory( getComponentFactory( + ::rtl::OUString::createFromAscii( _pImplementationName ), + Reference< XMultiServiceFactory >( static_cast< XMultiServiceFactory* >( _pServiceManager ) ) + ) ); + return xFactory.get(); + } + + //-------------------------------------------------------------------------- + Reference< XInterface > OModule::getComponentFactory( const ::rtl::OUString& _rImplementationName, + const Reference< XMultiServiceFactory >& /* _rxServiceManager */ ) + { + Reference< XInterface > xReturn; + + for ( ComponentDescriptions::const_iterator component = m_pImpl->m_aRegisteredComponents.begin(); + component != m_pImpl->m_aRegisteredComponents.end(); + ++component + ) + { + if ( component->sImplementationName == _rImplementationName ) + { + xReturn = component->pFactoryCreationFunc( + component->pComponentCreationFunc, + component->sImplementationName, + component->aSupportedServices, + NULL + ); + if ( xReturn.is() ) + { + xReturn->acquire(); + return xReturn.get(); + } + } + } + + return NULL; + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/configurationhelper.cxx b/comphelper/source/misc/configurationhelper.cxx new file mode 100644 index 000000000000..1016c88b341c --- /dev/null +++ b/comphelper/source/misc/configurationhelper.cxx @@ -0,0 +1,210 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +//_______________________________________________ +// includes +#include <comphelper/configurationhelper.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +//_______________________________________________ +// namespace + +namespace comphelper{ + +namespace css = ::com::sun::star; + +//_______________________________________________ +// definitions + +//----------------------------------------------- +css::uno::Reference< css::uno::XInterface > ConfigurationHelper::openConfig(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR , + const ::rtl::OUString& sPackage, + sal_Int32 eMode ) +{ + css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider( + xSMGR->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider"))), css::uno::UNO_QUERY_THROW); + + ::comphelper::SequenceAsVector< css::uno::Any > lParams; + css::beans::PropertyValue aParam ; + + // set root path + aParam.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")); + aParam.Value <<= sPackage; + lParams.push_back(css::uno::makeAny(aParam)); + + // enable all locales mode + if ((eMode & ConfigurationHelper::E_ALL_LOCALES)==ConfigurationHelper::E_ALL_LOCALES) + { + aParam.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("locale")); + aParam.Value <<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")); + lParams.push_back(css::uno::makeAny(aParam)); + } + + // enable lazy writing + sal_Bool bLazy = ((eMode & ConfigurationHelper::E_LAZY_WRITE)==ConfigurationHelper::E_LAZY_WRITE); + aParam.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("lazywrite")); + aParam.Value = css::uno::makeAny(bLazy); + lParams.push_back(css::uno::makeAny(aParam)); + + // open it + css::uno::Reference< css::uno::XInterface > xCFG; + + sal_Bool bReadOnly = ((eMode & ConfigurationHelper::E_READONLY)==ConfigurationHelper::E_READONLY); + if (bReadOnly) + xCFG = xConfigProvider->createInstanceWithArguments( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")), + lParams.getAsConstList()); + else + xCFG = xConfigProvider->createInstanceWithArguments( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationUpdateAccess")), + lParams.getAsConstList()); + + return xCFG; +} + +//----------------------------------------------- +css::uno::Any ConfigurationHelper::readRelativeKey(const css::uno::Reference< css::uno::XInterface > xCFG , + const ::rtl::OUString& sRelPath, + const ::rtl::OUString& sKey ) +{ + css::uno::Reference< css::container::XHierarchicalNameAccess > xAccess(xCFG, css::uno::UNO_QUERY_THROW); + + css::uno::Reference< css::beans::XPropertySet > xProps; + xAccess->getByHierarchicalName(sRelPath) >>= xProps; + if (!xProps.is()) + { + ::rtl::OUStringBuffer sMsg(256); + sMsg.appendAscii("The requested path \""); + sMsg.append (sRelPath ); + sMsg.appendAscii("\" does not exists." ); + + throw css::container::NoSuchElementException( + sMsg.makeStringAndClear(), + css::uno::Reference< css::uno::XInterface >()); + } + return xProps->getPropertyValue(sKey); +} + +//----------------------------------------------- +void ConfigurationHelper::writeRelativeKey(const css::uno::Reference< css::uno::XInterface > xCFG , + const ::rtl::OUString& sRelPath, + const ::rtl::OUString& sKey , + const css::uno::Any& aValue ) +{ + css::uno::Reference< css::container::XHierarchicalNameAccess > xAccess(xCFG, css::uno::UNO_QUERY_THROW); + + css::uno::Reference< css::beans::XPropertySet > xProps; + xAccess->getByHierarchicalName(sRelPath) >>= xProps; + if (!xProps.is()) + { + ::rtl::OUStringBuffer sMsg(256); + sMsg.appendAscii("The requested path \""); + sMsg.append (sRelPath ); + sMsg.appendAscii("\" does not exists." ); + + throw css::container::NoSuchElementException( + sMsg.makeStringAndClear(), + css::uno::Reference< css::uno::XInterface >()); + } + xProps->setPropertyValue(sKey, aValue); +} + +//----------------------------------------------- +css::uno::Reference< css::uno::XInterface > ConfigurationHelper::makeSureSetNodeExists(const css::uno::Reference< css::uno::XInterface > xCFG , + const ::rtl::OUString& sRelPathToSet, + const ::rtl::OUString& sSetNode ) +{ + css::uno::Reference< css::container::XHierarchicalNameAccess > xAccess(xCFG, css::uno::UNO_QUERY_THROW); + css::uno::Reference< css::container::XNameAccess > xSet; + xAccess->getByHierarchicalName(sRelPathToSet) >>= xSet; + if (!xSet.is()) + { + ::rtl::OUStringBuffer sMsg(256); + sMsg.appendAscii("The requested path \""); + sMsg.append (sRelPathToSet ); + sMsg.appendAscii("\" does not exists." ); + + throw css::container::NoSuchElementException( + sMsg.makeStringAndClear(), + css::uno::Reference< css::uno::XInterface >()); + } + + css::uno::Reference< css::uno::XInterface > xNode; + if (xSet->hasByName(sSetNode)) + xSet->getByName(sSetNode) >>= xNode; + else + { + css::uno::Reference< css::lang::XSingleServiceFactory > xNodeFactory(xSet, css::uno::UNO_QUERY_THROW); + xNode = xNodeFactory->createInstance(); + css::uno::Reference< css::container::XNameContainer > xSetReplace(xSet, css::uno::UNO_QUERY_THROW); + xSetReplace->insertByName(sSetNode, css::uno::makeAny(xNode)); + } + + return xNode; +} + +//----------------------------------------------- +css::uno::Any ConfigurationHelper::readDirectKey(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR , + const ::rtl::OUString& sPackage, + const ::rtl::OUString& sRelPath, + const ::rtl::OUString& sKey , + sal_Int32 eMode ) +{ + css::uno::Reference< css::uno::XInterface > xCFG = ConfigurationHelper::openConfig(xSMGR, sPackage, eMode); + return ConfigurationHelper::readRelativeKey(xCFG, sRelPath, sKey); +} + +//----------------------------------------------- +void ConfigurationHelper::writeDirectKey(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR , + const ::rtl::OUString& sPackage, + const ::rtl::OUString& sRelPath, + const ::rtl::OUString& sKey , + const css::uno::Any& aValue , + sal_Int32 eMode ) +{ + css::uno::Reference< css::uno::XInterface > xCFG = ConfigurationHelper::openConfig(xSMGR, sPackage, eMode); + ConfigurationHelper::writeRelativeKey(xCFG, sRelPath, sKey, aValue); + ConfigurationHelper::flush(xCFG); +} + +//----------------------------------------------- +void ConfigurationHelper::flush(const css::uno::Reference< css::uno::XInterface >& xCFG) +{ + css::uno::Reference< css::util::XChangesBatch > xBatch(xCFG, css::uno::UNO_QUERY_THROW); + xBatch->commitChanges(); +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/docpasswordhelper.cxx b/comphelper/source/misc/docpasswordhelper.cxx new file mode 100644 index 000000000000..36cb3cd15aff --- /dev/null +++ b/comphelper/source/misc/docpasswordhelper.cxx @@ -0,0 +1,474 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/*********************************************************************** + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/docpasswordhelper.hxx" +#include <com/sun/star/task/XInteractionHandler.hpp> +#include "comphelper/mediadescriptor.hxx" + +#include <osl/time.h> +#include <rtl/digest.h> +#include <rtl/random.h> + +using ::rtl::OUString; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::task::PasswordRequestMode; +using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER; +using ::com::sun::star::task::PasswordRequestMode_PASSWORD_REENTER; +using ::com::sun::star::task::XInteractionHandler; +using ::com::sun::star::task::XInteractionRequest; + +using namespace ::com::sun::star; + +namespace comphelper { + +// ============================================================================ + +static uno::Sequence< sal_Int8 > GeneratePBKDF2Hash( const ::rtl::OUString& aPassword, const uno::Sequence< sal_Int8 >& aSalt, sal_Int32 nCount, sal_Int32 nHashLength ) +{ + uno::Sequence< sal_Int8 > aResult; + + if ( aPassword.getLength() && aSalt.getLength() && nCount && nHashLength ) + { + ::rtl::OString aBytePass = ::rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_UTF8 ); + aResult.realloc( 16 ); + rtl_digest_PBKDF2( reinterpret_cast < sal_uInt8 * > ( aResult.getArray() ), + aResult.getLength(), + reinterpret_cast < const sal_uInt8 * > ( aBytePass.getStr() ), + aBytePass.getLength(), + reinterpret_cast < const sal_uInt8 * > ( aSalt.getConstArray() ), + aSalt.getLength(), + nCount ); + } + + return aResult; +} + +// ============================================================================ + +IDocPasswordVerifier::~IDocPasswordVerifier() +{ +} + +// ============================================================================ +uno::Sequence< beans::PropertyValue > DocPasswordHelper::GenerateNewModifyPasswordInfo( const ::rtl::OUString& aPassword ) +{ + uno::Sequence< beans::PropertyValue > aResult; + + uno::Sequence< sal_Int8 > aSalt = GenerateRandomByteSequence( 16 ); + sal_Int32 nCount = 1024; + + uno::Sequence< sal_Int8 > aNewHash = GeneratePBKDF2Hash( aPassword, aSalt, nCount, 16 ); + if ( aNewHash.getLength() ) + { + aResult.realloc( 4 ); + aResult[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "algorithm-name" ) ); + aResult[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PBKDF2" ) ); + aResult[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "salt" ) ); + aResult[1].Value <<= aSalt; + aResult[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "iteration-count" ) ); + aResult[2].Value <<= nCount; + aResult[3].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hash" ) ); + aResult[3].Value <<= aNewHash; + } + + return aResult; +} + +// ============================================================================ +sal_Bool DocPasswordHelper::IsModifyPasswordCorrect( const ::rtl::OUString& aPassword, const uno::Sequence< beans::PropertyValue >& aInfo ) +{ + sal_Bool bResult = sal_False; + if ( aPassword.getLength() && aInfo.getLength() ) + { + ::rtl::OUString sAlgorithm; + uno::Sequence< sal_Int8 > aSalt; + uno::Sequence< sal_Int8 > aHash; + sal_Int32 nCount = 0; + + for ( sal_Int32 nInd = 0; nInd < aInfo.getLength(); nInd++ ) + { + if ( aInfo[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "algorithm-name" ) ) ) ) + aInfo[nInd].Value >>= sAlgorithm; + else if ( aInfo[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "salt" ) ) ) ) + aInfo[nInd].Value >>= aSalt; + else if ( aInfo[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "iteration-count" ) ) ) ) + aInfo[nInd].Value >>= nCount; + else if ( aInfo[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hash" ) ) ) ) + aInfo[nInd].Value >>= aHash; + } + + if ( sAlgorithm.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PBKDF2" ) ) ) + && aSalt.getLength() && nCount > 0 && aHash.getLength() ) + { + uno::Sequence< sal_Int8 > aNewHash = GeneratePBKDF2Hash( aPassword, aSalt, nCount, aHash.getLength() ); + for ( sal_Int32 nInd = 0; nInd < aNewHash.getLength() && nInd < aHash.getLength() && aNewHash[nInd] == aHash[nInd]; nInd ++ ) + { + if ( nInd == aNewHash.getLength() - 1 && nInd == aHash.getLength() - 1 ) + bResult = sal_True; + } + } + } + + return bResult; +} + +// ============================================================================ +sal_uInt32 DocPasswordHelper::GetWordHashAsUINT32( + const ::rtl::OUString& aUString ) +{ + static sal_uInt16 pInitialCode[] = { + 0xE1F0, // 1 + 0x1D0F, // 2 + 0xCC9C, // 3 + 0x84C0, // 4 + 0x110C, // 5 + 0x0E10, // 6 + 0xF1CE, // 7 + 0x313E, // 8 + 0x1872, // 9 + 0xE139, // 10 + 0xD40F, // 11 + 0x84F9, // 12 + 0x280C, // 13 + 0xA96A, // 14 + 0x4EC3 // 15 + }; + + static sal_uInt16 pEncryptionMatrix[15][7] = { + { 0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09}, // last-14 + { 0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF}, // last-13 + { 0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0}, // last-12 + { 0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40}, // last-11 + { 0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5}, // last-10 + { 0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A}, // last-9 + { 0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9}, // last-8 + { 0x47D3, 0x8FA6, 0x8FA6, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0}, // last-7 + { 0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC}, // last-6 + { 0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10}, // last-5 + { 0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168}, // last-4 + { 0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C}, // last-3 + { 0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD}, // last-2 + { 0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC}, // last-1 + { 0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4} // last + }; + + sal_uInt32 nResult = 0; + sal_uInt32 nLen = aUString.getLength(); + + if ( nLen ) + { + if ( nLen > 15 ) + nLen = 15; + + sal_uInt16 nHighResult = pInitialCode[nLen - 1]; + sal_uInt16 nLowResult = 0; + + const sal_Unicode* pStr = aUString.getStr(); + for ( sal_uInt32 nInd = 0; nInd < nLen; nInd++ ) + { + // NO Encoding during conversion! + // The specification says that the low byte should be used in case it is not NULL + char nHighChar = (char)( pStr[nInd] >> 8 ); + char nLowChar = (char)( pStr[nInd] & 0xFF ); + char nChar = nLowChar ? nLowChar : nHighChar; + + for ( int nMatrixInd = 0; nMatrixInd < 7; ++nMatrixInd ) + { + if ( ( nChar & ( 1 << nMatrixInd ) ) != 0 ) + nHighResult = nHighResult ^ pEncryptionMatrix[15 - nLen + nInd][nMatrixInd]; + } + + nLowResult = ( ( ( nLowResult >> 14 ) & 0x0001 ) | ( ( nLowResult << 1 ) & 0x7FFF ) ) ^ nChar; + } + + nLowResult = (sal_uInt16)( ( ( ( nLowResult >> 14 ) & 0x001 ) | ( ( nLowResult << 1 ) & 0x7FF ) ) ^ nLen ^ 0xCE4B ); + + nResult = ( nHighResult << 16 ) | nLowResult; + } + + return nResult; +} + +// ============================================================================ +Sequence< sal_Int8 > DocPasswordHelper::GetWordHashAsSequence( + const ::rtl::OUString& aUString ) +{ + sal_uInt32 nHash = GetWordHashAsUINT32( aUString ); + Sequence< sal_Int8 > aResult( 4 ); + aResult[0] = ( nHash >> 24 ); + aResult[1] = ( ( nHash >> 16 ) & 0xFF ); + aResult[2] = ( ( nHash >> 8 ) & 0xFF ); + aResult[3] = ( nHash & 0xFF ); + + return aResult; +} + +// ============================================================================ +sal_uInt16 DocPasswordHelper::GetXLHashAsUINT16( + const ::rtl::OUString& aUString, + rtl_TextEncoding nEnc ) +{ + sal_uInt16 nResult = 0; + + ::rtl::OString aString = ::rtl::OUStringToOString( aUString, nEnc ); + + if ( aString.getLength() && aString.getLength() <= SAL_MAX_UINT16 ) + { + for ( sal_Int32 nInd = aString.getLength() - 1; nInd >= 0; nInd-- ) + { + nResult = ( ( nResult >> 14 ) & 0x01 ) | ( ( nResult << 1 ) & 0x7FFF ); + nResult ^= aString.getStr()[nInd]; + } + + nResult = ( ( nResult >> 14 ) & 0x01 ) | ( ( nResult << 1 ) & 0x7FFF ); + nResult ^= ( 0x8000 | ( 'N' << 8 ) | 'K' ); + nResult ^= aString.getLength(); + } + + return nResult; +} + +// ============================================================================ +Sequence< sal_Int8 > DocPasswordHelper::GetXLHashAsSequence( + const ::rtl::OUString& aUString, + rtl_TextEncoding nEnc ) +{ + sal_uInt16 nHash = GetXLHashAsUINT16( aUString, nEnc ); + Sequence< sal_Int8 > aResult( 2 ); + aResult[0] = ( nHash >> 8 ); + aResult[1] = ( nHash & 0xFF ); + + return aResult; +} + +// ============================================================================ +/*static*/ uno::Sequence< sal_Int8 > DocPasswordHelper::GenerateRandomByteSequence( sal_Int32 nLength ) +{ + uno::Sequence< sal_Int8 > aResult( nLength ); + + TimeValue aTime; + osl_getSystemTime( &aTime ); + rtlRandomPool aRandomPool = rtl_random_createPool (); + rtl_random_addBytes ( aRandomPool, &aTime, 8 ); + rtl_random_getBytes ( aRandomPool, aResult.getArray(), nLength ); + rtl_random_destroyPool ( aRandomPool ); + + return aResult; +} + + +// ============================================================================ +/*static*/ uno::Sequence< sal_Int8 > DocPasswordHelper::GenerateStd97Key( const ::rtl::OUString& aPassword, const uno::Sequence< sal_Int8 >& aDocId ) +{ + uno::Sequence< sal_Int8 > aResultKey; + if ( aPassword.getLength() && aDocId.getLength() == 16 ) + { + sal_uInt16 pPassData[16]; + rtl_zeroMemory( pPassData, sizeof(pPassData) ); + + sal_Int32 nPassLen = ::std::min< sal_Int32 >( aPassword.getLength(), 15 ); + rtl_copyMemory( pPassData, aPassword.getStr(), nPassLen * sizeof(pPassData[0]) ); + + aResultKey = GenerateStd97Key( pPassData, aDocId ); + } + + return aResultKey; +} + +// ============================================================================ +/*static*/ uno::Sequence< sal_Int8 > DocPasswordHelper::GenerateStd97Key( const sal_uInt16 pPassData[16], const uno::Sequence< sal_Int8 >& aDocId ) +{ + uno::Sequence< sal_Int8 > aResultKey; + if ( pPassData[0] && aDocId.getLength() == 16 ) + { + sal_uInt8 pKeyData[64]; + rtl_zeroMemory( pKeyData, sizeof(pKeyData) ); + + sal_Int32 nInd = 0; + + // Fill PassData into KeyData. + for ( nInd = 0; nInd < 16 && pPassData[nInd]; nInd++) + { + pKeyData[2*nInd] = sal::static_int_cast< sal_uInt8 >( (pPassData[nInd] >> 0) & 0xff ); + pKeyData[2*nInd + 1] = sal::static_int_cast< sal_uInt8 >( (pPassData[nInd] >> 8) & 0xff ); + } + + pKeyData[2*nInd] = 0x80; + pKeyData[56] = sal::static_int_cast< sal_uInt8 >( nInd << 4 ); + + // Fill raw digest of KeyData into KeyData. + rtlDigest hDigest = rtl_digest_create ( rtl_Digest_AlgorithmMD5 ); + (void)rtl_digest_updateMD5 ( + hDigest, pKeyData, sizeof(pKeyData)); + (void)rtl_digest_rawMD5 ( + hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5); + + // Update digest with KeyData and Unique. + for ( nInd = 0; nInd < 16; nInd++ ) + { + rtl_digest_updateMD5( hDigest, pKeyData, 5 ); + rtl_digest_updateMD5( hDigest, (const sal_uInt8*)aDocId.getConstArray(), aDocId.getLength() ); + } + + // Update digest with padding. + pKeyData[16] = 0x80; + rtl_zeroMemory( pKeyData + 17, sizeof(pKeyData) - 17 ); + pKeyData[56] = 0x80; + pKeyData[57] = 0x0a; + + rtl_digest_updateMD5( hDigest, &(pKeyData[16]), sizeof(pKeyData) - 16 ); + + // Fill raw digest of above updates + aResultKey.realloc( RTL_DIGEST_LENGTH_MD5 ); + rtl_digest_rawMD5 ( hDigest, (sal_uInt8*)aResultKey.getArray(), aResultKey.getLength() ); + + // Erase KeyData array and leave. + rtl_zeroMemory( pKeyData, sizeof(pKeyData) ); + } + + return aResultKey; +} + +// ============================================================================ + +/*static*/ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > DocPasswordHelper::requestAndVerifyDocPassword( + IDocPasswordVerifier& rVerifier, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rMediaEncData, + const OUString& rMediaPassword, + const Reference< XInteractionHandler >& rxInteractHandler, + const OUString& rDocumentName, + DocPasswordRequestType eRequestType, + const ::std::vector< OUString >* pDefaultPasswords, + bool* pbIsDefaultPassword ) +{ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > aEncData; + DocPasswordVerifierResult eResult = DocPasswordVerifierResult_WRONG_PASSWORD; + + // first, try provided default passwords + if( pbIsDefaultPassword ) + *pbIsDefaultPassword = false; + if( pDefaultPasswords ) + { + for( ::std::vector< OUString >::const_iterator aIt = pDefaultPasswords->begin(), aEnd = pDefaultPasswords->end(); (eResult == DocPasswordVerifierResult_WRONG_PASSWORD) && (aIt != aEnd); ++aIt ) + { + OSL_ENSURE( aIt->getLength() > 0, "DocPasswordHelper::requestAndVerifyDocPassword - unexpected empty default password" ); + if( aIt->getLength() > 0 ) + { + eResult = rVerifier.verifyPassword( *aIt, aEncData ); + if( pbIsDefaultPassword ) + *pbIsDefaultPassword = eResult == DocPasswordVerifierResult_OK; + } + } + } + + // try media encryption data (skip, if result is OK or ABORT) + if( eResult == DocPasswordVerifierResult_WRONG_PASSWORD ) + { + if( rMediaEncData.getLength() > 0 ) + { + eResult = rVerifier.verifyEncryptionData( rMediaEncData ); + if( eResult == DocPasswordVerifierResult_OK ) + aEncData = rMediaEncData; + } + } + + // try media password (skip, if result is OK or ABORT) + if( eResult == DocPasswordVerifierResult_WRONG_PASSWORD ) + { + if( rMediaPassword.getLength() > 0 ) + eResult = rVerifier.verifyPassword( rMediaPassword, aEncData ); + } + + // request a password (skip, if result is OK or ABORT) + if( (eResult == DocPasswordVerifierResult_WRONG_PASSWORD) && rxInteractHandler.is() ) try + { + PasswordRequestMode eRequestMode = PasswordRequestMode_PASSWORD_ENTER; + while( eResult == DocPasswordVerifierResult_WRONG_PASSWORD ) + { + DocPasswordRequest* pRequest = new DocPasswordRequest( eRequestType, eRequestMode, rDocumentName ); + Reference< XInteractionRequest > xRequest( pRequest ); + rxInteractHandler->handle( xRequest ); + if( pRequest->isPassword() ) + { + if( pRequest->getPassword().getLength() > 0 ) + eResult = rVerifier.verifyPassword( pRequest->getPassword(), aEncData ); + } + else + { + eResult = DocPasswordVerifierResult_ABORT; + } + eRequestMode = PasswordRequestMode_PASSWORD_REENTER; + } + } + catch( Exception& ) + { + } + + return (eResult == DocPasswordVerifierResult_OK) ? aEncData : uno::Sequence< beans::NamedValue >(); +} + +/*static*/ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > DocPasswordHelper::requestAndVerifyDocPassword( + IDocPasswordVerifier& rVerifier, + MediaDescriptor& rMediaDesc, + DocPasswordRequestType eRequestType, + const ::std::vector< OUString >* pDefaultPasswords ) +{ + uno::Sequence< beans::NamedValue > aMediaEncData = rMediaDesc.getUnpackedValueOrDefault( + MediaDescriptor::PROP_ENCRYPTIONDATA(), uno::Sequence< beans::NamedValue >() ); + OUString aMediaPassword = rMediaDesc.getUnpackedValueOrDefault( + MediaDescriptor::PROP_PASSWORD(), OUString() ); + Reference< XInteractionHandler > xInteractHandler = rMediaDesc.getUnpackedValueOrDefault( + MediaDescriptor::PROP_INTERACTIONHANDLER(), Reference< XInteractionHandler >() ); + OUString aDocumentName = rMediaDesc.getUnpackedValueOrDefault( + MediaDescriptor::PROP_URL(), OUString() ); + + bool bIsDefaultPassword = false; + uno::Sequence< beans::NamedValue > aEncryptionData = requestAndVerifyDocPassword( + rVerifier, aMediaEncData, aMediaPassword, xInteractHandler, aDocumentName, eRequestType, pDefaultPasswords, &bIsDefaultPassword ); + + rMediaDesc.erase( MediaDescriptor::PROP_PASSWORD() ); + rMediaDesc.erase( MediaDescriptor::PROP_ENCRYPTIONDATA() ); + + // insert valid password into media descriptor (but not a default password) + if( (aEncryptionData.getLength() > 0) && !bIsDefaultPassword ) + rMediaDesc[ MediaDescriptor::PROP_ENCRYPTIONDATA() ] <<= aEncryptionData; + + return aEncryptionData; +} + +// ============================================================================ + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/docpasswordrequest.cxx b/comphelper/source/misc/docpasswordrequest.cxx new file mode 100644 index 000000000000..ec9cf0ca21ed --- /dev/null +++ b/comphelper/source/misc/docpasswordrequest.cxx @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/docpasswordrequest.hxx" +#include <com/sun/star/task/DocumentMSPasswordRequest2.hpp> +#include <com/sun/star/task/DocumentPasswordRequest2.hpp> +#include <com/sun/star/task/PasswordRequest.hpp> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionPassword2.hpp> + +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Type; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::task::InteractionClassification_QUERY; +using ::com::sun::star::task::DocumentMSPasswordRequest2; +using ::com::sun::star::task::DocumentPasswordRequest2; +using ::com::sun::star::task::PasswordRequest; +using ::com::sun::star::task::PasswordRequestMode; +using ::com::sun::star::task::XInteractionAbort; +using ::com::sun::star::task::XInteractionContinuation; +using ::com::sun::star::task::XInteractionPassword2; +using ::com::sun::star::task::XInteractionRequest; + +namespace comphelper { + +// ============================================================================ + +class AbortContinuation : public ::cppu::WeakImplHelper1< XInteractionAbort > +{ +public: + inline explicit AbortContinuation() : mbSelected( false ) {} + + inline sal_Bool isSelected() const { return mbSelected; } + inline void reset() { mbSelected = false; } + + virtual void SAL_CALL select() throw( RuntimeException ) { mbSelected = true; } + +private: + sal_Bool mbSelected; +}; + +// ============================================================================ + +class PasswordContinuation : public ::cppu::WeakImplHelper1< XInteractionPassword2 > +{ +public: + inline explicit PasswordContinuation() : mbReadOnly( sal_False ), mbSelected( sal_False ) {} + + inline sal_Bool isSelected() const { return mbSelected; } + inline void reset() { mbSelected = sal_False; } + + virtual void SAL_CALL select() throw( RuntimeException ) { mbSelected = sal_True; } + + virtual void SAL_CALL setPassword( const OUString& rPass ) throw( RuntimeException ) { maPassword = rPass; } + virtual OUString SAL_CALL getPassword() throw( RuntimeException ) { return maPassword; } + + virtual void SAL_CALL setPasswordToModify( const OUString& rPass ) throw( RuntimeException ) { maModifyPassword = rPass; } + virtual OUString SAL_CALL getPasswordToModify() throw( RuntimeException ) { return maModifyPassword; } + + virtual void SAL_CALL setRecommendReadOnly( sal_Bool bReadOnly ) throw( RuntimeException ) { mbReadOnly = bReadOnly; } + virtual sal_Bool SAL_CALL getRecommendReadOnly() throw( RuntimeException ) { return mbReadOnly; } + +private: + OUString maPassword; + OUString maModifyPassword; + sal_Bool mbReadOnly; + sal_Bool mbSelected; +}; + +// ============================================================================ + +SimplePasswordRequest::SimplePasswordRequest( PasswordRequestMode eMode ) +: mpAbort( NULL ) +, mpPassword( NULL ) +{ + PasswordRequest aRequest( OUString(), Reference< XInterface >(), + InteractionClassification_QUERY, eMode ); + maRequest <<= aRequest; + + maContinuations.realloc( 2 ); + maContinuations[ 0 ].set( mpAbort = new AbortContinuation ); + maContinuations[ 1 ].set( mpPassword = new PasswordContinuation ); +} + +SimplePasswordRequest::~SimplePasswordRequest() +{ +} + +/*uno::*/Any SAL_CALL SimplePasswordRequest::queryInterface( const /*uno::*/Type& rType ) throw (RuntimeException) +{ + return ::cppu::queryInterface ( rType, + // OWeakObject interfaces + dynamic_cast< XInterface* > ( (XInteractionRequest *) this ), + static_cast< XWeak* > ( this ), + // my own interfaces + static_cast< XInteractionRequest* > ( this ) ); +} + +void SAL_CALL SimplePasswordRequest::acquire( ) throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL SimplePasswordRequest::release( ) throw () +{ + OWeakObject::release(); +} + +sal_Bool SimplePasswordRequest::isAbort() const +{ + return mpAbort->isSelected(); +} + +sal_Bool SimplePasswordRequest::isPassword() const +{ + return mpPassword->isSelected(); +} + +OUString SimplePasswordRequest::getPassword() const +{ + return mpPassword->getPassword(); +} + +Any SAL_CALL SimplePasswordRequest::getRequest() throw( RuntimeException ) +{ + return maRequest; +} + +Sequence< Reference< XInteractionContinuation > > SAL_CALL SimplePasswordRequest::getContinuations() throw( RuntimeException ) +{ + return maContinuations; +} + +// ============================================================================ + +DocPasswordRequest::DocPasswordRequest( DocPasswordRequestType eType, + PasswordRequestMode eMode, const OUString& rDocumentName, sal_Bool bPasswordToModify ) +: mpAbort( NULL ) +, mpPassword( NULL ) +{ + switch( eType ) + { + case DocPasswordRequestType_STANDARD: + { + DocumentPasswordRequest2 aRequest( OUString(), Reference< XInterface >(), + InteractionClassification_QUERY, eMode, rDocumentName, bPasswordToModify ); + maRequest <<= aRequest; + } + break; + case DocPasswordRequestType_MS: + { + DocumentMSPasswordRequest2 aRequest( OUString(), Reference< XInterface >(), + InteractionClassification_QUERY, eMode, rDocumentName, bPasswordToModify ); + maRequest <<= aRequest; + } + break; + /* no 'default', so compilers will complain about missing + implementation of a new enum value. */ + } + + maContinuations.realloc( 2 ); + maContinuations[ 0 ].set( mpAbort = new AbortContinuation ); + maContinuations[ 1 ].set( mpPassword = new PasswordContinuation ); +} + +DocPasswordRequest::~DocPasswordRequest() +{ +} + +/*uno::*/Any SAL_CALL DocPasswordRequest::queryInterface( const /*uno::*/Type& rType ) throw (RuntimeException) +{ + return ::cppu::queryInterface ( rType, + // OWeakObject interfaces + dynamic_cast< XInterface* > ( (XInteractionRequest *) this ), + static_cast< XWeak* > ( this ), + // my own interfaces + static_cast< XInteractionRequest* > ( this ) ); +} + +void SAL_CALL DocPasswordRequest::acquire( ) throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL DocPasswordRequest::release( ) throw () +{ + OWeakObject::release(); +} + +sal_Bool DocPasswordRequest::isAbort() const +{ + return mpAbort->isSelected(); +} + +sal_Bool DocPasswordRequest::isPassword() const +{ + return mpPassword->isSelected(); +} + +OUString DocPasswordRequest::getPassword() const +{ + return mpPassword->getPassword(); +} + +OUString DocPasswordRequest::getPasswordToModify() const +{ + return mpPassword->getPasswordToModify(); +} + +sal_Bool DocPasswordRequest::getRecommendReadOnly() const +{ + return mpPassword->getRecommendReadOnly(); +} + +Any SAL_CALL DocPasswordRequest::getRequest() throw( RuntimeException ) +{ + return maRequest; +} + +Sequence< Reference< XInteractionContinuation > > SAL_CALL DocPasswordRequest::getContinuations() throw( RuntimeException ) +{ + return maContinuations; +} + +// ============================================================================ + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/documentinfo.cxx b/comphelper/source/misc/documentinfo.cxx new file mode 100644 index 000000000000..a9b9a85f7f69 --- /dev/null +++ b/comphelper/source/misc/documentinfo.cxx @@ -0,0 +1,200 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/documentinfo.hxx" +#include "comphelper/namedvaluecollection.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/frame/XTitle.hpp> +/** === end UNO includes === **/ + +#include <cppuhelper/exc_hlp.hxx> + +#include <osl/diagnose.h> +#include <osl/thread.h> + +#include <boost/current_function.hpp> + +//........................................................................ +namespace comphelper { +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::frame::XModel; + using ::com::sun::star::frame::XTitle; + using ::com::sun::star::frame::XController; + using ::com::sun::star::beans::XPropertySet; + using ::com::sun::star::document::XDocumentPropertiesSupplier; + using ::com::sun::star::document::XDocumentProperties; + using ::com::sun::star::frame::XStorable; + using ::com::sun::star::beans::XPropertySetInfo; + using ::com::sun::star::frame::XTitle; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::frame::XFrame; + /** === end UNO using === **/ + + //==================================================================== + //= helper + //==================================================================== + namespace + { + ::rtl::OUString lcl_getTitle( const Reference< XInterface >& _rxComponent ) + { + Reference< XTitle > xTitle( _rxComponent, UNO_QUERY ); + if ( xTitle.is() ) + return xTitle->getTitle(); + return ::rtl::OUString(); + } + } + + //==================================================================== + //= DocumentInfo + //==================================================================== + //-------------------------------------------------------------------- + ::rtl::OUString DocumentInfo::getDocumentTitle( const Reference< XModel >& _rxDocument ) + { + ::rtl::OUString sTitle; + + if ( !_rxDocument.is() ) + return sTitle; + + ::rtl::OUString sDocURL; + try + { + // 1. ask the model and the controller for their XTitle::getTitle + sTitle = lcl_getTitle( _rxDocument ); + if ( sTitle.getLength() ) + return sTitle; + + Reference< XController > xController( _rxDocument->getCurrentController() ); + sTitle = lcl_getTitle( xController ); + if ( sTitle.getLength() ) + return sTitle; + + // work around a problem with embedded objects, which sometimes return + // private:object as URL + sDocURL = _rxDocument->getURL(); + if ( sDocURL.matchAsciiL( "private:", 8 ) ) + sDocURL = ::rtl::OUString(); + + // 2. if the document is not saved, yet, check the frame title + if ( sDocURL.getLength() == 0 ) + { + Reference< XFrame > xFrame; + if ( xController.is() ) + xFrame.set( xController->getFrame() ); + sTitle = lcl_getTitle( xFrame ); + if ( sTitle.getLength() ) + return sTitle; + } + + // 3. try the UNO DocumentInfo + Reference< XDocumentPropertiesSupplier > xDPS( _rxDocument, UNO_QUERY ); + if ( xDPS.is() ) + { + Reference< XDocumentProperties > xDocProps ( + xDPS->getDocumentProperties(), UNO_QUERY_THROW ); + OSL_ENSURE(xDocProps.is(), "no DocumentProperties"); + sTitle = xDocProps->getTitle(); + if ( sTitle.getLength() ) + return sTitle; + } + + // 4. try model arguments + NamedValueCollection aModelArgs( _rxDocument->getArgs() ); + sTitle = aModelArgs.getOrDefault( "Title", sTitle ); + if ( sTitle.getLength() ) + return sTitle; + + // 5. try the last segment of the document URL + // this formerly was an INetURLObject::getName( LAST_SEGMENT, true, DECODE_WITH_CHARSET ), + // but since we moved this code to comphelper, we do not have access to an INetURLObject anymore + // This heuristics here should be sufficient - finally, we will get an UNO title API in a not + // too distant future (hopefully), then this complete class is superfluous) + if ( sDocURL.getLength() == 0 ) + { + Reference< XStorable > xDocStorable( _rxDocument, UNO_QUERY_THROW ); + sDocURL = xDocStorable->getLocation(); + } + sal_Int32 nLastSepPos = sDocURL.lastIndexOf( '/' ); + if ( ( nLastSepPos != -1 ) && ( nLastSepPos == sDocURL.getLength() - 1 ) ) + { + sDocURL = sDocURL.copy( 0, nLastSepPos ); + nLastSepPos = sDocURL.lastIndexOf( '/' ); + } + sTitle = sDocURL.copy( nLastSepPos + 1 ); + + if ( sTitle.getLength() != 0 ) + return sTitle; + + // 5. + // <-- #i88104# (05-16-08) TKR: use the new XTitle Interface to get the Title --> + + Reference< XTitle > xTitle( _rxDocument, UNO_QUERY ); + if ( xTitle.is() ) + { + if ( xTitle->getTitle().getLength() != 0 ) + return xTitle->getTitle(); + } + } + catch ( const Exception& ) + { + ::com::sun::star::uno::Any caught( ::cppu::getCaughtException() ); + ::rtl::OString sMessage( "caught an exception!" ); + sMessage += "\ntype : "; + sMessage += ::rtl::OString( caught.getValueTypeName().getStr(), caught.getValueTypeName().getLength(), osl_getThreadTextEncoding() ); + sMessage += "\nmessage: "; + ::com::sun::star::uno::Exception exception; + caught >>= exception; + sMessage += ::rtl::OString( exception.Message.getStr(), exception.Message.getLength(), osl_getThreadTextEncoding() ); + sMessage += "\nin function:\n"; + sMessage += BOOST_CURRENT_FUNCTION; + sMessage += "\n"; + OSL_FAIL( sMessage ); + } + + return sTitle; + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/documentiologring.cxx b/comphelper/source/misc/documentiologring.cxx new file mode 100644 index 000000000000..fdc17013a6d9 --- /dev/null +++ b/comphelper/source/misc/documentiologring.cxx @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <com/sun/star/frame/DoubleInitializationException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +#include <comphelper_module.hxx> + +#include "documentiologring.hxx" + +using namespace ::com::sun::star; + +namespace comphelper +{ + +// ---------------------------------------------------------- +OSimpleLogRing::OSimpleLogRing( const uno::Reference< uno::XComponentContext >& /*xContext*/ ) +: m_aMessages( SIMPLELOGRING_SIZE ) +, m_bInitialized( sal_False ) +, m_bFull( sal_False ) +, m_nPos( 0 ) +{ +} + +// ---------------------------------------------------------- +OSimpleLogRing::~OSimpleLogRing() +{ +} + +// ---------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OSimpleLogRing::getSupportedServiceNames_static() +{ + uno::Sequence< rtl::OUString > aResult( 1 ); + aResult[0] = getServiceName_static(); + return aResult; +} + +// ---------------------------------------------------------- +::rtl::OUString SAL_CALL OSimpleLogRing::getImplementationName_static() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.logging.SimpleLogRing" ) ); +} + +// ---------------------------------------------------------- +::rtl::OUString SAL_CALL OSimpleLogRing::getSingletonName_static() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.DocumentIOLogRing" ) ); +} + +// ---------------------------------------------------------- +::rtl::OUString SAL_CALL OSimpleLogRing::getServiceName_static() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.SimpleLogRing" ) ); +} + +// ---------------------------------------------------------- +uno::Reference< uno::XInterface > SAL_CALL OSimpleLogRing::Create( const uno::Reference< uno::XComponentContext >& rxContext ) +{ + return static_cast< cppu::OWeakObject* >( new OSimpleLogRing( rxContext ) ); +} + +// XSimpleLogRing +// ---------------------------------------------------------- +void SAL_CALL OSimpleLogRing::logString( const ::rtl::OUString& aMessage ) throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + m_aMessages[m_nPos] = aMessage; + if ( ++m_nPos >= m_aMessages.getLength() ) + { + m_nPos = 0; + m_bFull = sal_True; + } + + // if used once then default initialized + m_bInitialized = sal_True; +} + +// ---------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OSimpleLogRing::getCollectedLog() throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nResLen = m_bFull ? m_aMessages.getLength() : m_nPos; + sal_Int32 nStart = m_bFull ? m_nPos : 0; + uno::Sequence< ::rtl::OUString > aResult( nResLen ); + + for ( sal_Int32 nInd = 0; nInd < nResLen; nInd++ ) + aResult[nInd] = m_aMessages[ ( nStart + nInd ) % m_aMessages.getLength() ]; + + // if used once then default initialized + m_bInitialized = sal_True; + + return aResult; +} + +// XInitialization +// ---------------------------------------------------------- +void SAL_CALL OSimpleLogRing::initialize( const uno::Sequence< uno::Any >& aArguments ) throw (uno::Exception, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bInitialized ) + throw frame::DoubleInitializationException(); + + if ( !m_refCount ) + throw uno::RuntimeException(); // the object must be refcounted already! + + sal_Int32 nLen = 0; + if ( aArguments.getLength() == 1 && ( aArguments[0] >>= nLen ) && nLen ) + m_aMessages.realloc( nLen ); + else + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonnull size is expected as the first argument!" ) ), + uno::Reference< uno::XInterface >(), + 0 ); + + m_bInitialized = sal_True; +} + +// XServiceInfo +// ---------------------------------------------------------- +::rtl::OUString SAL_CALL OSimpleLogRing::getImplementationName() throw (uno::RuntimeException) +{ + return getImplementationName_static(); +} + +// ---------------------------------------------------------- +::sal_Bool SAL_CALL OSimpleLogRing::supportsService( const ::rtl::OUString& aServiceName ) throw (uno::RuntimeException) +{ + const uno::Sequence< rtl::OUString > & aSupportedNames = getSupportedServiceNames_static(); + for ( sal_Int32 nInd = 0; nInd < aSupportedNames.getLength(); nInd++ ) + { + if ( aSupportedNames[ nInd ].equals( aServiceName ) ) + return sal_True; + } + + return sal_False; +} + +// ---------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OSimpleLogRing::getSupportedServiceNames() throw (uno::RuntimeException) +{ + return getSupportedServiceNames_static(); +} + +} // namespace comphelper + +void createRegistryInfo_OSimpleLogRing() +{ + static ::comphelper::module::OAutoRegistration< ::comphelper::OSimpleLogRing > aAutoRegistration; + static ::comphelper::module::OSingletonRegistration< ::comphelper::OSimpleLogRing > aSingletonRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/documentiologring.hxx b/comphelper/source/misc/documentiologring.hxx new file mode 100644 index 000000000000..90acd7f9152b --- /dev/null +++ b/comphelper/source/misc/documentiologring.hxx @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 __DOCUMENTIOLOGRING_HXX_ +#define __DOCUMENTIOLOGRING_HXX_ + +#include <com/sun/star/logging/XSimpleLogRing.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + +#include <osl/mutex.hxx> +#include <cppuhelper/implbase3.hxx> + +#define SIMPLELOGRING_SIZE 256 + +namespace comphelper +{ + +class OSimpleLogRing : public ::cppu::WeakImplHelper3< ::com::sun::star::logging::XSimpleLogRing, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::lang::XServiceInfo > +{ + ::osl::Mutex m_aMutex; + ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aMessages; + + sal_Bool m_bInitialized; + sal_Bool m_bFull; + sal_Int32 m_nPos; + +public: + OSimpleLogRing( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ); + virtual ~OSimpleLogRing(); + + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames_static(); + + static ::rtl::OUString SAL_CALL getImplementationName_static(); + + static ::rtl::OUString SAL_CALL getSingletonName_static(); + + static ::rtl::OUString SAL_CALL getServiceName_static(); + + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + Create( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + +// XSimpleLogRing + virtual void SAL_CALL logString( const ::rtl::OUString& aMessage ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getCollectedLog() 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); + +// 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); + +}; + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/evtlistenerhlp.cxx b/comphelper/source/misc/evtlistenerhlp.cxx new file mode 100644 index 000000000000..3d10c0d76ad8 --- /dev/null +++ b/comphelper/source/misc/evtlistenerhlp.cxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "comphelper/evtlistenerhlp.hxx" + +namespace comphelper +{ + OEventListenerHelper::OEventListenerHelper(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& + _rxListener) : m_xListener(_rxListener) + { + } + void SAL_CALL OEventListenerHelper::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException) + { + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener> xRef = m_xListener; + if(xRef.is()) + xRef->disposing(Source); + } +} + + + + + + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/evtmethodhelper.cxx b/comphelper/source/misc/evtmethodhelper.cxx new file mode 100644 index 000000000000..a94b85754e13 --- /dev/null +++ b/comphelper/source/misc/evtmethodhelper.cxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_comphelper.hxx" +#include "comphelper/evtmethodhelper.hxx" +#include "cppuhelper/typeprovider.hxx" + +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Type; + +namespace comphelper +{ + + Sequence< ::rtl::OUString> getEventMethodsForType(const Type& type) + { + typelib_InterfaceTypeDescription *pType=0; + type.getDescription( (typelib_TypeDescription**)&pType); + + if(!pType) + return Sequence< ::rtl::OUString>(); + + Sequence< ::rtl::OUString> aNames(pType->nMembers); + ::rtl::OUString* pNames = aNames.getArray(); + for(sal_Int32 i=0;i<pType->nMembers;i++,++pNames) + { + // the decription reference + typelib_TypeDescriptionReference* pMemberDescriptionReference = pType->ppMembers[i]; + // the description for the reference + typelib_TypeDescription* pMemberDescription = NULL; + typelib_typedescriptionreference_getDescription(&pMemberDescription, pMemberDescriptionReference); + if (pMemberDescription) + { + typelib_InterfaceMemberTypeDescription* pRealMemberDescription = + reinterpret_cast<typelib_InterfaceMemberTypeDescription*>(pMemberDescription); + *pNames = pRealMemberDescription->pMemberName; + } + } + typelib_typedescription_release( (typelib_TypeDescription *)pType ); + return aNames; + } + +} + + + + + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/ihwrapnofilter.cxx b/comphelper/source/misc/ihwrapnofilter.cxx new file mode 100644 index 000000000000..7d9ef608a1ae --- /dev/null +++ b/comphelper/source/misc/ihwrapnofilter.cxx @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/ihwrapnofilter.hxx" +#include <com/sun/star/document/NoSuchFilterRequest.hpp> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star; + + //---------------------------------------------------------------------------------------------------- + OIHWrapNoFilterDialog::OIHWrapNoFilterDialog( uno::Reference< task::XInteractionHandler > xInteraction ) + :m_xInter( xInteraction ) + { + } + + OIHWrapNoFilterDialog::~OIHWrapNoFilterDialog() + { + } + + //---------------------------------------------------------------------------------------------------- + uno::Sequence< ::rtl::OUString > SAL_CALL OIHWrapNoFilterDialog::impl_staticGetSupportedServiceNames() + { + uno::Sequence< ::rtl::OUString > aRet(1); + aRet[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandlerWrapper")); + return aRet; + } + + ::rtl::OUString SAL_CALL OIHWrapNoFilterDialog::impl_staticGetImplementationName() + { + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.task.InteractionHandlerWrapper")); + } + + //---------------------------------------------------------------------------------------------------- + // XInteractionHandler + //---------------------------------------------------------------------------------------------------- + void SAL_CALL OIHWrapNoFilterDialog::handle( const uno::Reference< task::XInteractionRequest >& xRequest) + throw( com::sun::star::uno::RuntimeException ) + { + if( !m_xInter.is() ) + return; + + uno::Any aRequest = xRequest->getRequest(); + document::NoSuchFilterRequest aNoSuchFilterRequest; + if ( aRequest >>= aNoSuchFilterRequest ) + return; + else + m_xInter->handle( xRequest ); + } + + //---------------------------------------------------------------------------------------------------- + // XInitialization + //---------------------------------------------------------------------------------------------------- + void SAL_CALL OIHWrapNoFilterDialog::initialize( const uno::Sequence< uno::Any >& ) + throw ( uno::Exception, + uno::RuntimeException, + frame::DoubleInitializationException ) + { + } + + //---------------------------------------------------------------------------------------------------- + // XServiceInfo + //---------------------------------------------------------------------------------------------------- + + ::rtl::OUString SAL_CALL OIHWrapNoFilterDialog::getImplementationName() + throw ( uno::RuntimeException ) + { + return impl_staticGetImplementationName(); + } + + ::sal_Bool SAL_CALL OIHWrapNoFilterDialog::supportsService( const ::rtl::OUString& ServiceName ) + throw ( uno::RuntimeException ) + { + uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames(); + + for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ ) + if ( ServiceName.compareTo( aSeq[nInd] ) == 0 ) + return sal_True; + + return sal_False; + } + + uno::Sequence< ::rtl::OUString > SAL_CALL OIHWrapNoFilterDialog::getSupportedServiceNames() + throw ( uno::RuntimeException ) + { + return impl_staticGetSupportedServiceNames(); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/instancelocker.cxx b/comphelper/source/misc/instancelocker.cxx new file mode 100644 index 000000000000..c71f84b62309 --- /dev/null +++ b/comphelper/source/misc/instancelocker.cxx @@ -0,0 +1,515 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +#include <com/sun/star/util/XCloseBroadcaster.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/frame/DoubleInitializationException.hpp> +#include <com/sun/star/frame/DoubleInitializationException.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include "instancelocker.hxx" + +using namespace ::com::sun::star; + + +// ==================================================================== +// OInstanceLocker +// ==================================================================== + +// -------------------------------------------------------- +OInstanceLocker::OInstanceLocker( const uno::Reference< uno::XComponentContext >& xContext ) +: m_xContext( xContext ) +, m_pLockListener( NULL ) +, m_pListenersContainer( NULL ) +, m_bDisposed( sal_False ) +, m_bInitialized( sal_False ) +{ +} + +// -------------------------------------------------------- +OInstanceLocker::~OInstanceLocker() +{ + if ( !m_bDisposed ) + { + m_refCount++; // to call dispose + try { + dispose(); + } + catch ( uno::RuntimeException& ) + {} + } + + if ( m_pListenersContainer ) + { + delete m_pListenersContainer; + m_pListenersContainer = NULL; + } +} + +// XComponent +// -------------------------------------------------------- +void SAL_CALL OInstanceLocker::dispose() + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) ); + if ( m_pListenersContainer ) + m_pListenersContainer->disposeAndClear( aSource ); + + if ( m_xLockListener.is() ) + { + if ( m_pLockListener ) + { + m_pLockListener->Dispose(); + m_pLockListener = NULL; + } + m_xLockListener = uno::Reference< uno::XInterface >(); + } + + m_bDisposed = sal_True; +} + +// -------------------------------------------------------- +void SAL_CALL OInstanceLocker::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bDisposed ) + throw lang::DisposedException(); // TODO + + if ( !m_pListenersContainer ) + m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pListenersContainer->addInterface( xListener ); +} + +// -------------------------------------------------------- +void SAL_CALL OInstanceLocker::removeEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_pListenersContainer ) + m_pListenersContainer->removeInterface( xListener ); +} + +// XInitialization +// -------------------------------------------------------- +void SAL_CALL OInstanceLocker::initialize( const uno::Sequence< uno::Any >& aArguments ) + throw (uno::Exception, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bInitialized ) + throw frame::DoubleInitializationException(); + + if ( m_bDisposed ) + throw lang::DisposedException(); // TODO + + if ( !m_refCount ) + throw uno::RuntimeException(); // the object must be refcounted already! + + uno::Reference< uno::XInterface > xInstance; + uno::Reference< embed::XActionsApproval > xApproval; + sal_Int32 nModes = 0; + + try + { + sal_Int32 nLen = aArguments.getLength(); + if ( nLen < 2 || nLen > 3 ) + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Wrong count of parameters!" ) ), + uno::Reference< uno::XInterface >(), + 0 ); + + if ( !( aArguments[0] >>= xInstance ) || !xInstance.is() ) + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonempty reference is expected as the first argument!" ) ), + uno::Reference< uno::XInterface >(), + 0 ); + + if ( + !( aArguments[1] >>= nModes ) || + ( + !( nModes & embed::Actions::PREVENT_CLOSE ) && + !( nModes & embed::Actions::PREVENT_TERMINATION ) + ) + ) + { + throw lang::IllegalArgumentException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("The correct modes set is expected as the second argument!" ) ), + uno::Reference< uno::XInterface >(), + 0 ); + } + + if ( nLen == 3 && !( aArguments[2] >>= xApproval ) ) + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("If the third argument is provided, it must be XActionsApproval implementation!" ) ), + uno::Reference< uno::XInterface >(), + 0 ); + + m_pLockListener = new OLockListener( uno::Reference< lang::XComponent > ( static_cast< lang::XComponent* >( this ) ), + xInstance, + nModes, + xApproval ); + m_xLockListener = uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( m_pLockListener ) ); + m_pLockListener->Init(); + } + catch( uno::Exception& ) + { + dispose(); + throw; + } + + m_bInitialized = sal_True; +} + + +// XServiceInfo +// -------------------------------------------------------- +::rtl::OUString SAL_CALL OInstanceLocker::getImplementationName( ) + throw (uno::RuntimeException) +{ + return getImplementationName_static(); +} + +// -------------------------------------------------------- +::sal_Bool SAL_CALL OInstanceLocker::supportsService( const ::rtl::OUString& ServiceName ) + throw (uno::RuntimeException) +{ + uno::Sequence< ::rtl::OUString > aSeq = getSupportedServiceNames(); + + for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ ) + if ( ServiceName.compareTo( aSeq[nInd] ) == 0 ) + return sal_True; + + return sal_False; +} + +// -------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OInstanceLocker::getSupportedServiceNames() + throw (uno::RuntimeException) +{ + return getSupportedServiceNames_static(); +} + +// Static methods +// -------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OInstanceLocker::getSupportedServiceNames_static() +{ + const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.InstanceLocker" ) ); + return uno::Sequence< rtl::OUString >( &aServiceName, 1 ); +} + +// -------------------------------------------------------- +::rtl::OUString SAL_CALL OInstanceLocker::getImplementationName_static() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.embed.InstanceLocker" ) ); +} + +// -------------------------------------------------------- +uno::Reference< uno::XInterface > SAL_CALL OInstanceLocker::Create( + const uno::Reference< uno::XComponentContext >& rxContext ) +{ + return static_cast< cppu::OWeakObject * >( new OInstanceLocker( rxContext ) ); +} + + + +// ==================================================================== +// OLockListener +// ==================================================================== + +// -------------------------------------------------------- +OLockListener::OLockListener( const uno::WeakReference< lang::XComponent >& xWrapper, + const uno::Reference< uno::XInterface >& xInstance, + sal_Int32 nMode, + const uno::Reference< embed::XActionsApproval > xApproval ) +: m_xInstance( xInstance ) +, m_xApproval( xApproval ) +, m_xWrapper( xWrapper ) +, m_bDisposed( sal_False ) +, m_bInitialized( sal_False ) +, m_nMode( nMode ) +{ +} + +// -------------------------------------------------------- +OLockListener::~OLockListener() +{ +} + +// -------------------------------------------------------- +void OLockListener::Dispose() +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + return; + + if ( m_nMode & embed::Actions::PREVENT_CLOSE ) + { + try + { + uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xInstance, uno::UNO_QUERY ); + if ( xCloseBroadcaster.is() ) + xCloseBroadcaster->removeCloseListener( static_cast< util::XCloseListener* >( this ) ); + + uno::Reference< util::XCloseable > xCloseable( m_xInstance, uno::UNO_QUERY ); + if ( xCloseable.is() ) + xCloseable->close( sal_True ); + } + catch( uno::Exception& ) + {} + } + + if ( m_nMode & embed::Actions::PREVENT_TERMINATION ) + { + try + { + uno::Reference< frame::XDesktop > xDesktop( m_xInstance, uno::UNO_QUERY_THROW ); + xDesktop->removeTerminateListener( static_cast< frame::XTerminateListener* >( this ) ); + } + catch( uno::Exception& ) + {} + } + + m_xInstance = uno::Reference< uno::XInterface >(); + m_bDisposed = sal_True; +} + +// XEventListener +// -------------------------------------------------------- +void SAL_CALL OLockListener::disposing( const lang::EventObject& aEvent ) + throw (uno::RuntimeException) +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + + // object is disposed + if ( aEvent.Source == m_xInstance ) + { + // the object does not listen for anything any more + m_nMode = 0; + + // dispose the wrapper; + uno::Reference< lang::XComponent > xComponent( m_xWrapper.get(), uno::UNO_QUERY ); + aGuard.clear(); + if ( xComponent.is() ) + { + try { xComponent->dispose(); } + catch( uno::Exception& ){} + } + } +} + + +// XCloseListener +// -------------------------------------------------------- +void SAL_CALL OLockListener::queryClosing( const lang::EventObject& aEvent, sal_Bool ) + throw (util::CloseVetoException, uno::RuntimeException) +{ + // GetsOwnership parameter is always ignored, the user of the service must close the object always + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + if ( !m_bDisposed && aEvent.Source == m_xInstance && ( m_nMode & embed::Actions::PREVENT_CLOSE ) ) + { + try + { + uno::Reference< embed::XActionsApproval > xApprove = m_xApproval; + + // unlock the mutex here + aGuard.clear(); + + if ( xApprove.is() && xApprove->approveAction( embed::Actions::PREVENT_CLOSE ) ) + throw util::CloseVetoException(); + } + catch( util::CloseVetoException& ) + { + // rethrow this exception + throw; + } + catch( uno::Exception& ) + { + // no action should be done + } + } +} + +// -------------------------------------------------------- +void SAL_CALL OLockListener::notifyClosing( const lang::EventObject& aEvent ) + throw (uno::RuntimeException) +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + + // object is closed, no reason to listen + if ( aEvent.Source == m_xInstance ) + { + uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( aEvent.Source, uno::UNO_QUERY ); + if ( xCloseBroadcaster.is() ) + { + xCloseBroadcaster->removeCloseListener( static_cast< util::XCloseListener* >( this ) ); + m_nMode &= ~embed::Actions::PREVENT_CLOSE; + if ( !m_nMode ) + { + // dispose the wrapper; + uno::Reference< lang::XComponent > xComponent( m_xWrapper.get(), uno::UNO_QUERY ); + aGuard.clear(); + if ( xComponent.is() ) + { + try { xComponent->dispose(); } + catch( uno::Exception& ){} + } + } + } + } +} + + +// XTerminateListener +// -------------------------------------------------------- +void SAL_CALL OLockListener::queryTermination( const lang::EventObject& aEvent ) + throw (frame::TerminationVetoException, uno::RuntimeException) +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + if ( aEvent.Source == m_xInstance && ( m_nMode & embed::Actions::PREVENT_TERMINATION ) ) + { + try + { + uno::Reference< embed::XActionsApproval > xApprove = m_xApproval; + + // unlock the mutex here + aGuard.clear(); + + if ( xApprove.is() && xApprove->approveAction( embed::Actions::PREVENT_TERMINATION ) ) + throw frame::TerminationVetoException(); + } + catch( frame::TerminationVetoException& ) + { + // rethrow this exception + throw; + } + catch( uno::Exception& ) + { + // no action should be done + } + } +} + +// -------------------------------------------------------- +void SAL_CALL OLockListener::notifyTermination( const lang::EventObject& aEvent ) + throw (uno::RuntimeException) +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + + // object is terminated, no reason to listen + if ( aEvent.Source == m_xInstance ) + { + uno::Reference< frame::XDesktop > xDesktop( aEvent.Source, uno::UNO_QUERY ); + if ( xDesktop.is() ) + { + try + { + xDesktop->removeTerminateListener( static_cast< frame::XTerminateListener* >( this ) ); + m_nMode &= ~embed::Actions::PREVENT_TERMINATION; + if ( !m_nMode ) + { + // dispose the wrapper; + uno::Reference< lang::XComponent > xComponent( m_xWrapper.get(), uno::UNO_QUERY ); + aGuard.clear(); + if ( xComponent.is() ) + { + try { xComponent->dispose(); } + catch( uno::Exception& ){} + } + } + } + catch( uno::Exception& ) + {} + } + } +} + + +// XInitialization +// -------------------------------------------------------- +sal_Bool OLockListener::Init() +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed || m_bInitialized ) + return sal_False; + + try + { + if ( m_nMode & embed::Actions::PREVENT_CLOSE ) + { + uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xInstance, uno::UNO_QUERY_THROW ); + xCloseBroadcaster->addCloseListener( static_cast< util::XCloseListener* >( this ) ); + } + + if ( m_nMode & embed::Actions::PREVENT_TERMINATION ) + { + uno::Reference< frame::XDesktop > xDesktop( m_xInstance, uno::UNO_QUERY_THROW ); + xDesktop->addTerminateListener( static_cast< frame::XTerminateListener* >( this ) ); + } + } + catch( uno::Exception& ) + { + // dispose the wrapper; + uno::Reference< lang::XComponent > xComponent( m_xWrapper.get(), uno::UNO_QUERY ); + aGuard.clear(); + if ( xComponent.is() ) + { + try { xComponent->dispose(); } + catch( uno::Exception& ){} + } + + throw; + } + + m_bInitialized = sal_True; + + return sal_True; +} + +void createRegistryInfo_OInstanceLocker() +{ + static ::comphelper::module::OAutoRegistration< OInstanceLocker > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/instancelocker.hxx b/comphelper/source/misc/instancelocker.hxx new file mode 100644 index 000000000000..809aced6e3c1 --- /dev/null +++ b/comphelper/source/misc/instancelocker.hxx @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 __INSTANCELOCKER_HXX_ +#define __INSTANCELOCKER_HXX_ + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/util/XCloseListener.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/embed/XActionsApproval.hpp> +#include <com/sun/star/embed/Actions.hpp> +#include <cppuhelper/weakref.hxx> +#include <osl/mutex.hxx> +#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/interfacecontainer.h> + + +class OLockListener; + +// the service is implemented as a wrapper to be able to die by refcount +// the disposing mechanics is required for java related scenarios +class OInstanceLocker : public ::cppu::WeakImplHelper3< ::com::sun::star::lang::XComponent, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::lang::XServiceInfo > +{ + ::osl::Mutex m_aMutex; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > m_xLockListener; + OLockListener* m_pLockListener; + + ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners + + sal_Bool m_bDisposed; + sal_Bool m_bInitialized; + +public: + OInstanceLocker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ); + ~OInstanceLocker(); + + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames_static(); + + static ::rtl::OUString SAL_CALL getImplementationName_static(); + + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + Create( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + +// XComponent + virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) 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); + +// 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); + +}; + + +class OLockListener : public ::cppu::WeakImplHelper2< ::com::sun::star::util::XCloseListener, + ::com::sun::star::frame::XTerminateListener > +{ + ::osl::Mutex m_aMutex; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > m_xInstance; + ::com::sun::star::uno::Reference< ::com::sun::star::embed::XActionsApproval > m_xApproval; + + ::com::sun::star::uno::WeakReference< ::com::sun::star::lang::XComponent > m_xWrapper; + + sal_Bool m_bDisposed; + sal_Bool m_bInitialized; + + sal_Int32 m_nMode; + +public: + OLockListener( const ::com::sun::star::uno::WeakReference< ::com::sun::star::lang::XComponent >& xWrapper, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xInstance, + sal_Int32 nMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XActionsApproval > xApproval ); + + ~OLockListener(); + + sal_Bool Init(); + void Dispose(); + +// XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + +// XCloseListener + virtual void SAL_CALL queryClosing( const ::com::sun::star::lang::EventObject& Source, sal_Bool GetsOwnership ) throw (::com::sun::star::util::CloseVetoException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL notifyClosing( 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& Event ) throw (::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException); + +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/interaction.cxx b/comphelper/source/misc/interaction.cxx new file mode 100644 index 000000000000..7a69ac4d5cbb --- /dev/null +++ b/comphelper/source/misc/interaction.cxx @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/interaction.hxx> +#include <osl/diagnose.h> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::task; + + //========================================================================= + //= OInteractionPassword + //========================================================================= + //-------------------------------------------------------------------- + void SAL_CALL OInteractionPassword::setPassword( const ::rtl::OUString& _Password ) throw (RuntimeException) + { + m_sPassword = _Password;; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL OInteractionPassword::getPassword( ) throw (RuntimeException) + { + return m_sPassword; + } + + //========================================================================= + //= OInteractionRequest + //========================================================================= + //------------------------------------------------------------------------- + OInteractionRequest::OInteractionRequest(const Any& _rRequestDescription) + :m_aRequest(_rRequestDescription) + { + } + + //------------------------------------------------------------------------- + void OInteractionRequest::addContinuation(const Reference< XInteractionContinuation >& _rxContinuation) + { + OSL_ENSURE(_rxContinuation.is(), "OInteractionRequest::addContinuation: invalid argument!"); + if (_rxContinuation.is()) + { + sal_Int32 nOldLen = m_aContinuations.getLength(); + m_aContinuations.realloc(nOldLen + 1); + m_aContinuations[nOldLen] = _rxContinuation; + } + } + + //------------------------------------------------------------------------- + void OInteractionRequest::clearContinuations() + { + m_aContinuations.realloc(0); + } + + //------------------------------------------------------------------------- + Any SAL_CALL OInteractionRequest::getRequest( ) throw(RuntimeException) + { + return m_aRequest; + } + + //------------------------------------------------------------------------- + Sequence< Reference< XInteractionContinuation > > SAL_CALL OInteractionRequest::getContinuations( ) throw(RuntimeException) + { + return m_aContinuations; + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/listenernotification.cxx b/comphelper/source/misc/listenernotification.cxx new file mode 100644 index 000000000000..0f7823a197c7 --- /dev/null +++ b/comphelper/source/misc/listenernotification.cxx @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/listenernotification.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + + //==================================================================== + //= OListenerContainer + //==================================================================== + //-------------------------------------------------------------------- + OListenerContainer::OListenerContainer( ::osl::Mutex& _rMutex ) + :m_aListeners( _rMutex ) + { + } + + OListenerContainer::~OListenerContainer() {} + + //-------------------------------------------------------------------- + void OListenerContainer::impl_addListener( const Reference< XEventListener >& _rxListener ) + { + OSL_PRECOND( _rxListener.is(), "OListenerContainer::impl_addListener: a NULL listener?!" ); + if ( _rxListener.is() ) + m_aListeners.addInterface( _rxListener ); + } + + //-------------------------------------------------------------------- + void OListenerContainer::impl_removeListener( const Reference< XEventListener >& _rxListener ) + { +#if OSL_DEBUG_LEVEL > 0 + ::cppu::OInterfaceIteratorHelper aIter( m_aListeners ); + bool bFound = false; + while ( aIter.hasMoreElements() && !bFound ) + { + bFound = ( Reference< XInterface >( aIter.next() ) == _rxListener ); + } + OSL_ENSURE( bFound, "OListenerContainer::impl_removeListener: sure your listener handling is correct? The given listener is not registered!" ); +#endif + m_aListeners.removeInterface( _rxListener ); + } + + //-------------------------------------------------------------------- + void OListenerContainer::disposing( const EventObject& _rEventSource ) + { + m_aListeners.disposeAndClear( _rEventSource ); + } + + //-------------------------------------------------------------------- + void OListenerContainer::clear() + { + m_aListeners.clear(); + } + + //-------------------------------------------------------------------- + bool OListenerContainer::impl_notify( const EventObject& _rEvent ) SAL_THROW(( Exception )) + { + ::cppu::OInterfaceIteratorHelper aIter( m_aListeners ); + bool bCancelled = false; + while ( aIter.hasMoreElements() && !bCancelled ) + { + Reference< XEventListener > xListener( static_cast< XEventListener* >( aIter.next() ) ); + if ( !xListener.is() ) + continue; + + try + { + bCancelled = !implNotify( xListener, _rEvent ); + } + catch( const DisposedException& e ) + { + // DisposedExceptions from the listener might indicate a + // broken connection to a different environment. + + OSL_ENSURE( e.Context.is(), "OListenerContainer::impl_notify: caught dispose exception with empty Context field" ); + + // If the exception stems from the listener then remove it + // from the list of listeners. If the Context field of the + // exception is empty this is interpreted to indicate the + // listener as well. + if ( e.Context == xListener || !e.Context.is() ) + aIter.remove(); + } + } + + return !bCancelled; + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/locale.cxx b/comphelper/source/misc/locale.cxx new file mode 100644 index 000000000000..0a791c41582c --- /dev/null +++ b/comphelper/source/misc/locale.cxx @@ -0,0 +1,351 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/locale.hxx> + +//_______________________________________________ +// includes +#include <rtl/ustrbuf.hxx> + +//_______________________________________________ +// namespace + +namespace comphelper{ + +//----------------------------------------------- +const sal_Unicode Locale::SEPERATOR_LC = (sal_Unicode)'-'; +const sal_Unicode Locale::SEPERATOR_CV = (sal_Unicode)'_'; +const sal_Unicode Locale::SEPERATOR_CV_LINUX = (sal_Unicode)'.'; + +//----------------------------------------------- +const Locale Locale::X_DEFAULT() +{ + static Locale aLocale( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("x")), + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("default"))); + return aLocale; +} + +//----------------------------------------------- +const Locale Locale::EN_US() +{ + static Locale aLocale( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US"))); + return aLocale; +} + +//----------------------------------------------- +const Locale Locale::X_NOTRANSLATE() +{ + static Locale aLocale( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("x")), + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("notranslate"))); + return aLocale; +} + +//----------------------------------------------- +Locale::Locale(const ::rtl::OUString& sISO) + throw(Locale::MalFormedLocaleException) +{ + fromISO(sISO); +} + +//----------------------------------------------- +Locale::Locale(const ::rtl::OUString& sLanguage, + const ::rtl::OUString& sCountry , + const ::rtl::OUString& sVariant ) +{ + // Use set methods to check values too! + setLanguage(sLanguage); + setCountry (sCountry ); + setVariant (sVariant ); +} + +//----------------------------------------------- +Locale::Locale() +{ + // Initialize instance ... otherwhise user will + // may be get exceptions if he e.g. copy this instance ... + (*this) = X_NOTRANSLATE(); +} + +//----------------------------------------------- +Locale::Locale(const Locale& aCopy) +{ + (*this) = aCopy; // recycle assign operator +} + +//----------------------------------------------- +::rtl::OUString Locale::getLanguage() const +{ + return m_sLanguage; +} + +//----------------------------------------------- +::rtl::OUString Locale::getCountry() const +{ + return m_sCountry; +} + +//----------------------------------------------- +::rtl::OUString Locale::getVariant() const +{ + return m_sVariant; +} + +//----------------------------------------------- +void Locale::setLanguage(const ::rtl::OUString& sLanguage) +{ + m_sLanguage = sLanguage; +} + +//----------------------------------------------- +void Locale::setCountry(const ::rtl::OUString& sCountry) +{ + m_sCountry = sCountry; +} + +//----------------------------------------------- +void Locale::setVariant(const ::rtl::OUString& sVariant) +{ + m_sVariant = sVariant; +} + +//----------------------------------------------- +/* Attention: Use own interface methods to set the + different parts of this locale. Because the + check the incoming value and throw an exception + automaticly ... + */ +void Locale::fromISO(const ::rtl::OUString& sISO) + throw(Locale::MalFormedLocaleException) +{ + m_sLanguage = ::rtl::OUString(); + m_sCountry = ::rtl::OUString(); + m_sVariant = ::rtl::OUString(); + + ::rtl::OUString sParser(sISO); + sParser.trim(); + + sal_Int32 nStart = 0; + sal_Int32 nEnd = 0; + + // extract language part + nEnd = sParser.indexOf(SEPERATOR_LC, nStart); + if (nEnd<0) + { + setLanguage(sParser); + return; + } + setLanguage(sParser.copy(nStart, nEnd-nStart)); + nStart = nEnd+1; + + // extract country + nEnd = sParser.indexOf(SEPERATOR_CV, nStart); + if (nEnd<0) + nEnd = sParser.indexOf(SEPERATOR_CV_LINUX, nStart); + if (nEnd<0) + { + setCountry(sParser.copy(nStart, sParser.getLength()-nStart)); + return; + } + nStart = nEnd+1; + + // extract variant + setVariant(sParser.copy(nStart, sParser.getLength()-nStart)); +} + +//----------------------------------------------- +::rtl::OUString Locale::toISO() const +{ + ::rtl::OUStringBuffer sISO(64); + + sISO.append(m_sLanguage); + if (m_sCountry.getLength()) + { + sISO.append(SEPERATOR_LC); + sISO.append(m_sCountry); + + if (m_sVariant.getLength()) + { + sISO.append(SEPERATOR_CV); + sISO.append(m_sVariant); + } + } + + return sISO.makeStringAndClear(); +} + +//----------------------------------------------- +sal_Bool Locale::equals(const Locale& aComparable) const +{ + return ( + m_sLanguage.equals(aComparable.m_sLanguage) && + m_sCountry.equals (aComparable.m_sCountry ) && + m_sVariant.equals (aComparable.m_sVariant ) + ); +} + +//----------------------------------------------- +sal_Bool Locale::similar(const Locale& aComparable) const +{ + return (m_sLanguage.equals(aComparable.m_sLanguage)); +} + +//----------------------------------------------- +::std::vector< ::rtl::OUString >::const_iterator Locale::getFallback(const ::std::vector< ::rtl::OUString >& lISOList , + const ::rtl::OUString& sReferenceISO) + throw(Locale::MalFormedLocaleException) +{ + Locale aReference(sReferenceISO); + + // Note: The same language or "en"/"en-US" should be preferred as fallback. + // On the other side some localized variables doesnt use localzation in real. + // May be the use a "fix" value only ... marked as X-DEFAULT or X-NOTRANSLATE. + // At least it can be discussed, if any language is a valid fallback ... + // But in case some office functionality depends on that (that means real functionality instead + // of pure UI descriptions) we should do anything, so it can work. + + ::std::vector< ::rtl::OUString >::const_iterator pSimilar = lISOList.end(); + ::std::vector< ::rtl::OUString >::const_iterator pEN_US = lISOList.end(); + ::std::vector< ::rtl::OUString >::const_iterator pEN = lISOList.end(); + ::std::vector< ::rtl::OUString >::const_iterator pXDefault = lISOList.end(); + ::std::vector< ::rtl::OUString >::const_iterator pXNoTranslate = lISOList.end(); + ::std::vector< ::rtl::OUString >::const_iterator pAny = lISOList.end(); + + ::std::vector< ::rtl::OUString >::const_iterator pIt; + for ( pIt = lISOList.begin(); + pIt != lISOList.end() ; + ++pIt ) + { + Locale aCheck(*pIt); + // found Locale, which match with 100% => return it + if (aCheck.equals(aReference)) + return pIt; + + // found similar Locale => safe it as possible fallback + if ( + (pSimilar == lISOList.end()) && + (aCheck.similar(aReference)) + ) + { + pSimilar = pIt; + } + else + // found en-US => safe it as fallback + if ( + (pEN_US == lISOList.end()) && + (aCheck.equals(EN_US()) ) + ) + { + pEN_US = pIt; + } + else + // found en[-XX] => safe it as fallback + if ( + (pEN == lISOList.end() ) && + (aCheck.similar(EN_US())) + ) + { + pEN = pIt; + } + else + // found an explicit default value(!) => safe it as fallback + if ( + (pXDefault == lISOList.end()) && + (aCheck.equals(X_DEFAULT()) ) + ) + { + pXDefault = pIt; + } + else + // found an implicit default value(!) => safe it as fallback + if ( + (pXNoTranslate == lISOList.end()) && + (aCheck.equals(X_NOTRANSLATE()) ) + ) + { + pXNoTranslate = pIt; + } + else + // safe the first locale, which isn't an explicit fallback + // as "last possible fallback" + if (pAny == lISOList.end()) + pAny = pIt; + } + + if (pSimilar != lISOList.end()) + return pSimilar; + + if (pEN_US != lISOList.end()) + return pEN_US; + + if (pEN != lISOList.end()) + return pEN; + + if (pXDefault != lISOList.end()) + return pXDefault; + + if (pXNoTranslate != lISOList.end()) + return pXNoTranslate; + + if (pAny != lISOList.end()) + return pAny; + + return lISOList.end(); +} + +//----------------------------------------------- +void Locale::operator=(const Locale& rCopy) +{ + // Take over these values without checking ... + // They was already checked if the copy was constructed + // and must be valid now! + m_sLanguage = rCopy.m_sLanguage; + m_sCountry = rCopy.m_sCountry; + m_sVariant = rCopy.m_sVariant; +} + +//----------------------------------------------- +sal_Bool Locale::operator==(const Locale& aComparable) const +{ + return equals(aComparable); +} + +//----------------------------------------------- +sal_Bool Locale::operator!=(const Locale& aComparable) const +{ + return !equals(aComparable); +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/logging.cxx b/comphelper/source/misc/logging.cxx new file mode 100644 index 000000000000..6d87b0fb528a --- /dev/null +++ b/comphelper/source/misc/logging.cxx @@ -0,0 +1,408 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <comphelper/logging.hxx> +#include <comphelper/componentcontext.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/LoggerPool.hpp> +#include <com/sun/star/logging/LogLevel.hpp> +#include <com/sun/star/resource/XResourceBundle.hpp> +#include <com/sun/star/resource/XResourceBundleLoader.hpp> +/** === end UNO includes === **/ + +#include <rtl/ustrbuf.hxx> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::logging::XLoggerPool; + using ::com::sun::star::logging::LoggerPool; + using ::com::sun::star::logging::XLogger; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::logging::XLogHandler; + using ::com::sun::star::resource::XResourceBundle; + using ::com::sun::star::resource::XResourceBundleLoader; + /** === end UNO using === **/ + namespace LogLevel = ::com::sun::star::logging::LogLevel; + + //==================================================================== + //= EventLogger_Impl - declaration + //==================================================================== + class EventLogger_Impl + { + private: + ::comphelper::ComponentContext m_aContext; + ::rtl::OUString m_sLoggerName; + Reference< XLogger > m_xLogger; + + public: + EventLogger_Impl( const Reference< XComponentContext >& _rxContext, const ::rtl::OUString& _rLoggerName ) + :m_aContext( _rxContext ) + ,m_sLoggerName( _rLoggerName ) + { + impl_createLogger_nothrow(); + } + + inline bool isValid() const { return m_xLogger.is(); } + inline const ::rtl::OUString& getName() const { return m_sLoggerName; } + inline const Reference< XLogger >& getLogger() const { return m_xLogger; } + inline const ::comphelper::ComponentContext& getContext() const { return m_aContext; } + + private: + void impl_createLogger_nothrow(); + }; + + //==================================================================== + //= EventLogger_Impl - implementation + //==================================================================== + //-------------------------------------------------------------------- + void EventLogger_Impl::impl_createLogger_nothrow() + { + try + { + Reference< XLoggerPool > xPool( LoggerPool::get( m_aContext.getUNOContext() ), UNO_QUERY_THROW ); + if ( m_sLoggerName.getLength() ) + m_xLogger = xPool->getNamedLogger( m_sLoggerName ); + else + m_xLogger = xPool->getDefaultLogger(); + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "EventLogger_Impl::impl_createLogger_nothrow: caught an exception!" ); + } + } + + //==================================================================== + //= EventLogger + //==================================================================== + //-------------------------------------------------------------------- + EventLogger::EventLogger( const Reference< XComponentContext >& _rxContext, const ::rtl::OUString& _rLoggerName ) + :m_pImpl( new EventLogger_Impl( _rxContext, _rLoggerName ) ) + { + } + + //-------------------------------------------------------------------- + EventLogger::EventLogger( const Reference< XComponentContext >& _rxContext, const sal_Char* _pAsciiLoggerName ) + :m_pImpl( new EventLogger_Impl( _rxContext, ::rtl::OUString::createFromAscii( _pAsciiLoggerName ) ) ) + { + } + + //-------------------------------------------------------------------- + EventLogger::~EventLogger() + { + } + + //-------------------------------------------------------------------- + const ::rtl::OUString& EventLogger::getName() const + { + return m_pImpl->getName(); + } + + //-------------------------------------------------------------------- + sal_Int32 EventLogger::getLogLevel() const + { + try + { + if ( m_pImpl->isValid() ) + return m_pImpl->getLogger()->getLevel(); + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "EventLogger::getLogLevel: caught an exception!" ); + } + + return LogLevel::OFF; + } + + //-------------------------------------------------------------------- + void EventLogger::setLogLevel( const sal_Int32 _nLogLevel ) const + { + try + { + if ( m_pImpl->isValid() ) + m_pImpl->getLogger()->setLevel( _nLogLevel ); + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "EventLogger::setLogLevel: caught an exception!" ); + } + } + + //-------------------------------------------------------------------- + bool EventLogger::isLoggable( const sal_Int32 _nLogLevel ) const + { + if ( !m_pImpl->isValid() ) + return false; + + try + { + return m_pImpl->getLogger()->isLoggable( _nLogLevel ); + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "EventLogger::isLoggable: caught an exception!" ); + } + + return false; + } + + //-------------------------------------------------------------------- + bool EventLogger::addLogHandler( const Reference< XLogHandler >& _rxLogHandler ) + { + try + { + if ( m_pImpl->isValid() ) + { + m_pImpl->getLogger()->addLogHandler( _rxLogHandler ); + return true; + } + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "EventLogger::addLogHandler: caught an exception!" ); + } + return false; + } + + //-------------------------------------------------------------------- + bool EventLogger::removeLogHandler( const Reference< XLogHandler >& _rxLogHandler ) + { + try + { + if ( m_pImpl->isValid() ) + { + m_pImpl->getLogger()->removeLogHandler( _rxLogHandler ); + return true; + } + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "EventLogger::removeLogHandler: caught an exception!" ); + } + return false; + } + + //-------------------------------------------------------------------- + namespace + { + void lcl_replaceParameter( ::rtl::OUString& _inout_Message, const ::rtl::OUString& _rPlaceHolder, const ::rtl::OUString& _rReplacement ) + { + sal_Int32 nPlaceholderPosition = _inout_Message.indexOf( _rPlaceHolder ); + OSL_ENSURE( nPlaceholderPosition >= 0, "lcl_replaceParameter: placeholder not found!" ); + if ( nPlaceholderPosition < 0 ) + return; + + _inout_Message = _inout_Message.replaceAt( nPlaceholderPosition, _rPlaceHolder.getLength(), _rReplacement ); + } + } + + //-------------------------------------------------------------------- + bool EventLogger::impl_log( const sal_Int32 _nLogLevel, + const sal_Char* _pSourceClass, const sal_Char* _pSourceMethod, const ::rtl::OUString& _rMessage, + const OptionalString& _rArgument1, const OptionalString& _rArgument2, + const OptionalString& _rArgument3, const OptionalString& _rArgument4, + const OptionalString& _rArgument5, const OptionalString& _rArgument6 ) const + { + // (if ::rtl::OUString had an indexOfAscii, we could save those ugly statics ...) + static ::rtl::OUString sPH1( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$1$" ) ) ); + static ::rtl::OUString sPH2( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$2$" ) ) ); + static ::rtl::OUString sPH3( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$3$" ) ) ); + static ::rtl::OUString sPH4( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$4$" ) ) ); + static ::rtl::OUString sPH5( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$5$" ) ) ); + static ::rtl::OUString sPH6( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$6$" ) ) ); + + ::rtl::OUString sMessage( _rMessage ); + if ( !!_rArgument1 ) + lcl_replaceParameter( sMessage, sPH1, *_rArgument1 ); + + if ( !!_rArgument2 ) + lcl_replaceParameter( sMessage, sPH2, *_rArgument2 ); + + if ( !!_rArgument3 ) + lcl_replaceParameter( sMessage, sPH3, *_rArgument3 ); + + if ( !!_rArgument4 ) + lcl_replaceParameter( sMessage, sPH4, *_rArgument4 ); + + if ( !!_rArgument5 ) + lcl_replaceParameter( sMessage, sPH5, *_rArgument5 ); + + if ( !!_rArgument6 ) + lcl_replaceParameter( sMessage, sPH6, *_rArgument6 ); + + try + { + Reference< XLogger > xLogger( m_pImpl->getLogger() ); + OSL_PRECOND( xLogger.is(), "EventLogger::impl_log: should never be called without a logger!" ); + if ( _pSourceClass && _pSourceMethod ) + { + xLogger->logp( + _nLogLevel, + ::rtl::OUString::createFromAscii( _pSourceClass ), + ::rtl::OUString::createFromAscii( _pSourceMethod ), + sMessage + ); + } + else + { + xLogger->log( _nLogLevel, sMessage ); + } + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "EventLogger::impl_log: caught an exception!" ); + } + + return false; + } + + //==================================================================== + //= ResourceBasedEventLogger_Data + //==================================================================== + struct ResourceBasedEventLogger_Data + { + /// the base name of the resource bundle + ::rtl::OUString sBundleBaseName; + /// did we already attempt to load the bundle? + bool bBundleLoaded; + /// the lazily loaded bundle + Reference< XResourceBundle > xBundle; + + ResourceBasedEventLogger_Data() + :sBundleBaseName() + ,bBundleLoaded( false ) + ,xBundle() + { + } + }; + + //-------------------------------------------------------------------- + bool lcl_loadBundle_nothrow( const ComponentContext& _rContext, ResourceBasedEventLogger_Data& _rLoggerData ) + { + if ( _rLoggerData.bBundleLoaded ) + return _rLoggerData.xBundle.is(); + + // no matter what happens below, don't attempt creation ever again + _rLoggerData.bBundleLoaded = true; + + try + { + Reference< XResourceBundleLoader > xLoader( _rContext.getSingleton( "com.sun.star.resource.OfficeResourceLoader" ), UNO_QUERY_THROW ); + _rLoggerData.xBundle = Reference< XResourceBundle >( xLoader->loadBundle_Default( _rLoggerData.sBundleBaseName ), UNO_QUERY_THROW ); + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "lcl_loadBundle_nothrow: caught an exception!" ); + } + + return _rLoggerData.xBundle.is(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString lcl_loadString_nothrow( const Reference< XResourceBundle >& _rxBundle, const sal_Int32 _nMessageResID ) + { + OSL_PRECOND( _rxBundle.is(), "lcl_loadString_nothrow: this will crash!" ); + ::rtl::OUString sMessage; + try + { + ::rtl::OUStringBuffer aBuffer; + aBuffer.appendAscii( "string:" ); + aBuffer.append( _nMessageResID ); + OSL_VERIFY( _rxBundle->getDirectElement( aBuffer.makeStringAndClear() ) >>= sMessage ); + } + catch( const Exception& e ) + { + (void)e; + OSL_FAIL( "lcl_loadString_nothrow: caught an exception!" ); + } + return sMessage; + } + + //==================================================================== + //= ResourceBasedEventLogger + //==================================================================== + //-------------------------------------------------------------------- + ResourceBasedEventLogger::ResourceBasedEventLogger( const Reference< XComponentContext >& _rxContext, const ::rtl::OUString& _rResourceBundleBaseName, + const ::rtl::OUString& _rLoggerName ) + :EventLogger( _rxContext, _rLoggerName ) + ,m_pData( new ResourceBasedEventLogger_Data ) + { + m_pData->sBundleBaseName = _rResourceBundleBaseName; + } + + //-------------------------------------------------------------------- + ResourceBasedEventLogger::ResourceBasedEventLogger( const Reference< XComponentContext >& _rxContext, const sal_Char* _pResourceBundleBaseName, + const sal_Char* _pAsciiLoggerName ) + :EventLogger( _rxContext, _pAsciiLoggerName ) + ,m_pData( new ResourceBasedEventLogger_Data ) + { + m_pData->sBundleBaseName = ::rtl::OUString::createFromAscii( _pResourceBundleBaseName ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString ResourceBasedEventLogger::impl_loadStringMessage_nothrow( const sal_Int32 _nMessageResID ) const + { + ::rtl::OUString sMessage; + if ( lcl_loadBundle_nothrow( m_pImpl->getContext(), *m_pData ) ) + sMessage = lcl_loadString_nothrow( m_pData->xBundle, _nMessageResID ); + if ( sMessage.getLength() == 0 ) + { + ::rtl::OUStringBuffer aBuffer; + aBuffer.appendAscii( "<invalid event resource: '" ); + aBuffer.append( m_pData->sBundleBaseName ); + aBuffer.appendAscii( ":" ); + aBuffer.append( _nMessageResID ); + aBuffer.appendAscii( "'>" ); + sMessage = aBuffer.makeStringAndClear(); + } + return sMessage; + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/mediadescriptor.cxx b/comphelper/source/misc/mediadescriptor.cxx new file mode 100644 index 000000000000..321573d3307d --- /dev/null +++ b/comphelper/source/misc/mediadescriptor.cxx @@ -0,0 +1,767 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/mediadescriptor.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <comphelper/stillreadwriteinteraction.hxx> + +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/ucb/InteractiveIOException.hpp> +#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> +#include <com/sun/star/ucb/CommandFailedException.hpp> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XUriReference.hpp> +#include <com/sun/star/ucb/PostCommandArgument2.hpp> +#include <com/sun/star/container/XNameAccess.hpp> + +#include <ucbhelper/interceptedinteraction.hxx> +#include <ucbhelper/content.hxx> +#include <ucbhelper/commandenvironment.hxx> +#include <ucbhelper/activedatasink.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/configurationhelper.hxx> + +#include <rtl/ustrbuf.hxx> + +//_______________________________________________ +// namespace + +namespace comphelper{ + +namespace css = ::com::sun::star; + +//_______________________________________________ +// definitions + +const ::rtl::OUString& MediaDescriptor::PROP_ABORTED() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Aborted")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_ASTEMPLATE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_COMPONENTDATA() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ComponentData")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTSERVICE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentService")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_ENCRYPTIONDATA() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("EncryptionData")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_FILENAME() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FileName")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_FILTERNAME() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterName")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_FILTEROPTIONS() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FilterOptions")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_FRAME() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Frame")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_FRAMENAME() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("FrameName")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_HIDDEN() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Hidden")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_INPUTSTREAM() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("InputStream")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_INTERACTIONHANDLER() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_JUMPMARK() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("JumpMark")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_MACROEXECUTIONMODE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("MacroExecutionMode")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_MEDIATYPE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("MediaType")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_MINIMIZED() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Minimized")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_NOAUTOSAVE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("NoAutoSave")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_OPENNEWVIEW() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("OpenNewView")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_OUTPUTSTREAM() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("OutputStream")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_POSTDATA() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("PostData")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_PREVIEW() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Preview")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_READONLY() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_REFERRER() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Referer")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_STATUSINDICATOR() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("StatusIndicator")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_STREAM() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Stream")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_STREAMFOROUTPUT() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("StreamForOutput")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_TEMPLATENAME() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TemplateName")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_TYPENAME() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("TypeName")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_UCBCONTENT() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("UCBContent")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_UPDATEDOCMODE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("UpdateDocMode")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_URL() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("URL")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_VERSION() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Version")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTTITLE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_MODEL() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Model")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_PASSWORD() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Password")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_TITLE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("Title")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_SALVAGEDFILE() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("SalvagedFile")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_VIEWONLY() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("ViewOnly")); + return sProp; +} + +const ::rtl::OUString& MediaDescriptor::PROP_DOCUMENTBASEURL() +{ + static const ::rtl::OUString sProp(RTL_CONSTASCII_USTRINGPARAM("DocumentBaseURL")); + return sProp; +} + +/*----------------------------------------------- + 10.03.2004 08:09 +-----------------------------------------------*/ +MediaDescriptor::MediaDescriptor() + : SequenceAsHashMap() +{ +} + +MediaDescriptor::MediaDescriptor(const css::uno::Sequence< css::beans::PropertyValue >& lSource) + : SequenceAsHashMap(lSource) +{ +} + +sal_Bool MediaDescriptor::isStreamReadOnly() const +{ + static ::rtl::OUString CONTENTSCHEME_FILE( RTL_CONSTASCII_USTRINGPARAM( "file" )); + static ::rtl::OUString CONTENTPROP_ISREADONLY( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" )); + static sal_Bool READONLY_FALLBACK = sal_False; + + sal_Bool bReadOnly = READONLY_FALLBACK; + + // check for explicit readonly state + const_iterator pIt = find(MediaDescriptor::PROP_READONLY()); + if (pIt != end()) + { + pIt->second >>= bReadOnly; + return bReadOnly; + } + + // streams based on post data are readonly by definition + pIt = find(MediaDescriptor::PROP_POSTDATA()); + if (pIt != end()) + return sal_True; + + // A XStream capsulate XInputStream and XOutputStream ... + // If it exists - the file must be open in read/write mode! + pIt = find(MediaDescriptor::PROP_STREAM()); + if (pIt != end()) + return sal_False; + + // Only file system content provider is able to provide XStream + // so for this content impossibility to create XStream triggers + // switch to readonly mode. + try + { + css::uno::Reference< css::ucb::XContent > xContent = getUnpackedValueOrDefault(MediaDescriptor::PROP_UCBCONTENT(), css::uno::Reference< css::ucb::XContent >()); + if (xContent.is()) + { + css::uno::Reference< css::ucb::XContentIdentifier > xId(xContent->getIdentifier(), css::uno::UNO_QUERY); + ::rtl::OUString aScheme; + if (xId.is()) + aScheme = xId->getContentProviderScheme(); + + if (aScheme.equalsIgnoreAsciiCase(CONTENTSCHEME_FILE)) + bReadOnly = sal_True; + else + { + ::ucbhelper::Content aContent(xContent, css::uno::Reference< css::ucb::XCommandEnvironment >()); + aContent.getPropertyValue(CONTENTPROP_ISREADONLY) >>= bReadOnly; + } + } + } + catch(const css::uno::RuntimeException& exRun) + { throw exRun; } + catch(const css::uno::Exception&) + {} + + return bReadOnly; +} + +// ---------------------------------------------------------------------------- + +css::uno::Any MediaDescriptor::getComponentDataEntry( const ::rtl::OUString& rName ) const +{ + css::uno::Any aEntry; + SequenceAsHashMap::const_iterator aPropertyIter = find( PROP_COMPONENTDATA() ); + if( aPropertyIter != end() ) + return NamedValueCollection( aPropertyIter->second ).get( rName ); + return css::uno::Any(); +} + +void MediaDescriptor::setComponentDataEntry( const ::rtl::OUString& rName, const css::uno::Any& rValue ) +{ + if( rValue.hasValue() ) + { + // get or create the 'ComponentData' property entry + css::uno::Any& rCompDataAny = operator[]( PROP_COMPONENTDATA() ); + // insert the value (retain sequence type, create NamedValue elements by default) + bool bHasNamedValues = !rCompDataAny.hasValue() || rCompDataAny.has< css::uno::Sequence< css::beans::NamedValue > >(); + bool bHasPropValues = rCompDataAny.has< css::uno::Sequence< css::beans::PropertyValue > >(); + OSL_ENSURE( bHasNamedValues || bHasPropValues, "MediaDescriptor::setComponentDataEntry - incompatible 'ComponentData' property in media descriptor" ); + if( bHasNamedValues || bHasPropValues ) + { + // insert or overwrite the passed value + SequenceAsHashMap aCompDataMap( rCompDataAny ); + aCompDataMap[ rName ] = rValue; + // write back the sequence (restore sequence with correct element type) + rCompDataAny = aCompDataMap.getAsConstAny( bHasPropValues ); + } + } + else + { + // if an empty Any is passed, clear the entry + clearComponentDataEntry( rName ); + } +} + +void MediaDescriptor::clearComponentDataEntry( const ::rtl::OUString& rName ) +{ + SequenceAsHashMap::iterator aPropertyIter = find( PROP_COMPONENTDATA() ); + if( aPropertyIter != end() ) + { + css::uno::Any& rCompDataAny = aPropertyIter->second; + bool bHasNamedValues = rCompDataAny.has< css::uno::Sequence< css::beans::NamedValue > >(); + bool bHasPropValues = rCompDataAny.has< css::uno::Sequence< css::beans::PropertyValue > >(); + OSL_ENSURE( bHasNamedValues || bHasPropValues, "MediaDescriptor::clearComponentDataEntry - incompatible 'ComponentData' property in media descriptor" ); + if( bHasNamedValues || bHasPropValues ) + { + // remove the value with the passed name + SequenceAsHashMap aCompDataMap( rCompDataAny ); + aCompDataMap.erase( rName ); + // write back the sequence, or remove it completely if it is empty + if( aCompDataMap.empty() ) + erase( aPropertyIter ); + else + rCompDataAny = aCompDataMap.getAsConstAny( bHasPropValues ); + } + } +} + +sal_Bool MediaDescriptor::addInputStream() +{ + return impl_addInputStream( sal_True ); +} + +/*-----------------------------------------------*/ +sal_Bool MediaDescriptor::addInputStreamOwnLock() +{ + // Own lock file implementation + + sal_Bool bUseLock = sal_True; // the system file locking is used per default + try + { + + css::uno::Reference< css::uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig( + ::comphelper::getProcessServiceFactory(), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ), + ::comphelper::ConfigurationHelper::E_STANDARD ); + if ( !xCommonConfig.is() ) + throw css::uno::RuntimeException(); + + ::comphelper::ConfigurationHelper::readRelativeKey( + xCommonConfig, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentSystemFileLocking" ) ) ) >>= bUseLock; + } + catch( const css::uno::Exception& ) + { + } + + return impl_addInputStream( bUseLock ); +} + +/*-----------------------------------------------*/ +sal_Bool MediaDescriptor::impl_addInputStream( sal_Bool bLockFile ) +{ + // check for an already existing stream item first + const_iterator pIt = find(MediaDescriptor::PROP_INPUTSTREAM()); + if (pIt != end()) + return sal_True; + + try + { + // No stream available - create a new one + // a) data comes as PostData ... + pIt = find(MediaDescriptor::PROP_POSTDATA()); + if (pIt != end()) + { + const css::uno::Any& rPostData = pIt->second; + css::uno::Reference< css::io::XInputStream > xPostData; + rPostData >>= xPostData; + + return impl_openStreamWithPostData( xPostData ); + } + + // b) ... or we must get it from the given URL + ::rtl::OUString sURL = getUnpackedValueOrDefault(MediaDescriptor::PROP_URL(), ::rtl::OUString()); + if (!sURL.getLength()) + throw css::uno::Exception( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found no URL." )), + css::uno::Reference< css::uno::XInterface >()); + + // Parse URL! Only the main part has to be used further. E.g. a jumpmark can make trouble + ::rtl::OUString sNormalizedURL = impl_normalizeURL( sURL ); + return impl_openStreamWithURL( sNormalizedURL, bLockFile ); + } +#if OSL_DEBUG_LEVEL > 0 + catch(const css::uno::Exception& ex) + { + ::rtl::OUStringBuffer sMsg(256); + sMsg.appendAscii("Invalid MediaDescriptor detected:\n"); + sMsg.append (ex.Message ); + OSL_FAIL(::rtl::OUStringToOString(sMsg.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr()); + } +#else + catch(const css::uno::Exception&) + {} +#endif + + return sal_False; +} + +sal_Bool MediaDescriptor::impl_openStreamWithPostData( const css::uno::Reference< css::io::XInputStream >& _rxPostData ) + throw(::com::sun::star::uno::RuntimeException) +{ + if ( !_rxPostData.is() ) + throw css::lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Found invalid PostData." )), + css::uno::Reference< css::uno::XInterface >(), 1); + + // PostData can't be used in read/write mode! + (*this)[MediaDescriptor::PROP_READONLY()] <<= sal_True; + + // prepare the environment + css::uno::Reference< css::task::XInteractionHandler > xInteraction = getUnpackedValueOrDefault( + MediaDescriptor::PROP_INTERACTIONHANDLER(), + css::uno::Reference< css::task::XInteractionHandler >()); + css::uno::Reference< css::ucb::XProgressHandler > xProgress; + ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment(xInteraction, xProgress); + css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv(static_cast< css::ucb::XCommandEnvironment* >(pCommandEnv), css::uno::UNO_QUERY); + + // media type + ::rtl::OUString sMediaType = getUnpackedValueOrDefault(MediaDescriptor::PROP_MEDIATYPE(), ::rtl::OUString()); + if (!sMediaType.getLength()) + { + sMediaType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-www-form-urlencoded" )); + (*this)[MediaDescriptor::PROP_MEDIATYPE()] <<= sMediaType; + } + + // url + ::rtl::OUString sURL( getUnpackedValueOrDefault( PROP_URL(), ::rtl::OUString() ) ); + + css::uno::Reference< css::io::XInputStream > xResultStream; + try + { + // seek PostData stream to the beginning + css::uno::Reference< css::io::XSeekable > xSeek( _rxPostData, css::uno::UNO_QUERY ); + if ( xSeek.is() ) + xSeek->seek( 0 ); + + // a content for the URL + ::ucbhelper::Content aContent( sURL, xCommandEnv ); + + // use post command + css::ucb::PostCommandArgument2 aPostArgument; + aPostArgument.Source = _rxPostData; + css::uno::Reference< css::io::XActiveDataSink > xSink( new ucbhelper::ActiveDataSink ); + aPostArgument.Sink = xSink; + aPostArgument.MediaType = sMediaType; + aPostArgument.Referer = getUnpackedValueOrDefault( PROP_REFERRER(), ::rtl::OUString() ); + + ::rtl::OUString sCommandName( RTL_CONSTASCII_USTRINGPARAM( "post" ) ); + aContent.executeCommand( sCommandName, css::uno::makeAny( aPostArgument ) ); + + // get result + xResultStream = xSink->getInputStream(); + } + catch( const css::uno::Exception& ) + { + } + + // success? + if ( !xResultStream.is() ) + { + OSL_FAIL( "no valid reply to the HTTP-Post" ); + return sal_False; + } + + (*this)[MediaDescriptor::PROP_INPUTSTREAM()] <<= xResultStream; + return sal_True; +} + +/*-----------------------------------------------*/ +sal_Bool MediaDescriptor::impl_openStreamWithURL( const ::rtl::OUString& sURL, sal_Bool bLockFile ) + throw(::com::sun::star::uno::RuntimeException) +{ + // prepare the environment + css::uno::Reference< css::task::XInteractionHandler > xOrgInteraction = getUnpackedValueOrDefault( + MediaDescriptor::PROP_INTERACTIONHANDLER(), + css::uno::Reference< css::task::XInteractionHandler >()); + + StillReadWriteInteraction* pInteraction = new StillReadWriteInteraction(xOrgInteraction); + css::uno::Reference< css::task::XInteractionHandler > xInteraction(static_cast< css::task::XInteractionHandler* >(pInteraction), css::uno::UNO_QUERY); + + css::uno::Reference< css::ucb::XProgressHandler > xProgress; + ::ucbhelper::CommandEnvironment* pCommandEnv = new ::ucbhelper::CommandEnvironment(xInteraction, xProgress); + css::uno::Reference< css::ucb::XCommandEnvironment > xCommandEnv(static_cast< css::ucb::XCommandEnvironment* >(pCommandEnv), css::uno::UNO_QUERY); + + // try to create the content + // no content -> no stream => return immediatly with FALSE + ::ucbhelper::Content aContent; + css::uno::Reference< css::ucb::XContent > xContent; + try + { + aContent = ::ucbhelper::Content(sURL, xCommandEnv); + xContent = aContent.get(); + } + catch(const css::uno::RuntimeException&) + { throw; } + catch(const css::ucb::ContentCreationException&) + { return sal_False; } // TODO error handling + catch(const css::uno::Exception&) + { return sal_False; } // TODO error handling + + // try to open the file in read/write mode + // (if its allowed to do so). + // But handle errors in a "hidden mode". Because + // we try it readonly later - if read/write isnt an option. + css::uno::Reference< css::io::XStream > xStream ; + css::uno::Reference< css::io::XInputStream > xInputStream; + + sal_Bool bReadOnly = sal_False; + sal_Bool bModeRequestedExplicitly = sal_False; + const_iterator pIt = find(MediaDescriptor::PROP_READONLY()); + if (pIt != end()) + { + pIt->second >>= bReadOnly; + bModeRequestedExplicitly = sal_True; + } + + if ( !bReadOnly && bLockFile ) + { + try + { + // TODO: use "special" still interaction to supress error messages + xStream = aContent.openWriteableStream(); + if (xStream.is()) + xInputStream = xStream->getInputStream(); + } + catch(const css::uno::RuntimeException&) + { throw; } + catch(const css::uno::Exception&) + { + // ignore exception, if reason was problem reasoned on + // open it in WRITEABLE mode! Then we try it READONLY + // later a second time. + // All other errors must be handled as real error an + // break this method. + if (!pInteraction->wasWriteError() || bModeRequestedExplicitly) + return sal_False; + xStream.clear(); + xInputStream.clear(); + } + } + + // If opening of the stream in read/write mode wasnt allowed + // or failed by an error - we must try it in readonly mode. + if (!xInputStream.is()) + { + rtl::OUString aScheme; + + try + { + css::uno::Reference< css::ucb::XContentIdentifier > xContId( + aContent.get().is() ? aContent.get()->getIdentifier() : 0 ); + + if ( xContId.is() ) + aScheme = xContId->getContentProviderScheme(); + + // Only file system content provider is able to provide XStream + // so for this content impossibility to create XStream triggers + // switch to readonly mode in case of opening with locking on + if( bLockFile && aScheme.equalsIgnoreAsciiCaseAscii( "file" ) ) + bReadOnly = sal_True; + else + { + sal_Bool bRequestReadOnly = bReadOnly; + aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bReadOnly; + if ( bReadOnly && !bRequestReadOnly && bModeRequestedExplicitly ) + return sal_False; // the document is explicitly requested with WRITEABLE mode + } + } + catch(const css::uno::RuntimeException&) + { throw; } + catch(const css::uno::Exception&) + { /* no error handling if IsReadOnly property does not exist for UCP */ } + + if ( bReadOnly ) + (*this)[MediaDescriptor::PROP_READONLY()] <<= bReadOnly; + + pInteraction->resetInterceptions(); + pInteraction->resetErrorStates(); + try + { + // all the contents except file-URLs should be opened as usual + if ( bLockFile || !aScheme.equalsIgnoreAsciiCaseAscii( "file" ) ) + xInputStream = aContent.openStream(); + else + xInputStream = aContent.openStreamNoLock(); + } + catch(const css::uno::RuntimeException&) + { throw; } + catch(const css::uno::Exception&) + { return sal_False; } + } + + // add streams to the descriptor + if (xContent.is()) + (*this)[MediaDescriptor::PROP_UCBCONTENT()] <<= xContent; + if (xStream.is()) + (*this)[MediaDescriptor::PROP_STREAM()] <<= xStream; + if (xInputStream.is()) + (*this)[MediaDescriptor::PROP_INPUTSTREAM()] <<= xInputStream; + + // At least we need an input stream. The r/w stream is optional ... + return xInputStream.is(); +} + +::rtl::OUString MediaDescriptor::impl_normalizeURL(const ::rtl::OUString& sURL) +{ + /* Remove Jumpmarks (fragments) of an URL only here. + They are not part of any URL and as a result may be + no ucb content can be created then. + On the other side arguments must exists ... because + they are part of an URL. + + Do not use the URLTransformer service here. Because + it parses the URL in another way. It's main part isnt enough + and it's complete part contains the jumpmark (fragment) parameter ... + */ + static ::rtl::OUString SERVICENAME_URIREFERENCEFACTORY( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.uri.UriReferenceFactory" )); + + try + { + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); + css::uno::Reference< css::uri::XUriReferenceFactory > xUriFactory(xSMGR->createInstance(SERVICENAME_URIREFERENCEFACTORY), css::uno::UNO_QUERY_THROW); + css::uno::Reference< css::uri::XUriReference > xUriRef = xUriFactory->parse(sURL); + if (xUriRef.is()) + { + xUriRef->clearFragment(); + return xUriRef->getUriReference(); + } + } + catch(const css::uno::RuntimeException& exRun) + { throw exRun; } + catch(const css::uno::Exception&) + {} + + // If an error ocurred ... return the original URL. + // It's a try .-) + return sURL; +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/mimeconfighelper.cxx b/comphelper/source/misc/mimeconfighelper.cxx new file mode 100644 index 000000000000..c81e761392b9 --- /dev/null +++ b/comphelper/source/misc/mimeconfighelper.cxx @@ -0,0 +1,943 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XContainerQuery.hpp> +#include <com/sun/star/document/XTypeDetection.hpp> + +#include <comphelper/fileformat.h> +#include <comphelper/mimeconfighelper.hxx> +#include <comphelper/classids.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/documentconstants.hxx> + + +using namespace ::com::sun::star; +using namespace comphelper; + +//----------------------------------------------------------------------- +MimeConfigurationHelper::MimeConfigurationHelper( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +: m_xFactory( xFactory ) +{ + if ( !m_xFactory.is() ) + throw uno::RuntimeException(); +} + +//----------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetStringClassIDRepresentation( const uno::Sequence< sal_Int8 >& aClassID ) +{ + ::rtl::OUString aResult; + + if ( aClassID.getLength() == 16 ) + { + for ( sal_Int32 nInd = 0; nInd < aClassID.getLength(); nInd++ ) + { + if ( nInd == 4 || nInd == 6 || nInd == 8 || nInd == 10 ) + aResult += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "-" )); + + sal_Int32 nDigit1 = (sal_Int32)( (sal_uInt8)aClassID[nInd] / 16 ); + sal_Int32 nDigit2 = (sal_uInt8)aClassID[nInd] % 16; + aResult += ::rtl::OUString::valueOf( nDigit1, 16 ); + aResult += ::rtl::OUString::valueOf( nDigit2, 16 ); + } + } + + return aResult; +} + +//----------------------------------------------------------------------- +sal_uInt8 GetDigit_Impl( sal_Char aChar ) +{ + if ( aChar >= '0' && aChar <= '9' ) + return aChar - '0'; + else if ( aChar >= 'a' && aChar <= 'f' ) + return aChar - 'a' + 10; + else if ( aChar >= 'A' && aChar <= 'F' ) + return aChar - 'A' + 10; + else + return 16; +} + +//----------------------------------------------------------------------- +uno::Sequence< sal_Int8 > MimeConfigurationHelper::GetSequenceClassIDRepresentation( const ::rtl::OUString& aClassID ) +{ + sal_Int32 nLength = aClassID.getLength(); + if ( nLength == 36 ) + { + ::rtl::OString aCharClassID = ::rtl::OUStringToOString( aClassID, RTL_TEXTENCODING_ASCII_US ); + const sal_Char* pString = aCharClassID.getStr(); + if ( pString ) + { + uno::Sequence< sal_Int8 > aResult( 16 ); + + sal_Int32 nStrPointer = 0; + sal_Int32 nSeqInd = 0; + while( nSeqInd < 16 && nStrPointer + 1 < nLength ) + { + sal_uInt8 nDigit1 = GetDigit_Impl( pString[nStrPointer++] ); + sal_uInt8 nDigit2 = GetDigit_Impl( pString[nStrPointer++] ); + + if ( nDigit1 > 15 || nDigit2 > 15 ) + break; + + aResult[nSeqInd++] = (sal_Int8)( nDigit1 * 16 + nDigit2 ); + + if ( nStrPointer < nLength && pString[nStrPointer] == '-' ) + nStrPointer++; + } + + if ( nSeqInd == 16 && nStrPointer == nLength ) + return aResult; + } + } + + return uno::Sequence< sal_Int8 >(); +} + +//----------------------------------------------------------------------- +uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetConfigurationByPath( const ::rtl::OUString& aPath ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + uno::Reference< container::XNameAccess > xConfig; + + try + { + if ( !m_xConfigProvider.is() ) + m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >( + m_xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" )) ), + uno::UNO_QUERY_THROW ); + + uno::Sequence< uno::Any > aArgs( 1 ); + beans::PropertyValue aPathProp; + aPathProp.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" )); + aPathProp.Value <<= aPath; + aArgs[0] <<= aPathProp; + + xConfig = uno::Reference< container::XNameAccess >( + m_xConfigProvider->createInstanceWithArguments( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )), + aArgs ), + uno::UNO_QUERY ); + } + catch( uno::Exception& ) + {} + + return xConfig; +} + +//----------------------------------------------------------------------- +uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetObjConfiguration() +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xObjectConfig.is() ) + m_xObjectConfig = GetConfigurationByPath( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Embedding/Objects" )) ); + + return m_xObjectConfig; +} + +//----------------------------------------------------------------------- +uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetVerbsConfiguration() +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xVerbsConfig.is() ) + m_xVerbsConfig = GetConfigurationByPath( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Embedding/Verbs" )) ); + + return m_xVerbsConfig; +} + +//----------------------------------------------------------------------- +uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetMediaTypeConfiguration() +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xMediaTypeConfig.is() ) + m_xMediaTypeConfig = GetConfigurationByPath( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Embedding/MimeTypeClassIDRelations" )) ); + + return m_xMediaTypeConfig; +} + +//----------------------------------------------------------------------- +uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetFilterFactory() +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xFilterFactory.is() ) + m_xFilterFactory.set( + m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.FilterFactory")) ), + uno::UNO_QUERY ); + + return m_xFilterFactory; +} + +//----------------------------------------------------------------------- +sal_Int32 MimeConfigurationHelper::GetFilterFlags( const ::rtl::OUString& aFilterName ) +{ + sal_Int32 nFlags = 0; + try + { + if ( aFilterName.getLength() ) + { + uno::Reference< container::XNameAccess > xFilterFactory( + GetFilterFactory(), + uno::UNO_SET_THROW ); + + uno::Any aFilterAny = xFilterFactory->getByName( aFilterName ); + uno::Sequence< beans::PropertyValue > aData; + if ( aFilterAny >>= aData ) + { + SequenceAsHashMap aFilterHM( aData ); + nFlags = aFilterHM.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")), (sal_Int32)0 ); + } + } + } catch( uno::Exception& ) + {} + + return nFlags; +} + +//------------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetDocServiceNameFromFilter( const ::rtl::OUString& aFilterName ) +{ + ::rtl::OUString aDocServiceName; + + try + { + uno::Reference< container::XNameAccess > xFilterFactory( + GetFilterFactory(), + uno::UNO_SET_THROW ); + + uno::Any aFilterAnyData = xFilterFactory->getByName( aFilterName ); + uno::Sequence< beans::PropertyValue > aFilterData; + if ( aFilterAnyData >>= aFilterData ) + { + for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ ) + if ( aFilterData[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DocumentService" ) ) ) + aFilterData[nInd].Value >>= aDocServiceName; + } + } + catch( uno::Exception& ) + {} + + return aDocServiceName; +} + +//------------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetDocServiceNameFromMediaType( const ::rtl::OUString& aMediaType ) +{ + uno::Reference< container::XContainerQuery > xTypeCFG( + m_xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.TypeDetection" )) ), + uno::UNO_QUERY ); + + if ( xTypeCFG.is() ) + { + try + { + // make query for all types matching the properties + uno::Sequence < beans::NamedValue > aSeq( 1 ); + aSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" )); + aSeq[0].Value <<= aMediaType; + + uno::Reference < container::XEnumeration > xEnum = xTypeCFG->createSubSetEnumerationByProperties( aSeq ); + while ( xEnum->hasMoreElements() ) + { + uno::Sequence< beans::PropertyValue > aType; + if ( xEnum->nextElement() >>= aType ) + { + for ( sal_Int32 nInd = 0; nInd < aType.getLength(); nInd++ ) + { + ::rtl::OUString aFilterName; + if ( aType[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PreferredFilter" ) ) + && ( aType[nInd].Value >>= aFilterName ) && aFilterName.getLength() ) + { + ::rtl::OUString aDocumentName = GetDocServiceNameFromFilter( aFilterName ); + if ( aDocumentName.getLength() ) + return aDocumentName; + } + } + } + } + } + catch( uno::Exception& ) + {} + } + + return ::rtl::OUString(); +} + +//------------------------------------------------------------------------- +sal_Bool MimeConfigurationHelper::GetVerbByShortcut( const ::rtl::OUString& aVerbShortcut, + embed::VerbDescriptor& aDescriptor ) +{ + sal_Bool bResult = sal_False; + + uno::Reference< container::XNameAccess > xVerbsConfig = GetVerbsConfiguration(); + uno::Reference< container::XNameAccess > xVerbsProps; + try + { + if ( xVerbsConfig.is() && ( xVerbsConfig->getByName( aVerbShortcut ) >>= xVerbsProps ) && xVerbsProps.is() ) + { + embed::VerbDescriptor aTempDescr; + if ( ( xVerbsProps->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerbID" )) ) >>= aTempDescr.VerbID ) + && ( xVerbsProps->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerbUIName" )) ) >>= aTempDescr.VerbName ) + && ( xVerbsProps->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerbFlags" )) ) >>= aTempDescr.VerbFlags ) + && ( xVerbsProps->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerbAttributes" )) ) >>= aTempDescr.VerbAttributes ) ) + { + aDescriptor = aTempDescr; + bResult = sal_True; + } + } + } + catch( uno::Exception& ) + { + } + + return bResult; +} + +//------------------------------------------------------------------------- +uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjPropsFromConfigEntry( + const uno::Sequence< sal_Int8 >& aClassID, + const uno::Reference< container::XNameAccess >& xObjectProps ) +{ + uno::Sequence< beans::NamedValue > aResult; + + if ( aClassID.getLength() == 16 ) + { + try + { + uno::Sequence< ::rtl::OUString > aObjPropNames = xObjectProps->getElementNames(); + + aResult.realloc( aObjPropNames.getLength() + 1 ); + aResult[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ClassID" )); + aResult[0].Value <<= aClassID; + + for ( sal_Int32 nInd = 0; nInd < aObjPropNames.getLength(); nInd++ ) + { + aResult[nInd + 1].Name = aObjPropNames[nInd]; + + if ( aObjPropNames[nInd].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ObjectVerbs" ) ) ) + { + uno::Sequence< ::rtl::OUString > aVerbShortcuts; + if ( xObjectProps->getByName( aObjPropNames[nInd] ) >>= aVerbShortcuts ) + { + uno::Sequence< embed::VerbDescriptor > aVerbDescriptors( aVerbShortcuts.getLength() ); + for ( sal_Int32 nVerbI = 0; nVerbI < aVerbShortcuts.getLength(); nVerbI++ ) + if ( !GetVerbByShortcut( aVerbShortcuts[nVerbI], aVerbDescriptors[nVerbI] ) ) + throw uno::RuntimeException(); + + aResult[nInd+1].Value <<= aVerbDescriptors; + } + else + throw uno::RuntimeException(); + } + else + aResult[nInd+1].Value = xObjectProps->getByName( aObjPropNames[nInd] ); + } + } + catch( uno::Exception& ) + { + aResult.realloc( 0 ); + } + } + + return aResult; +} + +//----------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetExplicitlyRegisteredObjClassID( const ::rtl::OUString& aMediaType ) +{ + ::rtl::OUString aStringClassID; + + uno::Reference< container::XNameAccess > xMediaTypeConfig = GetMediaTypeConfiguration(); + try + { + if ( xMediaTypeConfig.is() ) + xMediaTypeConfig->getByName( aMediaType ) >>= aStringClassID; + } + catch( uno::Exception& ) + { + } + + return aStringClassID; + +} + +//----------------------------------------------------------------------- +uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByStringClassID( + const ::rtl::OUString& aStringClassID ) +{ + uno::Sequence< beans::NamedValue > aObjProps; + + uno::Sequence< sal_Int8 > aClassID = GetSequenceClassIDRepresentation( aStringClassID ); + if ( ClassIDsEqual( aClassID, GetSequenceClassID( SO3_DUMMY_CLASSID ) ) ) + { + aObjProps.realloc(2); + aObjProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectFactory" )); + aObjProps[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" )); + aObjProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ClassID" )); + aObjProps[1].Value <<= aClassID; + return aObjProps; + } + + if ( aClassID.getLength() == 16 ) + { + uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration(); + uno::Reference< container::XNameAccess > xObjectProps; + try + { + // TODO/LATER: allow to provide ClassID string in any format, only digits are counted + if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() ) + aObjProps = GetObjPropsFromConfigEntry( aClassID, xObjectProps ); + } + catch( uno::Exception& ) + { + } + } + + return aObjProps; +} + +//----------------------------------------------------------------------- +uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByClassID( + const uno::Sequence< sal_Int8 >& aClassID ) +{ + uno::Sequence< beans::NamedValue > aObjProps; + if ( ClassIDsEqual( aClassID, GetSequenceClassID( SO3_DUMMY_CLASSID ) ) ) + { + aObjProps.realloc(2); + aObjProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectFactory" )); + aObjProps[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" )); + aObjProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ClassID" )); + aObjProps[1].Value <<= aClassID; + } + + ::rtl::OUString aStringClassID = GetStringClassIDRepresentation( aClassID ); + if ( aStringClassID.getLength() ) + { + uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration(); + uno::Reference< container::XNameAccess > xObjectProps; + try + { + if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() ) + aObjProps = GetObjPropsFromConfigEntry( aClassID, xObjectProps ); + } + catch( uno::Exception& ) + { + } + } + + return aObjProps; +} + +//----------------------------------------------------------------------- +uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByMediaType( const ::rtl::OUString& aMediaType ) +{ + uno::Sequence< beans::NamedValue > aObject = + GetObjectPropsByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType ) ); + if ( aObject.getLength() ) + return aObject; + + ::rtl::OUString aDocumentName = GetDocServiceNameFromMediaType( aMediaType ); + if ( aDocumentName.getLength() ) + return GetObjectPropsByDocumentName( aDocumentName ); + + return uno::Sequence< beans::NamedValue >(); +} + +//----------------------------------------------------------------------- +uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByFilter( const ::rtl::OUString& aFilterName ) +{ + ::rtl::OUString aDocumentName = GetDocServiceNameFromFilter( aFilterName ); + if ( aDocumentName.getLength() ) + return GetObjectPropsByDocumentName( aDocumentName ); + + return uno::Sequence< beans::NamedValue >(); +} + +//----------------------------------------------------------------------- +uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByDocumentName( const ::rtl::OUString& aDocName ) +{ + if ( aDocName.getLength() ) + { + uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration(); + if ( xObjConfig.is() ) + { + try + { + uno::Sequence< ::rtl::OUString > aClassIDs = xObjConfig->getElementNames(); + for ( sal_Int32 nInd = 0; nInd < aClassIDs.getLength(); nInd++ ) + { + uno::Reference< container::XNameAccess > xObjectProps; + ::rtl::OUString aEntryDocName; + + if ( ( xObjConfig->getByName( aClassIDs[nInd] ) >>= xObjectProps ) && xObjectProps.is() + && ( xObjectProps->getByName( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectDocumentServiceName" )) ) >>= aEntryDocName ) + && aEntryDocName.equals( aDocName ) ) + { + return GetObjPropsFromConfigEntry( GetSequenceClassIDRepresentation( aClassIDs[nInd] ), + xObjectProps ); + } + } + } + catch( uno::Exception& ) + {} + } + } + + return uno::Sequence< beans::NamedValue >(); +} + +//----------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetFactoryNameByClassID( const uno::Sequence< sal_Int8 >& aClassID ) +{ + return GetFactoryNameByStringClassID( GetStringClassIDRepresentation( aClassID ) ); +} + +//----------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetFactoryNameByStringClassID( const ::rtl::OUString& aStringClassID ) +{ + ::rtl::OUString aResult; + + if ( aStringClassID.getLength() ) + { + uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration(); + uno::Reference< container::XNameAccess > xObjectProps; + try + { + if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() ) + xObjectProps->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectFactory" )) ) >>= aResult; + } + catch( uno::Exception& ) + { + uno::Sequence< sal_Int8 > aClassID = GetSequenceClassIDRepresentation( aStringClassID ); + if ( ClassIDsEqual( aClassID, GetSequenceClassID( SO3_DUMMY_CLASSID ) ) ) + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" )); + } + } + + return aResult; +} + +//----------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetFactoryNameByDocumentName( const ::rtl::OUString& aDocName ) +{ + ::rtl::OUString aResult; + + if ( aDocName.getLength() ) + { + uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration(); + if ( xObjConfig.is() ) + { + try + { + uno::Sequence< ::rtl::OUString > aClassIDs = xObjConfig->getElementNames(); + for ( sal_Int32 nInd = 0; nInd < aClassIDs.getLength(); nInd++ ) + { + uno::Reference< container::XNameAccess > xObjectProps; + ::rtl::OUString aEntryDocName; + + if ( ( xObjConfig->getByName( aClassIDs[nInd] ) >>= xObjectProps ) && xObjectProps.is() + && ( xObjectProps->getByName( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectDocumentServiceName" )) ) >>= aEntryDocName ) + && aEntryDocName.equals( aDocName ) ) + { + xObjectProps->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectFactory" )) ) >>= aResult; + break; + } + } + } + catch( uno::Exception& ) + {} + } + } + + return aResult; +} + + +//----------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetFactoryNameByMediaType( const ::rtl::OUString& aMediaType ) +{ + ::rtl::OUString aResult = GetFactoryNameByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType ) ); + + if ( !aResult.getLength() ) + { + ::rtl::OUString aDocumentName = GetDocServiceNameFromMediaType( aMediaType ); + if ( aDocumentName.getLength() ) + aResult = GetFactoryNameByDocumentName( aDocumentName ); + } + + return aResult; +} + +//----------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName( + uno::Sequence< beans::PropertyValue >& aMediaDescr, + sal_Bool bIgnoreType ) +{ + ::rtl::OUString aFilterName; + + for ( sal_Int32 nInd = 0; nInd < aMediaDescr.getLength(); nInd++ ) + if ( aMediaDescr[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterName" ) ) ) + aMediaDescr[nInd].Value >>= aFilterName; + + if ( !aFilterName.getLength() ) + { + // filter name is not specified, so type detection should be done + + uno::Reference< document::XTypeDetection > xTypeDetection( + m_xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.TypeDetection" )) ), + uno::UNO_QUERY ); + + if ( !xTypeDetection.is() ) + throw uno::RuntimeException(); // TODO + + // typedetection can change the mode, add a stream and so on, thus a copy should be used + uno::Sequence< beans::PropertyValue > aTempMD( aMediaDescr ); + + // get TypeName + ::rtl::OUString aTypeName = xTypeDetection->queryTypeByDescriptor( aTempMD, sal_True ); + + // get FilterName + for ( sal_Int32 nInd = 0; nInd < aTempMD.getLength(); nInd++ ) + if ( aTempMD[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterName" ) ) ) + aTempMD[nInd].Value >>= aFilterName; + + if ( aFilterName.getLength() ) + { + sal_Int32 nOldLen = aMediaDescr.getLength(); + aMediaDescr.realloc( nOldLen + 1 ); + aMediaDescr[nOldLen].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" )); + aMediaDescr[ nOldLen ].Value <<= aFilterName; + + } + else if ( aTypeName.getLength() && !bIgnoreType ) + { + uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY ); + uno::Sequence< beans::PropertyValue > aTypes; + + if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) ) + { + for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ ) + { + if ( aTypes[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PreferredFilter" ) ) && ( aTypes[nInd].Value >>= aFilterName ) ) + { + sal_Int32 nOldLen = aMediaDescr.getLength(); + aMediaDescr.realloc( nOldLen + 1 ); + aMediaDescr[nOldLen].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" )); + aMediaDescr[ nOldLen ].Value = aTypes[nInd].Value; + break; + } + } + } + } + } + + return aFilterName; +} + +::rtl::OUString MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName( + uno::Sequence< beans::PropertyValue >& aMediaDescr, + uno::Sequence< beans::NamedValue >& aObject ) +{ + ::rtl::OUString aDocName; + for ( sal_Int32 nInd = 0; nInd < aObject.getLength(); nInd++ ) + if ( aObject[nInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ObjectDocumentServiceName" ) ) ) + { + aObject[nInd].Value >>= aDocName; + break; + } + + OSL_ENSURE( aDocName.getLength(), "The name must exist at this point!\n" ); + + + sal_Bool bNeedsAddition = sal_True; + for ( sal_Int32 nMedInd = 0; nMedInd < aMediaDescr.getLength(); nMedInd++ ) + if ( aMediaDescr[nMedInd].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DocumentService" ) ) ) + { + aMediaDescr[nMedInd].Value <<= aDocName; + bNeedsAddition = sal_False; + break; + } + + if ( bNeedsAddition ) + { + sal_Int32 nOldLen = aMediaDescr.getLength(); + aMediaDescr.realloc( nOldLen + 1 ); + aMediaDescr[nOldLen].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" )); + aMediaDescr[nOldLen].Value <<= aDocName; + } + + return UpdateMediaDescriptorWithFilterName( aMediaDescr, sal_True ); +} + +sal_Bool MimeConfigurationHelper::AddFilterNameCheckOwnFile( + uno::Sequence< beans::PropertyValue >& aMediaDescr ) +{ + sal_Bool bResult = sal_False; + + ::rtl::OUString aFilterName = UpdateMediaDescriptorWithFilterName( aMediaDescr, sal_False ); + if ( aFilterName.getLength() ) + { + sal_Int32 nFlags = GetFilterFlags( aFilterName ); + // check the OWN flag + bResult = ( nFlags & SFX_FILTER_OWN ); + } + + return bResult; +} + +//----------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetDefaultFilterFromServiceName( const ::rtl::OUString& aServiceName, sal_Int32 nVersion ) +{ + rtl::OUString aResult; + + if ( aServiceName.getLength() && nVersion ) + try + { + uno::Reference< container::XContainerQuery > xFilterQuery( + GetFilterFactory(), + uno::UNO_QUERY_THROW ); + + uno::Sequence< beans::NamedValue > aSearchRequest( 2 ); + aSearchRequest[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" )); + aSearchRequest[0].Value <<= aServiceName; + aSearchRequest[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileFormatVersion" )); + aSearchRequest[1].Value <<= nVersion; + + uno::Sequence< beans::PropertyValue > aFilterProps; + uno::Reference< container::XEnumeration > xFilterEnum = + xFilterQuery->createSubSetEnumerationByProperties( aSearchRequest ); + + // use the first filter that is found + if ( xFilterEnum.is() ) + while ( xFilterEnum->hasMoreElements() ) + { + uno::Sequence< beans::PropertyValue > aProps; + if ( xFilterEnum->nextElement() >>= aProps ) + { + SequenceAsHashMap aPropsHM( aProps ); + sal_Int32 nFlags = aPropsHM.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Flags" )), + (sal_Int32)0 ); + + // that should be import, export, own filter and not a template filter ( TemplatePath flag ) + sal_Int32 nRequired = ( SFX_FILTER_OWN | SFX_FILTER_EXPORT | SFX_FILTER_IMPORT ); + if ( ( ( nFlags & nRequired ) == nRequired ) && !( nFlags & SFX_FILTER_TEMPLATEPATH ) ) + { + // if there are more than one filter the preffered one should be used + // if there is no preffered filter the first one will be used + if ( !aResult.getLength() || ( nFlags & SFX_FILTER_PREFERED ) ) + aResult = aPropsHM.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" )), + ::rtl::OUString() ); + if ( nFlags & SFX_FILTER_PREFERED ) + break; // the preffered filter was found + } + } + } + } + catch( uno::Exception& ) + {} + + return aResult; +} + +//------------------------------------------------------------------------- +::rtl::OUString MimeConfigurationHelper::GetExportFilterFromImportFilter( const ::rtl::OUString& aImportFilterName ) +{ + ::rtl::OUString aExportFilterName; + + try + { + if ( aImportFilterName.getLength() ) + { + uno::Reference< container::XNameAccess > xFilterFactory( + GetFilterFactory(), + uno::UNO_SET_THROW ); + + uno::Any aImpFilterAny = xFilterFactory->getByName( aImportFilterName ); + uno::Sequence< beans::PropertyValue > aImpData; + if ( aImpFilterAny >>= aImpData ) + { + SequenceAsHashMap aImpFilterHM( aImpData ); + sal_Int32 nFlags = aImpFilterHM.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")), + (sal_Int32)0 ); + + if ( !( nFlags & SFX_FILTER_IMPORT ) ) + { + OSL_FAIL( "This is no import filter!" ); + throw uno::Exception(); + } + + if ( nFlags & SFX_FILTER_EXPORT ) + { + aExportFilterName = aImportFilterName; + } + else + { + ::rtl::OUString aDocumentServiceName = aImpFilterHM.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentService")), ::rtl::OUString() ); + ::rtl::OUString aTypeName = aImpFilterHM.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Type")), ::rtl::OUString() ); + + OSL_ENSURE( aDocumentServiceName.getLength() && aTypeName.getLength(), "Incomplete filter data!" ); + if ( aDocumentServiceName.getLength() && aTypeName.getLength() ) + { + uno::Sequence< beans::NamedValue > aSearchRequest( 2 ); + aSearchRequest[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Type")); + aSearchRequest[0].Value <<= aTypeName; + aSearchRequest[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentService")); + aSearchRequest[1].Value <<= aDocumentServiceName; + + uno::Sequence< beans::PropertyValue > aExportFilterProps = SearchForFilter( + uno::Reference< container::XContainerQuery >( xFilterFactory, uno::UNO_QUERY_THROW ), + aSearchRequest, + SFX_FILTER_EXPORT, + SFX_FILTER_INTERNAL ); + + if ( aExportFilterProps.getLength() ) + { + SequenceAsHashMap aExpPropsHM( aExportFilterProps ); + aExportFilterName = aExpPropsHM.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), ::rtl::OUString() ); + } + } + } + } + } + } + catch( uno::Exception& ) + {} + + return aExportFilterName; +} + +//------------------------------------------------------------------------- +// static +uno::Sequence< beans::PropertyValue > MimeConfigurationHelper::SearchForFilter( + const uno::Reference< container::XContainerQuery >& xFilterQuery, + const uno::Sequence< beans::NamedValue >& aSearchRequest, + sal_Int32 nMustFlags, + sal_Int32 nDontFlags ) +{ + uno::Sequence< beans::PropertyValue > aFilterProps; + uno::Reference< container::XEnumeration > xFilterEnum = + xFilterQuery->createSubSetEnumerationByProperties( aSearchRequest ); + + // the first default filter will be taken, + // if there is no filter with flag default the first acceptable filter will be taken + if ( xFilterEnum.is() ) + { + while ( xFilterEnum->hasMoreElements() ) + { + uno::Sequence< beans::PropertyValue > aProps; + if ( xFilterEnum->nextElement() >>= aProps ) + { + SequenceAsHashMap aPropsHM( aProps ); + sal_Int32 nFlags = aPropsHM.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")), + (sal_Int32)0 ); + if ( ( ( nFlags & nMustFlags ) == nMustFlags ) && !( nFlags & nDontFlags ) ) + { + if ( ( nFlags & SFX_FILTER_DEFAULT ) == SFX_FILTER_DEFAULT ) + { + aFilterProps = aProps; + break; + } + else if ( !aFilterProps.getLength() ) + aFilterProps = aProps; + } + } + } + } + + return aFilterProps; +} + + +//------------------------------------------------------------------------- +sal_Bool MimeConfigurationHelper::ClassIDsEqual( const uno::Sequence< sal_Int8 >& aClassID1, const uno::Sequence< sal_Int8 >& aClassID2 ) +{ + if ( aClassID1.getLength() != aClassID2.getLength() ) + return sal_False; + + for ( sal_Int32 nInd = 0; nInd < aClassID1.getLength(); nInd++ ) + if ( aClassID1[nInd] != aClassID2[nInd] ) + return sal_False; + + return sal_True; +} + +//------------------------------------------------------------------------- +uno::Sequence< sal_Int8 > MimeConfigurationHelper::GetSequenceClassID( sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3, + sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11, + sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15 ) +{ + uno::Sequence< sal_Int8 > aResult( 16 ); + aResult[0] = (sal_Int8)( n1 >> 24 ); + aResult[1] = (sal_Int8)( ( n1 << 8 ) >> 24 ); + aResult[2] = (sal_Int8)( ( n1 << 16 ) >> 24 ); + aResult[3] = (sal_Int8)( ( n1 << 24 ) >> 24 ); + aResult[4] = (sal_Int8)( n2 >> 8 ); + aResult[5] = (sal_Int8)( ( n2 << 8 ) >> 8 ); + aResult[6] = (sal_Int8)( n3 >> 8 ); + aResult[7] = (sal_Int8)( ( n3 << 8 ) >> 8 ); + aResult[8] = b8; + aResult[9] = b9; + aResult[10] = b10; + aResult[11] = b11; + aResult[12] = b12; + aResult[13] = b13; + aResult[14] = b14; + aResult[15] = b15; + + return aResult; +} + +//------------------------------------------------------------------------- +uno::Sequence<sal_Int8> MimeConfigurationHelper::GetSequenceClassIDFromObjectName(const ::rtl::OUString& _sObjectName) +{ + uno::Sequence<sal_Int8> aClassId; + uno::Reference< container::XNameAccess > xObjectNames = GetConfigurationByPath(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Embedding/ObjectNames"))); + uno::Reference< container::XNameAccess > xProps; + if ( xObjectNames.is() && (xObjectNames->getByName(_sObjectName) >>= xProps) && xProps.is() ) + { + ::rtl::OUString sValue; + xProps->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ClassID"))) >>= sValue; + aClassId = GetSequenceClassIDRepresentation(sValue); + } + return aClassId; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/namedvaluecollection.cxx b/comphelper/source/misc/namedvaluecollection.cxx new file mode 100644 index 000000000000..6ed6cd1af22e --- /dev/null +++ b/comphelper/source/misc/namedvaluecollection.cxx @@ -0,0 +1,360 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/namedvaluecollection.hxx> + +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/beans/PropertyState.hpp> + +#include <rtl/ustrbuf.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/instance.hxx> +#include <osl/diagnose.h> + +#include <boost/unordered_map.hpp> +#include <functional> +#include <algorithm> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::beans::PropertyValue; + using ::com::sun::star::beans::NamedValue; + using ::com::sun::star::uno::Type; + using ::com::sun::star::uno::cpp_acquire; + using ::com::sun::star::uno::cpp_release; + using ::com::sun::star::uno::cpp_queryInterface; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::beans::NamedValue; + using ::com::sun::star::beans::PropertyState_DIRECT_VALUE; + /** === end UNO using === **/ + + //==================================================================== + //= NamedValueCollection_Impl + //==================================================================== + typedef ::boost::unordered_map< ::rtl::OUString, Any, ::rtl::OUStringHash > NamedValueRepository; + + struct NamedValueCollection_Impl + { + NamedValueRepository aValues; + }; + + //==================================================================== + //= NamedValueCollection + //==================================================================== + //-------------------------------------------------------------------- + NamedValueCollection::NamedValueCollection() + :m_pImpl( new NamedValueCollection_Impl ) + { + } + + //-------------------------------------------------------------------- + NamedValueCollection::NamedValueCollection( const NamedValueCollection& _rCopySource ) + :m_pImpl( new NamedValueCollection_Impl ) + { + *this = _rCopySource; + } + + //-------------------------------------------------------------------- + NamedValueCollection& NamedValueCollection::operator=( const NamedValueCollection& i_rCopySource ) + { + m_pImpl->aValues = i_rCopySource.m_pImpl->aValues; + return *this; + } + + //-------------------------------------------------------------------- + NamedValueCollection::NamedValueCollection( const Any& _rElements ) + :m_pImpl( new NamedValueCollection_Impl ) + { + impl_assign( _rElements ); + } + + //-------------------------------------------------------------------- + NamedValueCollection::NamedValueCollection( const Sequence< Any >& _rArguments ) + :m_pImpl( new NamedValueCollection_Impl ) + { + impl_assign( _rArguments ); + } + + //-------------------------------------------------------------------- + NamedValueCollection::NamedValueCollection( const Sequence< PropertyValue >& _rArguments ) + :m_pImpl( new NamedValueCollection_Impl ) + { + impl_assign( _rArguments ); + } + + //-------------------------------------------------------------------- + NamedValueCollection::NamedValueCollection( const Sequence< NamedValue >& _rArguments ) + :m_pImpl( new NamedValueCollection_Impl ) + { + impl_assign( _rArguments ); + } + + //-------------------------------------------------------------------- + NamedValueCollection::~NamedValueCollection() + { + } + + //-------------------------------------------------------------------- + NamedValueCollection& NamedValueCollection::merge( const NamedValueCollection& _rAdditionalValues, bool _bOverwriteExisting ) + { + for ( NamedValueRepository::const_iterator namedValue = _rAdditionalValues.m_pImpl->aValues.begin(); + namedValue != _rAdditionalValues.m_pImpl->aValues.end(); + ++namedValue + ) + { + if ( _bOverwriteExisting || !impl_has( namedValue->first ) ) + impl_put( namedValue->first, namedValue->second ); + } + + return *this; + } + + //-------------------------------------------------------------------- + size_t NamedValueCollection::size() const + { + return m_pImpl->aValues.size(); + } + + //-------------------------------------------------------------------- + bool NamedValueCollection::empty() const + { + return m_pImpl->aValues.empty(); + } + + //-------------------------------------------------------------------- + ::std::vector< ::rtl::OUString > NamedValueCollection::getNames() const + { + ::std::vector< ::rtl::OUString > aNames; + for ( NamedValueRepository::const_iterator it = m_pImpl->aValues.begin(), end = m_pImpl->aValues.end(); it != end; ++it ) + { + aNames.push_back( it->first ); + } + return aNames; + } + + //-------------------------------------------------------------------- + void NamedValueCollection::impl_assign( const Any& i_rWrappedElements ) + { + Sequence< NamedValue > aNamedValues; + Sequence< PropertyValue > aPropertyValues; + NamedValue aNamedValue; + PropertyValue aPropertyValue; + + if ( i_rWrappedElements >>= aNamedValues ) + impl_assign( aNamedValues ); + else if ( i_rWrappedElements >>= aPropertyValues ) + impl_assign( aPropertyValues ); + else if ( i_rWrappedElements >>= aNamedValue ) + impl_assign( Sequence< NamedValue >( &aNamedValue, 1 ) ); + else if ( i_rWrappedElements >>= aPropertyValue ) + impl_assign( Sequence< PropertyValue >( &aPropertyValue, 1 ) ); + else + OSL_ENSURE( !i_rWrappedElements.hasValue(), "NamedValueCollection::impl_assign(Any): unsupported type!" ); + } + + //-------------------------------------------------------------------- + void NamedValueCollection::impl_assign( const Sequence< Any >& _rArguments ) + { + { + NamedValueRepository aEmpty; + m_pImpl->aValues.swap( aEmpty ); + } + + PropertyValue aPropertyValue; + NamedValue aNamedValue; + + const Any* pArgument = _rArguments.getConstArray(); + const Any* pArgumentEnd = _rArguments.getConstArray() + _rArguments.getLength(); + for ( ; pArgument != pArgumentEnd; ++pArgument ) + { + if ( *pArgument >>= aPropertyValue ) + m_pImpl->aValues[ aPropertyValue.Name ] = aPropertyValue.Value; + else if ( *pArgument >>= aNamedValue ) + m_pImpl->aValues[ aNamedValue.Name ] = aNamedValue.Value; +#if OSL_DEBUG_LEVEL > 0 + else if ( pArgument->hasValue() ) + { + ::rtl::OStringBuffer message; + message.append( "NamedValueCollection::impl_assign: encountered a value type which I cannot handle:\n" ); + message.append( ::rtl::OUStringToOString( pArgument->getValueTypeName(), RTL_TEXTENCODING_ASCII_US ) ); + OSL_FAIL( message.makeStringAndClear() ); + } +#endif + } + } + + //-------------------------------------------------------------------- + void NamedValueCollection::impl_assign( const Sequence< PropertyValue >& _rArguments ) + { + { + NamedValueRepository aEmpty; + m_pImpl->aValues.swap( aEmpty ); + } + + const PropertyValue* pArgument = _rArguments.getConstArray(); + const PropertyValue* pArgumentEnd = _rArguments.getConstArray() + _rArguments.getLength(); + for ( ; pArgument != pArgumentEnd; ++pArgument ) + m_pImpl->aValues[ pArgument->Name ] = pArgument->Value; + } + + //-------------------------------------------------------------------- + void NamedValueCollection::impl_assign( const Sequence< NamedValue >& _rArguments ) + { + { + NamedValueRepository aEmpty; + m_pImpl->aValues.swap( aEmpty ); + } + + const NamedValue* pArgument = _rArguments.getConstArray(); + const NamedValue* pArgumentEnd = _rArguments.getConstArray() + _rArguments.getLength(); + for ( ; pArgument != pArgumentEnd; ++pArgument ) + m_pImpl->aValues[ pArgument->Name ] = pArgument->Value; + } + + //-------------------------------------------------------------------- + bool NamedValueCollection::get_ensureType( const ::rtl::OUString& _rValueName, void* _pValueLocation, const Type& _rExpectedValueType ) const + { + NamedValueRepository::const_iterator pos = m_pImpl->aValues.find( _rValueName ); + if ( pos != m_pImpl->aValues.end() ) + { + if ( uno_type_assignData( + _pValueLocation, _rExpectedValueType.getTypeLibType(), + const_cast< void* >( pos->second.getValue() ), pos->second.getValueType().getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >( cpp_queryInterface ), + reinterpret_cast< uno_AcquireFunc >( cpp_acquire ), + reinterpret_cast< uno_ReleaseFunc >( cpp_release ) + ) ) + // argument exists, and could be extracted + return true; + + // argument exists, but is of wrong type + ::rtl::OUStringBuffer aBuffer; + aBuffer.appendAscii( "Invalid value type for '" ); + aBuffer.append ( _rValueName ); + aBuffer.appendAscii( "'.\nExpected: " ); + aBuffer.append ( _rExpectedValueType.getTypeName() ); + aBuffer.appendAscii( "\nFound: " ); + aBuffer.append ( pos->second.getValueType().getTypeName() ); + throw IllegalArgumentException( aBuffer.makeStringAndClear(), NULL, 0 ); + } + + // argument does not exist + return false; + } + + namespace + { + class theEmptyDefault : public rtl::Static<Any, theEmptyDefault> {}; + } + + //-------------------------------------------------------------------- + const Any& NamedValueCollection::impl_get( const ::rtl::OUString& _rValueName ) const + { + NamedValueRepository::const_iterator pos = m_pImpl->aValues.find( _rValueName ); + if ( pos != m_pImpl->aValues.end() ) + return pos->second; + + return theEmptyDefault::get(); + } + + //-------------------------------------------------------------------- + bool NamedValueCollection::impl_has( const ::rtl::OUString& _rValueName ) const + { + NamedValueRepository::const_iterator pos = m_pImpl->aValues.find( _rValueName ); + return ( pos != m_pImpl->aValues.end() ); + } + + //-------------------------------------------------------------------- + bool NamedValueCollection::impl_put( const ::rtl::OUString& _rValueName, const Any& _rValue ) + { + bool bHas = impl_has( _rValueName ); + m_pImpl->aValues[ _rValueName ] = _rValue; + return bHas; + } + + //-------------------------------------------------------------------- + bool NamedValueCollection::impl_remove( const ::rtl::OUString& _rValueName ) + { + NamedValueRepository::iterator pos = m_pImpl->aValues.find( _rValueName ); + if ( pos == m_pImpl->aValues.end() ) + return false; + m_pImpl->aValues.erase( pos ); + return true; + } + + //-------------------------------------------------------------------- + namespace + { + struct Value2PropertyValue : public ::std::unary_function< NamedValueRepository::value_type, PropertyValue > + { + PropertyValue operator()( const NamedValueRepository::value_type& _rValue ) + { + return PropertyValue( + _rValue.first, 0, _rValue.second, PropertyState_DIRECT_VALUE ); + } + }; + + struct Value2NamedValue : public ::std::unary_function< NamedValueRepository::value_type, NamedValue > + { + NamedValue operator()( const NamedValueRepository::value_type& _rValue ) + { + return NamedValue( _rValue.first, _rValue.second ); + } + }; + } + + //-------------------------------------------------------------------- + sal_Int32 NamedValueCollection::operator >>= ( Sequence< PropertyValue >& _out_rValues ) const + { + _out_rValues.realloc( m_pImpl->aValues.size() ); + ::std::transform( m_pImpl->aValues.begin(), m_pImpl->aValues.end(), _out_rValues.getArray(), Value2PropertyValue() ); + return _out_rValues.getLength(); + } + + //-------------------------------------------------------------------- + sal_Int32 NamedValueCollection::operator >>= ( Sequence< NamedValue >& _out_rValues ) const + { + _out_rValues.realloc( m_pImpl->aValues.size() ); + ::std::transform( m_pImpl->aValues.begin(), m_pImpl->aValues.end(), _out_rValues.getArray(), Value2NamedValue() ); + return _out_rValues.getLength(); + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/numberedcollection.cxx b/comphelper/source/misc/numberedcollection.cxx new file mode 100644 index 000000000000..e8374efc2e4d --- /dev/null +++ b/comphelper/source/misc/numberedcollection.cxx @@ -0,0 +1,278 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <comphelper/numberedcollection.hxx> + +//_______________________________________________ +// includes + +#include <com/sun/star/frame/UntitledNumbersConst.hpp> + +//_______________________________________________ +// namespace + +namespace comphelper{ + +namespace css = ::com::sun::star; + +//_______________________________________________ +// definitions + +static const ::rtl::OUString ERRMSG_INVALID_COMPONENT_PARAM(RTL_CONSTASCII_USTRINGPARAM("NULL as component reference not allowed.")); + +//----------------------------------------------- +NumberedCollection::NumberedCollection() + : ::cppu::BaseMutex () + , m_sUntitledPrefix () + , m_lComponents () + , m_xOwner () +{ +} + +//----------------------------------------------- +NumberedCollection::~NumberedCollection() +{ +} + +//----------------------------------------------- +void NumberedCollection::setOwner(const css::uno::Reference< css::uno::XInterface >& xOwner) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_xOwner = xOwner; + + // <- SYNCHRONIZED +} + +//----------------------------------------------- +void NumberedCollection::setUntitledPrefix(const ::rtl::OUString& sPrefix) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_sUntitledPrefix = sPrefix; + + // <- SYNCHRONIZED +} + +//----------------------------------------------- +::sal_Int32 SAL_CALL NumberedCollection::leaseNumber(const css::uno::Reference< css::uno::XInterface >& xComponent) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + if ( ! xComponent.is ()) + throw css::lang::IllegalArgumentException (ERRMSG_INVALID_COMPONENT_PARAM, m_xOwner.get(), 1); + + long pComponent = (long) xComponent.get (); + TNumberedItemHash::const_iterator pIt = m_lComponents.find (pComponent); + + // a) component already exists - return it's number directly + if (pIt != m_lComponents.end()) + return pIt->second.nNumber; + + // b) component must be added new to this container + + // b1) collection is full - no further components possible + // -> return INVALID_NUMBER + ::sal_Int32 nFreeNumber = impl_searchFreeNumber(); + if (nFreeNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) + return css::frame::UntitledNumbersConst::INVALID_NUMBER; + + // b2) add component to collection and return its number + TNumberedItem aItem; + aItem.xItem = css::uno::WeakReference< css::uno::XInterface >(xComponent); + aItem.nNumber = nFreeNumber; + m_lComponents[pComponent] = aItem; + + return nFreeNumber; + + // <- SYNCHRONIZED +} + +//----------------------------------------------- +void SAL_CALL NumberedCollection::releaseNumber(::sal_Int32 nNumber) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + if (nNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) + throw css::lang::IllegalArgumentException (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Special valkud INVALID_NUMBER not allowed as input parameter.")), m_xOwner.get(), 1); + + TDeadItemList lDeadItems; + TNumberedItemHash::iterator pComponent; + + for ( pComponent = m_lComponents.begin (); + pComponent != m_lComponents.end (); + ++pComponent ) + { + const TNumberedItem& rItem = pComponent->second; + const css::uno::Reference< css::uno::XInterface > xItem = rItem.xItem.get(); + + if ( ! xItem.is ()) + { + lDeadItems.push_back(pComponent->first); + continue; + } + + if (rItem.nNumber == nNumber) + { + m_lComponents.erase (pComponent); + break; + } + } + + impl_cleanUpDeadItems(m_lComponents, lDeadItems); + + // <- SYNCHRONIZED +} + +//----------------------------------------------- +void SAL_CALL NumberedCollection::releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface >& xComponent) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + if ( ! xComponent.is ()) + throw css::lang::IllegalArgumentException (ERRMSG_INVALID_COMPONENT_PARAM, m_xOwner.get(), 1); + + long pComponent = (long) xComponent.get (); + TNumberedItemHash::iterator pIt = m_lComponents.find (pComponent); + + // a) component exists and will be removed + if (pIt != m_lComponents.end()) + m_lComponents.erase(pIt); + + // else + // b) component does not exists - nothing todo here (ignore request!) + + // <- SYNCHRONIZED +} + +//----------------------------------------------- +::rtl::OUString SAL_CALL NumberedCollection::getUntitledPrefix() + throw (css::uno::RuntimeException) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + return m_sUntitledPrefix; + + // <- SYNCHRONIZED +} + +//----------------------------------------------- +/** create an ordered list of all possible numbers ... + e.g. {1,2,3,...,N} Max size of these list will be + current size of component list + 1 . + + "+1" ... because in case all numbers in range 1..n + are in use we need a new number n+1 :-) + + Every item which is already used as unique number + will be removed. At the end a list of e.g. {3,6,...,M} + exists where the first item represent the lowest free + number (in this example 3). + */ +::sal_Int32 NumberedCollection::impl_searchFreeNumber () +{ + // create ordered list of all possible numbers. + ::std::vector< ::sal_Int32 > lPossibleNumbers; + ::sal_Int32 c = (::sal_Int32)m_lComponents.size (); + ::sal_Int32 i = 1; + + // c cant be less then 0 ... otherwhise hash.size() has an error :-) + // But we need at least n+1 numbers here. + c += 1; + + for (i=1; i<=c; ++i) + lPossibleNumbers.push_back (i); + + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + TDeadItemList lDeadItems; + TNumberedItemHash::const_iterator pComponent; + + for ( pComponent = m_lComponents.begin (); + pComponent != m_lComponents.end (); + ++pComponent ) + { + const TNumberedItem& rItem = pComponent->second; + const css::uno::Reference< css::uno::XInterface > xItem = rItem.xItem.get(); + + if ( ! xItem.is ()) + { + lDeadItems.push_back(pComponent->first); + continue; + } + + ::std::vector< ::sal_Int32 >::iterator pPossible = ::std::find(lPossibleNumbers.begin (), lPossibleNumbers.end (), rItem.nNumber); + if (pPossible != lPossibleNumbers.end ()) + lPossibleNumbers.erase (pPossible); + } + + impl_cleanUpDeadItems(m_lComponents, lDeadItems); + + // a) non free numbers ... return INVALID_NUMBER + if (lPossibleNumbers.size () < 1) + return css::frame::UntitledNumbersConst::INVALID_NUMBER; + + // b) return first free number + return *(lPossibleNumbers.begin ()); + + // <- SYNCHRONIZED +} + +void NumberedCollection::impl_cleanUpDeadItems ( TNumberedItemHash& lItems , + const TDeadItemList& lDeadItems) +{ + TDeadItemList::const_iterator pIt; + + for ( pIt = lDeadItems.begin (); + pIt != lDeadItems.end (); + ++pIt ) + { + const long& rDeadItem = *pIt; + lItems.erase(rDeadItem); + } +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/numbers.cxx b/comphelper/source/misc/numbers.cxx new file mode 100644 index 000000000000..334a9e52178d --- /dev/null +++ b/comphelper/source/misc/numbers.cxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/numbers.hxx> +#include <osl/diagnose.h> +#include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/util/XNumberFormatTypes.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/Locale.hpp> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +namespace starbeans = ::com::sun::star::beans; +namespace starlang = ::com::sun::star::lang; + +//------------------------------------------------------------------------------ +sal_Int16 getNumberFormatType(const staruno::Reference<starutil::XNumberFormats>& xFormats, sal_Int32 nKey) +{ + sal_Int16 nReturn(starutil::NumberFormat::UNDEFINED); + if (xFormats.is()) + { + try + { + staruno::Reference<starbeans::XPropertySet> xFormat(xFormats->getByKey(nKey)); + if (xFormat.is()) + xFormat->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ))) >>= nReturn; + } + catch(...) + { + OSL_TRACE("getNumberFormatType : invalid key! (maybe created with another formatter ?)"); + } + } + return nReturn; +} + +//------------------------------------------------------------------------------ +sal_Int16 getNumberFormatType(const staruno::Reference<starutil::XNumberFormatter>& xFormatter, sal_Int32 nKey) +{ + OSL_ENSURE(xFormatter.is(), "getNumberFormatType : the formatter isn't valid !"); + staruno::Reference<starutil::XNumberFormatsSupplier> xSupplier( xFormatter->getNumberFormatsSupplier()); + OSL_ENSURE(xSupplier.is(), "getNumberFormatType : the formatter doesn't implement a supplier !"); + staruno::Reference<starutil::XNumberFormats> xFormats( xSupplier->getNumberFormats()); + return getNumberFormatType(xFormats, nKey); +} + +//------------------------------------------------------------------------------ +staruno::Any getNumberFormatDecimals(const staruno::Reference<starutil::XNumberFormats>& xFormats, sal_Int32 nKey) +{ + if (xFormats.is()) + { + try + { + staruno::Reference<starbeans::XPropertySet> xFormat( xFormats->getByKey(nKey)); + if (xFormat.is()) + { + static ::rtl::OUString PROPERTY_DECIMALS( RTL_CONSTASCII_USTRINGPARAM( "Decimals" )); + return xFormat->getPropertyValue(PROPERTY_DECIMALS); + } + } + catch(...) + { + OSL_TRACE("getNumberFormatDecimals : invalid key! (may be created with another formatter ?)"); + } + } + return staruno::makeAny((sal_Int16)0); +} + + +//------------------------------------------------------------------------------ +sal_Int32 getStandardFormat( + const staruno::Reference<starutil::XNumberFormatter>& xFormatter, + sal_Int16 nType, + const starlang::Locale& _rLocale) +{ + staruno::Reference<starutil::XNumberFormatsSupplier> xSupplier( xFormatter.is() ? xFormatter->getNumberFormatsSupplier() : staruno::Reference<starutil::XNumberFormatsSupplier>(NULL)); + staruno::Reference<starutil::XNumberFormats> xFormats( xSupplier.is() ? xSupplier->getNumberFormats() : staruno::Reference<starutil::XNumberFormats>(NULL)); + staruno::Reference<starutil::XNumberFormatTypes> xTypes(xFormats, staruno::UNO_QUERY); + OSL_ENSURE(xTypes.is(), "getStandardFormat : no format types !"); + + return xTypes.is() ? xTypes->getStandardFormat(nType, _rLocale) : 0; +} + +//------------------------------------------------------------------------------ +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; + +//------------------------------------------------------------------------------ +Any getNumberFormatProperty( const Reference< XNumberFormatter >& _rxFormatter, sal_Int32 _nKey, const rtl::OUString& _rPropertyName ) +{ + Any aReturn; + + OSL_ENSURE( _rxFormatter.is() && _rPropertyName.getLength(), "getNumberFormatProperty: invalid arguments!" ); + try + { + Reference< XNumberFormatsSupplier > xSupplier; + Reference< XNumberFormats > xFormats; + Reference< XPropertySet > xFormatProperties; + + if ( _rxFormatter.is() ) + xSupplier = _rxFormatter->getNumberFormatsSupplier(); + if ( xSupplier.is() ) + xFormats = xSupplier->getNumberFormats(); + if ( xFormats.is() ) + xFormatProperties = xFormats->getByKey( _nKey ); + + if ( xFormatProperties.is() ) + aReturn = xFormatProperties->getPropertyValue( _rPropertyName ); + } + catch( const Exception& ) + { + OSL_FAIL( "::getNumberFormatProperty: caught an exception (did you create the key with another formatter?)!" ); + } + + return aReturn; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/officeresourcebundle.cxx b/comphelper/source/misc/officeresourcebundle.cxx new file mode 100644 index 000000000000..2e2119cb2ee3 --- /dev/null +++ b/comphelper/source/misc/officeresourcebundle.cxx @@ -0,0 +1,243 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/officeresourcebundle.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/resource/XResourceBundle.hpp> +#include <com/sun/star/resource/XResourceBundleLoader.hpp> +#include <com/sun/star/lang/NullPointerException.hpp> +/** === end UNO includes === **/ +#include <osl/mutex.hxx> +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using com::sun::star::resource::XResourceBundle; + using com::sun::star::resource::XResourceBundleLoader; + using com::sun::star::resource::MissingResourceException; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::lang::NullPointerException; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::Any; + /** === end UNO using === **/ + + //==================================================================== + //= ResourceBundle_Impl + //==================================================================== + class ResourceBundle_Impl + { + private: + Reference< XComponentContext > m_xContext; + ::rtl::OUString m_sBaseName; + Reference< XResourceBundle > m_xBundle; + bool m_bAttemptedCreate; + mutable ::osl::Mutex m_aMutex; + + public: + ResourceBundle_Impl( const Reference< XComponentContext >& _context, const ::rtl::OUString& _baseName ) + :m_xContext( _context ) + ,m_sBaseName( _baseName ) + ,m_bAttemptedCreate( false ) + { + } + + public: + /** loads the string with the given resource id from the resource bundle + @param _resourceId + the id of the string to load + @return + the requested resource string. If no string with the given id exists in the resource bundle, + an empty string is returned. In a non-product version, an OSL_ENSURE will notify you of this + then. + */ + ::rtl::OUString loadString( sal_Int32 _resourceId ) const; + + /** determines whether the resource bundle has a string with the given id + @param _resourceId + the id of the string whose existence is to be checked + @return + <TRUE/> if and only if a string with the given ID exists in the resource + bundle. + */ + bool hasString( sal_Int32 _resourceId ) const; + + private: + /** loads the bundle represented by the instance + + The method is safe against multiple calls: If a previos call succeeded or failed, the + previous result will be returned, without any other processing. + + @precond + Our mutex is locked. + */ + bool impl_loadBundle_nothrow(); + + /** returns the resource bundle key for a string with a given resource id + */ + static ::rtl::OUString + impl_getStringResourceKey( sal_Int32 _resourceId ); + }; + + //-------------------------------------------------------------------- + ::rtl::OUString ResourceBundle_Impl::impl_getStringResourceKey( sal_Int32 _resourceId ) + { + ::rtl::OUStringBuffer key; + key.appendAscii( "string:" ); + key.append( _resourceId ); + return key.makeStringAndClear(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString ResourceBundle_Impl::loadString( sal_Int32 _resourceId ) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + ::rtl::OUString sString; + + if ( const_cast< ResourceBundle_Impl* >( this )->impl_loadBundle_nothrow() ) + { + try + { + OSL_VERIFY( m_xBundle->getByName( impl_getStringResourceKey( _resourceId ) ) >>= sString ); + } + catch( const Exception& ) + { + OSL_FAIL( "ResourceBundle_Impl::loadString: caught an exception!" ); + } + } + return sString; + } + + //-------------------------------------------------------------------- + bool ResourceBundle_Impl::hasString( sal_Int32 _resourceId ) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + bool has = false; + + if ( const_cast< ResourceBundle_Impl* >( this )->impl_loadBundle_nothrow() ) + { + try + { + has = m_xBundle->hasByName( impl_getStringResourceKey( _resourceId ) ); + } + catch( const Exception& ) + { + OSL_FAIL( "ResourceBundle_Impl::hasString: caught an exception!" ); + } + } + return has; + } + + //-------------------------------------------------------------------- + bool ResourceBundle_Impl::impl_loadBundle_nothrow() + { + if ( m_bAttemptedCreate ) + return m_xBundle.is(); + + m_bAttemptedCreate = true; + + Reference< XResourceBundleLoader > xLoader; + try + { + Any aValue( m_xContext->getValueByName( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "/singletons/com.sun.star.resource.OfficeResourceLoader" ) ) ) ); + OSL_VERIFY( aValue >>= xLoader ); + } + catch( const Exception& ) + { + OSL_FAIL( "ResourceBundle_Impl::impl_loadBundle_nopthrow: could not create the resource loader!" ); + } + + if ( !xLoader.is() ) + return false; + + try + { + m_xBundle = xLoader->loadBundle_Default( m_sBaseName ); + } + catch( const MissingResourceException& ) + { + OSL_FAIL( "ResourceBundle_Impl::impl_loadBundle_nopthrow: missing the given resource bundle!" ); + } + + return m_xBundle.is(); + } + + //==================================================================== + //= OfficeResourceBundle + //==================================================================== + //-------------------------------------------------------------------- + OfficeResourceBundle::OfficeResourceBundle( const Reference< XComponentContext >& _context, const ::rtl::OUString& _bundleBaseName ) + :m_pImpl( new ResourceBundle_Impl( _context, _bundleBaseName ) ) + { + if ( !_context.is() ) + throw NullPointerException(); + } + + //-------------------------------------------------------------------- + OfficeResourceBundle::OfficeResourceBundle( const Reference< XComponentContext >& _context, const sal_Char* _bundleBaseAsciiName ) + :m_pImpl( new ResourceBundle_Impl( _context, ::rtl::OUString::createFromAscii( _bundleBaseAsciiName ) ) ) + { + if ( !_context.is() ) + throw NullPointerException(); + } + + //-------------------------------------------------------------------- + OfficeResourceBundle::~OfficeResourceBundle() + { + } + + //-------------------------------------------------------------------- + ::rtl::OUString OfficeResourceBundle::loadString( sal_Int32 _resourceId ) const + { + return m_pImpl->loadString( _resourceId ); + } + + //-------------------------------------------------------------------- + bool OfficeResourceBundle::hasString( sal_Int32 _resourceId ) const + { + return m_pImpl->hasString( _resourceId ); + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/officerestartmanager.cxx b/comphelper/source/misc/officerestartmanager.cxx new file mode 100644 index 000000000000..20af7275ca4d --- /dev/null +++ b/comphelper/source/misc/officerestartmanager.cxx @@ -0,0 +1,213 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/awt/XRequestCallback.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <comphelper_module.hxx> +#include "officerestartmanager.hxx" + +using namespace ::com::sun::star; + +namespace comphelper +{ + +// ---------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OOfficeRestartManager::getSupportedServiceNames_static() +{ + uno::Sequence< rtl::OUString > aResult( 1 ); + aResult[0] = getServiceName_static(); + return aResult; +} + +// ---------------------------------------------------------- +::rtl::OUString SAL_CALL OOfficeRestartManager::getImplementationName_static() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.task.OfficeRestartManager" ) ); +} + +// ---------------------------------------------------------- +::rtl::OUString SAL_CALL OOfficeRestartManager::getSingletonName_static() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ); +} + +// ---------------------------------------------------------- +::rtl::OUString SAL_CALL OOfficeRestartManager::getServiceName_static() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.task.OfficeRestartManager" ) ); +} + +// ---------------------------------------------------------- +uno::Reference< uno::XInterface > SAL_CALL OOfficeRestartManager::Create( const uno::Reference< uno::XComponentContext >& rxContext ) +{ + return static_cast< cppu::OWeakObject* >( new OOfficeRestartManager( rxContext ) ); +} + +// XRestartManager +// ---------------------------------------------------------- +void SAL_CALL OOfficeRestartManager::requestRestart( const uno::Reference< task::XInteractionHandler >& /* xInteractionHandler */ ) + throw (uno::Exception, uno::RuntimeException) +{ + if ( !m_xContext.is() ) + throw uno::RuntimeException(); + + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // if the restart already running there is no need to trigger it again + if ( m_bRestartRequested ) + return; + + m_bRestartRequested = sal_True; + + // the office is still not initialized, no need to terminate, changing the state is enough + if ( !m_bOfficeInitialized ) + return; + } + + // TODO: use InteractionHandler to report errors + try + { + // register itself as a job that should be executed asynchronously + uno::Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_SET_THROW ); + + uno::Reference< awt::XRequestCallback > xRequestCallback( + xFactory->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.AsyncCallback" )), + m_xContext ), + uno::UNO_QUERY_THROW ); + + xRequestCallback->addCallback( this, uno::Any() ); + } + catch ( uno::Exception& ) + { + // the try to request restart has failed + m_bRestartRequested = sal_False; + } +} + +// ---------------------------------------------------------- +::sal_Bool SAL_CALL OOfficeRestartManager::isRestartRequested( ::sal_Bool bOfficeInitialized ) + throw (uno::Exception, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( bOfficeInitialized && !m_bOfficeInitialized ) + m_bOfficeInitialized = bOfficeInitialized; + + return m_bRestartRequested; +} + +// XCallback +// ---------------------------------------------------------- +void SAL_CALL OOfficeRestartManager::notify( const uno::Any& /* aData */ ) + throw ( uno::RuntimeException ) +{ + try + { + sal_Bool bSuccess = sal_False; + + if ( m_xContext.is() ) + { + uno::Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< frame::XDesktop > xDesktop( + xFactory->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ), m_xContext ), + uno::UNO_QUERY_THROW ); + + // Turn Quickstarter veto off + uno::Reference< beans::XPropertySet > xPropertySet( xDesktop, uno::UNO_QUERY_THROW ); + ::rtl::OUString aVetoPropName( RTL_CONSTASCII_USTRINGPARAM( "SuspendQuickstartVeto" ) ); + uno::Any aValue; + aValue <<= (sal_Bool)sal_True; + xPropertySet->setPropertyValue( aVetoPropName, aValue ); + + try + { + bSuccess = xDesktop->terminate(); + } catch( uno::Exception& ) + {} + + if ( !bSuccess ) + { + aValue <<= (sal_Bool)sal_False; + xPropertySet->setPropertyValue( aVetoPropName, aValue ); + } + } + + if ( !bSuccess ) + m_bRestartRequested = sal_False; + } + catch( uno::Exception& ) + { + // the try to restart has failed + m_bRestartRequested = sal_False; + } +} + +// XServiceInfo +// ---------------------------------------------------------- +::rtl::OUString SAL_CALL OOfficeRestartManager::getImplementationName() throw (uno::RuntimeException) +{ + return getImplementationName_static(); +} + +// ---------------------------------------------------------- +::sal_Bool SAL_CALL OOfficeRestartManager::supportsService( const ::rtl::OUString& aServiceName ) throw (uno::RuntimeException) +{ + const uno::Sequence< rtl::OUString > & aSupportedNames = getSupportedServiceNames_static(); + for ( sal_Int32 nInd = 0; nInd < aSupportedNames.getLength(); nInd++ ) + { + if ( aSupportedNames[ nInd ].equals( aServiceName ) ) + return sal_True; + } + + return sal_False; +} + +// ---------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL OOfficeRestartManager::getSupportedServiceNames() throw (uno::RuntimeException) +{ + return getSupportedServiceNames_static(); +} + +} // namespace comphelper + +void createRegistryInfo_OOfficeRestartManager() +{ + static ::comphelper::module::OAutoRegistration< ::comphelper::OOfficeRestartManager > aAutoRegistration; + static ::comphelper::module::OSingletonRegistration< ::comphelper::OOfficeRestartManager > aSingletonRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/officerestartmanager.hxx b/comphelper/source/misc/officerestartmanager.hxx new file mode 100644 index 000000000000..c0aabf65d531 --- /dev/null +++ b/comphelper/source/misc/officerestartmanager.hxx @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 __OFFICESTARTMANAGER_HXX_ +#define __OFFICESTARTMANAGER_HXX_ + +#include <com/sun/star/task/XRestartManager.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/awt/XCallback.hpp> + +#include <osl/mutex.hxx> +#include <cppuhelper/implbase3.hxx> + +namespace comphelper +{ + +class OOfficeRestartManager : public ::cppu::WeakImplHelper3< ::com::sun::star::task::XRestartManager + , ::com::sun::star::awt::XCallback + , ::com::sun::star::lang::XServiceInfo > +{ + ::osl::Mutex m_aMutex; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + + sal_Bool m_bOfficeInitialized; + sal_Bool m_bRestartRequested; + +public: + OOfficeRestartManager( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ) + : m_xContext( xContext ) + , m_bOfficeInitialized( sal_False ) + , m_bRestartRequested( sal_False ) + {} + + virtual ~OOfficeRestartManager() + {} + + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames_static(); + + static ::rtl::OUString SAL_CALL getImplementationName_static(); + + static ::rtl::OUString SAL_CALL getSingletonName_static(); + + static ::rtl::OUString SAL_CALL getServiceName_static(); + + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + Create( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + +// XRestartManager + virtual void SAL_CALL requestRestart( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xInteractionHandler ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isRestartRequested( ::sal_Bool bInitialized ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + +// XCallback + virtual void SAL_CALL notify( const ::com::sun::star::uno::Any& aData ) throw (::com::sun::star::uno::RuntimeException); + +// 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); + +}; + +} // namespace comphelper + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/proxyaggregation.cxx b/comphelper/source/misc/proxyaggregation.cxx new file mode 100644 index 000000000000..b24aa4407356 --- /dev/null +++ b/comphelper/source/misc/proxyaggregation.cxx @@ -0,0 +1,278 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/proxyaggregation.hxx> +#include <com/sun/star/reflection/XProxyFactory.hpp> + +//............................................................................. +namespace comphelper +{ +//............................................................................. + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::reflection; + + //========================================================================= + //= OProxyAggregation + //========================================================================= + //------------------------------------------------------------------------- + OProxyAggregation::OProxyAggregation( const Reference< XMultiServiceFactory >& _rxORB ) + :m_xORB( _rxORB ) + { + } + + //------------------------------------------------------------------------- + void OProxyAggregation::baseAggregateProxyFor( const Reference< XInterface >& _rxComponent, oslInterlockedCount& _rRefCount, + ::cppu::OWeakObject& _rDelegator ) + { + // first a factory for the proxy + Reference< XProxyFactory > xFactory( + m_xORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.ProxyFactory" ) ) ), + UNO_QUERY + ); + OSL_ENSURE( xFactory.is(), "OProxyAggregation::baseAggregateProxyFor: could not create a proxy factory!" ); + + // then the proxy itself + if ( xFactory.is() ) + { + { // i36686 OJ: achieve the desctruction of the tempoary -> otherwise it leads to _rRefCount -= 2 + m_xProxyAggregate = xFactory->createProxy( _rxComponent ); + } + if ( m_xProxyAggregate.is() ) + m_xProxyAggregate->queryAggregation( ::getCppuType( &m_xProxyTypeAccess ) ) >>= m_xProxyTypeAccess; + + // aggregate the proxy + osl_incrementInterlockedCount( &_rRefCount ); + if ( m_xProxyAggregate.is() ) + { + // At this point in time, the proxy has a ref count of exactly two - in m_xControlContextProxy, + // and in m_xProxyTypeAccess. + // Remember to _not_ reset these members unless the delegator of the proxy has been reset, too! + m_xProxyAggregate->setDelegator( _rDelegator ); + } + osl_decrementInterlockedCount( &_rRefCount ); + } + } + + //------------------------------------------------------------------------- + Any SAL_CALL OProxyAggregation::queryAggregation( const Type& _rType ) throw (RuntimeException) + { + return m_xProxyAggregate.is() ? m_xProxyAggregate->queryAggregation( _rType ) : Any(); + } + + //------------------------------------------------------------------------- + Sequence< Type > SAL_CALL OProxyAggregation::getTypes( ) throw (RuntimeException) + { + Sequence< Type > aTypes; + if ( m_xProxyAggregate.is() ) + { + if ( m_xProxyTypeAccess.is() ) + aTypes = m_xProxyTypeAccess->getTypes(); + } + return aTypes; + } + + //------------------------------------------------------------------------- + OProxyAggregation::~OProxyAggregation() + { + if ( m_xProxyAggregate.is() ) + m_xProxyAggregate->setDelegator( NULL ); + m_xProxyAggregate.clear(); + m_xProxyTypeAccess.clear(); + // this should remove the _two_only_ "real" references (means not delegated to + // ourself) to this proxy, and thus delete it + } + + //========================================================================= + //= OComponentProxyAggregationHelper + //========================================================================= + //------------------------------------------------------------------------- + OComponentProxyAggregationHelper::OComponentProxyAggregationHelper( const Reference< XMultiServiceFactory >& _rxORB, + ::cppu::OBroadcastHelper& _rBHelper ) + :OProxyAggregation( _rxORB ) + ,m_rBHelper( _rBHelper ) + { + OSL_ENSURE( _rxORB.is(), "OComponentProxyAggregationHelper::OComponentProxyAggregationHelper: invalid arguments!" ); + } + + //------------------------------------------------------------------------- + void OComponentProxyAggregationHelper::componentAggregateProxyFor( + const Reference< XComponent >& _rxComponent, oslInterlockedCount& _rRefCount, + ::cppu::OWeakObject& _rDelegator ) + { + OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregationHelper::componentAggregateProxyFor: invalid inner component!" ); + m_xInner = _rxComponent; + + // aggregate a proxy for the object + baseAggregateProxyFor( m_xInner.get(), _rRefCount, _rDelegator ); + + // add as event listener to the inner context, because we want to be notified of disposals + osl_incrementInterlockedCount( &_rRefCount ); + { + if ( m_xInner.is() ) + m_xInner->addEventListener( this ); + } + osl_decrementInterlockedCount( &_rRefCount ); + } + + //------------------------------------------------------------------------- + Any SAL_CALL OComponentProxyAggregationHelper::queryInterface( const Type& _rType ) throw (RuntimeException) + { + Any aReturn( BASE::queryInterface( _rType ) ); + if ( !aReturn.hasValue() ) + aReturn = OProxyAggregation::queryAggregation( _rType ); + return aReturn; + } + + //------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OComponentProxyAggregationHelper, BASE, OProxyAggregation ) + + //------------------------------------------------------------------------- + OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper( ) + { + OSL_ENSURE( m_rBHelper.bDisposed, "OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper: you should dispose your derived class in the dtor, if necessary!" ); + // if this asserts, add the following to your derived class dtor: + // + // if ( !m_rBHelper.bDisposed ) + // { + // acquire(); // to prevent duplicate dtor calls + // dispose(); + // } + + m_xInner.clear(); + } + + //------------------------------------------------------------------------- + void SAL_CALL OComponentProxyAggregationHelper::disposing( const EventObject& _rSource ) throw (RuntimeException) + { + if ( _rSource.Source == m_xInner ) + { // it's our inner context which is dying -> dispose ourself + if ( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose ) + { // (if necessary only, of course) + dispose(); + } + } + } + + //------------------------------------------------------------------------- + void SAL_CALL OComponentProxyAggregationHelper::dispose() throw( RuntimeException ) + { + ::osl::MutexGuard aGuard( m_rBHelper.rMutex ); + + // dispose our inner context + // before we do this, remove ourself as listener - else in disposing( EventObject ), we + // would dispose ourself a second time + Reference< XComponent > xComp( m_xInner, UNO_QUERY ); + if ( xComp.is() ) + { + xComp->removeEventListener( this ); + xComp->dispose(); + xComp.clear(); + } + } + + //========================================================================= + //= OComponentProxyAggregation + //========================================================================= + //------------------------------------------------------------------------- + OComponentProxyAggregation::OComponentProxyAggregation( const Reference< XMultiServiceFactory >& _rxORB, + const Reference< XComponent >& _rxComponent ) + :OComponentProxyAggregation_CBase( m_aMutex ) + ,OComponentProxyAggregationHelper( _rxORB, rBHelper ) + { + OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregation::OComponentProxyAggregation: accessible is no XComponent!" ); + if ( _rxComponent.is() ) + componentAggregateProxyFor( _rxComponent, m_refCount, *this ); + } + + //------------------------------------------------------------------------- + OComponentProxyAggregation::~OComponentProxyAggregation() + { + implEnsureDisposeInDtor( ); + } + + //------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( OComponentProxyAggregation, OComponentProxyAggregation_CBase, OComponentProxyAggregationHelper ) + + //------------------------------------------------------------------------- + IMPLEMENT_GET_IMPLEMENTATION_ID( OComponentProxyAggregation ) + + //------------------------------------------------------------------------- + Sequence< Type > SAL_CALL OComponentProxyAggregation::getTypes( ) throw (RuntimeException) + { + Sequence< Type > aTypes( OComponentProxyAggregationHelper::getTypes() ); + + // append XComponent, coming from OComponentProxyAggregation_CBase + sal_Int32 nLen = aTypes.getLength(); + aTypes.realloc( nLen + 1 ); + aTypes[ nLen ] = ::getCppuType( static_cast< Reference< XComponent >* >( NULL ) ); + + return aTypes; + } + + //------------------------------------------------------------------------- + void OComponentProxyAggregation::implEnsureDisposeInDtor( ) + { + if ( !rBHelper.bDisposed ) + { + acquire(); // to prevent duplicate dtor calls + dispose(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OComponentProxyAggregation::disposing( const EventObject& _rSource ) throw (RuntimeException) + { + // simly disambiguate - this is necessary for MSVC to distinguish + // "disposing( EventObject )" from "disposing()" + OComponentProxyAggregationHelper::disposing( _rSource ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OComponentProxyAggregation::disposing() throw (RuntimeException) + { + // call the dispose-functionality of the base, which will dispose our aggregated component + OComponentProxyAggregationHelper::dispose(); + } + + //-------------------------------------------------------------------- + void SAL_CALL OComponentProxyAggregation::dispose() throw( RuntimeException ) + { + // simply disambiguate + OComponentProxyAggregation_CBase::dispose(); + } + + +//............................................................................. +} // namespace comphelper +//............................................................................. + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/regpathhelper.cxx b/comphelper/source/misc/regpathhelper.cxx new file mode 100644 index 000000000000..1228e9278db9 --- /dev/null +++ b/comphelper/source/misc/regpathhelper.cxx @@ -0,0 +1,237 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <stdio.h> +#include <osl/file.hxx> +#include <osl/security.hxx> +#include <osl/thread.h> +#include <osl/process.h> +#include <rtl/textenc.h> +#include <rtl/uri.h> +#include <rtl/uri.hxx> + +using namespace osl; + +using ::rtl::OUString; +using ::rtl::OString; +using ::rtl::OStringToOUString; + +#define PATH_DELEMITTER '/' + +#define USER_REGISTRY_NAME_ENV "STAR_USER_REGISTRY" +#define SYSTEM_REGISTRY_NAME_ENV "STAR_REGISTRY" +#define REGISTRY_SYSTEM_NAME "services.rdb" + +#define REGISTRY_LOCAL_NAME "user60.rdb" + +#ifdef SAL_UNX +#define CONFIG_PATH_PREFIX "." +#else +#define CONFIG_PATH_PREFIX "" +#endif + +namespace comphelper +{ + +/** + @return sal_True, if the office is started in a portal + environment. + sal_False, if the common office is started + */ +static sal_Bool retrievePortalUserDir( OUString *pDirectory ) +{ + sal_uInt32 nArgs = osl_getCommandArgCount(); + sal_Bool bIsPortalUser = sal_False; + OUString sArg; + while( nArgs > 0 ) + { + if ( !osl_getCommandArg(--nArgs, &sArg.pData) ) + { + if ( sArg.indexOf(OUString( RTL_CONSTASCII_USTRINGPARAM( "-userid" ))) == 0 ) + { + + bIsPortalUser = sal_True; + sal_Int32 nStart = sArg.lastIndexOf( '[' ); + sal_Int32 nEnd = sArg.lastIndexOf( ']' ); + if( -1 == nStart || -1 == nEnd || nEnd < nStart) + { + *pDirectory = OUString(); + } + else + { + OUString aEncHome = sArg.copy( nStart + 1 , nEnd - nStart -1 ); + *pDirectory = rtl::Uri::decode(aEncHome, + rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8); + } + break; + } + } + } + return bIsPortalUser; +} + + +static OUString getDefaultLocalRegistry() +{ + OUString uBuffer, userRegistryName; + OUString portalUserDir; + + sal_Bool bIsPortalUser = retrievePortalUserDir( &portalUserDir ); + + if ( bIsPortalUser ) + { + if( portalUserDir.getLength() ) + { + FileBase::getFileURLFromSystemPath( portalUserDir , portalUserDir ); + userRegistryName = portalUserDir; + userRegistryName += OUString( RTL_CONSTASCII_USTRINGPARAM( + "/user/" REGISTRY_LOCAL_NAME ) ); + + // Directory creation is probably necessary for bootstrapping a new + // user in the portal environment (the ucb uses this function). + // This should be solved differently, as + // no one expects this function to create anything ... + OUString sSeparator(RTL_CONSTASCII_USTRINGPARAM("/")); + OUString sPath(RTL_CONSTASCII_USTRINGPARAM("file://")); + FileBase::RC retRC = FileBase::E_None; + + sal_Int32 nIndex = 3; + sPath += userRegistryName.getToken(2, '/', nIndex); + while( nIndex != -1 ) + { + sPath += sSeparator; + sPath += userRegistryName.getToken(0, '/', nIndex); + if( nIndex == -1 ) + break; + Directory aDir( sPath ); + if( aDir.open() == FileBase::E_NOENT ) + { + retRC = Directory::create(sPath); + if ( retRC != FileBase::E_None && retRC != FileBase::E_EXIST) + { + return OUString(); + } + } + } + } + } + else /* bIsPortalUser */ + { + ::osl::Security aUserSecurity; + aUserSecurity.getConfigDir( userRegistryName ); + userRegistryName += OUString( RTL_CONSTASCII_USTRINGPARAM( + "/" CONFIG_PATH_PREFIX REGISTRY_LOCAL_NAME ) ); + } + + return userRegistryName; +} + + +OUString getPathToUserRegistry() +{ + OUString userRegistryName; + FILE *f=NULL; + + // search the environment STAR_USER_REGISTRY + OString sBuffer( getenv(USER_REGISTRY_NAME_ENV) ); + if ( sBuffer.getLength() > 0 ) + { + f = fopen( sBuffer.getStr(), "r" ); + + if (f != NULL) + { + fclose(f); + userRegistryName = OStringToOUString( sBuffer, osl_getThreadTextEncoding() ); + } + } + + if ( !userRegistryName.getLength() ) + { + userRegistryName = getDefaultLocalRegistry(); + } + + return userRegistryName; +} + +OUString getPathToSystemRegistry() +{ + OUString uBuffer; + OUString registryBaseName( RTL_CONSTASCII_USTRINGPARAM(REGISTRY_SYSTEM_NAME) ); + OUString systemRegistryName; + FILE *f=NULL; + + // search in the directory of the executable + if(osl_Process_E_None == osl_getExecutableFile(&uBuffer.pData)) + { + sal_uInt32 lastIndex = uBuffer.lastIndexOf(PATH_DELEMITTER); + if (lastIndex > 0) + { + uBuffer = uBuffer.copy(0, lastIndex + 1); + } + + uBuffer += registryBaseName; + + if (!FileBase::getSystemPathFromFileURL(uBuffer, systemRegistryName)) + { + OString tmpStr( OUStringToOString(systemRegistryName, osl_getThreadTextEncoding()) ); + f = fopen( tmpStr.getStr(), "r" ); + } + } + + if (f == NULL) + { + // search the environment STAR_REGISTRY + OString tmpStr( getenv(SYSTEM_REGISTRY_NAME_ENV) ); + if ( tmpStr.getLength() > 0 ) + { + f = fopen(tmpStr.getStr(), "r"); + + if (f != NULL) + { + fclose(f); + systemRegistryName = OStringToOUString( tmpStr, osl_getThreadTextEncoding() ); + } else + { + systemRegistryName = OUString(); + } + } + } else + { + fclose(f); + } + + return systemRegistryName; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/scopeguard.cxx b/comphelper/source/misc/scopeguard.cxx new file mode 100644 index 000000000000..c37484be5b07 --- /dev/null +++ b/comphelper/source/misc/scopeguard.cxx @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/flagguard.hxx" +#include "osl/diagnose.h" +#include "com/sun/star/uno/Exception.hpp" + +namespace comphelper { + +ScopeGuard::~ScopeGuard() +{ + if (m_func) + { + if (m_excHandling == IGNORE_EXCEPTIONS) + { + try { + m_func(); + } + catch (com::sun::star::uno::Exception & exc) { + (void) exc; // avoid warning about unused variable + OSL_FAIL( + rtl::OUStringToOString( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "UNO exception occurred: ") ) + + exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + catch (...) { + OSL_FAIL( "unknown exception occurred!" ); + } + } + else + { + m_func(); + } + } +} + +void ScopeGuard::dismiss() +{ + m_func.clear(); +} + +FlagGuard::~FlagGuard() +{ +} + +FlagRestorationGuard::~FlagRestorationGuard() +{ +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/sequence.cxx b/comphelper/source/misc/sequence.cxx new file mode 100644 index 000000000000..622cfff4989d --- /dev/null +++ b/comphelper/source/misc/sequence.cxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/sequence.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +//------------------------------------------------------------------------------ +staruno::Sequence<sal_Int16> findValue(const staruno::Sequence< ::rtl::OUString >& _rList, const ::rtl::OUString& _rValue, sal_Bool _bOnlyFirst) +{ + sal_Int32 nLength = _rList.getLength(); + + if( _bOnlyFirst ) + { + ////////////////////////////////////////////////////////////////////// + // An welcher Position finde ich den Wert? + sal_Int32 nPos = -1; + const ::rtl::OUString* pTArray = _rList.getConstArray(); + for (sal_Int32 i = 0; i < nLength; ++i, ++pTArray) + { + if( pTArray->equals(_rValue) ) + { + nPos = i; + break; + } + } + + ////////////////////////////////////////////////////////////////////// + // Sequence fuellen + if( nPos>-1 ) + { + staruno::Sequence<sal_Int16> aRetSeq( 1 ); + aRetSeq.getArray()[0] = (sal_Int16)nPos; + + return aRetSeq; + } + + return staruno::Sequence<sal_Int16>(); + + } + else + { + staruno::Sequence<sal_Int16> aRetSeq( nLength ); + sal_Int16* pReturn = aRetSeq.getArray(); + + ////////////////////////////////////////////////////////////////////// + // Wie oft kommt der Wert vor? + const ::rtl::OUString* pTArray = _rList.getConstArray(); + for (sal_Int32 i = 0; i < nLength; ++i, ++pTArray) + { + if( pTArray->equals(_rValue) ) + { + *pReturn = (sal_Int16)i; + ++pReturn; + } + } + + aRetSeq.realloc(pReturn - aRetSeq.getArray()); + + return aRetSeq; + } +} +// ----------------------------------------------------------------------------- +sal_Bool existsValue(const ::rtl::OUString& Value,const staruno::Sequence< ::rtl::OUString >& _aList) +{ + const ::rtl::OUString * pIter = _aList.getConstArray(); + const ::rtl::OUString * pEnd = pIter + _aList.getLength(); + return ::std::find(pIter,pEnd,Value) != pEnd; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/sequenceashashmap.cxx b/comphelper/source/misc/sequenceashashmap.cxx new file mode 100644 index 000000000000..d119f10a3a0d --- /dev/null +++ b/comphelper/source/misc/sequenceashashmap.cxx @@ -0,0 +1,403 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +//_______________________________________________ +// includes +#include <comphelper/sequenceashashmap.hxx> + +//_______________________________________________ +// namespace + +namespace comphelper{ + +namespace css = ::com::sun::star; + +//_______________________________________________ +// definitions + +/*----------------------------------------------- + 04.11.2003 09:29 +-----------------------------------------------*/ +SequenceAsHashMap::SequenceAsHashMap() + : SequenceAsHashMapBase() +{ +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +SequenceAsHashMap::SequenceAsHashMap(const css::uno::Any& aSource) +{ + (*this) << aSource; +} + +//----------------------------------------------- +SequenceAsHashMap::SequenceAsHashMap(const css::uno::Sequence< css::uno::Any >& lSource) +{ + (*this) << lSource; +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +SequenceAsHashMap::SequenceAsHashMap(const css::uno::Sequence< css::beans::PropertyValue >& lSource) +{ + (*this) << lSource; +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +SequenceAsHashMap::SequenceAsHashMap(const css::uno::Sequence< css::beans::NamedValue >& lSource) +{ + (*this) << lSource; +} + +/*----------------------------------------------- + 04.11.2003 09:04 +-----------------------------------------------*/ +SequenceAsHashMap::~SequenceAsHashMap() +{ +} + +/*----------------------------------------------- + 04.11.2003 10:21 +-----------------------------------------------*/ +void SequenceAsHashMap::operator<<(const css::uno::Any& aSource) +{ + // An empty Any reset this instance! + if (!aSource.hasValue()) + { + clear(); + return; + } + + css::uno::Sequence< css::beans::NamedValue > lN; + if (aSource >>= lN) + { + (*this) << lN; + return; + } + + css::uno::Sequence< css::beans::PropertyValue > lP; + if (aSource >>= lP) + { + (*this) << lP; + return; + } + + throw css::beans::IllegalTypeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Any contains wrong type." )), + css::uno::Reference< css::uno::XInterface >()); +} + +//----------------------------------------------- +void SequenceAsHashMap::operator<<(const css::uno::Sequence< css::uno::Any >& lSource) +{ + sal_Int32 c = lSource.getLength(); + sal_Int32 i = 0; + + for (i=0; i<c; ++i) + { + css::beans::PropertyValue lP; + if (lSource[i] >>= lP) + { + if ( + (!lP.Name.getLength()) || + (!lP.Value.hasValue()) + ) + throw css::beans::IllegalTypeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PropertyValue struct contains no usefull informations." )), + css::uno::Reference< css::uno::XInterface >()); + (*this)[lP.Name] = lP.Value; + continue; + } + + css::beans::NamedValue lN; + if (lSource[i] >>= lN) + { + if ( + (!lN.Name.getLength()) || + (!lN.Value.hasValue()) + ) + throw css::beans::IllegalTypeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NamedValue struct contains no usefull informations." )), + css::uno::Reference< css::uno::XInterface >()); + (*this)[lN.Name] = lN.Value; + continue; + } + + // ignore VOID Any ... but reject wrong filled ones! + if (lSource[i].hasValue()) + throw css::beans::IllegalTypeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Any contains wrong type." )), + css::uno::Reference< css::uno::XInterface >()); + } +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +void SequenceAsHashMap::operator<<(const css::uno::Sequence< css::beans::PropertyValue >& lSource) +{ + clear(); + + sal_Int32 c = lSource.getLength(); + const css::beans::PropertyValue* pSource = lSource.getConstArray(); + + for (sal_Int32 i=0; i<c; ++i) + (*this)[pSource[i].Name] = pSource[i].Value; +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +void SequenceAsHashMap::operator<<(const css::uno::Sequence< css::beans::NamedValue >& lSource) +{ + clear(); + + sal_Int32 c = lSource.getLength(); + const css::beans::NamedValue* pSource = lSource.getConstArray(); + + for (sal_Int32 i=0; i<c; ++i) + (*this)[pSource[i].Name] = pSource[i].Value; +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +void SequenceAsHashMap::operator>>(css::uno::Sequence< css::beans::PropertyValue >& lDestination) const +{ + sal_Int32 c = (sal_Int32)size(); + lDestination.realloc(c); + css::beans::PropertyValue* pDestination = lDestination.getArray(); + + sal_Int32 i = 0; + for (const_iterator pThis = begin(); + pThis != end() ; + ++pThis ) + { + pDestination[i].Name = pThis->first ; + pDestination[i].Value = pThis->second; + ++i; + } +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +void SequenceAsHashMap::operator>>(css::uno::Sequence< css::beans::NamedValue >& lDestination) const +{ + sal_Int32 c = (sal_Int32)size(); + lDestination.realloc(c); + css::beans::NamedValue* pDestination = lDestination.getArray(); + + sal_Int32 i = 0; + for (const_iterator pThis = begin(); + pThis != end() ; + ++pThis ) + { + pDestination[i].Name = pThis->first ; + pDestination[i].Value = pThis->second; + ++i; + } +} + +/*----------------------------------------------- + 30.07.2007 14:10 +-----------------------------------------------*/ +const css::uno::Any SequenceAsHashMap::getAsConstAny(::sal_Bool bAsPropertyValueList) const +{ + css::uno::Any aDestination; + if (bAsPropertyValueList) + aDestination = css::uno::makeAny(getAsConstPropertyValueList()); + else + aDestination = css::uno::makeAny(getAsConstNamedValueList()); + return aDestination; +} + +/*----------------------------------------------- + 30.07.2007 14:10 +-----------------------------------------------*/ +const css::uno::Sequence< css::uno::Any > SequenceAsHashMap::getAsConstAnyList(::sal_Bool bAsPropertyValueList) const +{ + ::sal_Int32 i = 0; + ::sal_Int32 c = (::sal_Int32)size(); + css::uno::Sequence< css::uno::Any > lDestination(c); + css::uno::Any* pDestination = lDestination.getArray(); + + for (const_iterator pThis = begin(); + pThis != end() ; + ++pThis ) + { + if (bAsPropertyValueList) + { + css::beans::PropertyValue aProp; + aProp.Name = pThis->first; + aProp.Value = pThis->second; + pDestination[i] = css::uno::makeAny(aProp); + } + else + { + css::beans::NamedValue aProp; + aProp.Name = pThis->first; + aProp.Value = pThis->second; + pDestination[i] = css::uno::makeAny(aProp); + } + + ++i; + } + + return lDestination; +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +const css::uno::Sequence< css::beans::NamedValue > SequenceAsHashMap::getAsConstNamedValueList() const +{ + css::uno::Sequence< css::beans::NamedValue > lReturn; + (*this) >> lReturn; + return lReturn; +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +const css::uno::Sequence< css::beans::PropertyValue > SequenceAsHashMap::getAsConstPropertyValueList() const +{ + css::uno::Sequence< css::beans::PropertyValue > lReturn; + (*this) >> lReturn; + return lReturn; +} + +/*----------------------------------------------- + 07.03.2007 12:45 +-----------------------------------------------*/ +sal_Bool SequenceAsHashMap::match(const SequenceAsHashMap& rCheck) const +{ + const_iterator pCheck; + for ( pCheck = rCheck.begin(); + pCheck != rCheck.end() ; + ++pCheck ) + { + const ::rtl::OUString& sCheckName = pCheck->first; + const css::uno::Any& aCheckValue = pCheck->second; + const_iterator pFound = find(sCheckName); + + if (pFound == end()) + return sal_False; + + const css::uno::Any& aFoundValue = pFound->second; + if (aFoundValue != aCheckValue) + return sal_False; + } + + return sal_True; +} + +/*----------------------------------------------- + 30.07.2007 14:30 +-----------------------------------------------*/ +void SequenceAsHashMap::update(const SequenceAsHashMap& rUpdate) +{ + const_iterator pUpdate; + for ( pUpdate = rUpdate.begin(); + pUpdate != rUpdate.end() ; + ++pUpdate ) + { + const ::rtl::OUString& sName = pUpdate->first; + const css::uno::Any& aValue = pUpdate->second; + + (*this)[sName] = aValue; + } +} + +/*----------------------------------------------- + 04.11.2003 08:30 +-----------------------------------------------*/ +#if OSL_DEBUG_LEVEL > 1 +void SequenceAsHashMap::dbg_dumpToFile(const char* pFileName, + const char* pComment ) const +{ + if (!pFileName || !pComment) + return; + + FILE* pFile = fopen(pFileName, "a"); + if (!pFile) + return; + + ::rtl::OUStringBuffer sBuffer(1000); + sBuffer.appendAscii("\n----------------------------------------\n"); + sBuffer.appendAscii(pComment ); + sBuffer.appendAscii("\n----------------------------------------\n"); + sal_Int32 i = 0; + for (const_iterator pIt = begin(); + pIt != end() ; + ++pIt ) + { + sBuffer.appendAscii("[" ); + sBuffer.append (i++ ); + sBuffer.appendAscii("] " ); + sBuffer.appendAscii("\"" ); + sBuffer.append (pIt->first); + sBuffer.appendAscii("\" = \"" ); + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xv; + ::rtl::OUString sv; + sal_Int32 nv; + sal_Bool bv; + + if (pIt->second >>= sv) + sBuffer.append(sv); + else + if (pIt->second >>= nv) + sBuffer.append(nv); + else + if (pIt->second >>= bv) + sBuffer.appendAscii(bv ? "true" : "false"); + else + if (pIt->second >>= xv) + sBuffer.appendAscii(xv.is() ? "object" : "null"); + else + sBuffer.appendAscii("???"); + + sBuffer.appendAscii("\"\n"); + } + + fprintf(pFile, ::rtl::OUStringToOString(sBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr()); + fclose(pFile); +} +#endif // OSL_DEBUG_LEVEL > 1 + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/servicedecl.cxx b/comphelper/source/misc/servicedecl.cxx new file mode 100644 index 000000000000..6048709fd061 --- /dev/null +++ b/comphelper/source/misc/servicedecl.cxx @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/servicedecl.hxx" +#include "osl/diagnose.h" +#include "rtl/string.hxx" +#include "rtl/ustrbuf.hxx" +#include "cppuhelper/implbase2.hxx" +#include "comphelper/sequence.hxx" +#include "com/sun/star/lang/XSingleComponentFactory.hpp" +#include <vector> + +using namespace com::sun::star; + +namespace comphelper { +namespace service_decl { + +class ServiceDecl::Factory : + public cppu::WeakImplHelper2<lang::XSingleComponentFactory, + lang::XServiceInfo>, + private boost::noncopyable +{ +public: + explicit Factory( ServiceDecl const& rServiceDecl ) + : m_rServiceDecl(rServiceDecl) {} + + // XServiceInfo: + virtual rtl::OUString SAL_CALL getImplementationName() + throw (uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( rtl::OUString const& name ) + throw (uno::RuntimeException); + virtual uno::Sequence<rtl::OUString> SAL_CALL getSupportedServiceNames() + throw (uno::RuntimeException); + // XSingleComponentFactory: + virtual uno::Reference<uno::XInterface> SAL_CALL createInstanceWithContext( + uno::Reference<uno::XComponentContext> const& xContext ) + throw (uno::Exception); + virtual uno::Reference<uno::XInterface> SAL_CALL + createInstanceWithArgumentsAndContext( + uno::Sequence<uno::Any> const& args, + uno::Reference<uno::XComponentContext> const& xContext ) + throw (uno::Exception); + +private: + virtual ~Factory(); + + ServiceDecl const& m_rServiceDecl; +}; + +ServiceDecl::Factory::~Factory() +{ +} + +// XServiceInfo: +rtl::OUString ServiceDecl::Factory::getImplementationName() + throw (uno::RuntimeException) +{ + return m_rServiceDecl.getImplementationName(); +} + +sal_Bool ServiceDecl::Factory::supportsService( rtl::OUString const& name ) + throw (uno::RuntimeException) +{ + return m_rServiceDecl.supportsService(name); +} + +uno::Sequence<rtl::OUString> ServiceDecl::Factory::getSupportedServiceNames() + throw (uno::RuntimeException) +{ + return m_rServiceDecl.getSupportedServiceNames(); +} + +// XSingleComponentFactory: +uno::Reference<uno::XInterface> ServiceDecl::Factory::createInstanceWithContext( + uno::Reference<uno::XComponentContext> const& xContext ) + throw (uno::Exception) +{ + return m_rServiceDecl.m_createFunc( + m_rServiceDecl, uno::Sequence<uno::Any>(), xContext ); +} + +uno::Reference<uno::XInterface> +ServiceDecl::Factory::createInstanceWithArgumentsAndContext( + uno::Sequence<uno::Any > const& args, + uno::Reference<uno::XComponentContext> const& xContext ) + throw (uno::Exception) +{ + return m_rServiceDecl.m_createFunc( + m_rServiceDecl, args, xContext ); +} + +void * ServiceDecl::getFactory( sal_Char const* pImplName ) const +{ + if (rtl_str_compare(m_pImplName, pImplName) == 0) { + lang::XSingleComponentFactory * const pFac( new Factory(*this) ); + pFac->acquire(); + return pFac; + } + return 0; +} + +uno::Sequence<rtl::OUString> ServiceDecl::getSupportedServiceNames() const +{ + std::vector<rtl::OUString> vec; + + rtl::OString const str(m_pServiceNames); + sal_Int32 nIndex = 0; + do { + rtl::OString const token( str.getToken( 0, m_cDelim, nIndex ) ); + vec.push_back( rtl::OUString( token.getStr(), token.getLength(), + RTL_TEXTENCODING_ASCII_US ) ); + } + while (nIndex >= 0); + + return comphelper::containerToSequence(vec); +} + +bool ServiceDecl::supportsService( ::rtl::OUString const& name ) const +{ + rtl::OString const str(m_pServiceNames); + sal_Int32 nIndex = 0; + do { + rtl::OString const token( str.getToken( 0, m_cDelim, nIndex ) ); + if (name.equalsAsciiL( token.getStr(), token.getLength() )) + return true; + } + while (nIndex >= 0); + return false; +} + +rtl::OUString ServiceDecl::getImplementationName() const +{ + return rtl::OUString::createFromAscii(m_pImplName); +} + +} // namespace service_decl +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/serviceinfohelper.cxx b/comphelper/source/misc/serviceinfohelper.cxx new file mode 100644 index 000000000000..97f7f96ad8df --- /dev/null +++ b/comphelper/source/misc/serviceinfohelper.cxx @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_comphelper.hxx" + +#include "comphelper/serviceinfohelper.hxx" +#include <stdarg.h> + +// ##################################################################### + +namespace comphelper +{ + +/** returns an empty UString(). most times sufficient */ +::rtl::OUString SAL_CALL ServiceInfoHelper::getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) +{ + return ::rtl::OUString(); +} + +/** the base implementation iterates over the service names from <code>getSupportedServiceNames</code> */ +sal_Bool SAL_CALL ServiceInfoHelper::supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException) +{ + return supportsService( ServiceName, getSupportedServiceNames() ); +} + +sal_Bool SAL_CALL ServiceInfoHelper::supportsService( const ::rtl::OUString& ServiceName, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& SupportedServices ) throw() +{ + const ::rtl::OUString * pArray = SupportedServices.getConstArray(); + for( sal_Int32 i = 0; i < SupportedServices.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + return sal_False; +} + +/** the base implementation has no supported services */ +::com::sun::star::uno::Sequence< ::rtl::OUString > ServiceInfoHelper::getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException ) +{ + ::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq(0); + return aSeq; +} + +/** this method concatenates the given sequences and returns the result + */ +::com::sun::star::uno::Sequence< ::rtl::OUString > ServiceInfoHelper::concatSequences( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rSeq1, + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rSeq2 ) throw() +{ + const sal_Int32 nLen1 = rSeq1.getLength(); + const sal_Int32 nLen2 = rSeq2.getLength(); + + ::com::sun::star::uno::Sequence< ::rtl::OUString > aSeq( nLen1 + nLen2 ); + + ::rtl::OUString* pStrings = aSeq.getArray(); + + sal_Int32 nIdx; + const ::rtl::OUString* pStringSrc = rSeq1.getConstArray(); + for( nIdx = 0; nIdx < nLen1; nIdx++ ) + *pStrings++ = *pStringSrc++; + + pStringSrc = rSeq2.getConstArray(); + for( nIdx = 0; nIdx < nLen2; nIdx++ ) + *pStrings++ = *pStringSrc++; + + return aSeq; +} + +/** this method adds a variable number of char pointer to a given Sequence + */ +void ServiceInfoHelper::addToSequence( ::com::sun::star::uno::Sequence< ::rtl::OUString >& rSeq, sal_uInt16 nServices, /* char * */ ... ) throw() +{ + sal_uInt32 nCount = rSeq.getLength(); + + rSeq.realloc( nCount + nServices ); + rtl::OUString* pStrings = rSeq.getArray(); + + va_list marker; + va_start( marker, nServices ); + for( sal_uInt16 i = 0 ; i < nServices; i++ ) + pStrings[nCount++] = rtl::OUString::createFromAscii(va_arg( marker, char*)); + va_end( marker ); +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/sharedmutex.cxx b/comphelper/source/misc/sharedmutex.cxx new file mode 100644 index 000000000000..346fead794fe --- /dev/null +++ b/comphelper/source/misc/sharedmutex.cxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/sharedmutex.hxx" + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + //======================================================================== + //= SharedMutex + //======================================================================== + //------------------------------------------------------------------------ + SharedMutex::SharedMutex() + :m_pMutexImpl( new ::osl::Mutex ) + { + } + + //------------------------------------------------------------------------ + SharedMutex::SharedMutex( const SharedMutex& _rhs ) + :m_pMutexImpl() + { + *this = _rhs; + } + + //------------------------------------------------------------------------ + SharedMutex& SharedMutex::operator=( const SharedMutex& _rhs ) + { + m_pMutexImpl = _rhs.m_pMutexImpl; + return *this; + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/stillreadwriteinteraction.cxx b/comphelper/source/misc/stillreadwriteinteraction.cxx new file mode 100644 index 000000000000..f51353e47897 --- /dev/null +++ b/comphelper/source/misc/stillreadwriteinteraction.cxx @@ -0,0 +1,141 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/stillreadwriteinteraction.hxx> + +#include <com/sun/star/ucb/InteractiveIOException.hpp> + +#include <com/sun/star/task/XInteractionAbort.hpp> + +#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> + +namespace comphelper{ + + namespace css = ::com::sun::star; + +StillReadWriteInteraction::StillReadWriteInteraction(const css::uno::Reference< css::task::XInteractionHandler >& xHandler) + : m_bUsed (sal_False) + , m_bHandledByMySelf (sal_False) + , m_bHandledByInternalHandler(sal_False) +{ + ::std::vector< ::ucbhelper::InterceptedInteraction::InterceptedRequest > lInterceptions; + ::ucbhelper::InterceptedInteraction::InterceptedRequest aInterceptedRequest; + + aInterceptedRequest.Handle = HANDLE_INTERACTIVEIOEXCEPTION; + aInterceptedRequest.Request <<= css::ucb::InteractiveIOException(); + aInterceptedRequest.Continuation = ::getCppuType(static_cast< css::uno::Reference< css::task::XInteractionAbort >* >(0)); + aInterceptedRequest.MatchExact = sal_False; + lInterceptions.push_back(aInterceptedRequest); + + aInterceptedRequest.Handle = HANDLE_UNSUPPORTEDDATASINKEXCEPTION; + aInterceptedRequest.Request <<= css::ucb::UnsupportedDataSinkException(); + aInterceptedRequest.Continuation = ::getCppuType(static_cast< css::uno::Reference< css::task::XInteractionAbort >* >(0)); + aInterceptedRequest.MatchExact = sal_False; + lInterceptions.push_back(aInterceptedRequest); + + setInterceptedHandler(xHandler); + setInterceptions(lInterceptions); +} + +void StillReadWriteInteraction::resetInterceptions() +{ + setInterceptions(::std::vector< ::ucbhelper::InterceptedInteraction::InterceptedRequest >()); +} + +void StillReadWriteInteraction::resetErrorStates() +{ + m_bUsed = sal_False; + m_bHandledByMySelf = sal_False; + m_bHandledByInternalHandler = sal_False; +} + +sal_Bool StillReadWriteInteraction::wasWriteError() +{ + return (m_bUsed && m_bHandledByMySelf); +} + +ucbhelper::InterceptedInteraction::EInterceptionState StillReadWriteInteraction::intercepted(const ::ucbhelper::InterceptedInteraction::InterceptedRequest& aRequest, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest) +{ + // we are used! + m_bUsed = sal_True; + + // check if its a real interception - might some parameters are not the right ones ... + sal_Bool bAbort = sal_False; + switch(aRequest.Handle) + { + case HANDLE_INTERACTIVEIOEXCEPTION: + { + css::ucb::InteractiveIOException exIO; + xRequest->getRequest() >>= exIO; + bAbort = ( + (exIO.Code == css::ucb::IOErrorCode_ACCESS_DENIED ) + || (exIO.Code == css::ucb::IOErrorCode_LOCKING_VIOLATION ) + || (exIO.Code == css::ucb::IOErrorCode_NOT_EXISTING ) +#ifdef MACOSX + // this is a workaround for MAC, on this platform if the file is locked + // the returned error code looks to be wrong + || (exIO.Code == css::ucb::IOErrorCode_GENERAL ) +#endif + ); + } + break; + + case HANDLE_UNSUPPORTEDDATASINKEXCEPTION: + { + bAbort = sal_True; + } + break; + } + + // handle interaction by ourself + if (bAbort) + { + m_bHandledByMySelf = sal_True; + css::uno::Reference< css::task::XInteractionContinuation > xAbort = ::ucbhelper::InterceptedInteraction::extractContinuation( + xRequest->getContinuations(), + ::getCppuType(static_cast< css::uno::Reference< css::task::XInteractionAbort >* >(0))); + if (!xAbort.is()) + return ::ucbhelper::InterceptedInteraction::E_NO_CONTINUATION_FOUND; + xAbort->select(); + return ::ucbhelper::InterceptedInteraction::E_INTERCEPTED; + } + + // Otherwhise use internal handler. + if (m_xInterceptedHandler.is()) + { + m_bHandledByInternalHandler = sal_True; + m_xInterceptedHandler->handle(xRequest); + } + return ::ucbhelper::InterceptedInteraction::E_INTERCEPTED; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx new file mode 100644 index 000000000000..70b7852b579a --- /dev/null +++ b/comphelper/source/misc/storagehelper.cxx @@ -0,0 +1,541 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/embed/XEncryptionProtectedSource2.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/IllegalTypeException.hpp> +#include <com/sun/star/xml/crypto/XDigestContext.hpp> +#include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp> +#include <com/sun/star/xml/crypto/DigestID.hpp> + +#include <rtl/digest.h> + +#include <ucbhelper/content.hxx> + +#include <comphelper/fileformat.h> +#include <comphelper/processfactory.hxx> +#include <comphelper/documentconstants.hxx> + +#include <comphelper/storagehelper.hxx> + + +using namespace ::com::sun::star; + +namespace comphelper { + +// ---------------------------------------------------------------------- +uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetStorageFactory( + const uno::Reference< lang::XMultiServiceFactory >& xSF ) + throw ( uno::Exception ) +{ + uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory(); + if ( !xFactory.is() ) + throw uno::RuntimeException(); + + uno::Reference < lang::XSingleServiceFactory > xStorageFactory( + xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.StorageFactory" )) ), + uno::UNO_QUERY ); + + if ( !xStorageFactory.is() ) + throw uno::RuntimeException(); + + return xStorageFactory; +} + +// ---------------------------------------------------------------------- +uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetFileSystemStorageFactory( + const uno::Reference< lang::XMultiServiceFactory >& xSF ) + throw ( uno::Exception ) +{ + uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory(); + if ( !xFactory.is() ) + throw uno::RuntimeException(); + + uno::Reference < lang::XSingleServiceFactory > xStorageFactory( + xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.FileSystemStorageFactory" )) ), + uno::UNO_QUERY ); + + if ( !xStorageFactory.is() ) + throw uno::RuntimeException(); + + return xStorageFactory; +} + +// ---------------------------------------------------------------------- +uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorage( + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) + throw ( uno::Exception ) +{ + uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstance(), + uno::UNO_QUERY ); + if ( !xTempStorage.is() ) + throw uno::RuntimeException(); + + return xTempStorage; +} + +// ---------------------------------------------------------------------- +uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL( + const ::rtl::OUString& aURL, + sal_Int32 nStorageMode, + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) + throw ( uno::Exception ) +{ + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[0] <<= aURL; + aArgs[1] <<= nStorageMode; + + uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), + uno::UNO_QUERY ); + if ( !xTempStorage.is() ) + throw uno::RuntimeException(); + + return xTempStorage; +} + +// ---------------------------------------------------------------------- +uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL2( + const ::rtl::OUString& aURL, + sal_Int32 nStorageMode, + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) + throw ( uno::Exception ) +{ + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[0] <<= aURL; + aArgs[1] <<= nStorageMode; + + uno::Reference< lang::XSingleServiceFactory > xFact; + try { + ::ucbhelper::Content aCntnt( aURL, + uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); + if (aCntnt.isDocument()) { + xFact = GetStorageFactory( xFactory ); + } else { + xFact = GetFileSystemStorageFactory( xFactory ); + } + } catch (uno::Exception &) { } + + if (!xFact.is()) throw uno::RuntimeException(); + + uno::Reference< embed::XStorage > xTempStorage( + xFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY ); + if ( !xTempStorage.is() ) + throw uno::RuntimeException(); + + return xTempStorage; +} + +// ---------------------------------------------------------------------- +uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromInputStream( + const uno::Reference < io::XInputStream >& xStream, + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) + throw ( uno::Exception ) +{ + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[0] <<= xStream; + aArgs[1] <<= embed::ElementModes::READ; + + uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), + uno::UNO_QUERY ); + if ( !xTempStorage.is() ) + throw uno::RuntimeException(); + + return xTempStorage; +} + +// ---------------------------------------------------------------------- +uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromStream( + const uno::Reference < io::XStream >& xStream, + sal_Int32 nStorageMode, + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) + throw ( uno::Exception ) +{ + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[0] <<= xStream; + aArgs[1] <<= nStorageMode; + + uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), + uno::UNO_QUERY ); + if ( !xTempStorage.is() ) + throw uno::RuntimeException(); + + return xTempStorage; +} + +// ---------------------------------------------------------------------- +void OStorageHelper::CopyInputToOutput( + const uno::Reference< io::XInputStream >& xInput, + const uno::Reference< io::XOutputStream >& xOutput ) + throw ( uno::Exception ) +{ + static const sal_Int32 nConstBufferSize = 32000; + + sal_Int32 nRead; + uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize ); + + do + { + nRead = xInput->readBytes ( aSequence, nConstBufferSize ); + if ( nRead < nConstBufferSize ) + { + uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead ); + xOutput->writeBytes ( aTempBuf ); + } + else + xOutput->writeBytes ( aSequence ); + } + while ( nRead == nConstBufferSize ); +} + +// ---------------------------------------------------------------------- +uno::Reference< io::XInputStream > OStorageHelper::GetInputStreamFromURL( + const ::rtl::OUString& aURL, + const uno::Reference< lang::XMultiServiceFactory >& xSF ) + throw ( uno::Exception ) +{ + uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory(); + if ( !xFactory.is() ) + throw uno::RuntimeException(); + + uno::Reference < ::com::sun::star::ucb::XSimpleFileAccess > xTempAccess( + xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" )) ), + uno::UNO_QUERY ); + + if ( !xTempAccess.is() ) + throw uno::RuntimeException(); + + uno::Reference< io::XInputStream > xInputStream = xTempAccess->openFileRead( aURL ); + if ( !xInputStream.is() ) + throw uno::RuntimeException(); + + return xInputStream; +} + +// ---------------------------------------------------------------------- +void OStorageHelper::SetCommonStorageEncryptionData( + const uno::Reference< embed::XStorage >& xStorage, + const uno::Sequence< beans::NamedValue >& aEncryptionData ) + throw ( uno::Exception ) +{ + uno::Reference< embed::XEncryptionProtectedSource2 > xEncrSet( xStorage, uno::UNO_QUERY ); + if ( !xEncrSet.is() ) + throw io::IOException(); // TODO + + xEncrSet->setEncryptionData( aEncryptionData ); +} + +// ---------------------------------------------------------------------- +sal_Int32 OStorageHelper::GetXStorageFormat( + const uno::Reference< embed::XStorage >& xStorage ) + throw ( uno::Exception ) +{ + uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW ); + + ::rtl::OUString aMediaType; + xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" )) ) >>= aMediaType; + + sal_Int32 nResult = 0; + + // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service + if ( + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_DRAW_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CALC_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CHART_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_MATH_ASCII ) + ) + { + nResult = SOFFICE_FILEFORMAT_60; + } + else + if ( + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII ) || + aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII ) + ) + { + nResult = SOFFICE_FILEFORMAT_8; + } + else + { + // the mediatype is not known + throw beans::IllegalTypeException(); + } + + return nResult; +} + +// ---------------------------------------------------------------------- +uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromURL( + const ::rtl::OUString& aFormat, + const ::rtl::OUString& aURL, + sal_Int32 nStorageMode, + const uno::Reference< lang::XMultiServiceFactory >& xFactory, + sal_Bool bRepairStorage ) + throw ( uno::Exception ) +{ + uno::Sequence< beans::PropertyValue > aProps( 1 ); + aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aProps[0].Value <<= aFormat; + if ( bRepairStorage ) + { + aProps.realloc( 2 ); + aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) ); + aProps[1].Value <<= bRepairStorage; + } + + uno::Sequence< uno::Any > aArgs( 3 ); + aArgs[0] <<= aURL; + aArgs[1] <<= nStorageMode; + aArgs[2] <<= aProps; + + uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), + uno::UNO_QUERY ); + if ( !xTempStorage.is() ) + throw uno::RuntimeException(); + + return xTempStorage; +} + +// ---------------------------------------------------------------------- +uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromInputStream( + const ::rtl::OUString& aFormat, + const uno::Reference < io::XInputStream >& xStream, + const uno::Reference< lang::XMultiServiceFactory >& xFactory, + sal_Bool bRepairStorage ) + throw ( uno::Exception ) +{ + uno::Sequence< beans::PropertyValue > aProps( 1 ); + aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aProps[0].Value <<= aFormat; + if ( bRepairStorage ) + { + aProps.realloc( 2 ); + aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) ); + aProps[1].Value <<= bRepairStorage; + } + + uno::Sequence< uno::Any > aArgs( 3 ); + aArgs[0] <<= xStream; + aArgs[1] <<= embed::ElementModes::READ; + aArgs[2] <<= aProps; + + uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), + uno::UNO_QUERY ); + if ( !xTempStorage.is() ) + throw uno::RuntimeException(); + + return xTempStorage; +} + +// ---------------------------------------------------------------------- +uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromStream( + const ::rtl::OUString& aFormat, + const uno::Reference < io::XStream >& xStream, + sal_Int32 nStorageMode, + const uno::Reference< lang::XMultiServiceFactory >& xFactory, + sal_Bool bRepairStorage ) + throw ( uno::Exception ) +{ + uno::Sequence< beans::PropertyValue > aProps( 1 ); + aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aProps[0].Value <<= aFormat; + if ( bRepairStorage ) + { + aProps.realloc( 2 ); + aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) ); + aProps[1].Value <<= bRepairStorage; + } + + uno::Sequence< uno::Any > aArgs( 3 ); + aArgs[0] <<= xStream; + aArgs[1] <<= nStorageMode; + aArgs[2] <<= aProps; + + uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), + uno::UNO_QUERY ); + if ( !xTempStorage.is() ) + throw uno::RuntimeException(); + + return xTempStorage; +} + +// ---------------------------------------------------------------------- +uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData( const ::rtl::OUString& aPassword, const uno::Reference< lang::XMultiServiceFactory >& xSF ) +{ + // TODO/LATER: Should not the method be part of DocPasswordHelper? + uno::Sequence< beans::NamedValue > aEncryptionData; + sal_Int32 nSha1Ind = 0; + if ( aPassword.getLength() ) + { + // generate SHA256 start key + try + { + uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory(); + if ( !xFactory.is() ) + throw uno::RuntimeException(); + + uno::Reference< xml::crypto::XDigestContextSupplier > xDigestContextSupplier( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ), uno::UNO_QUERY_THROW ); + uno::Reference< xml::crypto::XDigestContext > xDigestContext( xDigestContextSupplier->getDigestContext( xml::crypto::DigestID::SHA256, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW ); + + ::rtl::OString aUTF8Password( ::rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_UTF8 ) ); + xDigestContext->updateDigest( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUTF8Password.getStr() ), aUTF8Password.getLength() ) ); + uno::Sequence< sal_Int8 > aDigest = xDigestContext->finalizeDigestAndDispose(); + + aEncryptionData.realloc( ++nSha1Ind ); + aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8; + aEncryptionData[0].Value <<= aDigest; + } + catch ( uno::Exception& ) + { + OSL_ENSURE( false, "Can not create SHA256 digest!" ); + } + + // MS_1252 encoding was used for SO60 document format password encoding, + // this encoding supports only a minor subset of nonascii characters, + // but for compatibility reasons it has to be used for old document formats + aEncryptionData.realloc( nSha1Ind + 2 ); + aEncryptionData[nSha1Ind].Name = PACKAGE_ENCRYPTIONDATA_SHA1UTF8; + aEncryptionData[nSha1Ind + 1].Name = PACKAGE_ENCRYPTIONDATA_SHA1MS1252; + + rtl_TextEncoding pEncoding[2] = { RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_MS_1252 }; + + for ( sal_Int32 nInd = 0; nInd < 2; nInd++ ) + { + ::rtl::OString aByteStrPass = ::rtl::OUStringToOString( aPassword, pEncoding[nInd] ); + + sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_SHA1]; + rtlDigestError nError = rtl_digest_SHA1( aByteStrPass.getStr(), + aByteStrPass.getLength(), + pBuffer, + RTL_DIGEST_LENGTH_SHA1 ); + + if ( nError != rtl_Digest_E_None ) + { + aEncryptionData.realloc( nSha1Ind ); + break; + } + + aEncryptionData[nSha1Ind+nInd].Value <<= uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 ); + } + } + + return aEncryptionData; +} + +// ---------------------------------------------------------------------- +sal_Bool OStorageHelper::IsValidZipEntryFileName( const ::rtl::OUString& aName, sal_Bool bSlashAllowed ) +{ + return IsValidZipEntryFileName( aName.getStr(), aName.getLength(), bSlashAllowed ); +} + +// ---------------------------------------------------------------------- +sal_Bool OStorageHelper::IsValidZipEntryFileName( + const sal_Unicode *pChar, sal_Int32 nLength, sal_Bool bSlashAllowed ) +{ + for ( sal_Int32 i = 0; i < nLength; i++ ) + { + switch ( pChar[i] ) + { + case '\\': + case '?': + case '<': + case '>': + case '\"': + case '|': + case ':': + return sal_False; + case '/': + if ( !bSlashAllowed ) + return sal_False; + break; + default: + if ( pChar[i] < 32 || (pChar[i] >= 0xD800 && pChar[i] <= 0xDFFF) ) + return sal_False; + } + } + return sal_True; +} + +// ---------------------------------------------------------------------- +sal_Bool OStorageHelper::PathHasSegment( const ::rtl::OUString& aPath, const ::rtl::OUString& aSegment ) +{ + sal_Bool bResult = sal_False; + const sal_Int32 nPathLen = aPath.getLength(); + const sal_Int32 nSegLen = aSegment.getLength(); + + if ( nSegLen && nPathLen >= nSegLen ) + { + ::rtl::OUString aEndSegment( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); + aEndSegment += aSegment; + + ::rtl::OUString aInternalSegment( aEndSegment ); + aInternalSegment += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); + + if ( aPath.indexOf( aInternalSegment ) >= 0 ) + bResult = sal_True; + + if ( !bResult && !aPath.compareTo( aSegment, nSegLen ) ) + { + if ( nPathLen == nSegLen || aPath.getStr()[nSegLen] == (sal_Unicode)'/' ) + bResult = sal_True; + } + + if ( !bResult && nPathLen > nSegLen && aPath.copy( nPathLen - nSegLen - 1, nSegLen + 1 ).equals( aEndSegment ) ) + bResult = sal_True; + } + + return bResult; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/string.cxx b/comphelper/source/misc/string.cxx new file mode 100644 index 000000000000..b31d11549815 --- /dev/null +++ b/comphelper/source/misc/string.cxx @@ -0,0 +1,380 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "sal/config.h" + +#include <cstddef> +#include <string.h> +#include <vector> +#include <algorithm> + +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/string.hxx> +#include <rtl/strbuf.hxx> +#include <sal/types.h> + +#include <comphelper/string.hxx> +#include <comphelper/stlunosequence.hxx> +#include <comphelper/stl_types.hxx> + +#include <com/sun/star/i18n/CharType.hpp> + + +namespace comphelper { namespace string { + +rtl::OUString searchAndReplaceAsciiL( + rtl::OUString const & source, char const * from, sal_Int32 fromLength, + rtl::OUString const & to, sal_Int32 beginAt, sal_Int32 * replacedAt) +{ + sal_Int32 n = source.indexOfAsciiL(from, fromLength, beginAt); + if (replacedAt != NULL) { + *replacedAt = n; + } + return n == -1 ? source : source.replaceAt(n, fromLength, to); +} + +::rtl::OUString searchAndReplaceAllAsciiWithAscii( + const ::rtl::OUString& _source, const sal_Char* _from, const sal_Char* _to, + const sal_Int32 _beginAt ) +{ + sal_Int32 fromLength = strlen( _from ); + sal_Int32 n = _source.indexOfAsciiL( _from, fromLength, _beginAt ); + if ( n == -1 ) + return _source; + + ::rtl::OUString dest( _source ); + ::rtl::OUString to( ::rtl::OUString::createFromAscii( _to ) ); + do + { + dest = dest.replaceAt( n, fromLength, to ); + n = dest.indexOfAsciiL( _from, fromLength, n + to.getLength() ); + } + while ( n != -1 ); + + return dest; +} + +::rtl::OUString& searchAndReplaceAsciiI( + ::rtl::OUString & _source, sal_Char const * _asciiPattern, ::rtl::OUString const & _replace, + sal_Int32 _beginAt, sal_Int32 * _replacedAt ) +{ + sal_Int32 fromLength = strlen( _asciiPattern ); + sal_Int32 n = _source.indexOfAsciiL( _asciiPattern, fromLength, _beginAt ); + if ( _replacedAt != NULL ) + *_replacedAt = n; + + if ( n != -1 ) + _source = _source.replaceAt( n, fromLength, _replace ); + + return _source; +} + +namespace +{ + template <typename T, typename O> T tmpl_replace(const T &rIn, + const T &rSearch, const T &rReplace) + { + if (rIn.isEmpty() || rSearch.isEmpty()) + return rIn; + + O aRet; + + sal_Int32 nFromIndex = 0; + while (nFromIndex < rIn.getLength()) + { + sal_Int32 nIndex = rIn.indexOf(rSearch, nFromIndex); + if (nIndex == -1) + { + aRet.append(rIn.copy(nFromIndex)); + break; + } + aRet.append(rIn.copy(nFromIndex, nIndex-nFromIndex)); + aRet.append(rReplace); + nFromIndex = nIndex+rSearch.getLength(); + } + + return aRet.makeStringAndClear(); + } +} + +rtl::OString replace(const rtl::OString &rIn, const rtl::OString &rSearch, + const rtl::OString &rReplace) +{ + return tmpl_replace<rtl::OString, rtl::OStringBuffer>(rIn, rSearch, + rReplace); +} + +rtl::OUString replace(const rtl::OUString &rIn, const rtl::OUString &rSearch, + const rtl::OUString &rReplace) +{ + return tmpl_replace<rtl::OUString, rtl::OUStringBuffer>(rIn, rSearch, + rReplace); +} + +sal_uInt32 decimalStringToNumber( + ::rtl::OUString const & str ) +{ + sal_uInt32 result = 0; + for( sal_Int32 i = 0 ; i < str.getLength() ; ) + { + sal_uInt32 c = str.iterateCodePoints(&i); + sal_uInt32 value = 0; + if( c <= 0x0039) // ASCII decimal digits, most common + value = c - 0x0030; + else if( c >= 0x1D7F6 ) // mathematical monospace digits + value = c - 0x1D7F6; + else if( c >= 0x1D7EC ) // mathematical sans-serif bold digits + value = c - 0x1D7EC; + else if( c >= 0x1D7E2 ) // mathematical sans-serif digits + value = c - 0x1D7E2; + else if( c >= 0x1D7D8 ) // mathematical double-struck digits + value = c - 0x1D7D8; + else if( c >= 0x1D7CE ) // mathematical bold digits + value = c - 0x1D7CE; + else if( c >= 0x11066 ) // brahmi digits + value = c - 0x11066; + else if( c >= 0x104A0 ) // osmanya digits + value = c - 0x104A0; + else if( c >= 0xFF10 ) // fullwidth digits + value = c - 0xFF10; + else if( c >= 0xABF0 ) // meetei mayek digits + value = c - 0xABF0; + else if( c >= 0xAA50 ) // cham digits + value = c - 0xAA50; + else if( c >= 0xA9D0 ) // javanese digits + value = c - 0xA9D0; + else if( c >= 0xA900 ) // kayah li digits + value = c - 0xA900; + else if( c >= 0xA8D0 ) // saurashtra digits + value = c - 0xA8D0; + else if( c >= 0xA620 ) // vai digits + value = c - 0xA620; + else if( c >= 0x1C50 ) // ol chiki digits + value = c - 0x1C50; + else if( c >= 0x1C40 ) // lepcha digits + value = c - 0x1C40; + else if( c >= 0x1BB0 ) // sundanese digits + value = c - 0x1BB0; + else if( c >= 0x1B50 ) // balinese digits + value = c - 0x1B50; + else if( c >= 0x1A90 ) // tai tham tham digits + value = c - 0x1A90; + else if( c >= 0x1A80 ) // tai tham hora digits + value = c - 0x1A80; + else if( c >= 0x19D0 ) // new tai lue digits + value = c - 0x19D0; + else if( c >= 0x1946 ) // limbu digits + value = c - 0x1946; + else if( c >= 0x1810 ) // mongolian digits + value = c - 0x1810; + else if( c >= 0x17E0 ) // khmer digits + value = c - 0x17E0; + else if( c >= 0x1090 ) // myanmar shan digits + value = c - 0x1090; + else if( c >= 0x1040 ) // myanmar digits + value = c - 0x1040; + else if( c >= 0x0F20 ) // tibetan digits + value = c - 0x0F20; + else if( c >= 0x0ED0 ) // lao digits + value = c - 0x0ED0; + else if( c >= 0x0E50 ) // thai digits + value = c - 0x0E50; + else if( c >= 0x0D66 ) // malayalam digits + value = c - 0x0D66; + else if( c >= 0x0CE6 ) // kannada digits + value = c - 0x0CE6; + else if( c >= 0x0C66 ) // telugu digits + value = c - 0x0C66; + else if( c >= 0x0BE6 ) // tamil digits + value = c - 0x0BE6; + else if( c >= 0x0B66 ) // oriya digits + value = c - 0x0B66; + else if( c >= 0x0AE6 ) // gujarati digits + value = c - 0x0AE6; + else if( c >= 0x0A66 ) // gurmukhi digits + value = c - 0x0A66; + else if( c >= 0x09E6 ) // bengali digits + value = c - 0x09E6; + else if( c >= 0x0966 ) // devanagari digit + value = c - 0x0966; + else if( c >= 0x07C0 ) // nko digits + value = c - 0x07C0; + else if( c >= 0x06F0 ) // extended arabic-indic digits + value = c - 0x06F0; + else if( c >= 0x0660 ) // arabic-indic digits + value = c - 0x0660; + result = result * 10 + value; + } + return result; +} + +using namespace ::com::sun::star; + +// convert between sequence of string and comma separated string + +::rtl::OUString convertCommaSeparated( + uno::Sequence< ::rtl::OUString > const& i_rSeq) +{ + ::rtl::OUStringBuffer buf; + ::comphelper::intersperse( + ::comphelper::stl_begin(i_rSeq), ::comphelper::stl_end(i_rSeq), + ::comphelper::OUStringBufferAppender(buf), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ", " ))); + return buf.makeStringAndClear(); +} + +uno::Sequence< ::rtl::OUString > + convertCommaSeparated( ::rtl::OUString const& i_rString ) +{ + std::vector< ::rtl::OUString > vec; + sal_Int32 idx = 0; + do { + ::rtl::OUString kw = + i_rString.getToken(0, static_cast<sal_Unicode> (','), idx); + kw = kw.trim(); + if (kw.getLength() > 0) { + vec.push_back(kw); + } + } while (idx >= 0); + uno::Sequence< ::rtl::OUString > kws(vec.size()); + std::copy(vec.begin(), vec.end(), stl_begin(kws)); + return kws; +} + + +sal_Int32 compareNatural( const ::rtl::OUString & rLHS, const ::rtl::OUString & rRHS, + const uno::Reference< i18n::XCollator > &rCollator, + const uno::Reference< i18n::XBreakIterator > &rBI, + const lang::Locale &rLocale ) +{ + sal_Int32 nRet = 0; + + sal_Int32 nLHSLastNonDigitPos = 0; + sal_Int32 nRHSLastNonDigitPos = 0; + sal_Int32 nLHSFirstDigitPos = 0; + sal_Int32 nRHSFirstDigitPos = 0; + + while (nLHSFirstDigitPos < rLHS.getLength() || nRHSFirstDigitPos < rRHS.getLength()) + { + sal_Int32 nLHSChunkLen; + sal_Int32 nRHSChunkLen; + + //Compare non digit block as normal strings + nLHSFirstDigitPos = rBI->nextCharBlock(rLHS, nLHSLastNonDigitPos, + rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER); + nRHSFirstDigitPos = rBI->nextCharBlock(rRHS, nRHSLastNonDigitPos, + rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER); + if (nLHSFirstDigitPos == -1) + nLHSFirstDigitPos = rLHS.getLength(); + if (nRHSFirstDigitPos == -1) + nRHSFirstDigitPos = rRHS.getLength(); + nLHSChunkLen = nLHSFirstDigitPos - nLHSLastNonDigitPos; + nRHSChunkLen = nRHSFirstDigitPos - nRHSLastNonDigitPos; + + nRet = rCollator->compareSubstring(rLHS, nLHSLastNonDigitPos, + nLHSChunkLen, rRHS, nRHSLastNonDigitPos, nRHSChunkLen); + if (nRet != 0) + break; + + //Compare digit block as one number vs another + nLHSLastNonDigitPos = rBI->endOfCharBlock(rLHS, nLHSFirstDigitPos, + rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER); + nRHSLastNonDigitPos = rBI->endOfCharBlock(rRHS, nRHSFirstDigitPos, + rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER); + if (nLHSLastNonDigitPos == -1) + nLHSLastNonDigitPos = rLHS.getLength(); + if (nRHSLastNonDigitPos == -1) + nRHSLastNonDigitPos = rRHS.getLength(); + nLHSChunkLen = nLHSLastNonDigitPos - nLHSFirstDigitPos; + nRHSChunkLen = nRHSLastNonDigitPos - nRHSFirstDigitPos; + + //To-Do: Possibly scale down those unicode codepoints that relate to + //numbers outside of the normal 0-9 range, e.g. see GetLocalizedChar in + //vcl + + sal_uInt32 nLHS = comphelper::string::decimalStringToNumber(rLHS.copy(nLHSFirstDigitPos, nLHSChunkLen)); + sal_uInt32 nRHS = comphelper::string::decimalStringToNumber(rRHS.copy(nRHSFirstDigitPos, nRHSChunkLen)); + + nRet = nLHS-nRHS; + if (nRet != 0) + break; + } + + //Squeeze these down to -1, 0, 1 in case it gets casted to a StringCompare + if (nRet > 0) + nRet = 1; + else if (nRet < 0) + nRet = -1; + + return nRet; +} + +NaturalStringSorter::NaturalStringSorter( + const uno::Reference< uno::XComponentContext > &rContext, + const lang::Locale &rLocale) : m_aLocale(rLocale) +{ + uno::Reference< lang::XMultiComponentFactory > xFactory(rContext->getServiceManager(), + uno::UNO_SET_THROW); + + m_xCollator = uno::Reference< i18n::XCollator >(xFactory->createInstanceWithContext( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.i18n.Collator")), rContext), + uno::UNO_QUERY_THROW); + m_xCollator->loadDefaultCollator(m_aLocale, 0); + m_xBI = uno::Reference< i18n::XBreakIterator >(xFactory->createInstanceWithContext( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.i18n.BreakIterator")), rContext), + uno::UNO_QUERY_THROW); +} + +namespace +{ + template <typename T> bool tmpl_isAsciiDecimalString(const T &rString) + { + for (sal_Int32 i = 0; i < rString.getLength(); ++i) + { + if ((rString[i] < '0') || (rString[i] > '9')) + return false; + } + return true; + } +} + +bool isAsciiDecimalString(const rtl::OString &rString) +{ + return tmpl_isAsciiDecimalString(rString); +} + +bool isAsciiDecimalString(const rtl::OUString &rString) +{ + return tmpl_isAsciiDecimalString(rString); +} + +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/synchronousdispatch.cxx b/comphelper/source/misc/synchronousdispatch.cxx new file mode 100644 index 000000000000..ca4d4b36f72a --- /dev/null +++ b/comphelper/source/misc/synchronousdispatch.cxx @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +/** === begin UNO includes === **/ +#include "com/sun/star/frame/XDispatchProvider.hpp" +#include "com/sun/star/frame/XSynchronousDispatch.hpp" +#include "com/sun/star/lang/XComponent.hpp" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/util/XURLTransformer.hpp" +/** === end UNO includes === **/ + +#include "comphelper/synchronousdispatch.hxx" +#include "comphelper/processfactory.hxx" + +#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +using namespace ::com::sun::star; + +//==================================================================== +//= SynchronousDispatch +//==================================================================== + +uno::Reference< lang::XComponent > SynchronousDispatch::dispatch( + const uno::Reference< uno::XInterface > &xStartPoint, + const rtl::OUString &sURL, + const rtl::OUString &sTarget, + const sal_Int32 nFlags, + const uno::Sequence< beans::PropertyValue > &lArguments ) +{ + util::URL aURL; + aURL.Complete = sURL; + uno::Reference < util::XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( + UNISTRING("com.sun.star.util.URLTransformer" )), + uno::UNO_QUERY ); + if ( xTrans.is() ) + xTrans->parseStrict( aURL ); + + uno::Reference < frame::XDispatch > xDispatcher; + uno::Reference < frame::XDispatchProvider > xProvider( xStartPoint, uno::UNO_QUERY ); + + if ( xProvider.is() ) + xDispatcher = xProvider->queryDispatch( aURL, sTarget, nFlags ); + + uno::Reference < lang::XComponent > aComponent; + + if ( xDispatcher.is() ) + { + try + { + uno::Any aRet; + uno::Reference < frame::XSynchronousDispatch > xSyncDisp( xDispatcher, uno::UNO_QUERY_THROW ); + + aRet = xSyncDisp->dispatchWithReturnValue( aURL, lArguments ); + + aRet >>= aComponent; + } + catch ( uno::Exception& ) + { + rtl::OUString aMsg = UNISTRING( "SynchronousDispatch::dispatch() Error while dispatching! "); + OSL_FAIL( OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr()); + } + } + + return aComponent; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/types.cxx b/comphelper/source/misc/types.cxx new file mode 100644 index 000000000000..629e890ae62a --- /dev/null +++ b/comphelper/source/misc/types.cxx @@ -0,0 +1,479 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/types.hxx> +#include <comphelper/extract.hxx> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/Time.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/FontStrikeout.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <osl/diagnose.h> +#include <typelib/typedescription.hxx> + +#include <memory.h> + + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::lang; + +//------------------------------------------------------------------------- +sal_Bool operator ==(const DateTime& _rLeft, const DateTime& _rRight) +{ + return ( _rLeft.HundredthSeconds == _rRight.HundredthSeconds) && + ( _rLeft.Seconds == _rRight.Seconds) && + ( _rLeft.Minutes == _rRight.Minutes) && + ( _rLeft.Hours == _rRight.Hours) && + ( _rLeft.Day == _rRight.Day) && + ( _rLeft.Month == _rRight.Month) && + ( _rLeft.Year == _rRight.Year) ; +} + +//------------------------------------------------------------------------- +sal_Bool operator ==(const Date& _rLeft, const Date& _rRight) +{ + return ( _rLeft.Day == _rRight.Day) && + ( _rLeft.Month == _rRight.Month) && + ( _rLeft.Year == _rRight.Year) ; +} + +//------------------------------------------------------------------------- +sal_Bool operator ==(const Time& _rLeft, const Time& _rRight) +{ + return ( _rLeft.HundredthSeconds == _rRight.HundredthSeconds) && + ( _rLeft.Seconds == _rRight.Seconds) && + ( _rLeft.Minutes == _rRight.Minutes) && + ( _rLeft.Hours == _rRight.Hours) ; +} + +//------------------------------------------------------------------------------ +sal_Int32 getINT32(const Any& _rAny) +{ + sal_Int32 nReturn = 0; + OSL_VERIFY( _rAny >>= nReturn ); + return nReturn; +} + +//------------------------------------------------------------------------------ +sal_Int16 getINT16(const Any& _rAny) +{ + sal_Int16 nReturn = 0; + OSL_VERIFY( _rAny >>= nReturn ); + return nReturn; +} + +//------------------------------------------------------------------------------ +double getDouble(const Any& _rAny) +{ + double nReturn = 0.0; + OSL_VERIFY( _rAny >>= nReturn ); + return nReturn; +} + +//------------------------------------------------------------------------------ +float getFloat(const Any& _rAny) +{ + float nReturn = 0.0; + OSL_VERIFY( _rAny >>= nReturn ); + return nReturn; +} + +//------------------------------------------------------------------------------ +::rtl::OUString getString(const Any& _rAny) +{ + ::rtl::OUString nReturn; + OSL_VERIFY( _rAny >>= nReturn ); + return nReturn; +} + +//------------------------------------------------------------------------------ +sal_Bool getBOOL(const Any& _rAny) +{ + sal_Bool nReturn = sal_False; + if (_rAny.getValueType() == ::getCppuBooleanType()) + nReturn = *(sal_Bool*)_rAny.getValue(); + else + OSL_FAIL("comphelper::getBOOL : invalid argument !"); + return nReturn; +} + +//------------------------------------------------------------------------------ +sal_Int32 getEnumAsINT32(const Any& _rAny) throw(IllegalArgumentException) +{ + sal_Int32 nReturn = 0; + if (! ::cppu::enum2int(nReturn,_rAny) ) + throw IllegalArgumentException(); + return nReturn; +} + +//------------------------------------------------------------------------------ +FontDescriptor getDefaultFont() +{ + FontDescriptor aReturn; + aReturn.Slant = FontSlant_DONTKNOW; + aReturn.Underline = FontUnderline::DONTKNOW; + aReturn.Strikeout = FontStrikeout::DONTKNOW; + return aReturn; +} + +//------------------------------------------------------------------------------ +sal_Bool isAssignableFrom(const Type& _rAssignable, const Type& _rFrom) +{ + // getthe type lib descriptions + typelib_TypeDescription* pAssignable = NULL; + _rAssignable.getDescription(&pAssignable); + + typelib_TypeDescription* pFrom = NULL; + _rFrom.getDescription(&pFrom); + + // and ask the type lib + return typelib_typedescription_isAssignableFrom(pAssignable, pFrom); +} + +//------------------------------------------------------------------ +template<class TYPE> +sal_Bool tryCompare(const void* _pData, const Any& _rValue, sal_Bool& _bIdentical, TYPE& _rOut) +{ + sal_Bool bSuccess = _rValue >>= _rOut; + _bIdentical = bSuccess && (_rOut == *reinterpret_cast<const TYPE*>(_pData)); + return bSuccess; +} + +//------------------------------------------------------------------ +sal_Bool tryCompare(const void* _pData, const Any& _rValue, sal_Bool& _bIdentical, sal_Unicode& _rOut) +{ + sal_Bool bSuccess = ( _rValue.getValueTypeClass() == TypeClass_CHAR ); + if ( bSuccess ) + _rOut = *static_cast< const sal_Unicode* >( _rValue.getValue() ); + _bIdentical = bSuccess && ( _rOut == *static_cast< const sal_Unicode* >( _pData ) ); + return bSuccess; +} + +//------------------------------------------------------------------ +sal_Bool compare_impl(const Type& _rType, const void* pData, const Any& _rValue) +{ + sal_Bool bRes = sal_True; + + if (_rType.getTypeClass() == TypeClass_ANY) + { + // beides AnyWerte + if (_rValue.getValueType().getTypeClass() == TypeClass_ANY) + bRes = compare_impl( + reinterpret_cast<const Any*>(pData)->getValueType(), + reinterpret_cast<const Any*>(pData)->getValue(), + *reinterpret_cast<const Any*>(_rValue.getValue())); + else + bRes = compare_impl( + reinterpret_cast<const Any*>(pData)->getValueType(), + reinterpret_cast<const Any*>(pData)->getValue(), + _rValue); + } + else if ( (_rType.getTypeClass() == TypeClass_VOID) + || (_rValue.getValueType().getTypeClass() == TypeClass_VOID) + ) + { + bRes = _rType.getTypeClass() == _rValue.getValueType().getTypeClass(); + } + else + { + sal_Bool bConversionSuccess = sal_False; + switch (_rType.getTypeClass()) + { + case TypeClass_VOID: + bConversionSuccess = sal_True; + bRes = _rValue.getValueType().getTypeClass() == TypeClass_VOID; + break; + case TypeClass_BOOLEAN: + { + sal_Bool aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_CHAR: + { + sal_Unicode aDummy(0); + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_STRING: + { + ::rtl::OUString aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_FLOAT: + { + float aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_DOUBLE: + { + double aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_BYTE: + { + sal_Int8 aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_SHORT: + { + sal_Int16 aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_ENUM: + { + sal_Int32 nAsInt32 = 0; + bConversionSuccess = ::cppu::enum2int(nAsInt32, _rValue); + bRes = bConversionSuccess && (nAsInt32== *reinterpret_cast<const sal_Int32*>(pData)); + break; + } + case TypeClass_LONG: + { + sal_Int32 aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_UNSIGNED_SHORT: + { + sal_uInt16 aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_UNSIGNED_LONG: + { + sal_uInt32 aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_INTERFACE: + { + InterfaceRef aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + case TypeClass_STRUCT: + if (isA(_rType, static_cast<FontDescriptor*>(NULL))) + { + FontDescriptor aTemp; + bConversionSuccess = _rValue >>= aTemp; + if (bConversionSuccess) + { + bRes = *(FontDescriptor*)pData == aTemp; + } + else + bRes = sal_False; + break; + } + if (isA(_rType, static_cast<Date*>(NULL))) + { + Date aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + if (isA(_rType, static_cast<Time*>(NULL))) + { + Time aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + if (isA(_rType, static_cast<DateTime*>(NULL))) + { + DateTime aDummy; + bConversionSuccess = tryCompare(pData, _rValue, bRes, aDummy); + break; + } + break; + case TypeClass_SEQUENCE: + if (isA(_rType, static_cast< Sequence<sal_Int8>* >(NULL))) + { + Sequence<sal_Int8> aTemp; + bConversionSuccess = _rValue >>= aTemp; + if (bConversionSuccess) + { + const Sequence<sal_Int8>& rLeftSeq = *reinterpret_cast<const Sequence<sal_Int8>*>(pData); + const Sequence<sal_Int8>& rRightSeq = aTemp; + bRes = rLeftSeq.getLength() == rRightSeq.getLength() && + memcmp(rLeftSeq.getConstArray(), rRightSeq.getConstArray(), rLeftSeq.getLength()) == 0; + } + } + else if (isA(_rType, static_cast< Sequence<sal_uInt8>* >(NULL))) + { + Sequence<sal_uInt8> aTemp; + bConversionSuccess = _rValue >>= aTemp; + if (bConversionSuccess) + { + const Sequence<sal_uInt8>& rLeftSeq = *reinterpret_cast<const Sequence<sal_uInt8>*>(pData); + const Sequence<sal_uInt8>& rRightSeq = aTemp; + bRes = rLeftSeq.getLength() == rRightSeq.getLength() && + memcmp(rLeftSeq.getConstArray(), rRightSeq.getConstArray(), rLeftSeq.getLength()) == 0; + } + } + else if (isA(_rType, static_cast< Sequence<sal_Int16>* >(NULL))) + { + Sequence<sal_Int16> aTemp; + bConversionSuccess = _rValue >>= aTemp; + if (bConversionSuccess) + { + const Sequence<sal_Int16>& rLeftSeq = *reinterpret_cast<const Sequence<sal_Int16>*>(pData); + const Sequence<sal_Int16>& rRightSeq = aTemp; + bRes = rLeftSeq.getLength() == rRightSeq.getLength() && + memcmp(rLeftSeq.getConstArray(), rRightSeq.getConstArray(), rLeftSeq.getLength()*sizeof(sal_Int16)) == 0; + } + } + else if (isA(_rType, static_cast< Sequence<sal_uInt16>* >(NULL))) + { + Sequence<sal_uInt16> aTemp; + bConversionSuccess = _rValue >>= aTemp; + if (bConversionSuccess) + { + const Sequence<sal_uInt16>& rLeftSeq = *reinterpret_cast<const Sequence<sal_uInt16>*>(pData); + const Sequence<sal_uInt16>& rRightSeq = aTemp; + bRes = rLeftSeq.getLength() == rRightSeq.getLength() && + memcmp(rLeftSeq.getConstArray(), rRightSeq.getConstArray(), rLeftSeq.getLength()*sizeof(sal_uInt16)) == 0; + } + } + else if (isA(_rType, static_cast< Sequence<sal_Int32>* >(NULL))) + { + Sequence<sal_Int32> aTemp; + bConversionSuccess = _rValue >>= aTemp; + if (bConversionSuccess) + { + const Sequence<sal_Int32>& rLeftSeq = *reinterpret_cast<const Sequence<sal_Int32>*>(pData); + const Sequence<sal_Int32>& rRightSeq = aTemp; + bRes = rLeftSeq.getLength() == rRightSeq.getLength() && + memcmp(rLeftSeq.getConstArray(), rRightSeq.getConstArray(), rLeftSeq.getLength()*sizeof(sal_Int32)) == 0; + } + } + else if (isA(_rType, static_cast< Sequence<sal_uInt32>* >(NULL))) + { + Sequence<sal_uInt32> aTemp; + bConversionSuccess = _rValue >>= aTemp; + if (bConversionSuccess) + { + const Sequence<sal_uInt32>& rLeftSeq = *reinterpret_cast<const Sequence<sal_uInt32>*>(pData); + const Sequence<sal_uInt32>& rRightSeq = aTemp; + bRes = rLeftSeq.getLength() == rRightSeq.getLength() && + memcmp(rLeftSeq.getConstArray(), rRightSeq.getConstArray(), rLeftSeq.getLength()*sizeof(sal_uInt32)) == 0; + } + } + else if (isA(_rType, static_cast< Sequence< ::rtl::OUString >* >(NULL))) + { + Sequence< ::rtl::OUString > aTemp; + bConversionSuccess = _rValue >>= aTemp; + if (bConversionSuccess) + { + const Sequence< ::rtl::OUString >& rLeftSeq = *reinterpret_cast<const Sequence< ::rtl::OUString>*>(pData); + const Sequence< ::rtl::OUString >& rRightSeq = aTemp; + sal_Int32 nSeqLen = rLeftSeq.getLength(); + bRes = ( nSeqLen == rRightSeq.getLength() ); + for ( sal_Int32 n = 0; bRes && ( n < nSeqLen ); n++ ) + { + const ::rtl::OUString& rS1 = rLeftSeq.getConstArray()[n]; + const ::rtl::OUString& rS2 = rRightSeq.getConstArray()[n]; + bRes = ( rS1 == rS2 ); + } + } + } + break; + default: + bRes = sal_False; + } + + bRes = bRes && bConversionSuccess; + } + return bRes; +} + +//------------------------------------------------------------------------------ +sal_Bool compare(const Any& rLeft, const Any& rRight) +{ + return compare_impl(rLeft.getValueType(), rLeft.getValue(), rRight); +} + +//------------------------------------------------------------------------- +sal_Bool operator ==(const FontDescriptor& _rLeft, const FontDescriptor& _rRight) +{ + return ( _rLeft.Name.equals( _rRight.Name ) ) && + ( _rLeft.Height == _rRight.Height ) && + ( _rLeft.Width == _rRight.Width ) && + ( _rLeft.StyleName.equals( _rRight.StyleName ) ) && + ( _rLeft.Family == _rRight.Family ) && + ( _rLeft.CharSet == _rRight.CharSet ) && + ( _rLeft.Pitch == _rRight.Pitch ) && + ( _rLeft.CharacterWidth == _rRight.CharacterWidth ) && + ( _rLeft.Weight == _rRight.Weight ) && + ( _rLeft.Slant == _rRight.Slant ) && + ( _rLeft.Underline == _rRight.Underline ) && + ( _rLeft.Strikeout == _rRight.Strikeout ) && + ( _rLeft.Orientation == _rRight.Orientation ) && + ( _rLeft.Kerning == _rRight.Kerning ) && + ( _rLeft.WordLineMode == _rRight.WordLineMode ) && + ( _rLeft.Type == _rRight.Type ) ; +} + +//------------------------------------------------------------------------- +Type getSequenceElementType(const Type& _rSequenceType) +{ + OSL_ENSURE(_rSequenceType.getTypeClass() == TypeClass_SEQUENCE, + "getSequenceElementType: must be called with a sequence type!"); + + if (!(_rSequenceType.getTypeClass() == TypeClass_SEQUENCE)) + return Type(); + + TypeDescription aTD(_rSequenceType); + typelib_IndirectTypeDescription* pSequenceTD = + reinterpret_cast< typelib_IndirectTypeDescription* >(aTD.get()); + + OSL_ASSERT(pSequenceTD); + OSL_ASSERT(pSequenceTD->pType); + + if (pSequenceTD && pSequenceTD->pType) + return Type(pSequenceTD->pType); + + return Type(); +} +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/uieventslogger.cxx b/comphelper/source/misc/uieventslogger.cxx new file mode 100644 index 000000000000..0491d9991271 --- /dev/null +++ b/comphelper/source/misc/uieventslogger.cxx @@ -0,0 +1,682 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <comphelper/uieventslogger.hxx> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/logging/LogLevel.hpp> +#include <com/sun/star/logging/XCsvLogFormatter.hpp> +#include <com/sun/star/logging/XLogHandler.hpp> +#include <com/sun/star/logging/XLogger.hpp> +#include <com/sun/star/logging/XLoggerPool.hpp> +#include <com/sun/star/oooimprovement/XCoreController.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/util/XStringSubstitution.hpp> +#include <comphelper/configurationhelper.hxx> +#include <comphelper/processfactory.hxx> +#include <map> +#include <osl/file.hxx> +#include <osl/mutex.hxx> +#include <osl/time.h> +#include <rtl/ustrbuf.hxx> +#include <rtl/instance.hxx> + + +using namespace com::sun::star::beans; +using namespace com::sun::star::frame; +using namespace com::sun::star::lang; +using namespace com::sun::star::logging; +using namespace com::sun::star::oooimprovement; +using namespace com::sun::star::uno; +using namespace com::sun::star::util; +using namespace cppu; +using namespace osl; +using namespace std; + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +namespace +{ + static void lcl_SetupOriginAppAbbr(map<OUString, OUString>& abbrs) + { + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextDocument"))] = OUString(sal_Unicode('W')); // Writer + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument"))] = OUString(sal_Unicode('C')); // Calc + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationDocument"))] = OUString(sal_Unicode('I')); // Impress + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocument"))] = OUString(sal_Unicode('D')); // Draw + }; + + static void lcl_SetupOriginWidgetAbbr(map<OUString,OUString>& abbrs) + { + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("ButtonToolbarController"))] = OUString(sal_Unicode('0')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("ComplexToolbarController"))] = OUString(sal_Unicode('1')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("ControlMenuController"))] = OUString(sal_Unicode('2')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("FontMenuController"))] = OUString(sal_Unicode('3')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("FontSizeMenuController"))] = OUString(sal_Unicode('4')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("FooterMenuController"))] = OUString(sal_Unicode('5')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("GenericToolbarController"))] = OUString(sal_Unicode('6')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("HeaderMenuController"))] = OUString(sal_Unicode('7')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("LanguageSelectionMenuController"))] = OUString(sal_Unicode('8')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("LangSelectionStatusbarController"))] = OUString(sal_Unicode('9')); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("MacrosMenuController"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("10")); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("MenuBarManager"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("11")); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("NewMenuController"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("12")); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectMenuController"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("13")); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("RecentFilesMenuController"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("14")); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("ToolbarsMenuController"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("15")); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("SfxToolBoxControl"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("16")); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("SfxAsyncExec"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("17")); + abbrs[OUString(RTL_CONSTASCII_USTRINGPARAM("AcceleratorExecute"))] = OUString(RTL_CONSTASCII_USTRINGPARAM("18")); + }; +} + +namespace comphelper +{ + // declaration of implementation + class UiEventsLogger_Impl; + class UiEventsLogger_Impl : public UiEventsLogger + { + private: + //typedefs and friends + friend class UiEventsLogger; + typedef UiEventsLogger_Impl* ptr; + + // instance methods and data + UiEventsLogger_Impl(); + void initializeLogger(); + void logDispatch(const ::com::sun::star::util::URL& url, + const Sequence<PropertyValue>& args); + void logRotated(); + void logVcl(const ::rtl::OUString& parent_id, + sal_Int32 window_type, + const ::rtl::OUString& id, + const ::rtl::OUString& method, + const ::rtl::OUString& param); + void rotate(); + void hotRotate(); + void prepareLogHandler(); + void checkIdleTimeout(); + OUString getCurrentPath(); + OUString getRotatedPath(); + void disposing(); + + bool m_Active; + TimeValue m_LastLogEventTime; + const OUString m_LogPath; + const TimeValue m_IdleTimeout; + sal_Int32 m_SessionLogEventCount; + Reference<XLogger> m_Logger; + Reference<XLogHandler> m_LogHandler; + Reference<XCsvLogFormatter> m_Formatter; + map<OUString, OUString> m_OriginAppAbbr; + map<OUString, OUString> m_OriginWidgetAbbr; + + + // static methods and data + static ptr getInstance(); + static bool shouldActivate(); + static bool getEnabledFromCoreController(); + static bool getEnabledFromCfg(); + static TimeValue getIdleTimeoutFromCfg(); + static OUString getLogPathFromCfg(); + static sal_Int32 findIdx(const Sequence<PropertyValue>& args, const OUString& key); + + static ptr instance; + static const sal_Int32 COLUMNS; + static const OUString CFG_ENABLED; + static const OUString CFG_IDLETIMEOUT; + static const OUString CFG_LOGGING; + static const OUString CFG_LOGPATH; + static const OUString CFG_OOOIMPROVEMENT; + static const OUString ETYPE_DISPATCH; + static const OUString ETYPE_ROTATED; + static const OUString ETYPE_VCL; + static const OUString CSSL_CSVFORMATTER; + static const OUString CSSL_FILEHANDLER; + static const OUString CSSL_LOGGERPOOL; + static const OUString CSSO_CORECONTROLLER; + static const OUString CSST_JOBEXECUTOR; + static const OUString CSSU_PATHSUB; + static const OUString LOGGERNAME; + static const OUString LOGORIGINAPP; + static const OUString LOGORIGINWIDGET; + static const OUString UNKNOWN_ORIGIN; + static const OUString FN_CURRENTLOG; + static const OUString FN_ROTATEDLOG; + static const OUString LOGROTATE_EVENTNAME; + static const OUString URL_UNO; + static const OUString URL_SPECIAL; + static const OUString URL_FILE; + }; +} + +namespace comphelper +{ + // consts + const sal_Int32 UiEventsLogger_Impl::COLUMNS = 9; + const OUString UiEventsLogger_Impl::CFG_ENABLED(RTL_CONSTASCII_USTRINGPARAM("EnablingAllowed")); + const OUString UiEventsLogger_Impl::CFG_IDLETIMEOUT(RTL_CONSTASCII_USTRINGPARAM("IdleTimeout")); + const OUString UiEventsLogger_Impl::CFG_LOGGING(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Logging")); + const OUString UiEventsLogger_Impl::CFG_LOGPATH(RTL_CONSTASCII_USTRINGPARAM("LogPath")); + const OUString UiEventsLogger_Impl::CFG_OOOIMPROVEMENT(RTL_CONSTASCII_USTRINGPARAM("OOoImprovement")); + + const OUString UiEventsLogger_Impl::CSSL_CSVFORMATTER(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.logging.CsvFormatter")); + const OUString UiEventsLogger_Impl::CSSL_FILEHANDLER(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.logging.FileHandler")); + const OUString UiEventsLogger_Impl::CSSL_LOGGERPOOL(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.logging.LoggerPool")); + const OUString UiEventsLogger_Impl::CSSO_CORECONTROLLER(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.oooimprovement.CoreController")); + const OUString UiEventsLogger_Impl::CSSU_PATHSUB(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.PathSubstitution")); + + const OUString UiEventsLogger_Impl::ETYPE_DISPATCH(RTL_CONSTASCII_USTRINGPARAM("dispatch")); + const OUString UiEventsLogger_Impl::ETYPE_ROTATED(RTL_CONSTASCII_USTRINGPARAM("rotated")); + const OUString UiEventsLogger_Impl::ETYPE_VCL(RTL_CONSTASCII_USTRINGPARAM("vcl")); + + const OUString UiEventsLogger_Impl::LOGGERNAME(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.oooimprovement.Core.UiEventsLogger")); + const OUString UiEventsLogger_Impl::LOGORIGINWIDGET(RTL_CONSTASCII_USTRINGPARAM("comphelper.UiEventsLogger.LogOriginWidget")); + const OUString UiEventsLogger_Impl::LOGORIGINAPP(RTL_CONSTASCII_USTRINGPARAM("comphelper.UiEventsLogger.LogOriginApp")); + + const OUString UiEventsLogger_Impl::UNKNOWN_ORIGIN(RTL_CONSTASCII_USTRINGPARAM("unknown origin")); + const OUString UiEventsLogger_Impl::FN_CURRENTLOG(RTL_CONSTASCII_USTRINGPARAM("Current")); + const OUString UiEventsLogger_Impl::FN_ROTATEDLOG(RTL_CONSTASCII_USTRINGPARAM("OOoImprove")); + const OUString UiEventsLogger_Impl::LOGROTATE_EVENTNAME(RTL_CONSTASCII_USTRINGPARAM("onOOoImprovementLogRotated")); + + const OUString UiEventsLogger_Impl::URL_UNO(RTL_CONSTASCII_USTRINGPARAM(".uno:")); + const OUString UiEventsLogger_Impl::URL_SPECIAL(RTL_CONSTASCII_USTRINGPARAM(".special:")); + const OUString UiEventsLogger_Impl::URL_FILE(RTL_CONSTASCII_USTRINGPARAM("file:")); + + namespace + { + struct theSingletonMutex : public rtl::Static< Mutex, theSingletonMutex > {}; + } + + // public UiEventsLogger interface + sal_Bool UiEventsLogger::isEnabled() + { + if ( UiEventsLogger_Impl::getEnabledFromCfg() ) + { + try { + Guard<Mutex> singleton_guard(theSingletonMutex::get()); + return UiEventsLogger_Impl::getInstance()->m_Active; + } catch(...) { return false; } // never throws + } // if ( ) + return sal_False; + } + + sal_Int32 UiEventsLogger::getSessionLogEventCount() + { + try { + Guard<Mutex> singleton_guard(theSingletonMutex::get()); + return UiEventsLogger_Impl::getInstance()->m_SessionLogEventCount; + } catch(...) { return 0; } // never throws + } + + void UiEventsLogger::appendDispatchOrigin( + Sequence<PropertyValue>& args, + const OUString& originapp, + const OUString& originwidget) + { + sal_Int32 old_length = args.getLength(); + args.realloc(old_length+2); + args[old_length].Name = UiEventsLogger_Impl::LOGORIGINAPP; + args[old_length].Value = static_cast<Any>(originapp); + args[old_length+1].Name = UiEventsLogger_Impl::LOGORIGINWIDGET; + args[old_length+1].Value = static_cast<Any>(originwidget); + } + + Sequence<PropertyValue> UiEventsLogger::purgeDispatchOrigin( + const Sequence<PropertyValue>& args) + { + Sequence<PropertyValue> result(args.getLength()); + sal_Int32 target_idx=0; + for(sal_Int32 source_idx=0; source_idx<args.getLength(); source_idx++) + if(args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINAPP + && args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINWIDGET) + result[target_idx++] = args[source_idx]; + result.realloc(target_idx); + return result; + } + + void UiEventsLogger::logDispatch( + const URL& url, + const Sequence<PropertyValue>& args) + { + try { + Guard<Mutex> singleton_guard(theSingletonMutex::get()); + UiEventsLogger_Impl::getInstance()->logDispatch(url, args); + } catch(...) { } // never throws + } + + void UiEventsLogger::logVcl( + const OUString& parent_id, + sal_Int32 window_type, + const OUString& id, + const OUString& method, + const OUString& param) + { + try { + Guard<Mutex> singleton_guard(theSingletonMutex::get()); + UiEventsLogger_Impl::getInstance()->logVcl(parent_id, window_type, id, method, param); + } catch(...) { } // never throws + } + + void UiEventsLogger::logVcl( + const OUString& parent_id, + sal_Int32 window_type, + const OUString& id, + const OUString& method, + sal_Int32 param) + { + OUStringBuffer buf; + UiEventsLogger::logVcl(parent_id, window_type, id, method, buf.append(param).makeStringAndClear()); + } + + void UiEventsLogger::logVcl( + const OUString& parent_id, + sal_Int32 window_type, + const OUString& id, + const OUString& method) + { + OUString empty; + UiEventsLogger::logVcl(parent_id, window_type, id, method, empty); + } + + void UiEventsLogger::disposing() + { + // we dont want to create an instance just to dispose it + Guard<Mutex> singleton_guard(theSingletonMutex::get()); + if(UiEventsLogger_Impl::instance!=UiEventsLogger_Impl::ptr()) + UiEventsLogger_Impl::getInstance()->disposing(); + } + + void UiEventsLogger::reinit() + { + Guard<Mutex> singleton_guard(theSingletonMutex::get()); + if(UiEventsLogger_Impl::instance) + { + UiEventsLogger_Impl::instance->disposing(); + delete UiEventsLogger_Impl::instance; + UiEventsLogger_Impl::instance = NULL; + } + } + + // private UiEventsLogger_Impl methods + UiEventsLogger_Impl::UiEventsLogger_Impl() + : m_Active(UiEventsLogger_Impl::shouldActivate()) + , m_LogPath(UiEventsLogger_Impl::getLogPathFromCfg()) + , m_IdleTimeout(UiEventsLogger_Impl::getIdleTimeoutFromCfg()) + , m_SessionLogEventCount(0) + { + lcl_SetupOriginAppAbbr(m_OriginAppAbbr); + lcl_SetupOriginWidgetAbbr(m_OriginWidgetAbbr); + m_LastLogEventTime.Seconds = m_LastLogEventTime.Nanosec = 0; + if(m_Active) rotate(); + if(m_Active) initializeLogger(); + } + + void UiEventsLogger_Impl::logDispatch( + const URL& url, + const Sequence<PropertyValue>& args) + { + if(!m_Active) return; + if(!url.Complete.match(URL_UNO) + && !url.Complete.match(URL_FILE) + && !url.Complete.match(URL_SPECIAL)) + { + return; + } + checkIdleTimeout(); + + Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); + logdata[0] = ETYPE_DISPATCH; + sal_Int32 originapp_idx = findIdx(args, LOGORIGINAPP); + if(originapp_idx!=-1) + { + OUString app; + args[originapp_idx].Value >>= app; + map<OUString, OUString>::iterator abbr_it = m_OriginAppAbbr.find(app); + if(abbr_it != m_OriginAppAbbr.end()) + app = abbr_it->second; + logdata[1] = app; + } + else + logdata[1] = UNKNOWN_ORIGIN; + sal_Int32 originwidget_idx = findIdx(args, LOGORIGINWIDGET); + if(originwidget_idx!=-1) + { + OUString widget; + args[originwidget_idx].Value >>= widget; + map<OUString, OUString>::iterator widget_it = m_OriginWidgetAbbr.find(widget); + if(widget_it != m_OriginWidgetAbbr.end()) + widget = widget_it->second; + logdata[2] = widget; + } + else + logdata[2] = UNKNOWN_ORIGIN; + if(url.Complete.match(URL_FILE)) + logdata[3] = URL_FILE; + else + logdata[3] = url.Main; + OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", + OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); + m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); + m_SessionLogEventCount++; + } + + void UiEventsLogger_Impl::logRotated() + { + Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); + logdata[0] = ETYPE_ROTATED; + OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", + OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); + m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); + } + + void UiEventsLogger_Impl::logVcl( + const OUString& parent_id, + sal_Int32 window_type, + const OUString& id, + const OUString& method, + const OUString& param) + { + if(!m_Active) return; + checkIdleTimeout(); + + OUStringBuffer buf; + Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); + logdata[0] = ETYPE_VCL; + logdata[4] = parent_id; + logdata[5] = buf.append(window_type).makeStringAndClear(); + logdata[6] = id; + logdata[7] = method; + logdata[8] = param; + OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", + OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), + OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); + m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); + m_SessionLogEventCount++; + } + + void UiEventsLogger_Impl::rotate() + { + FileBase::RC result = File::move(getCurrentPath(), getRotatedPath()); + if(result!=FileBase::E_None && result!=FileBase::E_NOENT) + m_Active = false; + } + + void UiEventsLogger_Impl::hotRotate() + { + logRotated(); + m_Logger->removeLogHandler(m_LogHandler); + m_LogHandler = NULL; + rotate(); + prepareLogHandler(); + if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is()) + { + m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY)); + m_LogHandler->setLevel(LogLevel::ALL); + m_Logger->addLogHandler(m_LogHandler); + } + else + m_Active = false; + } + + void UiEventsLogger_Impl::prepareLogHandler() + { + Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); + + Sequence<Any> init_args = Sequence<Any>(1); + init_args[0] = static_cast<Any>(getCurrentPath()); + Reference< XInterface > temp = + sm->createInstanceWithArguments(CSSL_FILEHANDLER, init_args); + m_LogHandler = Reference<XLogHandler>(temp, UNO_QUERY); + } + + void UiEventsLogger_Impl::checkIdleTimeout() + { + TimeValue now; + osl_getSystemTime(&now); + if(now.Seconds - m_LastLogEventTime.Seconds > m_IdleTimeout.Seconds && m_SessionLogEventCount>0) + hotRotate(); + m_LastLogEventTime = now; + } + + OUString UiEventsLogger_Impl::getCurrentPath() + { + OUStringBuffer current_path(m_LogPath); + current_path.appendAscii("/"); + current_path.append(FN_CURRENTLOG); + current_path.appendAscii(".csv"); + return current_path.makeStringAndClear(); + } + + OUString UiEventsLogger_Impl::getRotatedPath() + { + OUStringBuffer rotated_path(m_LogPath); + rotated_path.appendAscii("/"); + rotated_path.append(FN_ROTATEDLOG); + rotated_path.appendAscii("-"); + { + // ISO 8601 + char tsrotated_pathfer[20]; + oslDateTime now; + TimeValue now_tv; + osl_getSystemTime(&now_tv); + osl_getDateTimeFromTimeValue(&now_tv, &now); + const size_t rotated_pathfer_size = sizeof(tsrotated_pathfer); + snprintf(tsrotated_pathfer, rotated_pathfer_size, "%04i-%02i-%02iT%02i_%02i_%02i", + now.Year, + now.Month, + now.Day, + now.Hours, + now.Minutes, + now.Seconds); + rotated_path.appendAscii(tsrotated_pathfer); + rotated_path.appendAscii(".csv"); + } + return rotated_path.makeStringAndClear(); + } + + void UiEventsLogger_Impl::initializeLogger() + { + Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); + + // getting the Core Uno proxy object + // It will call disposing and make sure we clear all our references + { + Reference<XTerminateListener> xCore( + sm->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.oooimprovement.Core"))), + UNO_QUERY); + Reference<XDesktop> xDesktop( + sm->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop"))), + UNO_QUERY); + if(!(xCore.is() && xDesktop.is())) + { + m_Active = false; + return; + } + xDesktop->addTerminateListener(xCore); + } + // getting the LoggerPool + Reference<XLoggerPool> pool; + { + Reference<XInterface> temp = + sm->createInstance(CSSL_LOGGERPOOL); + pool = Reference<XLoggerPool>(temp, UNO_QUERY); + } + + // getting the Logger + m_Logger = pool->getNamedLogger(LOGGERNAME); + + // getting the FileHandler + prepareLogHandler(); + + // getting the Formatter + { + Reference<XInterface> temp = + sm->createInstance(CSSL_CSVFORMATTER); + m_Formatter = Reference<XCsvLogFormatter>(temp, UNO_QUERY); + } + + if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is()) + { + Sequence<OUString> columns = Sequence<OUString>(COLUMNS); + columns[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("eventtype")); + columns[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("originapp")); + columns[2] = OUString(RTL_CONSTASCII_USTRINGPARAM("originwidget")); + columns[3] = OUString(RTL_CONSTASCII_USTRINGPARAM("uno url")); + columns[4] = OUString(RTL_CONSTASCII_USTRINGPARAM("parent id")); + columns[5] = OUString(RTL_CONSTASCII_USTRINGPARAM("window type")); + columns[6] = OUString(RTL_CONSTASCII_USTRINGPARAM("id")); + columns[7] = OUString(RTL_CONSTASCII_USTRINGPARAM("method")); + columns[8] = OUString(RTL_CONSTASCII_USTRINGPARAM("parameter")); + m_Formatter->setColumnnames(columns); + m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY)); + m_Logger->setLevel(LogLevel::ALL); + m_LogHandler->setLevel(LogLevel::ALL); + m_Logger->addLogHandler(m_LogHandler); + } + else + m_Active = false; + } + + // private static UiEventsLogger_Impl + bool UiEventsLogger_Impl::shouldActivate() + { + return getEnabledFromCfg() && getEnabledFromCoreController(); + } + + OUString UiEventsLogger_Impl::getLogPathFromCfg() + { + OUString result; + Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); + + ConfigurationHelper::readDirectKey( + sm, + CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_LOGPATH, + ConfigurationHelper::E_READONLY + ) >>= result; + + Reference<XStringSubstitution> path_sub( + sm->createInstance(CSSU_PATHSUB), + UNO_QUERY); + if(path_sub.is()) + result = path_sub->substituteVariables(result, sal_False); + return result; + } + + TimeValue UiEventsLogger_Impl::getIdleTimeoutFromCfg() + { + sal_Int32 timeoutminutes = 360; + Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); + + ConfigurationHelper::readDirectKey( + sm, + CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_IDLETIMEOUT, + ConfigurationHelper::E_READONLY + ) >>= timeoutminutes; + TimeValue result; + result.Seconds = static_cast<sal_uInt32>(timeoutminutes)*60; + result.Nanosec = 0; + return result; + } + + bool UiEventsLogger_Impl::getEnabledFromCfg() + { + sal_Bool result = false; + Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); + ConfigurationHelper::readDirectKey( + sm, + CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_ENABLED, + ::comphelper::ConfigurationHelper::E_READONLY + ) >>= result; + return result; + } + + bool UiEventsLogger_Impl::getEnabledFromCoreController() + { + Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); + Reference<XCoreController> core_c( + sm->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.oooimprovement.CoreController"))), + UNO_QUERY); + if(!core_c.is()) return false; + return core_c->enablingUiEventsLoggerAllowed(1); + } + + UiEventsLogger_Impl::ptr UiEventsLogger_Impl::instance = UiEventsLogger_Impl::ptr(); + UiEventsLogger_Impl::ptr UiEventsLogger_Impl::getInstance() + { + if(instance == NULL) + instance = UiEventsLogger_Impl::ptr(new UiEventsLogger_Impl()); + return instance; + } + + sal_Int32 UiEventsLogger_Impl::findIdx(const Sequence<PropertyValue>& args, const OUString& key) + { + for(sal_Int32 i=0; i<args.getLength(); i++) + if(args[i].Name == key) + return i; + return -1; + } + + void UiEventsLogger_Impl::disposing() + { + m_Active = false; + m_Logger.clear() ; + m_LogHandler.clear(); + m_Formatter.clear(); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/weak.cxx b/comphelper/source/misc/weak.cxx new file mode 100644 index 000000000000..247554495815 --- /dev/null +++ b/comphelper/source/misc/weak.cxx @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/weak.hxx" + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; + +namespace comphelper +{ + +OWeakTypeObject::OWeakTypeObject() +{ +} + +OWeakTypeObject::~OWeakTypeObject() +{ +} + +Any SAL_CALL OWeakTypeObject::queryInterface(const Type & rType ) throw (RuntimeException) +{ + if( rType == XTypeProvider::static_type() ) + return Any( Reference< XTypeProvider >(this) ); + else + return ::cppu::OWeakObject::queryInterface( rType ); +} + +void SAL_CALL OWeakTypeObject::acquire() throw () +{ + ::cppu::OWeakObject::acquire(); +} + +void SAL_CALL OWeakTypeObject::release() throw () +{ + ::cppu::OWeakObject::release(); +} + +Sequence< Type > SAL_CALL OWeakTypeObject::getTypes( ) throw (RuntimeException) +{ + return Sequence< Type >(); +} + +Sequence< ::sal_Int8 > SAL_CALL OWeakTypeObject::getImplementationId( ) throw (RuntimeException) +{ + return Sequence< ::sal_Int8 >(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/misc/weakeventlistener.cxx b/comphelper/source/misc/weakeventlistener.cxx new file mode 100644 index 000000000000..333727e47a45 --- /dev/null +++ b/comphelper/source/misc/weakeventlistener.cxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/weakeventlistener.hxx> +#include <osl/diagnose.h> + + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + + //===================================================================== + //= OWeakListenerAdapter + //===================================================================== + //--------------------------------------------------------------------- + OWeakListenerAdapterBase::~OWeakListenerAdapterBase() + { + } + + //===================================================================== + //= OWeakEventListenerAdapter + //===================================================================== + //--------------------------------------------------------------------- + OWeakEventListenerAdapter::OWeakEventListenerAdapter( Reference< XWeak > _rxListener, Reference< XComponent > _rxBroadcaster ) + :OWeakEventListenerAdapter_Base( _rxListener, _rxBroadcaster ) + { + // add ourself as listener to the broadcaster + OSL_ENSURE( _rxBroadcaster.is(), "OWeakEventListenerAdapter::OWeakEventListenerAdapter: invalid broadcaster!" ); + if ( _rxBroadcaster.is() ) + { + osl_incrementInterlockedCount( &m_refCount ); + { + _rxBroadcaster->addEventListener( this ); + } + osl_decrementInterlockedCount( &m_refCount ); + OSL_ENSURE( m_refCount > 0, "OWeakEventListenerAdapter::OWeakEventListenerAdapter: oops - not to be used with implementations which hold their listeners weak!" ); + // the one and only reason for this adapter class (A) is to add as listener to a component (C) which + // holds its listeners hard, and forward all calls then to another listener (L) which is + // held weak by A. + // Now if C holds listeners weak, then we do not need A, we can add L directly to C. + } + + OSL_ENSURE( getListener().is(), "OWeakEventListenerAdapter::OWeakEventListenerAdapter: invalid listener (does not support the XEventListener interface)!" ); + } + + //--------------------------------------------------------------------- + void SAL_CALL OWeakEventListenerAdapter::disposing( ) + { + Reference< XComponent > xBroadcaster( getBroadcaster( ), UNO_QUERY ); + OSL_ENSURE( xBroadcaster.is(), "OWeakEventListenerAdapter::disposing: broadcaster is invalid in the meantime! How this?" ); + if ( xBroadcaster.is() ) + { + xBroadcaster->removeEventListener( this ); + } + + resetListener(); + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/officeinstdir/officeinstallationdirectories.cxx b/comphelper/source/officeinstdir/officeinstallationdirectories.cxx new file mode 100644 index 000000000000..35bcfecc7f9d --- /dev/null +++ b/comphelper/source/officeinstdir/officeinstallationdirectories.cxx @@ -0,0 +1,387 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ + +#include "osl/file.hxx" +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/util/XMacroExpander.hpp" + +#include "officeinstallationdirectories.hxx" + +using namespace com::sun::star; + +using namespace comphelper; + +//========================================================================= +// helpers +//========================================================================= + +//========================================================================= +static bool makeCanonicalFileURL( rtl::OUString & rURL ) +{ + OSL_ENSURE( rURL.matchAsciiL( "file:", sizeof( "file:" ) - 1 , 0 ) , + "File URL expected!" ); + + rtl::OUString aNormalizedURL; + if ( osl::FileBase::getAbsoluteFileURL( rtl::OUString(), + rURL, + aNormalizedURL ) + == osl::DirectoryItem::E_None ) + { + osl::DirectoryItem aDirItem; + if ( osl::DirectoryItem::get( aNormalizedURL, aDirItem ) + == osl::DirectoryItem::E_None ) + { + osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileURL ); + + if ( aDirItem.getFileStatus( aFileStatus ) + == osl::DirectoryItem::E_None ) + { + aNormalizedURL = aFileStatus.getFileURL(); + + if ( aNormalizedURL.getLength() > 0 ) + { + if ( aNormalizedURL + .getStr()[ aNormalizedURL.getLength() - 1 ] + != sal_Unicode( '/' ) ) + rURL = aNormalizedURL; + else + rURL = aNormalizedURL + .copy( 0, aNormalizedURL.getLength() - 1 ); + + return true; + } + } + } + } + return false; +} + +//========================================================================= +//========================================================================= +// +// OfficeInstallationDirectories Implementation. +// +//========================================================================= +//========================================================================= + +OfficeInstallationDirectories::OfficeInstallationDirectories( + const uno::Reference< uno::XComponentContext > & xCtx ) +: m_aOfficeBrandDirMacro( RTL_CONSTASCII_USTRINGPARAM( "$(brandbaseurl)" ) ), + m_aOfficeBaseDirMacro( RTL_CONSTASCII_USTRINGPARAM( "$(baseinsturl)" ) ), + m_aUserDirMacro( RTL_CONSTASCII_USTRINGPARAM( "$(userdataurl)" ) ), + m_xCtx( xCtx ), + m_pOfficeBrandDir( 0 ), + m_pOfficeBaseDir( 0 ), + m_pUserDir( 0 ) +{ +} + +//========================================================================= +// virtual +OfficeInstallationDirectories::~OfficeInstallationDirectories() +{ + delete m_pOfficeBrandDir; + delete m_pOfficeBaseDir; + delete m_pUserDir; +} + +//========================================================================= +// util::XOfficeInstallationDirectories +//========================================================================= + +// virtual +rtl::OUString SAL_CALL +OfficeInstallationDirectories::getOfficeInstallationDirectoryURL() + throw ( uno::RuntimeException ) +{ + initDirs(); + return rtl::OUString( *m_pOfficeBrandDir ); +} + +//========================================================================= +// virtual +rtl::OUString SAL_CALL +OfficeInstallationDirectories::getOfficeUserDataDirectoryURL() + throw ( uno::RuntimeException ) +{ + initDirs(); + return rtl::OUString( *m_pUserDir ); +} + + +//========================================================================= +// virtual +rtl::OUString SAL_CALL +OfficeInstallationDirectories::makeRelocatableURL( const rtl::OUString& URL ) + throw ( uno::RuntimeException ) +{ + if ( URL.getLength() > 0 ) + { + initDirs(); + + rtl::OUString aCanonicalURL( URL ); + makeCanonicalFileURL( aCanonicalURL ); + + sal_Int32 nIndex = aCanonicalURL.indexOf( *m_pOfficeBrandDir ); + if ( nIndex != -1 ) + { + return rtl::OUString( + aCanonicalURL.replaceAt( nIndex, + m_pOfficeBrandDir->getLength(), + m_aOfficeBrandDirMacro ) ); + } + else + { + nIndex = aCanonicalURL.indexOf( *m_pOfficeBaseDir ); + if ( nIndex != -1 ) + { + return rtl::OUString( + aCanonicalURL.replaceAt( nIndex, + m_pOfficeBaseDir->getLength(), + m_aOfficeBaseDirMacro ) ); + } + else + { + nIndex = aCanonicalURL.indexOf( *m_pUserDir ); + if ( nIndex != -1 ) + { + return rtl::OUString( + aCanonicalURL.replaceAt( nIndex, + m_pUserDir->getLength(), + m_aUserDirMacro ) ); + } + } + } + } + return rtl::OUString( URL ); +} + +//========================================================================= +// virtual +rtl::OUString SAL_CALL +OfficeInstallationDirectories::makeAbsoluteURL( const rtl::OUString& URL ) + throw ( uno::RuntimeException ) +{ + if ( URL.getLength() > 0 ) + { + sal_Int32 nIndex = URL.indexOf( m_aOfficeBrandDirMacro ); + if ( nIndex != -1 ) + { + initDirs(); + + return rtl::OUString( + URL.replaceAt( nIndex, + m_aOfficeBrandDirMacro.getLength(), + *m_pOfficeBrandDir ) ); + } + else + { + nIndex = URL.indexOf( m_aOfficeBaseDirMacro ); + if ( nIndex != -1 ) + { + initDirs(); + + return rtl::OUString( + URL.replaceAt( nIndex, + m_aOfficeBaseDirMacro.getLength(), + *m_pOfficeBaseDir ) ); + } + else + { + nIndex = URL.indexOf( m_aUserDirMacro ); + if ( nIndex != -1 ) + { + initDirs(); + + return rtl::OUString( + URL.replaceAt( nIndex, + m_aUserDirMacro.getLength(), + *m_pUserDir ) ); + } + } + } + } + return rtl::OUString( URL ); +} + +//========================================================================= +// lang::XServiceInfo +//========================================================================= + +// virtual +rtl::OUString SAL_CALL +OfficeInstallationDirectories::getImplementationName() + throw ( uno::RuntimeException ) +{ + return getImplementationName_static(); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL +OfficeInstallationDirectories::supportsService( const rtl::OUString& ServiceName ) + throw ( uno::RuntimeException ) +{ + const uno::Sequence< rtl::OUString > & aNames + = getSupportedServiceNames(); + const rtl::OUString * p = aNames.getConstArray(); + for ( sal_Int32 nPos = 0; nPos < aNames.getLength(); nPos++ ) + { + if ( p[ nPos ].equals( ServiceName ) ) + return sal_True; + } + return sal_False; + +} + +//========================================================================= +// virtual +uno::Sequence< ::rtl::OUString > SAL_CALL +OfficeInstallationDirectories::getSupportedServiceNames() + throw ( uno::RuntimeException ) +{ + return getSupportedServiceNames_static(); +} + +//========================================================================= +// static +rtl::OUString SAL_CALL +OfficeInstallationDirectories::getImplementationName_static() +{ + return rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.comp.util.OfficeInstallationDirectories" ) ); +} + +//========================================================================= +// static +uno::Sequence< ::rtl::OUString > SAL_CALL +OfficeInstallationDirectories::getSupportedServiceNames_static() +{ + const rtl::OUString aServiceName( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.OfficeInstallationDirectories" ) ); + return uno::Sequence< rtl::OUString >( &aServiceName, 1 ); +} + +//========================================================================= +// static +rtl::OUString SAL_CALL OfficeInstallationDirectories::getSingletonName_static() +{ + return rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.theOfficeInstallationDirectories" ) ); +} + +//========================================================================= +// static +uno::Reference< uno::XInterface > SAL_CALL +OfficeInstallationDirectories::Create( + const uno::Reference< uno::XComponentContext > & rxContext ) +{ + return static_cast< cppu::OWeakObject * >( + new OfficeInstallationDirectories( rxContext ) ); +} + +//========================================================================= +// non-UNO +//========================================================================= + +void OfficeInstallationDirectories::initDirs() +{ + if ( m_pOfficeBrandDir == 0 ) + { + osl::MutexGuard aGuard( m_aMutex ); + if ( m_pOfficeBrandDir == 0 ) + { + m_pOfficeBrandDir = new rtl::OUString; + m_pOfficeBaseDir = new rtl::OUString; + m_pUserDir = new rtl::OUString; + + uno::Reference< util::XMacroExpander > xExpander; + + m_xCtx->getValueByName( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "/singletons/com.sun.star.util.theMacroExpander" ) ) ) + >>= xExpander; + + OSL_ENSURE( xExpander.is(), + "Unable to obtain macro expander singleton!" ); + + if ( xExpander.is() ) + { + *m_pOfficeBrandDir = + xExpander->expandMacros( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "$BRAND_BASE_DIR" ) ) ); + + OSL_ENSURE( m_pOfficeBrandDir->getLength() > 0, + "Unable to obtain office brand installation directory!" ); + + makeCanonicalFileURL( *m_pOfficeBrandDir ); + + *m_pOfficeBaseDir = + xExpander->expandMacros( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap" ) ":BaseInstallation}" ) ) ); + + OSL_ENSURE( m_pOfficeBaseDir->getLength() > 0, + "Unable to obtain office base installation directory!" ); + + makeCanonicalFileURL( *m_pOfficeBaseDir ); + + *m_pUserDir = + xExpander->expandMacros( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap" ) ":UserInstallation}" ) ) ); + + OSL_ENSURE( m_pUserDir->getLength() > 0, + "Unable to obtain office user data directory!" ); + + makeCanonicalFileURL( *m_pUserDir ); + } + } + } +} + +void createRegistryInfo_OfficeInstallationDirectories() +{ + static ::comphelper::module::OSingletonRegistration< OfficeInstallationDirectories > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/officeinstdir/officeinstallationdirectories.hxx b/comphelper/source/officeinstdir/officeinstallationdirectories.hxx new file mode 100644 index 000000000000..00f5b81df3f9 --- /dev/null +++ b/comphelper/source/officeinstdir/officeinstallationdirectories.hxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_OFFICEINSTALLATIONDIRECTORIES_HXX +#define INCLUDED_OFFICEINSTALLATIONDIRECTORIES_HXX + +#include "osl/mutex.hxx" +#include "cppuhelper/implbase2.hxx" + +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/util/XOfficeInstallationDirectories.hpp" + +namespace comphelper { + +//========================================================================= + +typedef cppu::WeakImplHelper2< + com::sun::star::util::XOfficeInstallationDirectories, + com::sun::star::lang::XServiceInfo > UnoImplBase; + +struct mutex_holder +{ + osl::Mutex m_aMutex; +}; + +class OfficeInstallationDirectories : public mutex_holder, public UnoImplBase +{ +public: + OfficeInstallationDirectories( + const com::sun::star::uno::Reference< + com::sun::star::uno::XComponentContext > & xCtx ); + virtual ~OfficeInstallationDirectories(); + + // XOfficeInstallationDirectories + virtual ::rtl::OUString SAL_CALL + getOfficeInstallationDirectoryURL() + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL + getOfficeUserDataDirectoryURL() + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL + makeRelocatableURL( const ::rtl::OUString& URL ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL + makeAbsoluteURL( const ::rtl::OUString& URL ) + throw (::com::sun::star::uno::RuntimeException); + + // 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); + + // XServiceInfo - static versions (used for component registration) + static ::rtl::OUString SAL_CALL + getImplementationName_static(); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames_static(); + static ::rtl::OUString SAL_CALL + getSingletonName_static(); + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + Create( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& ); + +private: + void initDirs(); + + rtl::OUString m_aOfficeBrandDirMacro; + rtl::OUString m_aOfficeBaseDirMacro; + rtl::OUString m_aUserDirMacro; + com::sun::star::uno::Reference< + com::sun::star::uno::XComponentContext > m_xCtx; + rtl::OUString * m_pOfficeBrandDir; + rtl::OUString * m_pOfficeBaseDir; + rtl::OUString * m_pUserDir; +}; + +} // namespace comphelper + +#endif /* !INCLUDED_OFFICEINSTALLATIONDIRECTORIES_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/processfactory/componentfactory.cxx b/comphelper/source/processfactory/componentfactory.cxx new file mode 100644 index 000000000000..ec72a25dc615 --- /dev/null +++ b/comphelper/source/processfactory/componentfactory.cxx @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/componentfactory.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <cppuhelper/shlib.hxx> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; +using namespace ::rtl; + + +namespace comphelper +{ + +Reference< XInterface > getComponentInstance( + const OUString & rLibraryName, + const OUString & rImplementationName + ) +{ + Reference< XInterface > xI; + Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); + if ( xMSF.is() ) + xI = xMSF->createInstance( rImplementationName ); + if( !xI.is() ) + { + Reference< XSingleServiceFactory > xSSF = + loadLibComponentFactory( rLibraryName, rImplementationName, + Reference< XMultiServiceFactory >(), Reference< XRegistryKey >() ); + if (xSSF.is()) + xI = xSSF->createInstance(); + } + return xI; +} + + +Reference< XSingleServiceFactory > loadLibComponentFactory( + const OUString & rLibName, + const OUString & rImplName, + const Reference< XMultiServiceFactory > & xSF, + const Reference< XRegistryKey > & xKey + ) +{ + return Reference< XSingleServiceFactory >( ::cppu::loadSharedLibComponentFactory( + rLibName, OUString(), rImplName, xSF, xKey ), UNO_QUERY ); +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/processfactory/processfactory.cxx b/comphelper/source/processfactory/processfactory.cxx new file mode 100644 index 000000000000..f9b2218f7018 --- /dev/null +++ b/comphelper/source/processfactory/processfactory.cxx @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <osl/mutex.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include "com/sun/star/beans/XPropertySet.hpp" + + +using namespace ::com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace osl; + +namespace comphelper +{ + +/* + This function preserves only that the xProcessFactory variable will not be create when + the library is loaded. +*/ +Reference< XMultiServiceFactory > localProcessFactory( const Reference< XMultiServiceFactory >& xSMgr, sal_Bool bSet ) +{ + Guard< Mutex > aGuard( Mutex::getGlobalMutex() ); + + static Reference< XMultiServiceFactory > xProcessFactory; + if ( bSet ) + { + xProcessFactory = xSMgr; + } + + return xProcessFactory; +} + + +void setProcessServiceFactory(const Reference< XMultiServiceFactory >& xSMgr) +{ + localProcessFactory( xSMgr, sal_True ); +} + +Reference< XMultiServiceFactory > getProcessServiceFactory() +{ + Reference< XMultiServiceFactory> xReturn; + xReturn = localProcessFactory( xReturn, sal_False ); + return xReturn; +} + +Reference< XInterface > createProcessComponent( const ::rtl::OUString& _rServiceSpecifier ) SAL_THROW( ( RuntimeException ) ) +{ + Reference< XInterface > xComponent; + + Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() ); + if ( xFactory.is() ) + xComponent = xFactory->createInstance( _rServiceSpecifier ); + + return xComponent; +} + +Reference< XInterface > createProcessComponentWithArguments( const ::rtl::OUString& _rServiceSpecifier, + const Sequence< Any >& _rArgs ) SAL_THROW( ( RuntimeException ) ) +{ + Reference< XInterface > xComponent; + + Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() ); + if ( xFactory.is() ) + xComponent = xFactory->createInstanceWithArguments( _rServiceSpecifier, _rArgs ); + + return xComponent; +} + +Reference< XComponentContext > getProcessComponentContext() +{ + Reference< XComponentContext > xRet; + uno::Reference<beans::XPropertySet> const xProps( + comphelper::getProcessServiceFactory(), uno::UNO_QUERY ); + if (xProps.is()) { + try { + xRet.set( xProps->getPropertyValue( rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ), + uno::UNO_QUERY ); + } + catch (beans::UnknownPropertyException const&) { + } + } + return xRet; +} + +} // namespace comphelper + +extern "C" { +uno::XComponentContext * comphelper_getProcessComponentContext() +{ + uno::Reference<uno::XComponentContext> xRet; + xRet = ::comphelper::getProcessComponentContext(); + if (xRet.is()) + xRet->acquire(); + return xRet.get(); +} +} // extern "C" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/ChainablePropertySet.cxx b/comphelper/source/property/ChainablePropertySet.cxx new file mode 100644 index 000000000000..e3a02dce4c1b --- /dev/null +++ b/comphelper/source/property/ChainablePropertySet.cxx @@ -0,0 +1,323 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/ChainablePropertySet.hxx> +#include <comphelper/ChainablePropertySetInfo.hxx> +#include <osl/mutex.hxx> + +#include <memory> // STL auto_ptr + + +using namespace ::rtl; +using namespace ::comphelper; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +ChainablePropertySet::ChainablePropertySet( comphelper::ChainablePropertySetInfo* pInfo, osl::SolarMutex* pMutex ) + throw() +: mpInfo ( pInfo ) +, mpMutex ( pMutex ) +, mxInfo ( pInfo ) +{ +} + +ChainablePropertySet::~ChainablePropertySet() + throw() +{ +} + +// XPropertySet +Reference< XPropertySetInfo > SAL_CALL ChainablePropertySet::getPropertySetInfo( ) + throw(RuntimeException) +{ + return mxInfo; +} + +void ChainablePropertySet::lockMutex() +{ + if (mpMutex) + mpMutex->acquire(); +} + +void ChainablePropertySet::unlockMutex() +{ + if (mpMutex) + mpMutex->release(); +} + +void SAL_CALL ChainablePropertySet::setPropertyValue( const ::rtl::OUString& rPropertyName, const Any& rValue ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (mpMutex) + pMutexGuard.reset( new osl::SolarGuard(mpMutex) ); + + PropertyInfoHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName ); + + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) ); + + _preSetValues(); + _setSingleValue( *((*aIter).second), rValue ); + _postSetValues(); +} + +Any SAL_CALL ChainablePropertySet::getPropertyValue( const ::rtl::OUString& rPropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (mpMutex) + pMutexGuard.reset( new osl::SolarGuard(mpMutex) ); + + PropertyInfoHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName ); + + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) ); + + Any aAny; + _preGetValues (); + _getSingleValue( *((*aIter).second), aAny ); + _postGetValues (); + + return aAny; +} + +void SAL_CALL ChainablePropertySet::addPropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL ChainablePropertySet::removePropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL ChainablePropertySet::addVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL ChainablePropertySet::removeVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +// XMultiPropertySet +void SAL_CALL ChainablePropertySet::setPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames, const Sequence< Any >& aValues ) + throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (mpMutex) + pMutexGuard.reset( new osl::SolarGuard(mpMutex) ); + + const sal_Int32 nCount = aPropertyNames.getLength(); + + if( nCount != aValues.getLength() ) + throw IllegalArgumentException(); + + if( nCount ) + { + _preSetValues(); + + const Any * pAny = aValues.getConstArray(); + const OUString * pString = aPropertyNames.getConstArray(); + PropertyInfoHash::const_iterator aEnd = mpInfo->maMap.end(), aIter; + + for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny ) + { + aIter = mpInfo->maMap.find ( *pString ); + if ( aIter == aEnd ) + throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) ); + + _setSingleValue ( *((*aIter).second), *pAny ); + } + + _postSetValues(); + } +} + +Sequence< Any > SAL_CALL ChainablePropertySet::getPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames ) + throw(RuntimeException) +{ + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (mpMutex) + pMutexGuard.reset( new osl::SolarGuard(mpMutex) ); + + const sal_Int32 nCount = aPropertyNames.getLength(); + + Sequence < Any > aValues ( nCount ); + + if( nCount ) + { + _preGetValues(); + + Any * pAny = aValues.getArray(); + const OUString * pString = aPropertyNames.getConstArray(); + PropertyInfoHash::const_iterator aEnd = mpInfo->maMap.end(), aIter; + + for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny ) + { + aIter = mpInfo->maMap.find ( *pString ); + if ( aIter == aEnd ) + throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) ); + + _getSingleValue ( *((*aIter).second), *pAny ); + } + + _postGetValues(); + } + return aValues; +} + +void SAL_CALL ChainablePropertySet::addPropertiesChangeListener( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& ) + throw(RuntimeException) +{ + // todo +} + +void SAL_CALL ChainablePropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& ) + throw(RuntimeException) +{ + // todo +} + +void SAL_CALL ChainablePropertySet::firePropertiesChangeEvent( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& ) + throw(RuntimeException) +{ + // todo +} + +// XPropertyState +PropertyState SAL_CALL ChainablePropertySet::getPropertyState( const ::rtl::OUString& PropertyName ) + throw(UnknownPropertyException, RuntimeException) +{ + PropertyInfoHash::const_iterator aIter = mpInfo->maMap.find( PropertyName ); + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) ); + + PropertyState aState; + + _preGetPropertyState(); + _getPropertyState( *((*aIter).second), aState ); + _postGetPropertyState(); + + return aState; +} + +Sequence< PropertyState > SAL_CALL ChainablePropertySet::getPropertyStates( const Sequence< ::rtl::OUString >& rPropertyNames ) + throw(UnknownPropertyException, RuntimeException) +{ + const sal_Int32 nCount = rPropertyNames.getLength(); + + Sequence< PropertyState > aStates( nCount ); + if( nCount ) + { + PropertyState * pState = aStates.getArray(); + const OUString * pString = rPropertyNames.getConstArray(); + PropertyInfoHash::const_iterator aEnd = mpInfo->maMap.end(), aIter; + _preGetPropertyState(); + + for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState ) + { + aIter = mpInfo->maMap.find ( *pString ); + if ( aIter == aEnd ) + throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) ); + + _getPropertyState ( *((*aIter).second), *pState ); + } + _postGetPropertyState(); + } + return aStates; +} + +void SAL_CALL ChainablePropertySet::setPropertyToDefault( const ::rtl::OUString& rPropertyName ) + throw(UnknownPropertyException, RuntimeException) +{ + PropertyInfoHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName ); + + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) ); + _setPropertyToDefault( *((*aIter).second) ); +} + +Any SAL_CALL ChainablePropertySet::getPropertyDefault( const ::rtl::OUString& rPropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + PropertyInfoHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName ); + + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) ); + return _getPropertyDefault( *((*aIter).second) ); +} + +void ChainablePropertySet::_preGetPropertyState () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +void ChainablePropertySet::_getPropertyState( const comphelper::PropertyInfo&, PropertyState& ) + throw(UnknownPropertyException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +void ChainablePropertySet::_postGetPropertyState () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +void ChainablePropertySet::_setPropertyToDefault( const comphelper::PropertyInfo& ) + throw(UnknownPropertyException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +Any ChainablePropertySet::_getPropertyDefault( const comphelper::PropertyInfo& ) + throw(UnknownPropertyException, WrappedTargetException ) +{ + OSL_FAIL( "you have to implement this yourself!"); + + Any aAny; + return aAny; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/ChainablePropertySetInfo.cxx b/comphelper/source/property/ChainablePropertySetInfo.cxx new file mode 100644 index 000000000000..0f53c6d0260b --- /dev/null +++ b/comphelper/source/property/ChainablePropertySetInfo.cxx @@ -0,0 +1,145 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/ChainablePropertySetInfo.hxx> +#include <comphelper/TypeGeneration.hxx> + +using ::rtl::OUString; +using ::comphelper::PropertyInfo; +using ::comphelper::GenerateCppuType; +using ::comphelper::ChainablePropertySetInfo; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Type; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::beans::Property; +using ::com::sun::star::beans::XPropertySetInfo; +using ::com::sun::star::beans::UnknownPropertyException; + +ChainablePropertySetInfo::ChainablePropertySetInfo() + throw() +{ +} + +ChainablePropertySetInfo::ChainablePropertySetInfo( PropertyInfo* pMap ) + throw() +{ + add ( pMap ); +} + +ChainablePropertySetInfo::~ChainablePropertySetInfo() + throw() +{ +} + +void ChainablePropertySetInfo::add( PropertyInfo* pMap, sal_Int32 nCount ) + throw() +{ + // nCount < 0 => add all + // nCount == 0 => add nothing + // nCount > 0 => add at most nCount entries + if( maProperties.getLength() ) + maProperties.realloc( 0 ); + + while( pMap->mpName && ( ( nCount < 0) || ( nCount-- > 0 ) ) ) + { + OUString aName( pMap->mpName, pMap->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + +#ifdef DBG_UTIL + PropertyInfoHash::iterator aIter = maMap.find( aName ); + if( aIter != maMap.end() ) + OSL_FAIL( "Warning: PropertyInfo added twice, possible error!"); +#endif + maMap[aName] = pMap++; + } +} + +void ChainablePropertySetInfo::remove( const rtl::OUString& aName ) + throw() +{ + maMap.erase ( aName ); + if ( maProperties.getLength() ) + maProperties.realloc( 0 ); +} + +Sequence< ::Property > SAL_CALL ChainablePropertySetInfo::getProperties() + throw(::com::sun::star::uno::RuntimeException) +{ + sal_Int32 nSize = maMap.size(); + if( maProperties.getLength() != nSize ) + { + maProperties.realloc ( nSize ); + Property* pProperties = maProperties.getArray(); + + PropertyInfoHash::iterator aIter = maMap.begin(); + const PropertyInfoHash::iterator aEnd = maMap.end(); + for ( ; aIter != aEnd; ++aIter, ++pProperties) + { + PropertyInfo* pInfo = (*aIter).second; + + pProperties->Name = OUString( pInfo->mpName, pInfo->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + pProperties->Handle = pInfo->mnHandle; + const Type* pType; + GenerateCppuType ( pInfo->meCppuType, pType); + pProperties->Type = *pType; + pProperties->Attributes = pInfo->mnAttributes; + } + } + return maProperties; +} + +Property SAL_CALL ChainablePropertySetInfo::getPropertyByName( const ::rtl::OUString& rName ) + throw(::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + PropertyInfoHash::iterator aIter = maMap.find( rName ); + + if ( maMap.end() == aIter ) + throw UnknownPropertyException( rName, *this ); + + PropertyInfo *pInfo = (*aIter).second; + Property aProperty; + aProperty.Name = OUString( pInfo->mpName, pInfo->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + aProperty.Handle = pInfo->mnHandle; + const Type* pType = &aProperty.Type; + GenerateCppuType ( pInfo->meCppuType, pType ); + aProperty.Type = *pType; + aProperty.Attributes = pInfo->mnAttributes; + return aProperty; +} + +sal_Bool SAL_CALL ChainablePropertySetInfo::hasPropertyByName( const ::rtl::OUString& rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + return static_cast < sal_Bool > ( maMap.find ( rName ) != maMap.end() ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/MasterPropertySet.cxx b/comphelper/source/property/MasterPropertySet.cxx new file mode 100644 index 000000000000..78f33af7aed0 --- /dev/null +++ b/comphelper/source/property/MasterPropertySet.cxx @@ -0,0 +1,506 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <comphelper/MasterPropertySet.hxx> +#include <comphelper/MasterPropertySetInfo.hxx> +#include <comphelper/ChainablePropertySet.hxx> +#include <comphelper/ChainablePropertySetInfo.hxx> +#include <osl/mutex.hxx> + +#include <memory> // STL auto_ptr + +////////////////////////////////////////////////////////////////////// + +class AutoOGuardArray +{ + sal_Int32 nSize; + std::auto_ptr< osl::SolarGuard > * pGuardArray; + +public: + AutoOGuardArray( sal_Int32 nNumElements ); + ~AutoOGuardArray(); + + std::auto_ptr< osl::SolarGuard > & operator[] ( sal_Int32 i ) { return pGuardArray[i]; } +}; + +AutoOGuardArray::AutoOGuardArray( sal_Int32 nNumElements ) +{ + nSize = nNumElements; + pGuardArray = new std::auto_ptr< osl::SolarGuard >[ nSize ]; +} + +AutoOGuardArray::~AutoOGuardArray() +{ + //!! release auto_ptr's and thus the mutexes locks + delete [] pGuardArray; + +} + +////////////////////////////////////////////////////////////////////// + +using namespace ::rtl; +using namespace ::comphelper; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + + +SlaveData::SlaveData ( ChainablePropertySet *pSlave) +: mpSlave ( pSlave ) +, mxSlave ( pSlave ) +, mbInit ( sal_False ) +{ +} + +MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo* pInfo, osl::SolarMutex* pMutex ) + throw() +: mpInfo ( pInfo ) +, mpMutex ( pMutex ) +, mnLastId ( 0 ) +, mxInfo ( pInfo ) +{ +} + +void MasterPropertySet::lockMutex() +{ + if (mpMutex) + mpMutex->acquire(); +} +void MasterPropertySet::unlockMutex() +{ + if (mpMutex) + mpMutex->release(); +} + +MasterPropertySet::~MasterPropertySet() + throw() +{ + SlaveMap::iterator aEnd = maSlaveMap.end(), aIter = maSlaveMap.begin(); + while (aIter != aEnd ) + { + delete (*aIter).second; + ++aIter; + } +} + +// XPropertySet +Reference< XPropertySetInfo > SAL_CALL MasterPropertySet::getPropertySetInfo( ) + throw(RuntimeException) +{ + return mxInfo; +} + +void MasterPropertySet::registerSlave ( ChainablePropertySet *pNewSet ) + throw() +{ + maSlaveMap [ ++mnLastId ] = new SlaveData ( pNewSet ); + mpInfo->add ( pNewSet->mpInfo->maMap, mnLastId ); +} + +void SAL_CALL MasterPropertySet::setPropertyValue( const ::rtl::OUString& rPropertyName, const Any& rValue ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (mpMutex) + pMutexGuard.reset( new osl::SolarGuard(mpMutex) ); + + PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName ); + + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) ); + + if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours ! + { + _preSetValues(); + _setSingleValue( *((*aIter).second->mpInfo), rValue ); + _postSetValues(); + } + else + { + ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave; + + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard2; + if (pSlave->mpMutex) + pMutexGuard2.reset( new osl::SolarGuard(pSlave->mpMutex) ); + + pSlave->_preSetValues(); + pSlave->_setSingleValue( *((*aIter).second->mpInfo), rValue ); + pSlave->_postSetValues(); + } +} + +Any SAL_CALL MasterPropertySet::getPropertyValue( const ::rtl::OUString& rPropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (mpMutex) + pMutexGuard.reset( new osl::SolarGuard(mpMutex) ); + + PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName ); + + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) ); + + Any aAny; + if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours ! + { + _preGetValues(); + _getSingleValue( *((*aIter).second->mpInfo), aAny ); + _postGetValues(); + } + else + { + ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave; + + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard2; + if (pSlave->mpMutex) + pMutexGuard2.reset( new osl::SolarGuard(pSlave->mpMutex) ); + + pSlave->_preGetValues(); + pSlave->_getSingleValue( *((*aIter).second->mpInfo), aAny ); + pSlave->_postGetValues(); + } + return aAny; +} + +void SAL_CALL MasterPropertySet::addPropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL MasterPropertySet::removePropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL MasterPropertySet::addVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL MasterPropertySet::removeVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +// XMultiPropertySet +void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames, const Sequence< Any >& aValues ) + throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (mpMutex) + pMutexGuard.reset( new osl::SolarGuard(mpMutex) ); + + const sal_Int32 nCount = aPropertyNames.getLength(); + + if( nCount != aValues.getLength() ) + throw IllegalArgumentException(); + + if( nCount ) + { + _preSetValues(); + + const Any * pAny = aValues.getConstArray(); + const OUString * pString = aPropertyNames.getConstArray(); + PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter; + + //!! have an auto_ptr to an array of OGuards in order to have the + //!! allocated memory properly freed (exception safe!). + //!! Since the array itself has auto_ptrs as members we have to use a + //!! helper class 'AutoOGuardArray' in order to have + //!! the acquired locks properly released. + AutoOGuardArray aOGuardArray( nCount ); + + for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny ) + { + aIter = mpInfo->maMap.find ( *pString ); + if ( aIter == aEnd ) + throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) ); + + if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours ! + _setSingleValue( *((*aIter).second->mpInfo), *pAny ); + else + { + SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]; + if (!pSlave->IsInit()) + { + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + if (pSlave->mpSlave->mpMutex) + aOGuardArray[i].reset( new osl::SolarGuard(pSlave->mpSlave->mpMutex) ); + + pSlave->mpSlave->_preSetValues(); + pSlave->SetInit ( sal_True ); + } + pSlave->mpSlave->_setSingleValue( *((*aIter).second->mpInfo), *pAny ); + } + } + + _postSetValues(); + SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end(); + while (aSlaveIter != aSlaveEnd) + { + if ( (*aSlaveIter).second->IsInit()) + { + (*aSlaveIter).second->mpSlave->_postSetValues(); + (*aSlaveIter).second->SetInit ( sal_False ); + } + ++aSlaveIter; + } + } +} + +Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames ) + throw(RuntimeException) +{ + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (mpMutex) + pMutexGuard.reset( new osl::SolarGuard(mpMutex) ); + + const sal_Int32 nCount = aPropertyNames.getLength(); + + Sequence < Any > aValues ( nCount ); + + if( nCount ) + { + _preGetValues(); + + Any * pAny = aValues.getArray(); + const OUString * pString = aPropertyNames.getConstArray(); + PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter; + + //!! have an auto_ptr to an array of OGuards in order to have the + //!! allocated memory properly freed (exception safe!). + //!! Since the array itself has auto_ptrs as members we have to use a + //!! helper class 'AutoOGuardArray' in order to have + //!! the acquired locks properly released. + AutoOGuardArray aOGuardArray( nCount ); + + for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny ) + { + aIter = mpInfo->maMap.find ( *pString ); + if ( aIter == aEnd ) + throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) ); + + if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours ! + _getSingleValue( *((*aIter).second->mpInfo), *pAny ); + else + { + SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]; + if (!pSlave->IsInit()) + { + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + if (pSlave->mpSlave->mpMutex) + aOGuardArray[i].reset( new osl::SolarGuard(pSlave->mpSlave->mpMutex) ); + + pSlave->mpSlave->_preGetValues(); + pSlave->SetInit ( sal_True ); + } + pSlave->mpSlave->_getSingleValue( *((*aIter).second->mpInfo), *pAny ); + } + } + + _postSetValues(); + SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end(); + while (aSlaveIter != aSlaveEnd) + { + if ( (*aSlaveIter).second->IsInit()) + { + (*aSlaveIter).second->mpSlave->_postSetValues(); + (*aSlaveIter).second->SetInit ( sal_False ); + } + ++aSlaveIter; + } + } + return aValues; +} + +void SAL_CALL MasterPropertySet::addPropertiesChangeListener( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& ) + throw(RuntimeException) +{ + // todo +} + +void SAL_CALL MasterPropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& ) + throw(RuntimeException) +{ + // todo +} + +void SAL_CALL MasterPropertySet::firePropertiesChangeEvent( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& ) + throw(RuntimeException) +{ + // todo +} + +// XPropertyState +PropertyState SAL_CALL MasterPropertySet::getPropertyState( const ::rtl::OUString& PropertyName ) + throw(UnknownPropertyException, RuntimeException) +{ + PropertyDataHash::const_iterator aIter = mpInfo->maMap.find( PropertyName ); + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) ); + + PropertyState aState; + + if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours ! + { + _preGetPropertyState(); + _getPropertyState( *((*aIter).second->mpInfo), aState ); + _postGetPropertyState(); + } + else + { + ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave; + + // acquire mutex in c-tor and releases it in the d-tor (exception safe!). + std::auto_ptr< osl::SolarGuard > pMutexGuard; + if (pSlave->mpMutex) + pMutexGuard.reset( new osl::SolarGuard(pSlave->mpMutex) ); + + pSlave->_preGetPropertyState(); + pSlave->_getPropertyState( *((*aIter).second->mpInfo), aState ); + pSlave->_postGetPropertyState(); + } + + return aState; +} + +Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const Sequence< ::rtl::OUString >& rPropertyNames ) + throw(UnknownPropertyException, RuntimeException) +{ + const sal_Int32 nCount = rPropertyNames.getLength(); + + Sequence< PropertyState > aStates( nCount ); + if( nCount ) + { + PropertyState * pState = aStates.getArray(); + const OUString * pString = rPropertyNames.getConstArray(); + PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter; + _preGetPropertyState(); + + for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState ) + { + aIter = mpInfo->maMap.find ( *pString ); + if ( aIter == aEnd ) + throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) ); + + if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours ! + _getPropertyState( *((*aIter).second->mpInfo), *pState ); + else + { + SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]; + if (!pSlave->IsInit()) + { + pSlave->mpSlave->_preGetPropertyState(); + pSlave->SetInit ( sal_True ); + } + pSlave->mpSlave->_getPropertyState( *((*aIter).second->mpInfo), *pState ); + } + } + _postGetPropertyState(); + SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end(); + while (aSlaveIter != aSlaveEnd) + { + if ( (*aSlaveIter).second->IsInit()) + { + (*aSlaveIter).second->mpSlave->_postGetPropertyState(); + (*aSlaveIter).second->SetInit ( sal_False ); + } + ++aSlaveIter; + } + } + return aStates; +} + +void SAL_CALL MasterPropertySet::setPropertyToDefault( const ::rtl::OUString& rPropertyName ) + throw(UnknownPropertyException, RuntimeException) +{ + PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName ); + + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) ); + _setPropertyToDefault( *((*aIter).second->mpInfo) ); +} + +Any SAL_CALL MasterPropertySet::getPropertyDefault( const ::rtl::OUString& rPropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName ); + + if( aIter == mpInfo->maMap.end()) + throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) ); + return _getPropertyDefault( *((*aIter).second->mpInfo) ); +} + +void MasterPropertySet::_preGetPropertyState () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +void MasterPropertySet::_getPropertyState( const comphelper::PropertyInfo&, PropertyState& ) + throw(UnknownPropertyException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +void MasterPropertySet::_postGetPropertyState () + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +void MasterPropertySet::_setPropertyToDefault( const comphelper::PropertyInfo& ) + throw(UnknownPropertyException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +Any MasterPropertySet::_getPropertyDefault( const comphelper::PropertyInfo& ) + throw(UnknownPropertyException, WrappedTargetException ) +{ + OSL_FAIL( "you have to implement this yourself!"); + Any aAny; + return aAny; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/MasterPropertySetInfo.cxx b/comphelper/source/property/MasterPropertySetInfo.cxx new file mode 100644 index 000000000000..46dffe062c03 --- /dev/null +++ b/comphelper/source/property/MasterPropertySetInfo.cxx @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/MasterPropertySetInfo.hxx> +#include <comphelper/TypeGeneration.hxx> + +using ::rtl::OUString; +using ::comphelper::PropertyInfo; +using ::comphelper::GenerateCppuType; +using ::comphelper::MasterPropertySetInfo; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Type; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::beans::Property; +using ::com::sun::star::beans::XPropertySetInfo; +using ::com::sun::star::beans::UnknownPropertyException; + +MasterPropertySetInfo::MasterPropertySetInfo() + throw() +{ +} + +MasterPropertySetInfo::MasterPropertySetInfo( PropertyInfo* pMap ) + throw() +{ + add ( pMap ); +} + +MasterPropertySetInfo::~MasterPropertySetInfo() + throw() +{ + PropertyDataHash::iterator aEnd = maMap.end(), aIter = maMap.begin(); + while (aIter != aEnd ) + { + delete (*aIter).second; + ++aIter; + } +} + +void MasterPropertySetInfo::add( PropertyInfo* pMap, sal_Int32 nCount, sal_uInt8 nMapId ) + throw() +{ + // nCount < 0 => add all + // nCount == 0 => add nothing + // nCount > 0 => add at most nCount entries + if( maProperties.getLength() ) + maProperties.realloc( 0 ); + + for ( ; pMap->mpName && ( ( nCount < 0 ) || ( nCount > 0 ) ); --nCount, ++pMap ) + { + OUString aName( pMap->mpName, pMap->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + +#ifdef DBG_UTIL + PropertyDataHash::iterator aIter = maMap.find( aName ); + if( aIter != maMap.end() ) + OSL_FAIL( "Warning: PropertyInfo added twice, possible error!"); +#endif + maMap[aName] = new PropertyData ( nMapId, pMap ); + } +} + +void MasterPropertySetInfo::add( PropertyInfoHash &rHash, sal_uInt8 nMapId ) + throw() +{ + if( maProperties.getLength() ) + maProperties.realloc( 0 ); + PropertyInfoHash::iterator aIter = rHash.begin(), aEnd = rHash.end(); + + while ( aIter != aEnd ) + { +#ifdef DBG_UTIL + PropertyDataHash::iterator aDebugIter = maMap.find( (*aIter).first ); + if( aDebugIter != maMap.end() ) + OSL_FAIL( "Warning: PropertyInfo added twice, possible error!"); +#endif + maMap[(*aIter).first] = new PropertyData ( nMapId, (*aIter).second ); + ++aIter; + } +} + +void MasterPropertySetInfo::remove( const rtl::OUString& aName ) + throw() +{ + maMap.erase ( aName ); + if ( maProperties.getLength() ) + maProperties.realloc( 0 ); +} + +Sequence< ::Property > SAL_CALL MasterPropertySetInfo::getProperties() + throw(::com::sun::star::uno::RuntimeException) +{ + sal_Int32 nSize = maMap.size(); + if( maProperties.getLength() != nSize ) + { + maProperties.realloc ( nSize ); + Property* pProperties = maProperties.getArray(); + + PropertyDataHash::iterator aIter = maMap.begin(); + const PropertyDataHash::iterator aEnd = maMap.end(); + for ( ; aIter != aEnd; ++aIter, ++pProperties) + { + PropertyInfo* pInfo = (*aIter).second->mpInfo; + + pProperties->Name = OUString( pInfo->mpName, pInfo->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + pProperties->Handle = pInfo->mnHandle; + const Type* pType; + GenerateCppuType ( pInfo->meCppuType, pType); + pProperties->Type = *pType; + pProperties->Attributes = pInfo->mnAttributes; + } + } + return maProperties; +} + +Property SAL_CALL MasterPropertySetInfo::getPropertyByName( const ::rtl::OUString& rName ) + throw(::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + PropertyDataHash::iterator aIter = maMap.find( rName ); + + if ( maMap.end() == aIter ) + throw UnknownPropertyException( rName, *this ); + + PropertyInfo *pInfo = (*aIter).second->mpInfo; + Property aProperty; + aProperty.Name = OUString( pInfo->mpName, pInfo->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + aProperty.Handle = pInfo->mnHandle; + const Type* pType; + GenerateCppuType ( pInfo->meCppuType, pType ); + aProperty.Type = *pType; + + aProperty.Attributes = pInfo->mnAttributes; + return aProperty; +} + +sal_Bool SAL_CALL MasterPropertySetInfo::hasPropertyByName( const ::rtl::OUString& rName ) + throw(::com::sun::star::uno::RuntimeException) +{ + return static_cast < sal_Bool > ( maMap.find ( rName ) != maMap.end() ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/TypeGeneration.cxx b/comphelper/source/property/TypeGeneration.cxx new file mode 100644 index 000000000000..6c5f9e009e90 --- /dev/null +++ b/comphelper/source/property/TypeGeneration.cxx @@ -0,0 +1,236 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/TypeGeneration.hxx> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/style/LineSpacingMode.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/style/DropCapFormat.hpp> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/TabStop.hpp> +#include <com/sun/star/style/TabAlign.hpp> +#include <com/sun/star/style/PageStyleLayout.hpp> +#include <com/sun/star/style/BreakType.hpp> +#include <com/sun/star/text/XModule.hpp> +#include <com/sun/star/text/XTextRangeMover.hpp> +#include <com/sun/star/text/XFootnotesSettingsSupplier.hpp> +#include <com/sun/star/text/XFootnote.hpp> +#include <com/sun/star/text/XFootnotesSupplier.hpp> +#include <com/sun/star/text/XEndnotesSupplier.hpp> +#include <com/sun/star/text/XEndnotesSettingsSupplier.hpp> +#include <com/sun/star/text/FootnoteNumbering.hpp> +#include <com/sun/star/text/XTextSectionsSupplier.hpp> +#include <com/sun/star/text/XTextSection.hpp> +#include <com/sun/star/text/SectionFileLink.hpp> +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/text/HorizontalAdjust.hpp> +#include <com/sun/star/text/DocumentStatistic.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/HoriOrientationFormat.hpp> +#include <com/sun/star/text/NotePrintMode.hpp> +#include <com/sun/star/text/SizeType.hpp> +#include <com/sun/star/text/VertOrientationFormat.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> +//undef to prevent error (from sfx2/docfile.cxx) +#undef SEQUENCE +#include <com/sun/star/text/SetVariableType.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> +#include <com/sun/star/text/UserDataPart.hpp> +#include <com/sun/star/text/ChapterFormat.hpp> +#include <com/sun/star/text/XTextField.hpp> +#include <com/sun/star/text/PlaceholderType.hpp> +#include <com/sun/star/text/TemplateDisplayFormat.hpp> +#include <com/sun/star/text/UserFieldFormat.hpp> +#include <com/sun/star/text/PageNumberType.hpp> +#include <com/sun/star/text/ReferenceFieldPart.hpp> +#include <com/sun/star/text/FilenameDisplayFormat.hpp> +#include <com/sun/star/text/XDependentTextField.hpp> +#include <com/sun/star/text/GraphicCrop.hpp> +#include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp> +#include <com/sun/star/text/XTextTableCursor.hpp> +#include <com/sun/star/text/XTextTablesSupplier.hpp> +#include <com/sun/star/text/TableColumnSeparator.hpp> +#include <com/sun/star/text/XTextTable.hpp> +#include <com/sun/star/text/XDocumentIndexMark.hpp> +#include <com/sun/star/text/XDocumentIndexesSupplier.hpp> +#include <com/sun/star/text/XDocumentIndex.hpp> +#include <com/sun/star/text/XTextColumns.hpp> +#include <com/sun/star/text/TextColumnSequence.hpp> +#include <com/sun/star/text/XTextFramesSupplier.hpp> +#include <com/sun/star/text/XTextFrame.hpp> +#include <com/sun/star/beans/PropertyValues.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/XFastPropertySet.hpp> +#include <com/sun/star/beans/XVetoableChangeListener.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XPropertyStateChangeListener.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/XPropertiesChangeListener.hpp> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/PropertyStateChangeEvent.hpp> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/text/TextContentAnchorType.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/awt/XBitmap.hpp> +#include <com/sun/star/style/GraphicLocation.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/table/ShadowFormat.hpp> +#include <com/sun/star/table/BorderLine.hpp> +#include <com/sun/star/table/TableBorder.hpp> +#include <com/sun/star/table/TableBorderDistances.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/drawing/PointSequenceSequence.hpp> +#include <com/sun/star/i18n/XForbiddenCharacters.hpp> +#include <com/sun/star/drawing/ColorMode.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XConnection.hpp> +#include <com/sun/star/frame/XModel.hpp> +// #i28749# +#include <com/sun/star/drawing/HomogenMatrix3.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/embed/XEmbeddedObject.hpp> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::i18n; +using namespace ::comphelper; + +namespace comphelper +{ + void GenerateCppuType ( + CppuTypes eType, const com::sun::star::uno::Type*& pType ) + { + switch( eType ) + { + case CPPUTYPE_BOOLEAN: pType = &::getBooleanCppuType(); break; + case CPPUTYPE_INT8: pType = &::getCppuType( (sal_Int8*)0 ); break; + case CPPUTYPE_INT16: pType = &::getCppuType( (sal_Int16*)0 ); break; + case CPPUTYPE_INT32: pType = &::getCppuType( (sal_Int32*)0 ); break; + + case CPPUTYPE_DOUBLE: pType = &::getCppuType( (double*)0 ); break; + case CPPUTYPE_FLOAT: pType = &::getCppuType( (float*)0 ); break; + case CPPUTYPE_OUSTRING: pType = &::getCppuType( (OUString*)0 ); break; + case CPPUTYPE_FONTSLANT: pType = &::getCppuType( (FontSlant*)0 ); break; + case CPPUTYPE_LOCALE: pType = &::getCppuType( (Locale*)0 ); break; + case CPPUTYPE_PROPERTYVALUE:pType = &::getCppuType( (Sequence<PropertyValue>*)0 ); break; + case CPPUTYPE_PROPERTYVALUES: pType = &::getCppuType( (Sequence<PropertyValues>*)0 ); break; + case CPPUTYPE_BORDERLINE: pType = &::getCppuType( (table::BorderLine*)0 ); break; + case CPPUTYPE_BREAK: pType = &::getCppuType( (style::BreakType*)0 ); break; + case CPPUTYPE_GRAPHICLOC: pType = &::getCppuType( (style::GraphicLocation*)0 ); break; + case CPPUTYPE_DROPCAPFMT: pType = &::getCppuType( (style::DropCapFormat*)0 ); break; + case CPPUTYPE_LINESPACE: pType = &::getCppuType( (style::LineSpacing*)0 ); break; + + case CPPUTYPE_AWTSIZE: pType = &::getCppuType( (awt::Size*)0 ); break; + case CPPUTYPE_SHADOWFMT: pType = &::getCppuType( (table::ShadowFormat*)0 ); break; + case CPPUTYPE_TBLCOLSEP: pType = &::getCppuType( (Sequence<text::TableColumnSeparator>*)0 ); break; + case CPPUTYPE_PNTSEQSEQ: pType = &::getCppuType( (PointSequenceSequence*)0 ); break; + case CPPUTYPE_DOCIDXMRK: pType = &::getCppuType( (Sequence< Reference< XDocumentIndexMark > >*)0 ); break; + case CPPUTYPE_SEQINT8: pType = &::getCppuType( (Sequence<sal_Int8>*)0 ); break; + case CPPUTYPE_SEQTABSTOP: pType = &::getCppuType( (Sequence<style::TabStop>*)0 ); break; + case CPPUTYPE_SEQANCHORTYPE:pType = &::getCppuType( (Sequence<text::TextContentAnchorType>*)0 ); break; + case CPPUTYPE_SEQDEPTXTFLD: pType = &::getCppuType( (Sequence<Reference<XDependentTextField> >*)0); break; + case CPPUTYPE_TXTCNTANCHOR: pType = &::getCppuType( (text::TextContentAnchorType*)0 ); break; + case CPPUTYPE_WRAPTXTMODE: pType = &::getCppuType( (text::WrapTextMode*)0 ); break; + + case CPPUTYPE_COLORMODE: pType = &::getCppuType( (drawing::ColorMode*)0 ); break; + case CPPUTYPE_PAGESTYLELAY: pType = &::getCppuType( (style::PageStyleLayout*)0 ); break; + case CPPUTYPE_VERTALIGN: pType = &::getCppuType( (style::VerticalAlignment*)0 ); break; + case CPPUTYPE_TABLEBORDER: pType = &::getCppuType( (table::TableBorder*)0 ); break; + case CPPUTYPE_GRFCROP: pType = &::getCppuType( (text::GraphicCrop*)0 ); break; + case CPPUTYPE_SECTFILELNK: pType = &::getCppuType( (text::SectionFileLink*)0 ); break; + case CPPUTYPE_PAGENUMTYPE: pType = &::getCppuType( (text::PageNumberType*)0); break; + case CPPUTYPE_DATETIME: pType = &::getCppuType( (util::DateTime*)0 ); break; + case CPPUTYPE_DATE: pType = &::getCppuType( (util::Date*)0 ); break; + + case CPPUTYPE_REFINTERFACE: pType = &::getCppuType( (Reference<XInterface>*)0 ); break; + case CPPUTYPE_REFIDXREPL: pType = &::getCppuType( (Reference<container::XIndexReplace>*)0 ); break; + case CPPUTYPE_REFNAMECNT: pType = &::getCppuType( (Reference<container::XNameContainer>*)0 ); break; + case CPPUTYPE_REFTEXTFRAME: pType = &::getCppuType( (Reference<text::XTextFrame>*)0 ); break; + case CPPUTYPE_REFTEXTSECTION: pType = &::getCppuType( (Reference<text::XTextSection>*)0 ); break; + case CPPUTYPE_REFFOOTNOTE: pType = &::getCppuType( (Reference<text::XFootnote>*)0 ); break; + case CPPUTYPE_REFTEXT: pType = &::getCppuType( (Reference<text::XText>*)0 ); break; + case CPPUTYPE_REFTEXTCOL: pType = &::getCppuType( (Reference<text::XTextColumns>*)0 ); break; + case CPPUTYPE_REFFORBCHARS: pType = &::getCppuType( (Reference<XForbiddenCharacters>*)0 ); break; + case CPPUTYPE_REFIDXCNTNR: pType = &::getCppuType( (Reference<XIndexContainer>*)0 ); break; + case CPPUTYPE_REFTEXTCNTNT: pType = &::getCppuType( (Reference<XTextContent>*)0 ); break; + case CPPUTYPE_REFBITMAP: pType = &::getCppuType( (Reference<awt::XBitmap>*)0 ); break; + case CPPUTYPE_REFNMREPLACE: pType = &::getCppuType( (Reference<container::XNameReplace>*)0 ); break; + case CPPUTYPE_REFCELL: pType = &::getCppuType( (Reference<table::XCell>*)0 ); break; + case CPPUTYPE_REFDOCINDEX: pType = &::getCppuType( (Reference<text::XDocumentIndex>*)0 ); break; + case CPPUTYPE_REFDOCIDXMRK: pType = &::getCppuType( (Reference<text::XDocumentIndexMark>*)0 ); break; + case CPPUTYPE_REFTXTFIELD: pType = &::getCppuType( (Reference<text::XTextField>*)0 ); break; + case CPPUTYPE_REFTXTRANGE: pType = &::getCppuType( (Reference<text::XTextRange>*)0 ); break; + case CPPUTYPE_REFTXTTABLE: pType = &::getCppuType( (Reference<text::XTextTable>*)0 ); break; + case CPPUTYPE_AWTPOINT: pType = &::getCppuType( (awt::Point*)0 ); break; + case CPPUTYPE_REFLIBCONTAINER: pType = &::getCppuType( (Reference< script::XLibraryContainer >*)0); break; + case CPPUTYPE_OUSTRINGS: pType = &::getCppuType( (Sequence< ::rtl::OUString >*)0); break; + case CPPUTYPE_SEQANY: pType = &::getCppuType( (Sequence< uno::Any >*)0); break; + case CPPUTYPE_REFRESULTSET: pType = &::getCppuType( (Reference< sdbc::XResultSet >*)0); break; + case CPPUTYPE_REFCONNECTION: pType = &::getCppuType( (Reference< sdbc::XConnection >*)0); break; + case CPPUTYPE_REFMODEL: pType = &::getCppuType( (Reference< frame::XModel >*)0); break; + case CPPUTYPE_REFCOMPONENT: pType = &::getCppuType( (Reference< lang::XComponent >*)0 ); break; + // #i28749# + case CPPUTYPE_TRANSFORMATIONINHORIL2R: + { + pType = &::getCppuType( (drawing::HomogenMatrix3*)0 ); + } + break; + case CPPUTYPE_SEQNAMEDVALUE: pType = &::getCppuType( (Sequence<beans::NamedValue>*)0 ); break; + case CPPUTYPE_REFXGRAPHIC: pType = &::getCppuType( (Reference< graphic::XGraphic >*)0); break; + case CPPUTYPE_TABLEBORDERDISTANCES: pType = &::getCppuType( (table::TableBorderDistances*)0 ); break; + case CPPUTPYE_REFEMBEDDEDOBJECT: pType = &embed::XEmbeddedObject::static_type(); break; + default: + OSL_FAIL( "Unknown CPPU type" ); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/composedprops.cxx b/comphelper/source/property/composedprops.cxx new file mode 100644 index 000000000000..aa864f7ca47f --- /dev/null +++ b/comphelper/source/property/composedprops.cxx @@ -0,0 +1,359 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/composedprops.hxx> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <cppuhelper/implbase1.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::lang; + + //===================================================================== + //= OComposedPropertySetInfo + //===================================================================== + class OComposedPropertySetInfo : public ::cppu::WeakImplHelper1< XPropertySetInfo > + { + private: + Sequence< Property> m_aProperties; + + public: + OComposedPropertySetInfo(const Sequence< Property>& _rProperties); + + virtual Sequence< Property > SAL_CALL getProperties( ) throw(RuntimeException); + virtual Property SAL_CALL getPropertyByName( const ::rtl::OUString& _rName ) throw(UnknownPropertyException, RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& _rName ) throw(RuntimeException); + }; + + //===================================================================== + //= OComposedPropertySet + //===================================================================== + //--------------------------------------------------------------------- + OComposedPropertySet::OComposedPropertySet( + const Sequence< Reference< XPropertySet> > & _rElements, + const IPropertySetComposerCallback* _pPropertyMetaData) + :m_pInfo(NULL) + { + // copy the sequence + sal_Int32 nSingleSets = _rElements.getLength(); + if (nSingleSets) + { + m_aSingleSets.resize(nSingleSets); + const Reference< XPropertySet >* pSingleSets = _rElements.getConstArray(); + ::std::copy(pSingleSets, pSingleSets + nSingleSets, m_aSingleSets.begin()); + } + + // impl ctor + compose(_pPropertyMetaData); + } + + //--------------------------------------------------------------------- + OComposedPropertySet::~OComposedPropertySet() + { + if (m_pInfo) + m_pInfo->release(); + } + + //--------------------------------------------------------------------- + void OComposedPropertySet::compose(const IPropertySetComposerCallback* _pMetaData) + { + sal_Int32 nSingleSets = m_aSingleSets.size(); + + if (nSingleSets>0) + { + // get the properties of the first set + Reference< XPropertySet > xMasterSet = m_aSingleSets[0]; + Sequence< Property> aMasterProps; + if (xMasterSet.is()) + aMasterProps = xMasterSet->getPropertySetInfo()->getProperties(); + sal_Int32 nMasterPropsCount = aMasterProps.getLength(); + const Property* pMasterProps = aMasterProps.getConstArray(); + + // check which of the master properties should be included + Sequence<sal_Bool> aInclusionFlags(nMasterPropsCount); + sal_Bool* pInclusionFlags = aInclusionFlags.getArray(); + + // the states of all these properties + Sequence< PropertyState > aPropertyStates(nMasterPropsCount); + + for (sal_Int32 i=0; i<nMasterPropsCount; ++i) + pInclusionFlags[i] = sal_True; + + Reference< XPropertySet > xSecondarySet; + sal_Int32 nSecondaryPropertyCount; + Sequence< Property > aSecondaryProperties; + const Property* pPrimaryProperty = aMasterProps.getConstArray(); + for (sal_Int32 nPrimary=0; nPrimary<nMasterPropsCount; ++nPrimary, ++pPrimaryProperty) + { + if (_pMetaData && !_pMetaData->isComposeable(pPrimaryProperty->Name)) + // do not include this property + pInclusionFlags[nPrimary] = sal_False; + else + { + // search the property in all secondary sets + for (sal_Int32 i=1; i<nSingleSets; ++i) + { + xSecondarySet = m_aSingleSets[i]; + aSecondaryProperties = xSecondarySet->getPropertySetInfo()->getProperties(); + nSecondaryPropertyCount = aSecondaryProperties.getLength(); + const Property* pSecondaryProperties = aSecondaryProperties.getConstArray(); + + // search the current primary property in the secondary property sequence + sal_Int32 k=0; + while (k<nSecondaryPropertyCount && (pSecondaryProperties[k].Name != pPrimaryProperty->Name)) + ++k; + + if (k >= nSecondaryPropertyCount) + // not found -> do not include + pInclusionFlags[nPrimary] = sal_False; + } + } + } + + // count what's left .... + sal_Int32 nOverallProperties = 0; + for (sal_Int32 nCounter=0; nCounter<nMasterPropsCount; ++nCounter) + { + if (pInclusionFlags[nCounter]) + ++nOverallProperties; + } + + // and finally construct our sequence + m_aProperties = Sequence< Property >(nOverallProperties); + Property* pProperties = m_aProperties.getArray(); + const Property* pMasterProperties = pMasterProps; + sal_Int32 nOwnProperties = 0; + for (sal_Int32 nCopy = 0; nCopy < nMasterPropsCount; ++nCopy, ++pMasterProperties) + { + if (pInclusionFlags[nCopy]) + pProperties[nOwnProperties++] = *pMasterProperties; + } + } + } + + //------------------------------------------------------------------------------ + Reference< XPropertySetInfo > SAL_CALL OComposedPropertySet::getPropertySetInfo( ) throw(RuntimeException) + { + ::osl::MutexGuard aGuard(m_aMutex); + if (!m_pInfo) + { + m_pInfo = new OComposedPropertySetInfo(m_aProperties); + m_pInfo->acquire(); + } + return m_pInfo; + } + + //------------------------------------------------------------------------------ + PropertyState SAL_CALL OComposedPropertySet::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw(UnknownPropertyException, RuntimeException) + { + // assume DIRECT for the moment + PropertyState eState = PropertyState_DIRECT_VALUE; + + sal_Int32 nSingleSets = m_aSingleSets.size(); + if (nSingleSets>0) + { + // check the master state + Reference< XPropertySet > xMasterSet(m_aSingleSets[0]); + Any aPrimaryValue; + if (xMasterSet.is()) + { + Reference< XPropertyState > xMasterState(xMasterSet,UNO_QUERY); + aPrimaryValue = xMasterSet->getPropertyValue(_rPropertyName); + + if (xMasterState.is()) + eState = xMasterState->getPropertyState(_rPropertyName); + } + + // loop through the secondary sets + PropertyState eSecondaryState; + for (sal_Int32 i=1; i<nSingleSets; ++i) + { + Reference< XPropertySet > xSecondary(m_aSingleSets[i]); + Reference< XPropertyState > xSecondaryState(xSecondary, UNO_QUERY); + + // the secondary state + eSecondaryState = PropertyState_DIRECT_VALUE; + if(xSecondaryState.is()) + eSecondaryState = xSecondaryState->getPropertyState(_rPropertyName); + + // the secondary value + Any aSecondaryValue(xSecondary->getPropertyValue(_rPropertyName)); + + if ( (PropertyState_AMBIGUOUS_VALUE == eSecondaryState) // secondary is ambiguous + || !::comphelper::compare(aPrimaryValue, aSecondaryValue) // unequal values + ) + { + eState = PropertyState_AMBIGUOUS_VALUE; + break; + } + } + } + else + { + throw UnknownPropertyException( _rPropertyName, *this ); + } + + return eState; + } + + //--------------------------------------------------------------------- + Sequence< PropertyState > SAL_CALL OComposedPropertySet::getPropertyStates( const Sequence< ::rtl::OUString >& _rPropertyName ) throw(UnknownPropertyException, RuntimeException) + { + sal_Int32 nCount = _rPropertyName.getLength(); + Sequence< PropertyState > aReturn(nCount); + const ::rtl::OUString* pNames = _rPropertyName.getConstArray(); + PropertyState* pStates = aReturn.getArray(); + for (sal_Int32 i=0; i<nCount; ++i, ++pNames, ++pStates) + *pStates = getPropertyState(*pNames); + return aReturn; + } + + //--------------------------------------------------------------------- + void SAL_CALL OComposedPropertySet::setPropertyToDefault( const ::rtl::OUString& _rPropertyName ) throw(UnknownPropertyException, RuntimeException) + { + sal_Int32 nSingleSets = m_aSingleSets.size(); + for (sal_Int32 i=0; i<nSingleSets; ++i) + { + Reference< XPropertyState > xState(m_aSingleSets[i], UNO_QUERY); + if(xState.is()) + xState->setPropertyToDefault(_rPropertyName); + } + } + + //--------------------------------------------------------------------- + Any SAL_CALL OComposedPropertySet::getPropertyDefault( const ::rtl::OUString& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + { + return Any(); + } + + //------------------------------------------------------------------------------ + void SAL_CALL OComposedPropertySet::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) + { + sal_Int32 nSingleSets = m_aSingleSets.size(); + for (sal_Int32 i=0; i<nSingleSets; ++i) + { + if (m_aSingleSets[i].is()) + m_aSingleSets[i]->setPropertyValue(_rPropertyName, _rValue); + } + } + + //------------------------------------------------------------------------------ + Any SAL_CALL OComposedPropertySet::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + { + sal_Int32 nSingleSets = m_aSingleSets.size(); + + if ((nSingleSets>0) && (m_aSingleSets[0].is())) + return m_aSingleSets[0]->getPropertyValue(_rPropertyName); + return Any(); + } + + //------------------------------------------------------------------------------ + void SAL_CALL OComposedPropertySet::addPropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + { + // TODO: + // hold the single property sets weak + // be a property change listener on all single property sets (for all composed properties) + // upon property change + // determine the new state/value of the composed property + // broadcast the new composed property value + } + + //------------------------------------------------------------------------------ + void SAL_CALL OComposedPropertySet::removePropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + { + // TODO + } + + //------------------------------------------------------------------------------ + void SAL_CALL OComposedPropertySet::addVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + { + OSL_FAIL("OComposedPropertySet::addVetoableChangeListener: no implemented (yet)!"); + } + + //------------------------------------------------------------------------------ + void SAL_CALL OComposedPropertySet::removeVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + { + OSL_FAIL("OComposedPropertySet::removeVetoableChangeListener: no implemented (yet)!"); + } + + //------------------------------------------------------------------------------ + OComposedPropertySetInfo::OComposedPropertySetInfo(const Sequence< Property>& rSeq) + :m_aProperties(rSeq) + { + } + + //------------------------------------------------------------------------------ + Sequence< Property> SAL_CALL OComposedPropertySetInfo::getProperties() throw(RuntimeException) + { + return m_aProperties; + } + + //------------------------------------------------------------------------------ + Property SAL_CALL OComposedPropertySetInfo::getPropertyByName( const ::rtl::OUString& _rName ) throw(UnknownPropertyException, RuntimeException) + { + sal_Int32 nLength = m_aProperties.getLength(); + const Property* pProps = m_aProperties.getConstArray(); + // TODO TODO TODO: this O(n) search really sucks ... + for (sal_Int32 i=0; i<nLength; ++i, ++pProps) + { + if (pProps->Name == _rName) + return *pProps; + } + + throw UnknownPropertyException( _rName, *this ); + } + + //------------------------------------------------------------------------------ + sal_Bool SAL_CALL OComposedPropertySetInfo::hasPropertyByName( const ::rtl::OUString& _rName ) throw(RuntimeException) + { + sal_Int32 nLength = m_aProperties.getLength(); + const Property* pProps = m_aProperties.getConstArray(); + // TODO TODO TODO: this O(n) search really sucks ... + for( sal_Int32 i=0; i<nLength; ++i,++pProps ) + { + if(pProps->Name == _rName) + return sal_True; + } + + return sal_False; + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/genericpropertyset.cxx b/comphelper/source/property/genericpropertyset.cxx new file mode 100644 index 000000000000..d2ba51ee9954 --- /dev/null +++ b/comphelper/source/property/genericpropertyset.cxx @@ -0,0 +1,298 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <cppuhelper/weakagg.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <comphelper/propertysethelper.hxx> +#include <osl/mutex.hxx> +#include <comphelper/genericpropertyset.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <comphelper/stl_types.hxx> +#include <comphelper/servicehelper.hxx> +#include <osl/mutex.hxx> +#include <rtl/uuid.h> + +/////////////////////////////////////////////////////////////////////// + +using namespace ::rtl; +using namespace ::osl; +using namespace ::cppu; +using namespace ::comphelper; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; + +DECLARE_STL_USTRINGACCESS_MAP( Any, GenericAnyMapImpl ); + +namespace comphelper +{ + struct IMPL_GenericPropertySet_MutexContainer + { + Mutex maMutex ; + } ; + + class GenericPropertySet : public OWeakAggObject, + public XServiceInfo, + public XTypeProvider, + public PropertySetHelper, + private IMPL_GenericPropertySet_MutexContainer + { + private: + GenericAnyMapImpl maAnyMap; + ::cppu::OMultiTypeInterfaceContainerHelperVar< ::rtl::OUString, ::rtl::OUStringHash,UStringEqual> m_aListener; + + protected: + virtual void _setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException ); + virtual void _getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValue ) throw( UnknownPropertyException, WrappedTargetException ); + + public: + GenericPropertySet( PropertySetInfo* pInfo ) throw(); + virtual ~GenericPropertySet() throw(); + + // XInterface + virtual Any SAL_CALL queryAggregation( const Type & rType ) throw( RuntimeException); + virtual Any SAL_CALL queryInterface( const Type & rType ) throw( RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw( RuntimeException); + + // XServiceInfo + virtual rtl::OUString SAL_CALL getImplementationName() throw( RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName ) throw( RuntimeException ); + virtual Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw( RuntimeException ); + + // XPropertySet + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + }; + +} + +/////////////////////////////////////////////////////////////////////// + +GenericPropertySet::GenericPropertySet( PropertySetInfo* pInfo ) throw() +: PropertySetHelper( pInfo ) +,m_aListener(maMutex) +{ +} + +GenericPropertySet::~GenericPropertySet() throw() +{ +} +void SAL_CALL GenericPropertySet::addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + Reference < XPropertySetInfo > xInfo = getPropertySetInfo( ); + if ( xInfo.is() ) + { + if ( !aPropertyName.getLength() ) + { + Sequence< Property> aSeq = xInfo->getProperties(); + const Property* pIter = aSeq.getConstArray(); + const Property* pEnd = pIter + aSeq.getLength(); + for( ; pIter != pEnd ; ++pIter) + { + m_aListener.addInterface(pIter->Name,xListener); + } + } + else if ( xInfo->hasPropertyByName(aPropertyName) ) + m_aListener.addInterface(aPropertyName,xListener); + else + throw UnknownPropertyException( aPropertyName, *this ); + } +} + +void SAL_CALL GenericPropertySet::removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + ResettableMutexGuard aGuard( maMutex ); + Reference < XPropertySetInfo > xInfo = getPropertySetInfo( ); + aGuard.clear(); + if ( xInfo.is() ) + { + if ( !aPropertyName.getLength() ) + { + Sequence< Property> aSeq = xInfo->getProperties(); + const Property* pIter = aSeq.getConstArray(); + const Property* pEnd = pIter + aSeq.getLength(); + for( ; pIter != pEnd ; ++pIter) + { + m_aListener.removeInterface(pIter->Name,xListener); + } + } + else if ( xInfo->hasPropertyByName(aPropertyName) ) + m_aListener.removeInterface(aPropertyName,xListener); + else + throw UnknownPropertyException( aPropertyName, *this ); + } +} + +void GenericPropertySet::_setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException ) +{ + ResettableMutexGuard aGuard( maMutex ); + + while( *ppEntries ) + { + const OUString aPropertyName( (*ppEntries)->mpName, (*ppEntries)->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + OInterfaceContainerHelper * pHelper = m_aListener.getContainer(aPropertyName); + + maAnyMap[ aPropertyName ] = *pValues; + + if ( pHelper ) + { + PropertyChangeEvent aEvt; + aEvt.PropertyName = aPropertyName; + aEvt.NewValue = *pValues; + aGuard.clear(); + pHelper->notifyEach( &XPropertyChangeListener::propertyChange, aEvt ); + aGuard.reset(); + } + + ppEntries++; + pValues++; + } +} + +void GenericPropertySet::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, Any* pValue ) + throw( UnknownPropertyException, WrappedTargetException ) +{ + MutexGuard aGuard( maMutex ); + + while( *ppEntries ) + { + const OUString aPropertyName( (*ppEntries)->mpName, (*ppEntries)->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + *pValue = maAnyMap[ aPropertyName ]; + + ppEntries++; + pValue++; + } +} + +// XInterface + +Any SAL_CALL GenericPropertySet::queryInterface( const Type & rType ) + throw( RuntimeException ) +{ + return OWeakAggObject::queryInterface( rType ); +} + +Any SAL_CALL GenericPropertySet::queryAggregation( const Type & rType ) + throw(RuntimeException) +{ + Any aAny; + + if( rType == ::getCppuType((const Reference< XServiceInfo >*)0) ) + aAny <<= Reference< XServiceInfo >(this); + else if( rType == ::getCppuType((const Reference< XTypeProvider >*)0) ) + aAny <<= Reference< XTypeProvider >(this); + else if( rType == ::getCppuType((const Reference< XPropertySet >*)0) ) + aAny <<= Reference< XPropertySet >(this); + else if( rType == ::getCppuType((const Reference< XMultiPropertySet >*)0) ) + aAny <<= Reference< XMultiPropertySet >(this); + else + aAny <<= OWeakAggObject::queryAggregation( rType ); + + return aAny; +} + +void SAL_CALL GenericPropertySet::acquire() throw() +{ + OWeakAggObject::acquire(); +} + +void SAL_CALL GenericPropertySet::release() throw() +{ + OWeakAggObject::release(); +} + +uno::Sequence< uno::Type > SAL_CALL GenericPropertySet::getTypes() + throw (uno::RuntimeException) +{ + uno::Sequence< uno::Type > aTypes( 5 ); + uno::Type* pTypes = aTypes.getArray(); + + *pTypes++ = ::getCppuType((const uno::Reference< XAggregation>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XServiceInfo>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XTypeProvider>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XPropertySet>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XMultiPropertySet>*)0); + + return aTypes; +} + +namespace +{ + class theGenericPropertySetImplmentationId : public rtl::Static< UnoTunnelIdInit, theGenericPropertySetImplmentationId > {}; +} + +uno::Sequence< sal_Int8 > SAL_CALL GenericPropertySet::getImplementationId() + throw (uno::RuntimeException) +{ + return theGenericPropertySetImplmentationId::get().getSeq(); +} + +// XServiceInfo + +sal_Bool SAL_CALL GenericPropertySet::supportsService( const OUString& ServiceName ) throw(RuntimeException) +{ + Sequence< OUString > aSNL( getSupportedServiceNames() ); + const OUString * pArray = aSNL.getConstArray(); + + for( sal_Int32 i = 0; i < aSNL.getLength(); ++i ) + if( pArray[i] == ServiceName ) + return sal_True; + + return sal_False; +} + +OUString SAL_CALL GenericPropertySet::getImplementationName() throw( RuntimeException ) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.comphelper.GenericPropertySet") ); +} + +Sequence< OUString > SAL_CALL GenericPropertySet::getSupportedServiceNames( ) + throw( RuntimeException ) +{ + Sequence< OUString > aSNS( 1 ); + aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.XPropertySet" )); + return aSNS; +} + +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > comphelper::GenericPropertySet_CreateInstance( comphelper::PropertySetInfo* pInfo ) +{ + return (XPropertySet*)new GenericPropertySet( pInfo ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/opropertybag.cxx b/comphelper/source/property/opropertybag.cxx new file mode 100644 index 000000000000..c67605977ddf --- /dev/null +++ b/comphelper/source/property/opropertybag.cxx @@ -0,0 +1,584 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "opropertybag.hxx" +#include "comphelper_module.hxx" + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/Property.hpp> + +#include <comphelper/namedvaluecollection.hxx> + +#include <cppuhelper/exc_hlp.hxx> +#include <osl/thread.h> + +#include <algorithm> +#include <functional> +#include <iterator> + + +//-------------------------------------------------------------------------- +using namespace ::com::sun::star; + +void createRegistryInfo_OPropertyBag() +{ + static ::comphelper::module::OAutoRegistration< ::comphelper::OPropertyBag > aAutoRegistration; +} + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + 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; + + //==================================================================== + //= OPropertyBag + //==================================================================== + //-------------------------------------------------------------------- + OPropertyBag::OPropertyBag( const Reference< XComponentContext >& _rxContext ) + :OPropertyBag_PBase( GetBroadcastHelper(), this ) + ,::cppu::IEventNotificationHook() + ,m_aContext( _rxContext ) + ,m_bAutoAddProperties( false ) + ,m_NotifyListeners(m_aMutex) + ,m_isModified(false) + + { + } + + //-------------------------------------------------------------------- + OPropertyBag::~OPropertyBag() + { + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( OPropertyBag, OPropertyBag_Base, OPropertyBag_PBase ) + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyBag, OPropertyBag_Base, OPropertyBag_PBase ) + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > OPropertyBag::getSupportedServiceNames_static() throw( RuntimeException ) + { + Sequence< ::rtl::OUString > aServices(1); + aServices[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.PropertyBag" ) ); + return aServices; + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException) + { + ::comphelper::NamedValueCollection aArguments( _rArguments ); + + Sequence< Type > aTypes; + if ( aArguments.get_ensureType( "AllowedTypes", aTypes ) ) + ::std::copy( + aTypes.getConstArray(), + aTypes.getConstArray() + aTypes.getLength(), + ::std::insert_iterator< TypeBag >( m_aAllowedTypes, m_aAllowedTypes.begin() ) + ); + + aArguments.get_ensureType( "AutomaticAddition", m_bAutoAddProperties ); + bool AllowEmptyPropertyName(false); + aArguments.get_ensureType( "AllowEmptyPropertyName", + AllowEmptyPropertyName ); + if (AllowEmptyPropertyName) { + m_aDynamicProperties.setAllowEmptyPropertyName( + AllowEmptyPropertyName); + } + } + + //-------------------------------------------------------------------- + ::rtl::OUString OPropertyBag::getImplementationName_static() throw( RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.comphelper.OPropertyBag" ) ); + } + + //-------------------------------------------------------------------- + Reference< XInterface > SAL_CALL OPropertyBag::Create( const Reference< XComponentContext >& _rxContext ) + { + return *new OPropertyBag( _rxContext ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL OPropertyBag::getImplementationName() throw (RuntimeException) + { + return getImplementationName_static(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL OPropertyBag::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aServices( getSupportedServiceNames_static() ); + const ::rtl::OUString* pStart = aServices.getConstArray(); + const ::rtl::OUString* pEnd = aServices.getConstArray() + aServices.getLength(); + return ::std::find( pStart, pEnd, rServiceName ) != pEnd; + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL OPropertyBag::getSupportedServiceNames( ) throw (RuntimeException) + { + return getSupportedServiceNames_static(); + } + + //-------------------------------------------------------------------- + void OPropertyBag::fireEvents( + sal_Int32 * /*pnHandles*/, + sal_Int32 nCount, + sal_Bool bVetoable, + bool bIgnoreRuntimeExceptionsWhileFiring) + { + if (nCount && !bVetoable) { + setModifiedImpl(sal_True, bIgnoreRuntimeExceptionsWhileFiring); + } + } + + void OPropertyBag::setModifiedImpl(::sal_Bool bModified, + bool bIgnoreRuntimeExceptionsWhileFiring) + { + { // do not lock mutex while notifying (#i93514#) to prevent deadlock + ::osl::MutexGuard aGuard( m_aMutex ); + m_isModified = bModified; + } + if (bModified) { + try { + Reference<XInterface> xThis(*this); + EventObject event(xThis); + m_NotifyListeners.notifyEach( + &XModifyListener::modified, event); + } catch (RuntimeException &) { + if (!bIgnoreRuntimeExceptionsWhileFiring) { + throw; + } + } catch (Exception &) { + // ignore + } + } + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL OPropertyBag::isModified() + throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + return m_isModified; + } + + void SAL_CALL OPropertyBag::setModified( ::sal_Bool bModified ) + throw (PropertyVetoException, RuntimeException) + { + setModifiedImpl(bModified, false); + } + + void SAL_CALL OPropertyBag::addModifyListener( + const Reference< XModifyListener > & xListener) + throw (RuntimeException) + { + m_NotifyListeners.addInterface(xListener); + } + + void SAL_CALL OPropertyBag::removeModifyListener( + const Reference< XModifyListener > & xListener) + throw (RuntimeException) + { + m_NotifyListeners.removeInterface(xListener); + } + + //-------------------------------------------------------------------- + Reference< XPropertySetInfo > SAL_CALL OPropertyBag::getPropertySetInfo( ) throw(RuntimeException) + { + return createPropertySetInfo( getInfoHelper() ); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL OPropertyBag::has( const Any& /*aElement*/ ) throw (RuntimeException) + { + // XSet is only a workaround for addProperty not being able to add default-void properties. + // So, everything of XSet except insert is implemented empty + return sal_False; + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::insert( const Any& _element ) throw (IllegalArgumentException, ElementExistException, RuntimeException) + { + // This is a workaround for addProperty not being able to add default-void properties. + // If we ever have a smarter XPropertyContainer::addProperty interface, we can remove this, ehm, well, hack. + Property aProperty; + if ( !( _element >>= aProperty ) ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + ::osl::ClearableMutexGuard g( m_aMutex ); + + // check whether the type is allowed, everything else will be checked + // by m_aDynamicProperties + if ( !m_aAllowedTypes.empty() + && m_aAllowedTypes.find( aProperty.Type ) == m_aAllowedTypes.end() + ) + throw IllegalTypeException( ::rtl::OUString(), *this ); + + m_aDynamicProperties.addVoidProperty( aProperty.Name, aProperty.Type, findFreeHandle(), aProperty.Attributes ); + + // our property info is dirty + m_pArrayHelper.reset(); + + g.clear(); + setModified(sal_True); + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::remove( const Any& /*aElement*/ ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException) + { + // XSet is only a workaround for addProperty not being able to add default-void properties. + // So, everything of XSet except insert is implemented empty + throw NoSuchElementException( ::rtl::OUString(), *this ); + } + + + //-------------------------------------------------------------------- + Reference< XEnumeration > SAL_CALL OPropertyBag::createEnumeration( ) throw (RuntimeException) + { + // XSet is only a workaround for addProperty not being able to add default-void properties. + // So, everything of XSet except insert is implemented empty + return NULL; + } + + //-------------------------------------------------------------------- + Type SAL_CALL OPropertyBag::getElementType( ) throw (RuntimeException) + { + // XSet is only a workaround for addProperty not being able to add default-void properties. + // So, everything of XSet except insert is implemented empty + return Type(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL OPropertyBag::hasElements( ) throw (RuntimeException) + { + // XSet is only a workaround for addProperty not being able to add default-void properties. + // So, everything of XSet except insert is implemented empty + return sal_False; + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const + { + m_aDynamicProperties.getFastPropertyValue( _nHandle, _rValue ); + } + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL OPropertyBag::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException) + { + return m_aDynamicProperties.convertFastPropertyValue( _nHandle, _rValue, _rConvertedValue, _rOldValue ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception) + { + m_aDynamicProperties.setFastPropertyValue( nHandle, rValue ); + } + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& SAL_CALL OPropertyBag::getInfoHelper() + { + if ( !m_pArrayHelper.get() ) + { + Sequence< Property > aProperties; + m_aDynamicProperties.describeProperties( aProperties ); + m_pArrayHelper.reset( new ::cppu::OPropertyArrayHelper( aProperties ) ); + } + return *m_pArrayHelper; + + } + + //-------------------------------------------------------------------- + sal_Int32 OPropertyBag::findFreeHandle() const + { + const sal_Int32 nPrime = 1009; + const sal_Int32 nSeed = 11; + + sal_Int32 nCheck = nSeed; + while ( m_aDynamicProperties.hasPropertyByHandle( nCheck ) && ( nCheck != 1 ) ) + { + nCheck = ( nCheck * nSeed ) % nPrime; + } + + if ( nCheck == 1 ) + { // uh ... we already have 1008 handles used up + // -> simply count upwards + while ( m_aDynamicProperties.hasPropertyByHandle( nCheck ) ) + ++nCheck; + } + + return nCheck; + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException) + { + ::osl::ClearableMutexGuard g( m_aMutex ); + + // check whether the type is allowed, everything else will be checked + // by m_aDynamicProperties + Type aPropertyType = _rInitialValue.getValueType(); + if ( _rInitialValue.hasValue() + && !m_aAllowedTypes.empty() + && m_aAllowedTypes.find( aPropertyType ) == m_aAllowedTypes.end() + ) + throw IllegalTypeException( ::rtl::OUString(), *this ); + + m_aDynamicProperties.addProperty( _rName, findFreeHandle(), _nAttributes, _rInitialValue ); + + // our property info is dirty + m_pArrayHelper.reset(); + + g.clear(); + setModified(sal_True); + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::removeProperty( const ::rtl::OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException) + { + ::osl::ClearableMutexGuard g( m_aMutex ); + + m_aDynamicProperties.removeProperty( _rName ); + + // our property info is dirty + m_pArrayHelper.reset(); + + g.clear(); + setModified(sal_True); + } + + //-------------------------------------------------------------------- + namespace + { + struct ComparePropertyValueByName : public ::std::binary_function< PropertyValue, PropertyValue, bool > + { + bool operator()( const PropertyValue& _rLHS, const PropertyValue& _rRHS ) + { + return _rLHS.Name < _rRHS.Name; + } + }; + + template< typename CLASS > + struct TransformPropertyToName : public ::std::unary_function< CLASS, ::rtl::OUString > + { + const ::rtl::OUString& operator()( const CLASS& _rProp ) + { + return _rProp.Name; + } + }; + + struct ExtractPropertyValue : public ::std::unary_function< PropertyValue, Any > + { + const Any& operator()( const PropertyValue& _rProp ) + { + return _rProp.Value; + } + }; + } + + //-------------------------------------------------------------------- + Sequence< PropertyValue > SAL_CALL OPropertyBag::getPropertyValues( ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // all registered properties + Sequence< Property > aProperties; + m_aDynamicProperties.describeProperties( aProperties ); + + // their names + Sequence< ::rtl::OUString > aNames( aProperties.getLength() ); + ::std::transform( + aProperties.getConstArray(), + aProperties.getConstArray() + aProperties.getLength(), + aNames.getArray(), + TransformPropertyToName< Property >() + ); + + // their values + Sequence< Any > aValues; + try + { + aValues = OPropertyBag_PBase::getPropertyValues( aNames ); + if ( aValues.getLength() != aNames.getLength() ) + throw RuntimeException(); + } + catch( const RuntimeException& ) + { + throw; + } + catch( const Exception& ) + { + // ignore + } + + // merge names and values, and retrieve the state/handle + ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper(); + + Sequence< PropertyValue > aPropertyValues( aNames.getLength() ); + const ::rtl::OUString* pName = aNames.getConstArray(); + const ::rtl::OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength(); + const Any* pValue = aValues.getArray(); + PropertyValue* pPropertyValue = aPropertyValues.getArray(); + + for ( ; pName != pNamesEnd; ++pName, ++pValue, ++pPropertyValue ) + { + pPropertyValue->Name = *pName; + pPropertyValue->Handle = rPropInfo.getHandleByName( *pName ); + pPropertyValue->Value = *pValue; + pPropertyValue->State = getPropertyStateByHandle( pPropertyValue->Handle ); + } + + return aPropertyValues; + } + + //-------------------------------------------------------------------- + void OPropertyBag::impl_setPropertyValues_throw( const Sequence< PropertyValue >& _rProps ) + { + // sort (the XMultiPropertySet interface requires this) + Sequence< PropertyValue > aProperties( _rProps ); + ::std::sort( + aProperties.getArray(), + aProperties.getArray() + aProperties.getLength(), + ComparePropertyValueByName() + ); + + // a sequence of names + Sequence< ::rtl::OUString > aNames( aProperties.getLength() ); + ::std::transform( + aProperties.getConstArray(), + aProperties.getConstArray() + aProperties.getLength(), + aNames.getArray(), + TransformPropertyToName< PropertyValue >() + ); + + try + { + // check for unknown properties + // we cannot simply rely on the XMultiPropertySet::setPropertyValues + // implementation of our base class, since it does not throw + // an UnknownPropertyException. More precise, XMultiPropertySet::setPropertyValues + // does not allow to throw this exception, while XPropertyAccess::setPropertyValues + // requires it + sal_Int32 nCount = aNames.getLength(); + + Sequence< sal_Int32 > aHandles( nCount ); + sal_Int32* pHandle = aHandles.getArray(); + const PropertyValue* pProperty = aProperties.getConstArray(); + for ( const ::rtl::OUString* pName = aNames.getConstArray(); + pName != aNames.getConstArray() + aNames.getLength(); + ++pName, ++pHandle, ++pProperty + ) + { + ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper(); + *pHandle = rPropInfo.getHandleByName( *pName ); + if ( *pHandle != -1 ) + continue; + + // there's a property requested which we do not know + if ( m_bAutoAddProperties ) + { + // add the property + sal_Int16 nAttributes = PropertyAttribute::BOUND | PropertyAttribute::REMOVEABLE | PropertyAttribute::MAYBEDEFAULT; + addProperty( *pName, nAttributes, pProperty->Value ); + continue; + } + + // no way out + throw UnknownPropertyException( *pName, *this ); + } + + // a sequence of values + Sequence< Any > aValues( aProperties.getLength() ); + ::std::transform( + aProperties.getConstArray(), + aProperties.getConstArray() + aProperties.getLength(), + aValues.getArray(), + ExtractPropertyValue() + ); + + setFastPropertyValues( nCount, aHandles.getArray(), aValues.getConstArray(), nCount ); + } + catch( const PropertyVetoException& ) { throw; } + catch( const IllegalArgumentException& ) { throw; } + catch( const WrappedTargetException& ) { throw; } + catch( const RuntimeException& ) { throw; } + catch( const UnknownPropertyException& ) { throw; } + catch( const Exception& ) + { + throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() ); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + impl_setPropertyValues_throw( _rProps ); + } + + //-------------------------------------------------------------------- + PropertyState OPropertyBag::getPropertyStateByHandle( sal_Int32 _nHandle ) + { + // for properties which do not support the MAYBEDEFAULT attribute, don't rely on the base class, but + // assume they're always in DIRECT state. + // (Note that this probably would belong into the base class. However, this would mean we would need + // to check all existent usages of the base class, where MAYBEDEFAULT is *not* set, but + // a default is nonetheless supplied/used. This is hard to accomplish reliably, in the + // current phase. + // #i78593# / 2007-07-07 / frank.schoenheit@sun.com + + ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper(); + sal_Int16 nAttributes(0); + OSL_VERIFY( rPropInfo.fillPropertyMembersByHandle( NULL, &nAttributes, _nHandle ) ); + if ( ( nAttributes & PropertyAttribute::MAYBEDEFAULT ) == 0 ) + return PropertyState_DIRECT_VALUE; + + return OPropertyBag_PBase::getPropertyStateByHandle( _nHandle ); + } + + //-------------------------------------------------------------------- + Any OPropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const + { + Any aDefault; + m_aDynamicProperties.getPropertyDefaultByHandle( _nHandle, aDefault ); + return aDefault; + } + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/opropertybag.hxx b/comphelper/source/property/opropertybag.hxx new file mode 100644 index 000000000000..6d0a6e1f4f54 --- /dev/null +++ b/comphelper/source/property/opropertybag.hxx @@ -0,0 +1,245 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 COMPHELPER_OPROPERTYBAG_HXX +#define COMPHELPER_OPROPERTYBAG_HXX + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/container/XSet.hpp> +/** === end UNO includes === **/ + +#include <cppuhelper/implbase6.hxx> +#include <comphelper/propstate.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <comphelper/propertybag.hxx> +#include <comphelper/componentcontext.hxx> +#include <comphelper/uno3.hxx> + +#include <map> +#include <set> +#include <memory> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + struct SAL_DLLPRIVATE UnoTypeLess : public ::std::unary_function< ::com::sun::star::uno::Type, bool > + { + inline bool operator()( const ::com::sun::star::uno::Type& _rLHS, const ::com::sun::star::uno::Type& _rRHS ) const + { + return rtl_ustr_compare( + _rLHS.getTypeLibType()->pTypeName->buffer, + _rRHS.getTypeLibType()->pTypeName->buffer + ) < 0; + } + }; + + typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > MapInt2Any; + typedef ::std::set< ::com::sun::star::uno::Type, UnoTypeLess > TypeBag; + + //==================================================================== + //= OPropertyBag + //==================================================================== + typedef ::cppu::WeakAggImplHelper6 < ::com::sun::star::beans::XPropertyContainer + , ::com::sun::star::beans::XPropertyAccess + , ::com::sun::star::util::XModifiable + , ::com::sun::star::lang::XServiceInfo + , ::com::sun::star::lang::XInitialization + , ::com::sun::star::container::XSet + > OPropertyBag_Base; + typedef ::comphelper::OPropertyStateHelper OPropertyBag_PBase; + + class OPropertyBag :public ::comphelper::OMutexAndBroadcastHelper // must be before OPropertyBag_PBase + ,public OPropertyBag_PBase + ,public OPropertyBag_Base + ,public ::cppu::IEventNotificationHook + { + private: + ::comphelper::ComponentContext + m_aContext; + + /// our IPropertyArrayHelper implementation + ::std::auto_ptr< ::cppu::OPropertyArrayHelper > + m_pArrayHelper; + ::comphelper::PropertyBag + m_aDynamicProperties; + /// set of allowed property types + TypeBag m_aAllowedTypes; + /// should we automatically add properties which are tried to set, if they don't exist previously? + bool m_bAutoAddProperties; + + /// for notification + ::cppu::OInterfaceContainerHelper m_NotifyListeners; + /// modify flag + bool m_isModified; + + public: + OPropertyBag( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext ); + + // XServiceInfo - static versions + static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(void) throw( ::com::sun::star::uno::RuntimeException ); + static ::rtl::OUString getImplementationName_static(void) throw( ::com::sun::star::uno::RuntimeException ); + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&); + + protected: + virtual ~OPropertyBag(); + DECLARE_XINTERFACE() + DECLARE_XTYPEPROVIDER() + + /** === begin UNO interface implementations == **/ + // 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); + + // 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); + + // XModifiable: + virtual ::sal_Bool SAL_CALL isModified( ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setModified( ::sal_Bool bModified ) + throw (::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::uno::RuntimeException); + + // XModifyBroadcaster + virtual void SAL_CALL addModifyListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::util::XModifyListener > & xListener) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::util::XModifyListener > & xListener) + throw (::com::sun::star::uno::RuntimeException); + + // XPropertyContainer + virtual void SAL_CALL addProperty( const ::rtl::OUString& Name, ::sal_Int16 Attributes, const ::com::sun::star::uno::Any& DefaultValue ) throw (::com::sun::star::beans::PropertyExistException, ::com::sun::star::beans::IllegalTypeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeProperty( const ::rtl::OUString& Name ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::NotRemoveableException, ::com::sun::star::uno::RuntimeException); + + // XPropertyAccess + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException); + + // XSet + virtual ::sal_Bool SAL_CALL has( const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insert( const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL remove( const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); + + // XEnumerationAccess (base of XSet) + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createEnumeration( ) throw (::com::sun::star::uno::RuntimeException); + + // XElementAccess (basf of XEnumerationAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException); + /** === UNO interface implementations == **/ + + // XPropertyState + virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 _nHandle ) const; + + // OPropertyStateHelper + virtual ::com::sun::star::beans::PropertyState getPropertyStateByHandle( sal_Int32 _nHandle ); + + // OPropertySetHelper + virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const; + virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any & rConvertedValue, ::com::sun::star::uno::Any & rOldValue, sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::lang::IllegalArgumentException); + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception); + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); + + // IEventNotificationHook + virtual void fireEvents( + sal_Int32 * pnHandles, + sal_Int32 nCount, + sal_Bool bVetoable, + bool bIgnoreRuntimeExceptionsWhileFiring); + + void SAL_CALL setModifiedImpl( ::sal_Bool bModified, + bool bIgnoreRuntimeExceptionsWhileFiring); + + private: + /** finds a free property handle + @precond + our mutex is locked + */ + sal_Int32 findFreeHandle() const; + + /** implements the setPropertyValues method + @param _rProps + the property values to set + + @throws PropertyVetoException + if the XMultiPropertySet::setPropertyValues call does so + + @throws ::com::sun::star::lang::IllegalArgumentException + if the XMultiPropertySet::setPropertyValues call does so + + @throws ::com::sun::star::lang::WrappedTargetException + if the XMultiPropertySet::setPropertyValues call does so + + @throws ::com::sun::star::uno::RuntimeException + if the XMultiPropertySet::setPropertyValues call does so + + @throws ::com::sun::star::beans::UnknownPropertyException + if the XMultiPropertySet::setPropertyValues call does so, and <arg>_bTolerateUnknownProperties</arg> + was set to <FALSE/> + + @throws ::com::sun::star::lang::WrappedTargetException + if the XMultiPropertySet::setPropertyValues call did throw an exception not listed + above + */ + void impl_setPropertyValues_throw( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rProps ); + + private: + OPropertyBag(); // never implemented + OPropertyBag( const OPropertyBag& ); // never implemented + OPropertyBag& operator=( const OPropertyBag& ); // never implemented + protected: + using ::cppu::OPropertySetHelper::getPropertyValues; + using ::cppu::OPropertySetHelper::setPropertyValues; + using ::cppu::OPropertySetHelper::getFastPropertyValue; + }; + +//........................................................................ +} // namespace comphelper +//........................................................................ + +#endif // COMPHELPER_OPROPERTYBAG_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propagg.cxx b/comphelper/source/property/propagg.cxx new file mode 100644 index 000000000000..945ace837808 --- /dev/null +++ b/comphelper/source/property/propagg.cxx @@ -0,0 +1,1049 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "comphelper/propagg.hxx" +#include "comphelper/property.hxx" +#include <cppuhelper/queryinterface.hxx> +#include <osl/diagnose.h> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#if OSL_DEBUG_LEVEL > 0 +#include <typeinfo> +#include <rtl/strbuf.hxx> +#endif + +#include <algorithm> +#include <set> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + + using namespace internal; + + //------------------------------------------------------------------------------ + namespace + { + const Property* lcl_findPropertyByName( const Sequence< Property >& _rProps, const ::rtl::OUString& _rName ) + { + sal_Int32 nLen = _rProps.getLength(); + const Property* pProperties = _rProps.getConstArray(); + Property aNameProp(_rName, 0, Type(), 0); + const Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen, aNameProp, PropertyCompareByName()); + if ( pResult && ( pResult == pProperties + nLen || pResult->Name != _rName) ) + pResult = NULL; + + return pResult; + } + } +//================================================================== +//= OPropertyArrayAggregationHelper +//================================================================== + +//------------------------------------------------------------------------------ +OPropertyArrayAggregationHelper::OPropertyArrayAggregationHelper( + const Sequence< Property >& _rProperties, const Sequence< Property >& _rAggProperties, + IPropertyInfoService* _pInfoService, sal_Int32 _nFirstAggregateId ) + :m_aProperties( _rProperties ) +{ + sal_Int32 nDelegatorProps = _rProperties.getLength(); + sal_Int32 nAggregateProps = _rAggProperties.getLength(); + + // make room for all properties + sal_Int32 nMergedProps = nDelegatorProps + nAggregateProps; + m_aProperties.realloc( nMergedProps ); + + const Property* pAggregateProps = _rAggProperties.getConstArray(); + const Property* pDelegateProps = _rProperties.getConstArray(); + Property* pMergedProps = m_aProperties.getArray(); + + // if properties are present both at the delegatee and the aggregate, then the former are supposed to win. + // So, we'll need an existence check. + ::std::set< ::rtl::OUString > aDelegatorProps; + + // create the map for the delegator properties + sal_Int32 nMPLoop = 0; + for ( ; nMPLoop < nDelegatorProps; ++nMPLoop, ++pDelegateProps ) + { + m_aPropertyAccessors[ pDelegateProps->Handle ] = OPropertyAccessor( -1, nMPLoop, sal_False ); + OSL_ENSURE( aDelegatorProps.find( pDelegateProps->Name ) == aDelegatorProps.end(), + "OPropertyArrayAggregationHelper::OPropertyArrayAggregationHelper: duplicate delegatee property!" ); + aDelegatorProps.insert( pDelegateProps->Name ); + } + + // create the map for the aggregate properties + sal_Int32 nAggregateHandle = _nFirstAggregateId; + pMergedProps += nDelegatorProps; + for ( ; nMPLoop < nMergedProps; ++pAggregateProps ) + { + // if the aggregate property is present at the delegatee already, ignore it + if ( aDelegatorProps.find( pAggregateProps->Name ) != aDelegatorProps.end() ) + { + --nMergedProps; + continue; + } + + // next aggregate property - remember it + *pMergedProps = *pAggregateProps; + + // determine the handle for the property which we will expose to the outside world + sal_Int32 nHandle = -1; + // ask the infor service first + if ( _pInfoService ) + nHandle = _pInfoService->getPreferedPropertyId( pMergedProps->Name ); + + if ( -1 == nHandle ) + // no handle from the info service -> default + nHandle = nAggregateHandle++; + else + { // check if we alread have a property with the given handle + const Property* pPropsTilNow = m_aProperties.getConstArray(); + for ( sal_Int32 nCheck = 0; nCheck < nMPLoop; ++nCheck, ++pPropsTilNow ) + if ( pPropsTilNow->Handle == nHandle ) + { // conflicts -> use another one (which we don't check anymore, assuming _nFirstAggregateId was large enough) + nHandle = nAggregateHandle++; + break; + } + } + + // remember the accessor for this property + m_aPropertyAccessors[ nHandle ] = OPropertyAccessor( pMergedProps->Handle, nMPLoop, sal_True ); + pMergedProps->Handle = nHandle; + + ++nMPLoop; + ++pMergedProps; + } + m_aProperties.realloc( nMergedProps ); + pMergedProps = m_aProperties.getArray(); // reset, needed again below + + // sortieren der Properties nach Namen + ::std::sort( pMergedProps, pMergedProps+nMergedProps, PropertyCompareByName()); + + pMergedProps = m_aProperties.getArray(); + + // Positionen in der Map abgleichen + for ( nMPLoop = 0; nMPLoop < nMergedProps; ++nMPLoop, ++pMergedProps ) + m_aPropertyAccessors[ pMergedProps->Handle ].nPos = nMPLoop; +} + +//------------------------------------------------------------------ +OPropertyArrayAggregationHelper::PropertyOrigin OPropertyArrayAggregationHelper::classifyProperty( const ::rtl::OUString& _rName ) +{ + PropertyOrigin eOrigin = UNKNOWN_PROPERTY; + // look up the name + const Property* pPropertyDescriptor = lcl_findPropertyByName( m_aProperties, _rName ); + if ( pPropertyDescriptor ) + { + // look up the handle for this name + ConstPropertyAccessorMapIterator aPos = m_aPropertyAccessors.find( pPropertyDescriptor->Handle ); + OSL_ENSURE( m_aPropertyAccessors.end() != aPos, "OPropertyArrayAggregationHelper::classifyProperty: should have this handle in my map!" ); + if ( m_aPropertyAccessors.end() != aPos ) + { + eOrigin = aPos->second.bAggregate ? AGGREGATE_PROPERTY : DELEGATOR_PROPERTY; + } + } + return eOrigin; +} + +//------------------------------------------------------------------ +Property OPropertyArrayAggregationHelper::getPropertyByName( const ::rtl::OUString& _rPropertyName ) throw( UnknownPropertyException ) +{ + const Property* pProperty = findPropertyByName( _rPropertyName ); + + if ( !pProperty ) + throw UnknownPropertyException(); + + return *pProperty; +} + +//------------------------------------------------------------------------------ +sal_Bool OPropertyArrayAggregationHelper::hasPropertyByName(const ::rtl::OUString& _rPropertyName) +{ + return NULL != findPropertyByName( _rPropertyName ); +} + +//------------------------------------------------------------------------------ +const Property* OPropertyArrayAggregationHelper::findPropertyByName(const :: rtl::OUString& _rName ) const +{ + return lcl_findPropertyByName( m_aProperties, _rName ); +} + +//------------------------------------------------------------------------------ +sal_Int32 OPropertyArrayAggregationHelper::getHandleByName(const ::rtl::OUString& _rPropertyName) +{ + const Property* pProperty = findPropertyByName( _rPropertyName ); + return pProperty ? pProperty->Handle : -1; +} + +//------------------------------------------------------------------------------ +sal_Bool OPropertyArrayAggregationHelper::fillPropertyMembersByHandle( + ::rtl::OUString* _pPropName, sal_Int16* _pAttributes, sal_Int32 _nHandle) +{ + ConstPropertyAccessorMapIterator i = m_aPropertyAccessors.find(_nHandle); + sal_Bool bRet = i != m_aPropertyAccessors.end(); + if (bRet) + { + const ::com::sun::star::beans::Property& rProperty = m_aProperties.getConstArray()[(*i).second.nPos]; + if (_pPropName) + *_pPropName = rProperty.Name; + if (_pAttributes) + *_pAttributes = rProperty.Attributes; + } + return bRet; +} + +//------------------------------------------------------------------------------ +sal_Bool OPropertyArrayAggregationHelper::getPropertyByHandle( sal_Int32 _nHandle, Property& _rProperty ) const +{ + ConstPropertyAccessorMapIterator pos = m_aPropertyAccessors.find(_nHandle); + if ( pos != m_aPropertyAccessors.end() ) + { + _rProperty = m_aProperties[ pos->second.nPos ]; + return sal_True; + } + return sal_False; +} + +//------------------------------------------------------------------------------ +sal_Bool OPropertyArrayAggregationHelper::fillAggregatePropertyInfoByHandle( + ::rtl::OUString* _pPropName, sal_Int32* _pOriginalHandle, sal_Int32 _nHandle) const +{ + ConstPropertyAccessorMapIterator i = m_aPropertyAccessors.find(_nHandle); + sal_Bool bRet = i != m_aPropertyAccessors.end() && (*i).second.bAggregate; + if (bRet) + { + if (_pOriginalHandle) + *_pOriginalHandle = (*i).second.nOriginalHandle; + if (_pPropName) + { + OSL_ENSURE((*i).second.nPos < m_aProperties.getLength(),"Invalid index for sequence!"); + const ::com::sun::star::beans::Property& rProperty = m_aProperties.getConstArray()[(*i).second.nPos]; + *_pPropName = rProperty.Name; + } + } + return bRet; +} + + +//------------------------------------------------------------------------------ + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> OPropertyArrayAggregationHelper::getProperties() +{ + return m_aProperties; +} + + +//------------------------------------------------------------------------------ +sal_Int32 OPropertyArrayAggregationHelper::fillHandles( + sal_Int32* _pHandles, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropNames ) +{ + sal_Int32 nHitCount = 0; + const ::rtl::OUString* pReqProps = _rPropNames.getConstArray(); + sal_Int32 nReqLen = _rPropNames.getLength(); + +#if OSL_DEBUG_LEVEL > 0 + // assure that the sequence is sorted + { + const ::rtl::OUString* pLookup = _rPropNames.getConstArray(); + const ::rtl::OUString* pEnd = _rPropNames.getConstArray() + _rPropNames.getLength() - 1; + for (; pLookup < pEnd; ++pLookup) + { + const ::rtl::OUString* pCompare = pLookup + 1; + const ::rtl::OUString* pCompareEnd = pEnd + 1; + for (; pCompare < pCompareEnd; ++pCompare) + { + OSL_ENSURE(pLookup->compareTo(*pCompare) < 0, "OPropertyArrayAggregationHelper::fillHandles : property names are not sorted!"); + } + } + } +#endif + + const ::com::sun::star::beans::Property* pCur = m_aProperties.getConstArray(); + const ::com::sun::star::beans::Property* pEnd = m_aProperties.getConstArray() + m_aProperties.getLength(); + + for( sal_Int32 i = 0; i < nReqLen; ++i ) + { + // Logarithmus ermitteln + sal_uInt32 n = (sal_uInt32)(pEnd - pCur); + sal_Int32 nLog = 0; + while( n ) + { + nLog += 1; + n = n >> 1; + } + + // Anzahl der noch zu suchenden Properties * dem Log2 der verbleibenden + // zu dursuchenden Properties. + if( (nReqLen - i) * nLog >= pEnd - pCur ) + { + // linear search is better + while( pCur < pEnd && pReqProps[i] > pCur->Name ) + { + pCur++; + } + if( pCur < pEnd && pReqProps[i] == pCur->Name ) + { + _pHandles[i] = pCur->Handle; + nHitCount++; + } + else + _pHandles[i] = -1; + } + else + { + // binary search is better + sal_Int32 nCompVal = 1; + const ::com::sun::star::beans::Property* pOldEnd = pEnd--; + const ::com::sun::star::beans::Property* pMid = pCur; + + while( nCompVal != 0 && pCur <= pEnd ) + { + pMid = (pEnd - pCur) / 2 + pCur; + + nCompVal = pReqProps[i].compareTo( pMid->Name ); + + if( nCompVal > 0 ) + pCur = pMid + 1; + else + pEnd = pMid - 1; + } + + if( nCompVal == 0 ) + { + _pHandles[i] = pMid->Handle; + nHitCount++; + pCur = pMid +1; + } + else if( nCompVal > 0 ) + { + _pHandles[i] = -1; + pCur = pMid + 1; + } + else + { + _pHandles[i] = -1; + pCur = pMid; + } + pEnd = pOldEnd; + } + } + return nHitCount; +} + +//================================================================== +//= PropertyForwarder +//================================================================== +namespace internal +{ + class PropertyForwarder + { + private: + OPropertySetAggregationHelper& m_rAggregationHelper; + ::std::set< sal_Int32 > m_aProperties; + sal_Int32 m_nCurrentlyForwarding; + + public: + PropertyForwarder( OPropertySetAggregationHelper& _rAggregationHelper ); + ~PropertyForwarder(); + + /** declares that the forwarder should be responsible for the given property + + @param _nHandle + the public handle (<em>not</em> the original handle!) of the property + */ + void takeResponsibilityFor( sal_Int32 _nHandle ); + + /** checks whether the forwarder is responsible for the given property + */ + bool isResponsibleFor( sal_Int32 _nHandle ); + + /// actually forwards a property value to the aggregate + void doForward( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception ); + + sal_Int32 getCurrentlyForwardedProperty( ) const { return m_nCurrentlyForwarding; } + }; + + //-------------------------------------------------------------------------- + PropertyForwarder::PropertyForwarder( OPropertySetAggregationHelper& _rAggregationHelper ) + :m_rAggregationHelper( _rAggregationHelper ) + ,m_nCurrentlyForwarding( -1 ) + { + } + + //-------------------------------------------------------------------------- + PropertyForwarder::~PropertyForwarder() + { + } + + //-------------------------------------------------------------------------- + void PropertyForwarder::takeResponsibilityFor( sal_Int32 _nHandle ) + { + m_aProperties.insert( _nHandle ); + } + + //-------------------------------------------------------------------------- + bool PropertyForwarder::isResponsibleFor( sal_Int32 _nHandle ) + { + return m_aProperties.find( _nHandle ) != m_aProperties.end(); + } + + //-------------------------------------------------------------------------- + void PropertyForwarder::doForward( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception ) + { + OSL_ENSURE( m_rAggregationHelper.m_xAggregateSet.is(), "PropertyForwarder::doForward: no property set!" ); + if ( m_rAggregationHelper.m_xAggregateSet.is() ) + { + m_rAggregationHelper.forwardingPropertyValue( _nHandle ); + + OSL_ENSURE( m_nCurrentlyForwarding == -1, "PropertyForwarder::doForward: reentrance?" ); + m_nCurrentlyForwarding = _nHandle; + + try + { + m_rAggregationHelper.m_xAggregateSet->setPropertyValue( m_rAggregationHelper.getPropertyName( _nHandle ), _rValue ); + // TODO: cache the property name? (it's a O(log n) search) + } + catch( const Exception& ) + { + m_rAggregationHelper.forwardedPropertyValue( _nHandle, false ); + throw; + } + + m_nCurrentlyForwarding = -1; + + m_rAggregationHelper.forwardedPropertyValue( _nHandle, true ); + } + } +} + +//================================================================== +//= OPropertySetAggregationHelper +//================================================================== + +//------------------------------------------------------------------------------ +OPropertySetAggregationHelper::OPropertySetAggregationHelper( ::cppu::OBroadcastHelper& rBHlp ) + :OPropertyStateHelper( rBHlp ) + ,m_bListening( sal_False ) +{ + m_pForwarder = new PropertyForwarder( *this ); +} + +//------------------------------------------------------------------------------ +OPropertySetAggregationHelper::~OPropertySetAggregationHelper() +{ + delete m_pForwarder; +} + +//------------------------------------------------------------------------------ + ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::queryInterface(const ::com::sun::star::uno::Type& _rType) throw( ::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aReturn = OPropertyStateHelper::queryInterface(_rType); + + if ( !aReturn.hasValue() ) + aReturn = cppu::queryInterface(_rType + ,static_cast< ::com::sun::star::beans::XPropertiesChangeListener*>(this) + ,static_cast< ::com::sun::star::beans::XVetoableChangeListener*>(this) + ,static_cast< ::com::sun::star::lang::XEventListener*>(static_cast< ::com::sun::star::beans::XPropertiesChangeListener*>(this)) + ); + + return aReturn; +} + +//------------------------------------------------------------------------------ +void OPropertySetAggregationHelper::disposing() +{ + osl::MutexGuard aGuard(rBHelper.rMutex); + + if ( m_xAggregateSet.is() && m_bListening ) + { + // als einziger Listener anmelden + m_xAggregateMultiSet->removePropertiesChangeListener(this); + m_xAggregateSet->removeVetoableChangeListener(::rtl::OUString(), this); + m_bListening = sal_False; + } + + OPropertyStateHelper::disposing(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::disposing(const ::com::sun::star::lang::EventObject& _rSource) throw ( ::com::sun::star::uno::RuntimeException) +{ + OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::disposing : don't have an aggregate anymore !"); + if (_rSource.Source == m_xAggregateSet) + m_bListening = sal_False; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::propertiesChange(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent>& _rEvents) throw( ::com::sun::star::uno::RuntimeException) +{ + OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::propertiesChange : have no aggregate !"); + + sal_Int32 nLen = _rEvents.getLength(); + cppu::IPropertyArrayHelper& rPH = getInfoHelper(); + + if (1 == nLen) + { + const ::com::sun::star::beans::PropertyChangeEvent& evt = _rEvents.getConstArray()[0]; + OSL_ENSURE(evt.PropertyName.getLength() > 0, "OPropertySetAggregationHelper::propertiesChange : invalid event !"); + // we had a bug where this assertion would have us saved a whole day :) (72514) + sal_Int32 nHandle = rPH.getHandleByName( evt.PropertyName ); + + // If nHandle is -1 the event marks a (aggregate) property which we hide to callers + // If isCurrentlyForwardingProperty( nHandle ) is <TRUE/>, then we ourself triggered + // setting this property. In this case, it will be notified later (by the OPropertySetHelper + // implementation) + + if ( ( nHandle != -1 ) && !isCurrentlyForwardingProperty( nHandle ) ) + fire(&nHandle, &evt.NewValue, &evt.OldValue, 1, sal_False); + } + else + { + sal_Int32* pHandles = new sal_Int32[nLen]; + ::com::sun::star::uno::Any* pNewValues = new ::com::sun::star::uno::Any[nLen]; + ::com::sun::star::uno::Any* pOldValues = new ::com::sun::star::uno::Any[nLen]; + + const ::com::sun::star::beans::PropertyChangeEvent* pEvents = _rEvents.getConstArray(); + sal_Int32 nDest = 0; + for (sal_Int32 nSource=0; nSource<nLen; ++nSource, ++pEvents) + { + sal_Int32 nHandle = rPH.getHandleByName(pEvents->PropertyName); + if ( ( nHandle != -1 ) && !isCurrentlyForwardingProperty( nHandle ) ) + { // same as above : -1 is valid (73247) ... + pHandles[nDest] = nHandle; + pNewValues[nDest] = pEvents->NewValue; + pOldValues[nDest] = pEvents->OldValue; + ++nDest; + } + } + + if (nDest) + fire(pHandles, pNewValues, pOldValues, nDest, sal_False); + + delete[] pHandles; + delete[] pNewValues; + delete[] pOldValues; + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::vetoableChange(const ::com::sun::star::beans::PropertyChangeEvent& _rEvent) throw( ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException) +{ + OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::vetoableChange : have no aggregate !"); + + cppu::IPropertyArrayHelper& rPH = getInfoHelper(); + + sal_Int32 nHandle = rPH.getHandleByName(_rEvent.PropertyName); + fire(&nHandle, &_rEvent.NewValue, &_rEvent.OldValue, 1, sal_True); +} + +//------------------------------------------------------------------------------ +void OPropertySetAggregationHelper::setAggregation(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxDelegate) + throw( ::com::sun::star::lang::IllegalArgumentException ) +{ + osl::MutexGuard aGuard(rBHelper.rMutex); + + if (m_bListening && m_xAggregateSet.is()) + { + m_xAggregateMultiSet->removePropertiesChangeListener(this); + m_xAggregateSet->removeVetoableChangeListener(::rtl::OUString(), this); + m_bListening = sal_False; + } + + m_xAggregateState = m_xAggregateState.query( _rxDelegate ); + m_xAggregateSet = m_xAggregateSet.query( _rxDelegate ); + m_xAggregateMultiSet = m_xAggregateMultiSet.query( _rxDelegate ); + m_xAggregateFastSet = m_xAggregateFastSet.query( _rxDelegate ); + + // must support XPropertySet and XMultiPropertySet + if ( m_xAggregateSet.is() && !m_xAggregateMultiSet.is() ) + throw ::com::sun::star::lang::IllegalArgumentException(); +} + +//------------------------------------------------------------------------------ +void OPropertySetAggregationHelper::startListening() +{ + osl::MutexGuard aGuard(rBHelper.rMutex); + + if (!m_bListening && m_xAggregateSet.is()) + { + // als einziger Listener anmelden + ::com::sun::star::uno::Sequence< ::rtl::OUString > aPropertyNames; + m_xAggregateMultiSet->addPropertiesChangeListener(aPropertyNames, this); + m_xAggregateSet->addVetoableChangeListener(::rtl::OUString(), this); + + m_bListening = sal_True; + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::addVetoableChangeListener(const ::rtl::OUString& _rPropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener>& _rxListener) + throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + OPropertySetHelper::addVetoableChangeListener(_rPropertyName, _rxListener); + if (!m_bListening) + startListening(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::addPropertyChangeListener(const ::rtl::OUString& _rPropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener>& _rxListener) + throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + OPropertySetHelper::addPropertyChangeListener(_rPropertyName, _rxListener); + if (!m_bListening) + startListening(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::addPropertiesChangeListener(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropertyNames, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener>& _rxListener) + throw( ::com::sun::star::uno::RuntimeException) +{ + OPropertySetHelper::addPropertiesChangeListener(_rPropertyNames, _rxListener); + if (!m_bListening) + startListening(); +} + +//------------------------------------------------------------------------------ +sal_Int32 OPropertySetAggregationHelper::getOriginalHandle(sal_Int32 nHandle) const +{ + OPropertyArrayAggregationHelper& rPH = (OPropertyArrayAggregationHelper&)const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper(); + sal_Int32 nOriginalHandle = -1; + rPH.fillAggregatePropertyInfoByHandle(NULL, &nOriginalHandle, nHandle); + return nOriginalHandle; +} + +//-------------------------------------------------------------------------- +::rtl::OUString OPropertySetAggregationHelper::getPropertyName( sal_Int32 _nHandle ) const +{ + OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper() ); + Property aProperty; + OSL_VERIFY( rPH.getPropertyByHandle( _nHandle, aProperty ) ); + return aProperty.Name; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::setFastPropertyValue(sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue) + throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() ); + ::rtl::OUString aPropName; + sal_Int32 nOriginalHandle = -1; + + // does the handle belong to the aggregation ? + if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, _nHandle)) + if (m_xAggregateFastSet.is()) + m_xAggregateFastSet->setFastPropertyValue(nOriginalHandle, _rValue); + else + m_xAggregateSet->setPropertyValue(aPropName, _rValue); + else + OPropertySetHelper::setFastPropertyValue(_nHandle, _rValue); +} + +//------------------------------------------------------------------------------ +void OPropertySetAggregationHelper::getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const +{ + OPropertyArrayAggregationHelper& rPH = (OPropertyArrayAggregationHelper&)const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper(); + ::rtl::OUString aPropName; + sal_Int32 nOriginalHandle = -1; + + if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle)) + { + if (m_xAggregateFastSet.is()) + rValue = m_xAggregateFastSet->getFastPropertyValue(nOriginalHandle); + else + rValue = m_xAggregateSet->getPropertyValue(aPropName); + } + else if ( m_pForwarder->isResponsibleFor( nHandle ) ) + { + // this is a property which has been "overwritten" in our instance (thus + // fillAggregatePropertyInfoByHandle didn't find it) + rValue = m_xAggregateSet->getPropertyValue( getPropertyName( nHandle ) ); + } +} + +//------------------------------------------------------------------------------ + ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::getFastPropertyValue(sal_Int32 nHandle) + throw( ::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() ); + ::rtl::OUString aPropName; + sal_Int32 nOriginalHandle = -1; + ::com::sun::star::uno::Any aValue; + + if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle)) + { + if (m_xAggregateFastSet.is()) + aValue = m_xAggregateFastSet->getFastPropertyValue(nOriginalHandle); + else + aValue = m_xAggregateSet->getPropertyValue(aPropName); + } + else + aValue = OPropertySetHelper::getFastPropertyValue(nHandle); + + return aValue; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::setPropertyValues( + const Sequence< ::rtl::OUString >& _rPropertyNames, const Sequence< Any >& _rValues ) + throw ( PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ) +{ + OSL_ENSURE( !rBHelper.bInDispose, "OPropertySetAggregationHelper::setPropertyValues : do not use within the dispose call !"); + OSL_ENSURE( !rBHelper.bDisposed, "OPropertySetAggregationHelper::setPropertyValues : object is disposed" ); + + // check where the properties come from + if (!m_xAggregateSet.is()) + OPropertySetHelper::setPropertyValues(_rPropertyNames, _rValues); + else if (_rPropertyNames.getLength() == 1) // use the more efficient way + { + try + { + setPropertyValue( _rPropertyNames[0], _rValues[0] ); + } + catch( const UnknownPropertyException& ) + { + // by definition of XMultiPropertySet::setPropertyValues, unknown properties are to be ignored + #if OSL_DEBUG_LEVEL > 0 + ::rtl::OStringBuffer aMessage; + aMessage.append( "OPropertySetAggregationHelper::setPropertyValues: unknown property '" ); + aMessage.append( ::rtl::OUStringToOString( _rPropertyNames[0], RTL_TEXTENCODING_ASCII_US ) ); + aMessage.append( "'" ); + aMessage.append( "\n(implementation " ); + aMessage.append( typeid( *this ).name() ); + aMessage.append( ")" ); + OSL_FAIL( aMessage.getStr() ); + #endif + } + } + else + { + OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() ); + + // determine which properties belong to the aggregate, and which ones to the delegator + const ::rtl::OUString* pNames = _rPropertyNames.getConstArray(); + sal_Int32 nAggCount(0); + sal_Int32 nLen(_rPropertyNames.getLength()); + + for ( sal_Int32 i = 0; i < nLen; ++i, ++pNames ) + { + OPropertyArrayAggregationHelper::PropertyOrigin ePropOrg = rPH.classifyProperty( *pNames ); + if ( OPropertyArrayAggregationHelper::UNKNOWN_PROPERTY == ePropOrg ) + throw WrappedTargetException( ::rtl::OUString(), static_cast< XMultiPropertySet* >( this ), makeAny( UnknownPropertyException( ) ) ); + // due to a flaw in the API design, this method is not allowed to throw an UnknownPropertyException + // so we wrap it into a WrappedTargetException + + if ( OPropertyArrayAggregationHelper::AGGREGATE_PROPERTY == ePropOrg ) + ++nAggCount; + } + + pNames = _rPropertyNames.getConstArray(); // reset, we'll need it again below ... + + // all properties belong to the aggregate + if (nAggCount == nLen) + m_xAggregateMultiSet->setPropertyValues(_rPropertyNames, _rValues); + + // all properties belong to the aggregating object + else if (nAggCount == 0) + OPropertySetHelper::setPropertyValues(_rPropertyNames, _rValues); + + // mixed + else + { + const ::com::sun::star::uno::Any* pValues = _rValues.getConstArray(); + ::com::sun::star::uno::Any* pConvertedValues = NULL; + ::com::sun::star::uno::Any* pOldValues = NULL; + sal_Int32* pHandles = NULL; + + try + { + // dividing the Names and _rValues + + // aggregate's names + Sequence< ::rtl::OUString > AggPropertyNames( nAggCount ); + ::rtl::OUString* pAggNames = AggPropertyNames.getArray(); + // aggregate's values + Sequence< Any > AggValues( nAggCount ); + Any* pAggValues = AggValues.getArray(); + + // delegator names + Sequence< ::rtl::OUString > DelPropertyNames( nLen - nAggCount ); + ::rtl::OUString* pDelNames = DelPropertyNames.getArray(); + + // delegator values + Sequence< Any > DelValues( nLen - nAggCount ); + Any* pDelValues = DelValues.getArray(); + + for ( sal_Int32 i = 0; i < nLen; ++i, ++pNames, ++pValues ) + { + if ( OPropertyArrayAggregationHelper::AGGREGATE_PROPERTY == rPH.classifyProperty( *pNames ) ) + { + *pAggNames++ = *pNames; + *pAggValues++ = *pValues; + } + else + { + *pDelNames++ = *pNames; + *pDelValues++ = *pValues; + } + } + + // reset, needed below + pDelValues = DelValues.getArray(); + + pHandles = new sal_Int32[ nLen - nAggCount ]; + + // get the map table + cppu::IPropertyArrayHelper& rPH2 = getInfoHelper(); + + // fill the handle array + sal_Int32 nHitCount = rPH2.fillHandles( pHandles, DelPropertyNames ); + if (nHitCount != 0) + { + + pConvertedValues = new ::com::sun::star::uno::Any[ nHitCount ]; + pOldValues = new ::com::sun::star::uno::Any[ nHitCount ]; + nHitCount = 0; + sal_Int32 i; + + { + // must lock the mutex outside the loop. So all values are consistent. + osl::MutexGuard aGuard( rBHelper.rMutex ); + for( i = 0; i < (nLen - nAggCount); ++i ) + { + if( pHandles[i] != -1 ) + { + sal_Int16 nAttributes; + rPH2.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] ); + if( nAttributes & ::com::sun::star::beans::PropertyAttribute::READONLY ) + throw ::com::sun::star::beans::PropertyVetoException(); + // Will the property change? + if( convertFastPropertyValue( pConvertedValues[ nHitCount ], pOldValues[nHitCount], + pHandles[i], pDelValues[i] ) ) + { + // only increment if the property really change + pHandles[nHitCount] = pHandles[i]; + nHitCount++; + } + } + } + // release guard to fire events + } + + // fire vetoable events + fire( pHandles, pConvertedValues, pOldValues, nHitCount, sal_True ); + + // setting the agg Properties + m_xAggregateMultiSet->setPropertyValues(AggPropertyNames, AggValues); + + { + // must lock the mutex outside the loop. + osl::MutexGuard aGuard( rBHelper.rMutex ); + // Loop over all changed properties + for( i = 0; i < nHitCount; i++ ) + { + // Will the property change? + setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] ); + } + // release guard to fire events + } + + // fire change events + fire( pHandles, pConvertedValues, pOldValues, nHitCount, sal_False ); + } + else + m_xAggregateMultiSet->setPropertyValues(AggPropertyNames, AggValues); + + } + catch(::com::sun::star::uno::Exception&) + { + delete [] pHandles; + delete [] pOldValues; + delete [] pConvertedValues; + throw; + } + + delete [] pHandles; + delete [] pOldValues; + delete [] pConvertedValues; + } + } +} + +// XPropertyState +//------------------------------------------------------------------------------ + ::com::sun::star::beans::PropertyState SAL_CALL OPropertySetAggregationHelper::getPropertyState(const ::rtl::OUString& _rPropertyName) + throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() ); + sal_Int32 nHandle = rPH.getHandleByName( _rPropertyName ); + + if (nHandle == -1) + { + throw ::com::sun::star::beans::UnknownPropertyException(); + } + + ::rtl::OUString aPropName; + sal_Int32 nOriginalHandle = -1; + if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle)) + { + if (m_xAggregateState.is()) + return m_xAggregateState->getPropertyState(_rPropertyName); + else + return ::com::sun::star::beans::PropertyState_DIRECT_VALUE; + } + else + return getPropertyStateByHandle(nHandle); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::setPropertyToDefault(const ::rtl::OUString& _rPropertyName) + throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() ); + sal_Int32 nHandle = rPH.getHandleByName(_rPropertyName); + if (nHandle == -1) + { + throw ::com::sun::star::beans::UnknownPropertyException(); + } + + ::rtl::OUString aPropName; + sal_Int32 nOriginalHandle = -1; + if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle)) + { + if (m_xAggregateState.is()) + m_xAggregateState->setPropertyToDefault(_rPropertyName); + } + else + { + try + { + setPropertyToDefaultByHandle( nHandle ); + } + catch( const UnknownPropertyException& ) { throw; } + catch( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + OSL_FAIL( "OPropertySetAggregationHelper::setPropertyToDefault: caught an exception which is not allowed to leave here!" ); + } + } +} + +//------------------------------------------------------------------------------ + ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::getPropertyDefault(const ::rtl::OUString& aPropertyName) + throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() ); + sal_Int32 nHandle = rPH.getHandleByName( aPropertyName ); + + if ( nHandle == -1 ) + throw ::com::sun::star::beans::UnknownPropertyException(); + + ::rtl::OUString aPropName; + sal_Int32 nOriginalHandle = -1; + if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle)) + { + if (m_xAggregateState.is()) + return m_xAggregateState->getPropertyDefault(aPropertyName); + else + return ::com::sun::star::uno::Any(); + } + else + return getPropertyDefaultByHandle(nHandle); +} + +//------------------------------------------------------------------------------ +sal_Bool SAL_CALL OPropertySetAggregationHelper::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw(IllegalArgumentException) +{ + sal_Bool bModified = sal_False; + + OSL_ENSURE( m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::convertFastPropertyValue: this is no forwarded property - did you use declareForwardedProperty for it?" ); + if ( m_pForwarder->isResponsibleFor( _nHandle ) ) + { + // need to determine the type of the property for conversion + OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() ); + Property aProperty; + OSL_VERIFY( rPH.getPropertyByHandle( _nHandle, aProperty ) ); + + Any aCurrentValue; + getFastPropertyValue( aCurrentValue, _nHandle ); + bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, aCurrentValue, aProperty.Type ); + } + + return bModified; +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception ) +{ + OSL_ENSURE( m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast: this is no forwarded property - did you use declareForwardedProperty for it?" ); + if ( m_pForwarder->isResponsibleFor( _nHandle ) ) + m_pForwarder->doForward( _nHandle, _rValue ); +} + +//------------------------------------------------------------------------------ +void OPropertySetAggregationHelper::declareForwardedProperty( sal_Int32 _nHandle ) +{ + OSL_ENSURE( !m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::declareForwardedProperty: already declared!" ); + m_pForwarder->takeResponsibilityFor( _nHandle ); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::forwardingPropertyValue( sal_Int32 ) +{ + // not interested in +} + +//------------------------------------------------------------------------------ +void SAL_CALL OPropertySetAggregationHelper::forwardedPropertyValue( sal_Int32, bool ) +{ + // not interested in +} + +//------------------------------------------------------------------------------ +bool OPropertySetAggregationHelper::isCurrentlyForwardingProperty( sal_Int32 _nHandle ) const +{ + return m_pForwarder->getCurrentlyForwardedProperty() == _nHandle; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/property.cxx b/comphelper/source/property/property.cxx new file mode 100644 index 000000000000..b20eba9c47f9 --- /dev/null +++ b/comphelper/source/property/property.cxx @@ -0,0 +1,249 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + + +#include <comphelper/property.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/types.hxx> +#include <osl/diagnose.h> + +#if OSL_DEBUG_LEVEL > 0 + #include <rtl/strbuf.hxx> + #include <cppuhelper/exc_hlp.hxx> + #include <osl/thread.h> + #include <com/sun/star/lang/XServiceInfo.hpp> + #include <typeinfo> +#endif +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/genfunc.h> + +#include <algorithm> +#include <boost/bind.hpp> + +//......................................................................... +namespace comphelper +{ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::beans::XPropertySet; + using ::com::sun::star::beans::XPropertySetInfo; + using ::com::sun::star::beans::Property; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::Type; + using ::com::sun::star::uno::cpp_queryInterface; + using ::com::sun::star::uno::cpp_acquire; + using ::com::sun::star::uno::cpp_release; +#if OSL_DEBUG_LEVEL > 0 + using ::com::sun::star::lang::XServiceInfo; +#endif + using ::com::sun::star::uno::UNO_QUERY; + /** === end UNO using === **/ + namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute; + +//------------------------------------------------------------------ +void copyProperties(const Reference<XPropertySet>& _rxSource, + const Reference<XPropertySet>& _rxDest) +{ + if (!_rxSource.is() || !_rxDest.is()) + { + OSL_FAIL("copyProperties: invalid arguments !"); + return; + } + + Reference< XPropertySetInfo > xSourceProps = _rxSource->getPropertySetInfo(); + Reference< XPropertySetInfo > xDestProps = _rxDest->getPropertySetInfo(); + + Sequence< Property > aSourceProps = xSourceProps->getProperties(); + const Property* pSourceProps = aSourceProps.getConstArray(); + Property aDestProp; + for (sal_Int32 i=0; i<aSourceProps.getLength(); ++i, ++pSourceProps) + { + if ( xDestProps->hasPropertyByName(pSourceProps->Name) ) + { + try + { + aDestProp = xDestProps->getPropertyByName(pSourceProps->Name); + if (0 == (aDestProp.Attributes & PropertyAttribute::READONLY) ) + { + const Any aSourceValue = _rxSource->getPropertyValue(pSourceProps->Name); + if ( 0 != (aDestProp.Attributes & PropertyAttribute::MAYBEVOID) || aSourceValue.hasValue() ) + _rxDest->setPropertyValue(pSourceProps->Name, aSourceValue); + } + } + catch (Exception&) + { +#if OSL_DEBUG_LEVEL > 0 + ::rtl::OStringBuffer aBuffer; + aBuffer.append( "::comphelper::copyProperties: could not copy property '" ); + aBuffer.append( ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US ) ); + aBuffer.append( "' to the destination set (a '" ); + + Reference< XServiceInfo > xSI( _rxDest, UNO_QUERY ); + if ( xSI.is() ) + { + aBuffer.append( ::rtl::OUStringToOString( xSI->getImplementationName(), osl_getThreadTextEncoding() ) ); + } + else + { + aBuffer.append( typeid( *_rxDest.get() ).name() ); + } + aBuffer.append( "' implementation).\n" ); + + Any aException( ::cppu::getCaughtException() ); + aBuffer.append( "Caught an exception of type '" ); + ::rtl::OUString sExceptionType( aException.getValueTypeName() ); + aBuffer.append( ::rtl::OString( sExceptionType.getStr(), sExceptionType.getLength(), RTL_TEXTENCODING_ASCII_US ) ); + aBuffer.append( "'" ); + + Exception aBaseException; + if ( ( aException >>= aBaseException ) && aBaseException.Message.getLength() ) + { + aBuffer.append( ", saying '" ); + aBuffer.append( ::rtl::OString( aBaseException.Message.getStr(), aBaseException.Message.getLength(), osl_getThreadTextEncoding() ) ); + aBuffer.append( "'" ); + } + aBuffer.append( "." ); + + OSL_FAIL( aBuffer.getStr() ); +#endif + } + } + } +} + +//------------------------------------------------------------------ +sal_Bool hasProperty(const rtl::OUString& _rName, const Reference<XPropertySet>& _rxSet) +{ + if (_rxSet.is()) + { + // XPropertySetInfoRef xInfo(rxSet->getPropertySetInfo()); + return _rxSet->getPropertySetInfo()->hasPropertyByName(_rName); + } + return sal_False; +} + +//------------------------------------------------------------------ +bool findProperty(Property& o_rProp, + Sequence<Property>& i_seqProps, + const ::rtl::OUString& i_rPropName) +{ + const Property* pAry(i_seqProps.getConstArray()); + const sal_Int32 nLen(i_seqProps.getLength()); + const Property* pRes( + std::find_if(pAry,pAry+nLen, + boost::bind(PropertyStringEqualFunctor(), + _1, + boost::cref(i_rPropName)))); + if( pRes == pAry+nLen ) + return false; + + o_rProp = *pRes; + return true; +} + +//------------------------------------------------------------------ +void RemoveProperty(Sequence<Property>& _rProps, const rtl::OUString& _rPropName) +{ + sal_Int32 nLen = _rProps.getLength(); + + // binaere Suche + const Property* pProperties = _rProps.getConstArray(); + Property aNameProp(_rPropName, 0, Type(), 0); + const Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen, aNameProp, PropertyCompareByName()); + + // gefunden ? + if ( pResult && (pResult != pProperties + nLen) && (pResult->Name == _rPropName) ) + { + OSL_ENSURE(pResult->Name.equals(_rPropName), "::RemoveProperty Properties nicht sortiert"); + removeElementAt(_rProps, pResult - pProperties); + } +} + +//------------------------------------------------------------------ +void ModifyPropertyAttributes(Sequence<Property>& seqProps, const ::rtl::OUString& sPropName, sal_Int16 nAddAttrib, sal_Int16 nRemoveAttrib) +{ + sal_Int32 nLen = seqProps.getLength(); + + // binaere Suche + Property* pProperties = seqProps.getArray(); + Property aNameProp(sPropName, 0, Type(), 0); + Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen, aNameProp, PropertyCompareByName()); + + // gefunden ? + if ( pResult && (pResult != pProperties + nLen) && (pResult->Name == sPropName) ) + { + pResult->Attributes |= nAddAttrib; + pResult->Attributes &= ~nRemoveAttrib; + } +} + +//------------------------------------------------------------------ +sal_Bool tryPropertyValue(Any& _rConvertedValue, Any& _rOldValue, const Any& _rValueToSet, const Any& _rCurrentValue, const Type& _rExpectedType) +{ + sal_Bool bModified(sal_False); + if (_rCurrentValue.getValue() != _rValueToSet.getValue()) + { + if ( _rValueToSet.hasValue() && ( !_rExpectedType.equals( _rValueToSet.getValueType() ) ) ) + { + _rConvertedValue = Any( NULL, _rExpectedType.getTypeLibType() ); + + if ( !uno_type_assignData( + const_cast< void* >( _rConvertedValue.getValue() ), _rConvertedValue.getValueType().getTypeLibType(), + const_cast< void* >( _rValueToSet.getValue() ), _rValueToSet.getValueType().getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >( + cpp_queryInterface), + reinterpret_cast< uno_AcquireFunc >(cpp_acquire), + reinterpret_cast< uno_ReleaseFunc >(cpp_release) + ) + ) + throw starlang::IllegalArgumentException(); + } + else + _rConvertedValue = _rValueToSet; + + if ( _rCurrentValue != _rConvertedValue ) + { + _rOldValue = _rCurrentValue; + bModified = sal_True; + } + } + return bModified; +} + +//......................................................................... +} +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propertybag.cxx b/comphelper/source/property/propertybag.cxx new file mode 100644 index 000000000000..3170411de510 --- /dev/null +++ b/comphelper/source/property/propertybag.cxx @@ -0,0 +1,223 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "comphelper/propertybag.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/beans/IllegalTypeException.hpp> +#include <com/sun/star/beans/PropertyExistException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/NotRemoveableException.hpp> +/** === end UNO includes === **/ + +#include <map> + +//........................................................................ +namespace comphelper +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::Type; + using ::com::sun::star::uno::TypeClass_VOID; + using ::com::sun::star::beans::IllegalTypeException; + using ::com::sun::star::beans::PropertyExistException; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::beans::Property; + using ::com::sun::star::beans::NotRemoveableException; + using ::com::sun::star::beans::UnknownPropertyException; + /** === end UNO using === **/ + namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute; + + //==================================================================== + //= PropertyBag_Impl + //==================================================================== + typedef ::std::map< sal_Int32, Any > MapInt2Any; + struct PropertyBag_Impl + { + PropertyBag_Impl() : m_bAllowEmptyPropertyName(false) { } + MapInt2Any aDefaults; + bool m_bAllowEmptyPropertyName; + }; + + //==================================================================== + //= PropertyBag + //==================================================================== + //-------------------------------------------------------------------- + PropertyBag::PropertyBag() + :m_pImpl( new PropertyBag_Impl ) + { + } + + PropertyBag::~PropertyBag() + { + } + + //-------------------------------------------------------------------- + void PropertyBag::setAllowEmptyPropertyName( bool i_isAllowed ) + { + m_pImpl->m_bAllowEmptyPropertyName = i_isAllowed; + } + + //-------------------------------------------------------------------- + namespace + { + void lcl_checkForEmptyName( const bool _allowEmpty, const ::rtl::OUString& _name ) + { + if ( !_allowEmpty && !_name.getLength() ) + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The property name must not be empty." ) ), + // TODO: resource + NULL, + 1 + ); + } + + void lcl_checkNameAndHandle( const ::rtl::OUString& _name, const sal_Int32 _handle, const PropertyBag& _container ) + { + if ( _container.hasPropertyByName( _name ) || _container.hasPropertyByHandle( _handle ) ) + throw PropertyExistException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Property name or handle already used." ) ), + // TODO: resource + NULL ); + + } + } + + //-------------------------------------------------------------------- + void PropertyBag::addVoidProperty( const ::rtl::OUString& _rName, const Type& _rType, sal_Int32 _nHandle, sal_Int32 _nAttributes ) + { + if ( _rType.getTypeClass() == TypeClass_VOID ) + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal property type: VOID" ) ), + // TODO: resource + NULL, + 1 + ); + + // check name/handle sanity + lcl_checkForEmptyName( m_pImpl->m_bAllowEmptyPropertyName, _rName ); + lcl_checkNameAndHandle( _rName, _nHandle, *this ); + + // register the property + OSL_ENSURE( _nAttributes & PropertyAttribute::MAYBEVOID, "PropertyBag::addVoidProperty: this is for default-void properties only!" ); + registerPropertyNoMember( _rName, _nHandle, _nAttributes | PropertyAttribute::MAYBEVOID, _rType, NULL ); + + // remember the default + m_pImpl->aDefaults.insert( MapInt2Any::value_type( _nHandle, Any() ) ); + } + + //-------------------------------------------------------------------- + void PropertyBag::addProperty( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, const Any& _rInitialValue ) + { + // check type sanity + Type aPropertyType = _rInitialValue.getValueType(); + if ( aPropertyType.getTypeClass() == TypeClass_VOID ) + throw IllegalTypeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The initial value must be non-NULL to determine the property type." ) ), + // TODO: resource + NULL ); + + // check name/handle sanity + lcl_checkForEmptyName( m_pImpl->m_bAllowEmptyPropertyName, _rName ); + lcl_checkNameAndHandle( _rName, _nHandle, *this ); + + // register the property + registerPropertyNoMember( _rName, _nHandle, _nAttributes, aPropertyType, + _rInitialValue.hasValue() ? _rInitialValue.getValue() : NULL ); + + // remember the default + m_pImpl->aDefaults.insert( MapInt2Any::value_type( _nHandle, _rInitialValue ) ); + } + + //-------------------------------------------------------------------- + void PropertyBag::removeProperty( const ::rtl::OUString& _rName ) + { + const Property& rProp = getProperty( _rName ); + // will throw an UnknownPropertyException if necessary + if ( ( rProp.Attributes & PropertyAttribute::REMOVEABLE ) == 0 ) + throw NotRemoveableException( ::rtl::OUString(), NULL ); + const sal_Int32 nHandle = rProp.Handle; + + revokeProperty( nHandle ); + + m_pImpl->aDefaults.erase( nHandle ); + } + + //-------------------------------------------------------------------- + void PropertyBag::getFastPropertyValue( sal_Int32 _nHandle, Any& _out_rValue ) const + { + if ( !hasPropertyByHandle( _nHandle ) ) + throw UnknownPropertyException(); + + OPropertyContainerHelper::getFastPropertyValue( _out_rValue, _nHandle ); + } + + //-------------------------------------------------------------------- + bool PropertyBag::convertFastPropertyValue( sal_Int32 _nHandle, const Any& _rNewValue, Any& _out_rConvertedValue, Any& _out_rCurrentValue ) const + { + if ( !hasPropertyByHandle( _nHandle ) ) + throw UnknownPropertyException(); + + return const_cast< PropertyBag* >( this )->OPropertyContainerHelper::convertFastPropertyValue( + _out_rConvertedValue, _out_rCurrentValue, _nHandle, _rNewValue ); + } + + //-------------------------------------------------------------------- + void PropertyBag::setFastPropertyValue( sal_Int32 _nHandle, const Any& _rValue ) + { + if ( !hasPropertyByHandle( _nHandle ) ) + throw UnknownPropertyException(); + + OPropertyContainerHelper::setFastPropertyValue( _nHandle, _rValue ); + } + + //-------------------------------------------------------------------- + void PropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _out_rValue ) const + { + if ( !hasPropertyByHandle( _nHandle ) ) + throw UnknownPropertyException(); + + MapInt2Any::const_iterator pos = m_pImpl->aDefaults.find( _nHandle ); + OSL_ENSURE( pos != m_pImpl->aDefaults.end(), "PropertyBag::getPropertyDefaultByHandle: inconsistency!" ); + if ( pos != m_pImpl->aDefaults.end() ) + _out_rValue = pos->second; + else + _out_rValue.clear(); + } + + +//........................................................................ +} // namespace comphelper +//........................................................................ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propertycontainer.cxx b/comphelper/source/property/propertycontainer.cxx new file mode 100644 index 000000000000..a826eca2bd92 --- /dev/null +++ b/comphelper/source/property/propertycontainer.cxx @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/propertycontainer.hxx> +#include <comphelper/property.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <osl/diagnose.h> +#include <uno/data.h> +#include <com/sun/star/uno/genfunc.h> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <rtl/ustrbuf.hxx> + +#include <algorithm> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +//========================================================================== +//= OPropertyContainer +//========================================================================== +//-------------------------------------------------------------------------- +OPropertyContainer::OPropertyContainer(::cppu::OBroadcastHelper& _rBHelper) + :OPropertyContainer_Base(_rBHelper) +{ +} + +// ------------------------------------------------------------------------- +OPropertyContainer::~OPropertyContainer() +{ +} + +//-------------------------------------------------------------------------- +Sequence< Type > SAL_CALL OPropertyContainer::getTypes() throw (RuntimeException) +{ + // just the types from our one and only base class + ::cppu::OTypeCollection aTypes( + ::getCppuType( static_cast< Reference< XPropertySet >* >(NULL)), + ::getCppuType( static_cast< Reference< XFastPropertySet >* >(NULL)), + ::getCppuType( static_cast< Reference< XMultiPropertySet >* >(NULL)) + ); + return aTypes.getTypes(); +} + +//-------------------------------------------------------------------------- +void SAL_CALL OPropertyContainer::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue ) throw ( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + OPropertyContainer_Base::setFastPropertyValue( nHandle, rValue ); +} + +//-------------------------------------------------------------------------- +sal_Bool OPropertyContainer::convertFastPropertyValue( + Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException) +{ + return OPropertyContainerHelper::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ); +} + +//-------------------------------------------------------------------------- +void OPropertyContainer::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (Exception) +{ + OPropertyContainerHelper::setFastPropertyValue( _nHandle, _rValue ); +} + +//-------------------------------------------------------------------------- +void OPropertyContainer::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const +{ + OPropertyContainerHelper::getFastPropertyValue( _rValue, _nHandle ); +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propertycontainerhelper.cxx b/comphelper/source/property/propertycontainerhelper.cxx new file mode 100644 index 000000000000..b984c3a2e635 --- /dev/null +++ b/comphelper/source/property/propertycontainerhelper.cxx @@ -0,0 +1,547 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/propertycontainerhelper.hxx> +#include <comphelper/property.hxx> +#include <osl/diagnose.h> +#include <uno/data.h> +#include <com/sun/star/uno/genfunc.h> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/UnknownPropertyException.hpp> +#include <rtl/ustrbuf.hxx> + +#include <algorithm> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +//-------------------------------------------------------------------------- +namespace +{ + // comparing two property descriptions + struct PropertyDescriptionCompareByHandle : public ::std::binary_function< PropertyDescription, PropertyDescription, bool > + { + bool operator() (const PropertyDescription& x, const PropertyDescription& y) const + { + return x.aProperty.Handle < y.aProperty.Handle; + } + }; + // comparing two property descriptions + struct PropertyDescriptionHandleCompare : public ::std::binary_function< PropertyDescription, PropertyDescription, bool > + { + bool operator() (const PropertyDescription& x, const PropertyDescription& y) const + { + return x.aProperty.Handle < y.aProperty.Handle; + } + }; + // comparing two property descriptions (by name) + struct PropertyDescriptionNameMatch : public ::std::unary_function< PropertyDescription, bool > + { + ::rtl::OUString m_rCompare; + PropertyDescriptionNameMatch( const ::rtl::OUString& _rCompare ) : m_rCompare( _rCompare ) { } + + bool operator() (const PropertyDescription& x ) const + { + return x.aProperty.Name.equals(m_rCompare); + } + }; +} + +//========================================================================== +//= OPropertyContainerHelper +//========================================================================== +//-------------------------------------------------------------------------- +OPropertyContainerHelper::OPropertyContainerHelper() + :m_bUnused(sal_False) +{ +} + +// ------------------------------------------------------------------------- +OPropertyContainerHelper::~OPropertyContainerHelper() +{ +} + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::registerProperty(const ::rtl::OUString& _rName, sal_Int32 _nHandle, + sal_Int32 _nAttributes, void* _pPointerToMember, const Type& _rMemberType) +{ + OSL_ENSURE((_nAttributes & PropertyAttribute::MAYBEVOID) == 0, + "OPropertyContainerHelper::registerProperty: don't use this for properties which may be void ! There is a method called \"registerMayBeVoidProperty\" for this !"); + OSL_ENSURE(!_rMemberType.equals(::getCppuType(static_cast< Any* >(NULL))), + "OPropertyContainerHelper::registerProperty: don't give my the type of an uno::Any ! Really can't handle this !"); + OSL_ENSURE(_pPointerToMember, + "OPropertyContainerHelper::registerProperty: you gave me nonsense : the pointer must be non-NULL"); + + PropertyDescription aNewProp; + aNewProp.aProperty = Property( _rName, _nHandle, _rMemberType, (sal_Int16)_nAttributes ); + aNewProp.eLocated = PropertyDescription::ltDerivedClassRealType; + aNewProp.aLocation.pDerivedClassMember = _pPointerToMember; + + implPushBackProperty(aNewProp); +} + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::revokeProperty( sal_Int32 _nHandle ) +{ + PropertiesIterator aPos = searchHandle( _nHandle ); + if ( aPos == m_aProperties.end() ) + throw UnknownPropertyException(); + m_aProperties.erase( aPos ); +} + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::registerMayBeVoidProperty(const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, + Any* _pPointerToMember, const Type& _rExpectedType) +{ + OSL_ENSURE((_nAttributes & PropertyAttribute::MAYBEVOID) != 0, + "OPropertyContainerHelper::registerMayBeVoidProperty: why calling this when the attributes say nothing about may-be-void ?"); + OSL_ENSURE(!_rExpectedType.equals(::getCppuType(static_cast< Any* >(NULL))), + "OPropertyContainerHelper::registerMayBeVoidProperty: don't give my the type of an uno::Any ! Really can't handle this !"); + OSL_ENSURE(_pPointerToMember, + "OPropertyContainerHelper::registerMayBeVoidProperty: you gave me nonsense : the pointer must be non-NULL"); + + _nAttributes |= PropertyAttribute::MAYBEVOID; + + PropertyDescription aNewProp; + aNewProp.aProperty = Property( _rName, _nHandle, _rExpectedType, (sal_Int16)_nAttributes ); + aNewProp.eLocated = PropertyDescription::ltDerivedClassAnyType; + aNewProp.aLocation.pDerivedClassMember = _pPointerToMember; + + implPushBackProperty(aNewProp); +} + + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::registerPropertyNoMember(const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, + const Type& _rType, const void* _pInitialValue) +{ + OSL_ENSURE(!_rType.equals(::getCppuType(static_cast< Any* >(NULL))), + "OPropertyContainerHelper::registerPropertyNoMember : don't give my the type of an uno::Any ! Really can't handle this !"); + OSL_ENSURE(_pInitialValue || ((_nAttributes & PropertyAttribute::MAYBEVOID) != 0), + "OPropertyContainerHelper::registerPropertyNoMember : you should not ommit the initial value if the property can't be void ! This will definitivly crash later !"); + + PropertyDescription aNewProp; + aNewProp.aProperty = Property( _rName, _nHandle, _rType, (sal_Int16)_nAttributes ); + aNewProp.eLocated = PropertyDescription::ltHoldMyself; + aNewProp.aLocation.nOwnClassVectorIndex = m_aHoldProperties.size(); + if (_pInitialValue) + m_aHoldProperties.push_back(Any(_pInitialValue, _rType)); + else + m_aHoldProperties.push_back(Any()); + + implPushBackProperty(aNewProp); +} + +//-------------------------------------------------------------------------- +sal_Bool OPropertyContainerHelper::isRegisteredProperty( sal_Int32 _nHandle ) const +{ + return const_cast< OPropertyContainerHelper* >( this )->searchHandle( _nHandle ) != m_aProperties.end(); +} + +//-------------------------------------------------------------------------- +sal_Bool OPropertyContainerHelper::isRegisteredProperty( const ::rtl::OUString& _rName ) const +{ + // TODO: the current structure is from a time where properties were + // static, not dynamic. Since we allow that properties are also dynamic, + // i.e. registered and revoked even though the XPropertySet has already been + // accessed, a vector is not really the best data structure anymore ... + + ConstPropertiesIterator pos = ::std::find_if( + m_aProperties.begin(), + m_aProperties.end(), + PropertyDescriptionNameMatch( _rName ) + ); + return pos != m_aProperties.end(); +} + +//-------------------------------------------------------------------------- +namespace +{ + struct ComparePropertyHandles + { + bool operator()( const PropertyDescription& _rLHS, const PropertyDescription& _nRHS ) const + { + return _rLHS.aProperty.Handle < _nRHS.aProperty.Handle; + } + }; +} + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::implPushBackProperty(const PropertyDescription& _rProp) +{ +#ifdef DBG_UTIL + for ( PropertiesIterator checkConflicts = m_aProperties.begin(); + checkConflicts != m_aProperties.end(); + ++checkConflicts + ) + { + OSL_ENSURE(checkConflicts->aProperty.Name != _rProp.aProperty.Name, "OPropertyContainerHelper::implPushBackProperty: name already exists!"); + OSL_ENSURE(checkConflicts->aProperty.Handle != _rProp.aProperty.Handle, "OPropertyContainerHelper::implPushBackProperty: handle already exists!"); + } +#endif + + PropertiesIterator pos = ::std::lower_bound( + m_aProperties.begin(), m_aProperties.end(), + _rProp, ComparePropertyHandles() ); + + m_aProperties.insert( pos, _rProp ); +} + +//-------------------------------------------------------------------------- +namespace +{ + void lcl_throwIllegalPropertyValueTypeException( const PropertyDescription& _rProperty, const Any& _rValue ) + { + ::rtl::OUStringBuffer aErrorMessage; + aErrorMessage.appendAscii( "The given value cannot be converted to the required property type." ); + aErrorMessage.appendAscii( "\n(property name \"" ); + aErrorMessage.append( _rProperty.aProperty.Name ); + aErrorMessage.appendAscii( "\", found value type \"" ); + aErrorMessage.append( _rValue.getValueType().getTypeName() ); + aErrorMessage.appendAscii( "\", required property type \"" ); + aErrorMessage.append( _rProperty.aProperty.Type.getTypeName() ); + aErrorMessage.appendAscii( "\")" ); + throw IllegalArgumentException( aErrorMessage.makeStringAndClear(), NULL, 4 ); + } +} + +//-------------------------------------------------------------------------- +sal_Bool OPropertyContainerHelper::convertFastPropertyValue( + Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) SAL_THROW( (IllegalArgumentException) ) +{ + sal_Bool bModified = sal_False; + + // get the property somebody is asking for + PropertiesIterator aPos = searchHandle(_nHandle); + if (aPos == m_aProperties.end()) + { + OSL_FAIL( "OPropertyContainerHelper::convertFastPropertyValue: unknown handle!" ); + // should not happen if the derived class has built a correct property set info helper to be used by + // our base class OPropertySetHelper + return bModified; + } + + switch (aPos->eLocated) + { + // similar handling for the two cases where the value is stored in an any + case PropertyDescription::ltHoldMyself: + case PropertyDescription::ltDerivedClassAnyType: + { + sal_Bool bMayBeVoid = ((aPos->aProperty.Attributes & PropertyAttribute::MAYBEVOID) != 0); + + + // non modifiable version of the value-to-be-set + Any aNewRequestedValue( _rValue ); + + // normalization + // #i29490# + if ( !aNewRequestedValue.getValueType().equals( aPos->aProperty.Type ) ) + { // the actually given value is not of the same type as the one required + Any aProperlyTyped( NULL, aPos->aProperty.Type.getTypeLibType() ); + + if ( uno_type_assignData( + const_cast< void* >( aProperlyTyped.getValue() ), aProperlyTyped.getValueType().getTypeLibType(), + const_cast< void* >( aNewRequestedValue.getValue() ), aNewRequestedValue.getValueType().getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >( cpp_queryInterface ), + reinterpret_cast< uno_AcquireFunc >( cpp_acquire ), + reinterpret_cast< uno_ReleaseFunc >( cpp_release ) + ) + ) + { + // we were able to query the given XInterface-derivee for the interface + // which is required for this property + aNewRequestedValue = aProperlyTyped; + } + } + + // argument check + if ( ! ( (bMayBeVoid && !aNewRequestedValue.hasValue()) // void is allowed if the attribute says so + || (aNewRequestedValue.getValueType().equals(aPos->aProperty.Type)) // else the types have to be equal + ) + ) + { + lcl_throwIllegalPropertyValueTypeException( *aPos, _rValue ); + } + + Any* pPropContainer = NULL; + // the pointer to the any which holds the property value, no matter if located in the derived clas + // or in out vector + + if (PropertyDescription::ltHoldMyself == aPos->eLocated) + { + OSL_ENSURE(aPos->aLocation.nOwnClassVectorIndex < (sal_Int32)m_aHoldProperties.size(), + "OPropertyContainerHelper::convertFastPropertyValue: invalid position !"); + PropertyContainerIterator aIter = m_aHoldProperties.begin() + aPos->aLocation.nOwnClassVectorIndex; + pPropContainer = &(*aIter); + } + else + pPropContainer = reinterpret_cast<Any*>(aPos->aLocation.pDerivedClassMember); + + // check if the new value differs from the current one + if (!pPropContainer->hasValue() || !aNewRequestedValue.hasValue()) + bModified = pPropContainer->hasValue() != aNewRequestedValue.hasValue(); + else + bModified = !uno_type_equalData( + const_cast< void* >( pPropContainer->getValue() ), aPos->aProperty.Type.getTypeLibType(), + const_cast< void* >( aNewRequestedValue.getValue() ), aPos->aProperty.Type.getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >( cpp_queryInterface ), + reinterpret_cast< uno_ReleaseFunc >( cpp_release ) + ); + + if (bModified) + { + _rOldValue = *pPropContainer; + _rConvertedValue = aNewRequestedValue; + } + } + break; + case PropertyDescription::ltDerivedClassRealType: + // let the UNO runtime library do any possible conversion + // this may include a change of the type - for instance, if a LONG is required, + // but a short is given, then this is valid, as it can be converted without any potential + // data loss + + Any aProperlyTyped; + const Any* pNewValue = &_rValue; + + if (!_rValue.getValueType().equals(aPos->aProperty.Type)) + { + sal_Bool bConverted = sal_False; + + // a temporary any of the correct (required) type + aProperlyTyped = Any( NULL, aPos->aProperty.Type.getTypeLibType() ); + // (need this as we do not want to overwrite the derived class member here) + + if ( uno_type_assignData( + const_cast<void*>(aProperlyTyped.getValue()), aProperlyTyped.getValueType().getTypeLibType(), + const_cast<void*>(_rValue.getValue()), _rValue.getValueType().getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >( cpp_queryInterface ), + reinterpret_cast< uno_AcquireFunc >( cpp_acquire ), + reinterpret_cast< uno_ReleaseFunc >( cpp_release ) + ) + ) + { + // could query for the requested interface + bConverted = sal_True; + pNewValue = &aProperlyTyped; + } + + if ( !bConverted ) + lcl_throwIllegalPropertyValueTypeException( *aPos, _rValue ); + } + + // from here on, we should have the proper type + OSL_ENSURE( pNewValue->getValueType() == aPos->aProperty.Type, + "OPropertyContainerHelper::convertFastPropertyValue: conversion failed!" ); + bModified = !uno_type_equalData( + aPos->aLocation.pDerivedClassMember, aPos->aProperty.Type.getTypeLibType(), + const_cast<void*>(pNewValue->getValue()), aPos->aProperty.Type.getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >( cpp_queryInterface ), + reinterpret_cast< uno_ReleaseFunc >( cpp_release ) + ); + + if (bModified) + { + _rOldValue.setValue(aPos->aLocation.pDerivedClassMember, aPos->aProperty.Type); + _rConvertedValue = *pNewValue; + } + break; + } + + return bModified; +} + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::setFastPropertyValue(sal_Int32 _nHandle, const Any& _rValue) SAL_THROW( (Exception) ) +{ + // get the property somebody is asking for + PropertiesIterator aPos = searchHandle(_nHandle); + if (aPos == m_aProperties.end()) + { + OSL_FAIL( "OPropertyContainerHelper::setFastPropertyValue: unknown handle!" ); + // should not happen if the derived class has built a correct property set info helper to be used by + // our base class OPropertySetHelper + return; + } + + switch (aPos->eLocated) + { + case PropertyDescription::ltHoldMyself: + m_aHoldProperties[aPos->aLocation.nOwnClassVectorIndex] = _rValue; + break; + + case PropertyDescription::ltDerivedClassAnyType: + *reinterpret_cast< Any* >(aPos->aLocation.pDerivedClassMember) = _rValue; + break; + + case PropertyDescription::ltDerivedClassRealType: +#if OSL_DEBUG_LEVEL > 0 + sal_Bool bSuccess = +#endif + // copy the data from the to-be-set value + uno_type_assignData( + aPos->aLocation.pDerivedClassMember, aPos->aProperty.Type.getTypeLibType(), + const_cast< void* >( _rValue.getValue() ), _rValue.getValueType().getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >( cpp_queryInterface ), + reinterpret_cast< uno_AcquireFunc >( cpp_acquire ), + reinterpret_cast< uno_ReleaseFunc >( cpp_release ) ); + + OSL_ENSURE( bSuccess, + "OPropertyContainerHelper::setFastPropertyValue: ooops .... the value could not be assigned!"); + + break; + } +} + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const +{ + // get the property somebody is asking for + PropertiesIterator aPos = const_cast<OPropertyContainerHelper*>(this)->searchHandle(_nHandle); + if (aPos == m_aProperties.end()) + { + OSL_FAIL( "OPropertyContainerHelper::getFastPropertyValue: unknown handle!" ); + // should not happen if the derived class has built a correct property set info helper to be used by + // our base class OPropertySetHelper + return; + } + + switch (aPos->eLocated) + { + case PropertyDescription::ltHoldMyself: + OSL_ENSURE(aPos->aLocation.nOwnClassVectorIndex < (sal_Int32)m_aHoldProperties.size(), + "OPropertyContainerHelper::convertFastPropertyValue: invalid position !"); + _rValue = m_aHoldProperties[aPos->aLocation.nOwnClassVectorIndex]; + break; + case PropertyDescription::ltDerivedClassAnyType: + _rValue = *reinterpret_cast<Any*>(aPos->aLocation.pDerivedClassMember); + break; + case PropertyDescription::ltDerivedClassRealType: + _rValue.setValue(aPos->aLocation.pDerivedClassMember, aPos->aProperty.Type); + break; + } +} + +//-------------------------------------------------------------------------- +OPropertyContainerHelper::PropertiesIterator OPropertyContainerHelper::searchHandle(sal_Int32 _nHandle) +{ + PropertyDescription aHandlePropDesc; + aHandlePropDesc.aProperty.Handle = _nHandle; + // search a lower bound + PropertiesIterator aLowerBound = ::std::lower_bound( + m_aProperties.begin(), + m_aProperties.end(), + aHandlePropDesc, + PropertyDescriptionHandleCompare()); + + // check for identity + if ((aLowerBound != m_aProperties.end()) && aLowerBound->aProperty.Handle != _nHandle) + aLowerBound = m_aProperties.end(); + + return aLowerBound; +} + +//-------------------------------------------------------------------------- +const Property& OPropertyContainerHelper::getProperty( const ::rtl::OUString& _rName ) const +{ + ConstPropertiesIterator pos = ::std::find_if( + m_aProperties.begin(), + m_aProperties.end(), + PropertyDescriptionNameMatch( _rName ) + ); + if ( pos == m_aProperties.end() ) + throw UnknownPropertyException( _rName, NULL ); + + return pos->aProperty; +} + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::modifyAttributes(sal_Int32 _nHandle, sal_Int32 _nAddAttrib, sal_Int32 _nRemoveAttrib) +{ + // get the property somebody is asking for + PropertiesIterator aPos = searchHandle(_nHandle); + if (aPos == m_aProperties.end()) + { + OSL_FAIL( "OPropertyContainerHelper::modifyAttributes: unknown handle!" ); + // should not happen if the derived class has built a correct property set info helper to be used by + // our base class OPropertySetHelper + return; + } + aPos->aProperty.Handle |= _nAddAttrib; + aPos->aProperty.Handle &= ~_nRemoveAttrib; +} + +//-------------------------------------------------------------------------- +void OPropertyContainerHelper::describeProperties(Sequence< Property >& _rProps) const +{ + Sequence< Property > aOwnProps(m_aProperties.size()); + Property* pOwnProps = aOwnProps.getArray(); + + for ( ConstPropertiesIterator aLoop = m_aProperties.begin(); + aLoop != m_aProperties.end(); + ++aLoop, ++pOwnProps + ) + { + pOwnProps->Name = aLoop->aProperty.Name; + pOwnProps->Handle = aLoop->aProperty.Handle; + pOwnProps->Attributes = (sal_Int16)aLoop->aProperty.Attributes; + pOwnProps->Type = aLoop->aProperty.Type; + } + + // as our property vector is sorted by handles, not by name, we have to sort aOwnProps + ::std::sort(aOwnProps.getArray(), aOwnProps.getArray() + aOwnProps.getLength(), PropertyCompareByName()); + + // unfortunally the STL merge function does not allow the output range to overlap one of the input ranges, + // so we need an extra sequence + Sequence< Property > aOutput; + aOutput.realloc(_rProps.getLength() + aOwnProps.getLength()); + // do the merge + ::std::merge( _rProps.getConstArray(), _rProps.getConstArray() + _rProps.getLength(), // input 1 + aOwnProps.getConstArray(), aOwnProps.getConstArray() + aOwnProps.getLength(), // input 2 + aOutput.getArray(), // output + PropertyCompareByName() // compare operator + ); + + // copy the output + _rProps = aOutput; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propertysethelper.cxx b/comphelper/source/property/propertysethelper.cxx new file mode 100644 index 000000000000..0ad27a6949ed --- /dev/null +++ b/comphelper/source/property/propertysethelper.cxx @@ -0,0 +1,331 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/propertysetinfo.hxx" +#include "comphelper/propertysethelper.hxx" + +/////////////////////////////////////////////////////////////////////// + +using namespace ::rtl; +using namespace ::comphelper; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; + +namespace comphelper +{ +class PropertySetHelperImpl +{ +public: + PropertyMapEntry* find( const OUString& aName ) const throw(); + + PropertySetInfo* mpInfo; +}; +} + +PropertyMapEntry* PropertySetHelperImpl::find( const OUString& aName ) const throw() +{ + PropertyMap::const_iterator aIter = mpInfo->getPropertyMap()->find( aName ); + + if( mpInfo->getPropertyMap()->end() != aIter ) + { + return (*aIter).second; + } + else + { + return NULL; + } +} + +/////////////////////////////////////////////////////////////////////// + +PropertySetHelper::PropertySetHelper( ) +{ + mp = new PropertySetHelperImpl; + mp->mpInfo = new PropertySetInfo; + mp->mpInfo->acquire(); +} + +PropertySetHelper::PropertySetHelper( comphelper::PropertySetInfo* pInfo ) throw() +{ + mp = new PropertySetHelperImpl; + mp->mpInfo = pInfo; + pInfo->acquire(); +} + +PropertySetHelper::PropertySetHelper( comphelper::PropertySetInfo* pInfo, __sal_NoAcquire ) throw() +{ + mp = new PropertySetHelperImpl; + mp->mpInfo = pInfo; +} + +PropertySetHelper::~PropertySetHelper() throw() +{ + mp->mpInfo->release(); + delete mp; +} + +void PropertySetHelper::setInfo( comphelper::PropertySetInfo* pInfo ) throw() +{ + OSL_ENSURE( pInfo != NULL, "need pInfo" ); + OSL_ENSURE( mp->mpInfo != NULL, "where's the old pInfo?" ); + + mp->mpInfo->release(); + mp->mpInfo = pInfo; + mp->mpInfo->acquire(); +} + +// XPropertySet +Reference< XPropertySetInfo > SAL_CALL PropertySetHelper::getPropertySetInfo( ) throw(RuntimeException) +{ + return mp->mpInfo; +} + +void SAL_CALL PropertySetHelper::setPropertyValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + PropertyMapEntry* aEntries[2]; + aEntries[0] = mp->find( aPropertyName ); + + if( NULL == aEntries[0] ) + throw UnknownPropertyException( aPropertyName, static_cast< XPropertySet* >( this ) ); + + aEntries[1] = NULL; + + _setPropertyValues( (const PropertyMapEntry**)aEntries, &aValue ); +} + +Any SAL_CALL PropertySetHelper::getPropertyValue( const ::rtl::OUString& PropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + PropertyMapEntry* aEntries[2]; + aEntries[0] = mp->find( PropertyName ); + + if( NULL == aEntries[0] ) + throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) ); + + aEntries[1] = NULL; + + Any aAny; + _getPropertyValues( (const PropertyMapEntry**)aEntries, &aAny ); + + return aAny; +} + +void SAL_CALL PropertySetHelper::addPropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::removePropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::addVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::removeVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + // todo +} + +// XMultiPropertySet +void SAL_CALL PropertySetHelper::setPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames, const Sequence< Any >& aValues ) throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + const sal_Int32 nCount = aPropertyNames.getLength(); + + if( nCount != aValues.getLength() ) + throw IllegalArgumentException(); + + if( nCount ) + { + PropertyMapEntry** pEntries = new PropertyMapEntry*[nCount+1]; + pEntries[nCount] = NULL; + const OUString* pNames = aPropertyNames.getConstArray(); + + sal_Bool bUnknown = sal_False; + sal_Int32 n; + for( n = 0; !bUnknown && ( n < nCount ); n++, pNames++ ) + { + pEntries[n] = mp->find( *pNames ); + bUnknown = NULL == pEntries[n]; + } + + if( !bUnknown ) + _setPropertyValues( (const PropertyMapEntry**)pEntries, aValues.getConstArray() ); + + delete[] pEntries; + + if( bUnknown ) + throw UnknownPropertyException( *pNames, static_cast< XPropertySet* >( this ) ); + } +} + +Sequence< Any > SAL_CALL PropertySetHelper::getPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames ) throw(RuntimeException) +{ + const sal_Int32 nCount = aPropertyNames.getLength(); + + Sequence< Any > aValues; + if( nCount ) + { + PropertyMapEntry** pEntries = new PropertyMapEntry*[nCount+1]; + pEntries[nCount] = NULL; + const OUString* pNames = aPropertyNames.getConstArray(); + + sal_Bool bUnknown = sal_False; + sal_Int32 n; + for( n = 0; !bUnknown && ( n < nCount ); n++, pNames++ ) + { + pEntries[n] = mp->find( *pNames ); + bUnknown = NULL == pEntries[n]; + } + + if( !bUnknown ) + { + aValues.realloc(nCount); + _getPropertyValues( (const PropertyMapEntry**)pEntries, aValues.getArray() ); + } + + delete[] pEntries; + + if( bUnknown ) + throw UnknownPropertyException( *pNames, static_cast< XPropertySet* >( this ) ); + } + + return aValues; +} + +void SAL_CALL PropertySetHelper::addPropertiesChangeListener( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& ) throw(RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& ) throw(RuntimeException) +{ + // todo +} + +void SAL_CALL PropertySetHelper::firePropertiesChangeEvent( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& ) throw(RuntimeException) +{ + // todo +} + +// XPropertyState +PropertyState SAL_CALL PropertySetHelper::getPropertyState( const ::rtl::OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException) +{ + PropertyMapEntry* aEntries[2]; + + aEntries[0] = mp->find( PropertyName ); + if( aEntries[0] == NULL ) + throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) ); + + aEntries[1] = NULL; + + PropertyState aState; + _getPropertyStates( (const PropertyMapEntry**)aEntries, &aState ); + + return aState; +} + +Sequence< PropertyState > SAL_CALL PropertySetHelper::getPropertyStates( const Sequence< ::rtl::OUString >& aPropertyName ) throw(UnknownPropertyException, RuntimeException) +{ + const sal_Int32 nCount = aPropertyName.getLength(); + + Sequence< PropertyState > aStates( nCount ); + + if( nCount ) + { + const OUString* pNames = aPropertyName.getConstArray(); + + sal_Bool bUnknown = sal_False; + + PropertyMapEntry** pEntries = new PropertyMapEntry*[nCount+1]; + + sal_Int32 n; + for( n = 0; !bUnknown && (n < nCount); n++, pNames++ ) + { + pEntries[n] = mp->find( *pNames ); + bUnknown = NULL == pEntries[n]; + } + + pEntries[nCount] = NULL; + + if( !bUnknown ) + _getPropertyStates( (const PropertyMapEntry**)pEntries, aStates.getArray() ); + + delete[] pEntries; + + if( bUnknown ) + throw UnknownPropertyException( *pNames, static_cast< XPropertySet* >( this ) ); + } + + return aStates; +} + +void SAL_CALL PropertySetHelper::setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw(UnknownPropertyException, RuntimeException) +{ + PropertyMapEntry *pEntry = mp->find( PropertyName ); + if( NULL == pEntry ) + throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) ); + + _setPropertyToDefault( pEntry ); +} + +Any SAL_CALL PropertySetHelper::getPropertyDefault( const ::rtl::OUString& aPropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + PropertyMapEntry* pEntry = mp->find( aPropertyName ); + if( NULL == pEntry ) + throw UnknownPropertyException( aPropertyName, static_cast< XPropertySet* >( this ) ); + + return _getPropertyDefault( pEntry ); +} + +void PropertySetHelper::_getPropertyStates( const comphelper::PropertyMapEntry**, PropertyState* ) throw(UnknownPropertyException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +void PropertySetHelper::_setPropertyToDefault( const comphelper::PropertyMapEntry* ) throw(UnknownPropertyException ) +{ + OSL_FAIL( "you have to implement this yourself!"); +} + +Any PropertySetHelper::_getPropertyDefault( const comphelper::PropertyMapEntry* ) throw(UnknownPropertyException, WrappedTargetException ) +{ + OSL_FAIL( "you have to implement this yourself!"); + + Any aAny; + return aAny; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propertysetinfo.cxx b/comphelper/source/property/propertysetinfo.cxx new file mode 100644 index 000000000000..4746a7e9ce43 --- /dev/null +++ b/comphelper/source/property/propertysetinfo.cxx @@ -0,0 +1,217 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper/propertysetinfo.hxx" + +using namespace ::rtl; +using namespace ::comphelper; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; + +namespace comphelper +{ +class PropertyMapImpl +{ +public: + PropertyMapImpl() throw(); + virtual ~PropertyMapImpl() throw(); + + void add( PropertyMapEntry* pMap, sal_Int32 nCount = -1 ) throw(); + void remove( const OUString& aName ) throw(); + + Sequence< Property > getProperties() throw(); + + const PropertyMap* getPropertyMap() const throw(); + + Property getPropertyByName( const OUString& aName ) throw( UnknownPropertyException ); + sal_Bool hasPropertyByName( const OUString& aName ) throw(); + +private: + PropertyMap maPropertyMap; + Sequence< Property > maProperties; +}; +} + +PropertyMapImpl::PropertyMapImpl() throw() +{ +} + +PropertyMapImpl::~PropertyMapImpl() throw() +{ +} + +void PropertyMapImpl::add( PropertyMapEntry* pMap, sal_Int32 nCount ) throw() +{ + // nCount < 0 => add all + // nCount == 0 => add nothing + // nCount > 0 => add at most nCount entries + + while( pMap->mpName && ( ( nCount < 0) || ( nCount-- > 0 ) ) ) + { + OUString aName( pMap->mpName, pMap->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + +#ifdef DBG_UTIL + PropertyMap::iterator aIter = maPropertyMap.find( aName ); + if( aIter != maPropertyMap.end() ) + { + OSL_FAIL( "Warning: PropertyMapEntry added twice, possible error!"); + } +#endif + if( NULL == pMap->mpType ) + { + OSL_FAIL( "No type in PropertyMapEntry!"); + pMap->mpType = &::getCppuType((const sal_Int32*)0); + } + + maPropertyMap[aName] = pMap; + + if( maProperties.getLength() ) + maProperties.realloc( 0 ); + + pMap = &pMap[1]; + } +} + +void PropertyMapImpl::remove( const OUString& aName ) throw() +{ + maPropertyMap.erase( aName ); + + if( maProperties.getLength() ) + maProperties.realloc( 0 ); +} + +Sequence< Property > PropertyMapImpl::getProperties() throw() +{ + // maybe we have to generate the properties after + // a change in the property map or at first call + // to getProperties + if( maProperties.getLength() != (sal_Int32)maPropertyMap.size() ) + { + maProperties = Sequence< Property >( maPropertyMap.size() ); + Property* pProperties = maProperties.getArray(); + + PropertyMap::iterator aIter = maPropertyMap.begin(); + const PropertyMap::iterator aEnd = maPropertyMap.end(); + while( aIter != aEnd ) + { + PropertyMapEntry* pEntry = (*aIter).second; + + pProperties->Name = OUString( pEntry->mpName, pEntry->mnNameLen, RTL_TEXTENCODING_ASCII_US ); + pProperties->Handle = pEntry->mnHandle; + pProperties->Type = *pEntry->mpType; + pProperties->Attributes = pEntry->mnAttributes; + + ++pProperties; + ++aIter; + } + } + + return maProperties; +} + +const PropertyMap* PropertyMapImpl::getPropertyMap() const throw() +{ + return &maPropertyMap; +} + +Property PropertyMapImpl::getPropertyByName( const OUString& aName ) throw( UnknownPropertyException ) +{ + PropertyMap::iterator aIter = maPropertyMap.find( aName ); + + if( maPropertyMap.end() == aIter ) + throw UnknownPropertyException( aName, NULL ); + + PropertyMapEntry* pEntry = (*aIter).second; + + return Property( aName, pEntry->mnHandle, *pEntry->mpType, pEntry->mnAttributes ); +} + +sal_Bool PropertyMapImpl::hasPropertyByName( const OUString& aName ) throw() +{ + return maPropertyMap.find( aName ) != maPropertyMap.end(); +} + +/////////////////////////////////////////////////////////////////////// + +PropertySetInfo::PropertySetInfo() throw() +{ + mpMap = new PropertyMapImpl(); +} + +PropertySetInfo::PropertySetInfo( PropertyMapEntry* pMap ) throw() +{ + mpMap = new PropertyMapImpl(); + mpMap->add( pMap ); +} + +PropertySetInfo::~PropertySetInfo() throw() +{ + delete mpMap; +} + +void PropertySetInfo::add( PropertyMapEntry* pMap ) throw() +{ + mpMap->add( pMap ); +} + +void PropertySetInfo::add( PropertyMapEntry* pMap, sal_Int32 nCount ) throw() +{ + mpMap->add( pMap, nCount ); +} + +void PropertySetInfo::remove( const rtl::OUString& aName ) throw() +{ + mpMap->remove( aName ); +} + +Sequence< ::com::sun::star::beans::Property > SAL_CALL PropertySetInfo::getProperties() throw(::com::sun::star::uno::RuntimeException) +{ + return mpMap->getProperties(); +} + +Property SAL_CALL PropertySetInfo::getPropertyByName( const ::rtl::OUString& aName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + return mpMap->getPropertyByName( aName ); +} + +sal_Bool SAL_CALL PropertySetInfo::hasPropertyByName( const ::rtl::OUString& Name ) throw(::com::sun::star::uno::RuntimeException) +{ + return mpMap->hasPropertyByName( Name ); +} + +const PropertyMap* PropertySetInfo::getPropertyMap() const throw() +{ + return mpMap->getPropertyMap(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propertystatecontainer.cxx b/comphelper/source/property/propertystatecontainer.cxx new file mode 100644 index 000000000000..f1611efd77f4 --- /dev/null +++ b/comphelper/source/property/propertystatecontainer.cxx @@ -0,0 +1,197 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include "comphelper/propertystatecontainer.hxx" +#include <rtl/ustrbuf.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::lang; + + namespace + { + static ::rtl::OUString lcl_getUnknownPropertyErrorMessage( const ::rtl::OUString& _rPropertyName ) + { + // TODO: perhaps it's time to think about resources in the comphelper module? + // Would be nice to have localized exception strings (a simply resource file containing + // strings only would suffice, and could be realized with an UNO service, so we do not + // need the dependency to the Tools project) + ::rtl::OUStringBuffer sMessage; + sMessage.appendAscii( "The property \"" ); + sMessage.append( _rPropertyName ); + sMessage.appendAscii( "\" is unknown." ); + return sMessage.makeStringAndClear(); + } + } + + //===================================================================== + //= OPropertyStateContainer + //===================================================================== + //--------------------------------------------------------------------- + OPropertyStateContainer::OPropertyStateContainer( ::cppu::OBroadcastHelper& _rBHelper ) + :OPropertyContainer( _rBHelper ) + { + } + + //-------------------------------------------------------------------- + Any SAL_CALL OPropertyStateContainer::queryInterface( const Type& _rType ) throw (RuntimeException) + { + Any aReturn = OPropertyContainer::queryInterface( _rType ); + if ( !aReturn.hasValue() ) + aReturn = OPropertyStateContainer_TBase::queryInterface( _rType ); + return aReturn; + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyStateContainer, OPropertyContainer, OPropertyStateContainer_TBase ) + + //-------------------------------------------------------------------- + sal_Int32 OPropertyStateContainer::getHandleForName( const ::rtl::OUString& _rPropertyName ) SAL_THROW( ( UnknownPropertyException ) ) + { + // look up the handle for the name + ::cppu::IPropertyArrayHelper& rPH = getInfoHelper(); + sal_Int32 nHandle = rPH.getHandleByName( _rPropertyName ); + + if ( -1 == nHandle ) + throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( _rPropertyName ), static_cast< XPropertyState* >( this ) ); + + return nHandle; + } + + //-------------------------------------------------------------------- + PropertyState SAL_CALL OPropertyStateContainer::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException) + { + return getPropertyStateByHandle( getHandleForName( _rPropertyName ) ); + } + + //-------------------------------------------------------------------- + Sequence< PropertyState > SAL_CALL OPropertyStateContainer::getPropertyStates( const Sequence< ::rtl::OUString >& _rPropertyNames ) throw (UnknownPropertyException, RuntimeException) + { + sal_Int32 nProperties = _rPropertyNames.getLength(); + Sequence< PropertyState> aStates( nProperties ); + if ( !nProperties ) + return aStates; + +#ifdef _DEBUG + // precondition: property sequence is sorted (the algorythm below relies on this) + { + const ::rtl::OUString* pNames = _rPropertyNames.getConstArray(); + const ::rtl::OUString* pNamesCompare = pNames + 1; + const ::rtl::OUString* pNamesEnd = _rPropertyNames.getConstArray() + _rPropertyNames.getLength(); + for ( ; pNamesCompare != pNamesEnd; ++pNames, ++pNamesCompare ) + OSL_PRECOND( pNames->compareTo( *pNamesCompare ) < 0, + "OPropertyStateContainer::getPropertyStates: property sequence not sorted!" ); + } +#endif + + const ::rtl::OUString* pLookup = _rPropertyNames.getConstArray(); + const ::rtl::OUString* pLookupEnd = pLookup + nProperties; + PropertyState* pStates = aStates.getArray(); + + cppu::IPropertyArrayHelper& rHelper = getInfoHelper(); + Sequence< Property> aAllProperties = rHelper.getProperties(); + sal_Int32 nAllProperties = aAllProperties.getLength(); + const Property* pAllProperties = aAllProperties.getConstArray(); + const Property* pAllPropertiesEnd = pAllProperties + nAllProperties; + + osl::MutexGuard aGuard( rBHelper.rMutex ); + for ( ; ( pAllProperties != pAllPropertiesEnd ) && ( pLookup != pLookupEnd ); ++pAllProperties ) + { +#ifdef _DEBUG + if ( pAllProperties < pAllPropertiesEnd - 1 ) + OSL_ENSURE( pAllProperties->Name.compareTo( (pAllProperties + 1)->Name ) < 0, + "OPropertyStateContainer::getPropertyStates: all-properties not sorted!" ); +#endif + if ( pAllProperties->Name.equals( *pLookup ) ) + { + *pStates++ = getPropertyState( *pLookup ); + ++pLookup; + } + } + + if ( pLookup != pLookupEnd ) + // we run out of properties from the IPropertyArrayHelper, but still have properties to lookup + // -> we were asked for a nonexistent property + throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( *pLookup ), static_cast< XPropertyState* >( this ) ); + + return aStates; + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyStateContainer::setPropertyToDefault( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException) + { + setPropertyToDefaultByHandle( getHandleForName( _rPropertyName ) ); + } + + //-------------------------------------------------------------------- + Any SAL_CALL OPropertyStateContainer::getPropertyDefault( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) + { + Any aDefault; + getPropertyDefaultByHandle( getHandleForName( _rPropertyName ), aDefault ); + return aDefault; + } + + //-------------------------------------------------------------------- + PropertyState OPropertyStateContainer::getPropertyStateByHandle( sal_Int32 _nHandle ) + { + // simply compare the current and the default value + Any aCurrentValue; getFastPropertyValue( aCurrentValue, _nHandle ); + Any aDefaultValue; getPropertyDefaultByHandle( _nHandle, aDefaultValue ); + + sal_Bool bEqual = uno_type_equalData( + const_cast< void* >( aCurrentValue.getValue() ), aCurrentValue.getValueType().getTypeLibType(), + const_cast< void* >( aDefaultValue.getValue() ), aDefaultValue.getValueType().getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface), + reinterpret_cast< uno_ReleaseFunc >(cpp_release) + ); + if ( bEqual ) + return PropertyState_DEFAULT_VALUE; + else + return PropertyState_DIRECT_VALUE; + } + + //-------------------------------------------------------------------- + void OPropertyStateContainer::setPropertyToDefaultByHandle( sal_Int32 _nHandle ) + { + Any aDefault; + getPropertyDefaultByHandle( _nHandle, aDefault ); + setFastPropertyValue( _nHandle, aDefault ); + } + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propmultiplex.cxx b/comphelper/source/property/propmultiplex.cxx new file mode 100644 index 000000000000..a7e9c1e395d0 --- /dev/null +++ b/comphelper/source/property/propmultiplex.cxx @@ -0,0 +1,184 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/propmultiplex.hxx> +#include <osl/diagnose.h> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +//======================================================================== +//= OPropertyChangeListener +//======================================================================== +//------------------------------------------------------------------------ +OPropertyChangeListener::~OPropertyChangeListener() +{ + if (m_pAdapter) + m_pAdapter->dispose(); +} + +//------------------------------------------------------------------ +void OPropertyChangeListener::_disposing(const EventObject&) throw( RuntimeException) +{ + // nothing to do here +} + +//------------------------------------------------------------------ +void OPropertyChangeListener::disposeAdapter() +{ + if ( m_pAdapter ) + m_pAdapter->dispose(); + + // will automatically set a new adapter + OSL_ENSURE( !m_pAdapter, "OPropertyChangeListener::disposeAdapter: what did dispose do?" ); +} + +//------------------------------------------------------------------ +void OPropertyChangeListener::setAdapter(OPropertyChangeMultiplexer* pAdapter) +{ + if (m_pAdapter) + { + ::osl::MutexGuard aGuard(m_rMutex); + m_pAdapter->release(); + m_pAdapter = NULL; + } + + if (pAdapter) + { + ::osl::MutexGuard aGuard(m_rMutex); + m_pAdapter = pAdapter; + m_pAdapter->acquire(); + } +} + +//======================================================================== +//= OPropertyChangeMultiplexer +//======================================================================== +//------------------------------------------------------------------ +OPropertyChangeMultiplexer::OPropertyChangeMultiplexer(OPropertyChangeListener* _pListener, const Reference< XPropertySet>& _rxSet, sal_Bool _bAutoReleaseSet) + :m_xSet(_rxSet) + ,m_pListener(_pListener) + ,m_nLockCount(0) + ,m_bListening(sal_False) + ,m_bAutoSetRelease(_bAutoReleaseSet) +{ + m_pListener->setAdapter(this); +} + +//------------------------------------------------------------------ +OPropertyChangeMultiplexer::~OPropertyChangeMultiplexer() +{ +} + +//------------------------------------------------------------------ +void OPropertyChangeMultiplexer::lock() +{ + ++m_nLockCount; +} + +//------------------------------------------------------------------ +void OPropertyChangeMultiplexer::unlock() +{ + --m_nLockCount; +} + +//------------------------------------------------------------------ +void OPropertyChangeMultiplexer::dispose() +{ + if (m_bListening) + { + Reference< XPropertyChangeListener> xPreventDelete(this); + + const ::rtl::OUString* pProperties = m_aProperties.getConstArray(); + for (sal_Int32 i = 0; i < m_aProperties.getLength(); ++i, ++pProperties) + m_xSet->removePropertyChangeListener(*pProperties, static_cast< XPropertyChangeListener*>(this)); + + m_pListener->setAdapter(NULL); + + m_pListener = NULL; + m_bListening = sal_False; + + if (m_bAutoSetRelease) + m_xSet = NULL; + } +} + +// XEventListener +//------------------------------------------------------------------ +void SAL_CALL OPropertyChangeMultiplexer::disposing( const EventObject& _rSource) throw( RuntimeException) +{ + if (m_pListener) + { + // tell the listener + if (!locked()) + m_pListener->_disposing(_rSource); + // disconnect the listener + if (m_pListener) // may have been reset whilest calling into _disposing + m_pListener->setAdapter(NULL); + } + + m_pListener = NULL; + m_bListening = sal_False; + + if (m_bAutoSetRelease) + m_xSet = NULL; +} + +// XPropertyChangeListener +//------------------------------------------------------------------ +void SAL_CALL OPropertyChangeMultiplexer::propertyChange( const PropertyChangeEvent& _rEvent ) throw( RuntimeException) +{ + if (m_pListener && !locked()) + m_pListener->_propertyChanged(_rEvent); +} + +//------------------------------------------------------------------ +void OPropertyChangeMultiplexer::addProperty(const ::rtl::OUString& _sPropertyName) +{ + if (m_xSet.is()) + { + m_xSet->addPropertyChangeListener(_sPropertyName, static_cast< XPropertyChangeListener*>(this)); + m_aProperties.realloc(m_aProperties.getLength() + 1); + m_aProperties.getArray()[m_aProperties.getLength()-1] = _sPropertyName; + m_bListening = sal_True; + } +} + +//......................................................................... +} +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propstate.cxx b/comphelper/source/property/propstate.cxx new file mode 100644 index 000000000000..ec621cb43833 --- /dev/null +++ b/comphelper/source/property/propstate.cxx @@ -0,0 +1,253 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/propstate.hxx> +#include <com/sun/star/uno/genfunc.h> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/sequence.hxx> +#include <rtl/instance.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::Type; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::lang::XTypeProvider; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::cpp_queryInterface; + using ::com::sun::star::uno::cpp_release; + using ::com::sun::star::beans::PropertyState_DEFAULT_VALUE; + using ::com::sun::star::beans::PropertyState_DIRECT_VALUE; + + //===================================================================== + // OPropertyStateHelper + //===================================================================== + + //--------------------------------------------------------------------- + ::com::sun::star::uno::Any SAL_CALL OPropertyStateHelper::queryInterface(const ::com::sun::star::uno::Type& _rType) throw( ::com::sun::star::uno::RuntimeException) + { + ::com::sun::star::uno::Any aReturn = OPropertySetHelper::queryInterface(_rType); + // our own ifaces + if ( !aReturn.hasValue() ) + aReturn = ::cppu::queryInterface(_rType, static_cast< ::com::sun::star::beans::XPropertyState*>(this)); + + return aReturn; + } + + //--------------------------------------------------------------------- + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> OPropertyStateHelper::getTypes() throw( ::com::sun::star::uno::RuntimeException) + { + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> aTypes(4); + ::com::sun::star::uno::Type* pTypes = aTypes.getArray(); + // base class types + pTypes[0] = getCppuType(( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>*)NULL); + pTypes[1] = getCppuType(( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet>*)NULL); + pTypes[2] = getCppuType(( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet>*)NULL); + // my own type + pTypes[3] = getCppuType(( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState>*)NULL); + return aTypes; + } + + OPropertyStateHelper::OPropertyStateHelper( + ::cppu::OBroadcastHelper& rBHlp, + ::cppu::IEventNotificationHook *i_pFireEvents) + : ::cppu::OPropertySetHelper(rBHlp, i_pFireEvents) { } + + OPropertyStateHelper::~OPropertyStateHelper() {} + + //--------------------------------------------------------------------- + void OPropertyStateHelper::firePropertyChange(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aNewValue, const ::com::sun::star::uno::Any& aOldValue) + { + fire(&nHandle, &aNewValue, &aOldValue, 1, sal_False); + } + + // XPropertyState + //--------------------------------------------------------------------- + ::com::sun::star::beans::PropertyState SAL_CALL OPropertyStateHelper::getPropertyState(const ::rtl::OUString& _rsName) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) + { + cppu::IPropertyArrayHelper& rPH = getInfoHelper(); + sal_Int32 nHandle = rPH.getHandleByName(_rsName); + + if (nHandle == -1) + throw ::com::sun::star::beans::UnknownPropertyException(); + + return getPropertyStateByHandle(nHandle); + } + + //--------------------------------------------------------------------- + void SAL_CALL OPropertyStateHelper::setPropertyToDefault(const ::rtl::OUString& _rsName) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) + { + cppu::IPropertyArrayHelper& rPH = getInfoHelper(); + sal_Int32 nHandle = rPH.getHandleByName(_rsName); + + if (nHandle == -1) + throw ::com::sun::star::beans::UnknownPropertyException(); + + setPropertyToDefaultByHandle(nHandle); + } + + //--------------------------------------------------------------------- + ::com::sun::star::uno::Any SAL_CALL OPropertyStateHelper::getPropertyDefault(const ::rtl::OUString& _rsName) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { + cppu::IPropertyArrayHelper& rPH = getInfoHelper(); + sal_Int32 nHandle = rPH.getHandleByName(_rsName); + + if (nHandle == -1) + throw ::com::sun::star::beans::UnknownPropertyException(); + + return getPropertyDefaultByHandle(nHandle); + } + + //--------------------------------------------------------------------- + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState> SAL_CALL OPropertyStateHelper::getPropertyStates(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropertyNames) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) + { + sal_Int32 nLen = _rPropertyNames.getLength(); + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState> aRet(nLen); + ::com::sun::star::beans::PropertyState* pValues = aRet.getArray(); + const ::rtl::OUString* pNames = _rPropertyNames.getConstArray(); + + cppu::IPropertyArrayHelper& rHelper = getInfoHelper(); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> aProps = rHelper.getProperties(); + const ::com::sun::star::beans::Property* pProps = aProps.getConstArray(); + sal_Int32 nPropCount = aProps.getLength(); + + osl::MutexGuard aGuard(rBHelper.rMutex); + for (sal_Int32 i=0, j=0; i<nPropCount && j<nLen; ++i, ++pProps) + { + // get the values only for valid properties + if (pProps->Name.equals(*pNames)) + { + *pValues = getPropertyState(*pNames); + ++pValues; + ++pNames; + ++j; + } + } + + return aRet; + } + + //--------------------------------------------------------------------- + ::com::sun::star::beans::PropertyState OPropertyStateHelper::getPropertyStateByHandle( sal_Int32 _nHandle ) + { + // simply compare the current and the default value + Any aCurrentValue = getPropertyDefaultByHandle( _nHandle ); + Any aDefaultValue; getFastPropertyValue( aDefaultValue, _nHandle ); + + sal_Bool bEqual = uno_type_equalData( + const_cast< void* >( aCurrentValue.getValue() ), aCurrentValue.getValueType().getTypeLibType(), + const_cast< void* >( aDefaultValue.getValue() ), aDefaultValue.getValueType().getTypeLibType(), + reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface), + reinterpret_cast< uno_ReleaseFunc >(cpp_release) + ); + return bEqual ? PropertyState_DEFAULT_VALUE : PropertyState_DIRECT_VALUE; + } + + //--------------------------------------------------------------------- + void OPropertyStateHelper::setPropertyToDefaultByHandle( sal_Int32 _nHandle ) + { + setFastPropertyValue( _nHandle, getPropertyDefaultByHandle( _nHandle ) ); + } + + //--------------------------------------------------------------------- + ::com::sun::star::uno::Any OPropertyStateHelper::getPropertyDefaultByHandle( sal_Int32 ) const + { + return ::com::sun::star::uno::Any(); + } + + //===================================================================== + // OStatefulPropertySet + //===================================================================== + //--------------------------------------------------------------------- + OStatefulPropertySet::OStatefulPropertySet() + :OPropertyStateHelper( GetBroadcastHelper() ) + { + } + + //--------------------------------------------------------------------- + OStatefulPropertySet::~OStatefulPropertySet() + { + } + + //--------------------------------------------------------------------- + Sequence< Type > SAL_CALL OStatefulPropertySet::getTypes() throw(RuntimeException) + { + Sequence< Type > aOwnTypes( 2 ); + aOwnTypes[0] = XWeak::static_type(); + aOwnTypes[1] = XTypeProvider::static_type(); + + return concatSequences( + aOwnTypes, + OPropertyStateHelper::getTypes() + ); + } + + namespace { struct lcl_ImplId : public rtl::Static< ::cppu::OImplementationId, lcl_ImplId > {}; } + + //--------------------------------------------------------------------- + Sequence< sal_Int8 > SAL_CALL OStatefulPropertySet::getImplementationId() throw(RuntimeException) + { + ::cppu::OImplementationId &rID = lcl_ImplId::get(); + return rID.getImplementationId(); + } + + //--------------------------------------------------------------------- + Any SAL_CALL OStatefulPropertySet::queryInterface( const Type& _rType ) throw(RuntimeException) + { + Any aReturn = OWeakObject::queryInterface( _rType ); + if ( !aReturn.hasValue() ) + aReturn = ::cppu::queryInterface( _rType, static_cast< XTypeProvider* >( this ) ); + if ( !aReturn.hasValue() ) + aReturn = OPropertyStateHelper::queryInterface( _rType ); + return aReturn; + } + + //--------------------------------------------------------------------- + void SAL_CALL OStatefulPropertySet::acquire() throw() + { + ::cppu::OWeakObject::acquire(); + } + + //--------------------------------------------------------------------- + void SAL_CALL OStatefulPropertySet::release() throw() + { + ::cppu::OWeakObject::release(); + } + +//......................................................................... +} +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/basicio.cxx b/comphelper/source/streaming/basicio.cxx new file mode 100644 index 000000000000..662c5545c56e --- /dev/null +++ b/comphelper/source/streaming/basicio.cxx @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/basicio.hxx> + +//......................................................................... +namespace comphelper +{ +//......................................................................... + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectOutputStream>& operator << ( + const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, + const starawt::FontDescriptor& _rFont) +{ + _rxOutStream->writeUTF( _rFont.Name ); + _rxOutStream->writeShort( _rFont.Height ); + _rxOutStream->writeShort( _rFont.Width ); + _rxOutStream->writeUTF( _rFont.StyleName ); + _rxOutStream->writeShort( _rFont.Family ); + _rxOutStream->writeShort( _rFont.CharSet ); + _rxOutStream->writeShort( _rFont.Pitch ); + _rxOutStream->writeDouble( _rFont.CharacterWidth ); + _rxOutStream->writeDouble( _rFont.Weight ); + _rxOutStream->writeShort( static_cast< sal_Int16 >(_rFont.Slant) ); + _rxOutStream->writeShort( _rFont.Underline ); + _rxOutStream->writeShort( _rFont.Strikeout ); + _rxOutStream->writeDouble( _rFont.Orientation ); + _rxOutStream->writeBoolean( _rFont.Kerning ); + _rxOutStream->writeBoolean( _rFont.WordLineMode ); + _rxOutStream->writeShort( _rFont.Type ); + return _rxOutStream; +} + +// FontDescriptor +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectInputStream>& operator >> ( + const staruno::Reference<stario::XObjectInputStream>& _rxInStream, + starawt::FontDescriptor& _rFont) +{ + // schreiben des Fontdescriptors + _rFont.Name = _rxInStream->readUTF(); + _rFont.Height = _rxInStream->readShort(); + _rFont.Width = _rxInStream->readShort(); + _rFont.StyleName = _rxInStream->readUTF(); + _rFont.Family = _rxInStream->readShort(); + _rFont.CharSet = _rxInStream->readShort(); + _rFont.Pitch = _rxInStream->readShort(); + _rFont.CharacterWidth = static_cast< float >(_rxInStream->readDouble()); + _rFont.Weight = static_cast< float >(_rxInStream->readDouble()); + _rFont.Slant = (starawt::FontSlant)_rxInStream->readShort(); + _rFont.Underline = _rxInStream->readShort(); + _rFont.Strikeout = _rxInStream->readShort(); + _rFont.Orientation = static_cast< float >(_rxInStream->readDouble()); + _rFont.Kerning = _rxInStream->readBoolean(); + _rFont.WordLineMode = _rxInStream->readBoolean(); + _rFont.Type = _rxInStream->readShort(); + return _rxInStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Bool& _rVal) +{ + _rVal = _rxInStream->readBoolean(); + return _rxInStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Bool _bVal) +{ + _rxOutStream->writeBoolean(_bVal); + return _rxOutStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, ::rtl::OUString& rStr) +{ + rStr = _rxInStream->readUTF(); + return _rxInStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, const ::rtl::OUString& rStr) +{ + _rxOutStream->writeUTF(rStr); + return _rxOutStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Int16& _rValue) +{ + _rValue = _rxInStream->readShort(); + return _rxInStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Int16 _nValue) +{ + _rxOutStream->writeShort(_nValue); + return _rxOutStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_uInt16& _rValue) +{ + _rValue = _rxInStream->readShort(); + return _rxInStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_uInt16 _nValue) +{ + _rxOutStream->writeShort(_nValue); + return _rxOutStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_uInt32& _rValue) +{ + _rValue = _rxInStream->readLong(); + return _rxInStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_uInt32 _nValue) +{ + _rxOutStream->writeLong(_nValue); + return _rxOutStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectInputStream>& operator >> (const staruno::Reference<stario::XObjectInputStream>& _rxInStream, sal_Int32& _rValue) +{ + _rValue = _rxInStream->readLong(); + return _rxInStream; +} + +//------------------------------------------------------------------------------ +const staruno::Reference<stario::XObjectOutputStream>& operator << (const staruno::Reference<stario::XObjectOutputStream>& _rxOutStream, sal_Int32 _nValue) +{ + _rxOutStream->writeLong(_nValue); + return _rxOutStream; +} + +//......................................................................... +} // namespace comphelper +//......................................................................... + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/memorystream.cxx b/comphelper/source/streaming/memorystream.cxx new file mode 100644 index 000000000000..fd17bd9e5db6 --- /dev/null +++ b/comphelper/source/streaming/memorystream.cxx @@ -0,0 +1,250 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XSeekableInputStream.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/implbase4.hxx> + +#include <string.h> +#include <vector> + +using ::rtl::OUString; +using ::cppu::OWeakObject; +using ::cppu::WeakImplHelper4; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::osl; + +namespace comphelper +{ + +class UNOMemoryStream : public WeakImplHelper4 < XStream, XSeekableInputStream, XOutputStream, XTruncate > +{ +public: + UNOMemoryStream(); + virtual ~UNOMemoryStream(); + + // XStream + virtual Reference< XInputStream > SAL_CALL getInputStream( ) throw (RuntimeException); + virtual Reference< XOutputStream > SAL_CALL getOutputStream( ) throw (RuntimeException); + + // XInputStream + virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual sal_Int32 SAL_CALL available() throw (NotConnectedException, IOException, RuntimeException); + virtual void SAL_CALL closeInput() throw (NotConnectedException, IOException, RuntimeException); + + // XSeekable + virtual void SAL_CALL seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException); + virtual sal_Int64 SAL_CALL getPosition() throw (IOException, RuntimeException); + virtual sal_Int64 SAL_CALL getLength() throw (IOException, RuntimeException); + + // XOutputStream + virtual void SAL_CALL writeBytes( const Sequence< sal_Int8 >& aData ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual void SAL_CALL flush() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + virtual void SAL_CALL closeOutput() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + + // XTruncate + virtual void SAL_CALL truncate() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo - static versions (used for component registration) + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static Reference< XInterface > SAL_CALL Create( const Reference< ::com::sun::star::uno::XComponentContext >& ); + +private: + std::vector< sal_Int8 > maData; + sal_Int32 mnCursor; +}; + +UNOMemoryStream::UNOMemoryStream() +: mnCursor(0) +{ +} + +UNOMemoryStream::~UNOMemoryStream() +{ +} + +// XStream +Reference< XInputStream > SAL_CALL UNOMemoryStream::getInputStream( ) throw (RuntimeException) +{ + return this; +} + +Reference< XOutputStream > SAL_CALL UNOMemoryStream::getOutputStream( ) throw (RuntimeException) +{ + return this; +} + +// XInputStream +sal_Int32 SAL_CALL UNOMemoryStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + if( nBytesToRead < 0 ) + throw IOException(); + + nBytesToRead = std::min( nBytesToRead, available() ); + aData.realloc( nBytesToRead ); + + if( nBytesToRead ) + { + sal_Int8* pData = static_cast<sal_Int8*>(&(*maData.begin())); + sal_Int8* pCursor = &((pData)[mnCursor]); + memcpy( (void*)aData.getArray(), (void*)pCursor, nBytesToRead ); + + mnCursor += nBytesToRead; + } + + return nBytesToRead; +} + +sal_Int32 SAL_CALL UNOMemoryStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + return readBytes( aData, nMaxBytesToRead ); +} + +void SAL_CALL UNOMemoryStream::skipBytes( sal_Int32 nBytesToSkip ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + if( nBytesToSkip < 0 ) + throw IOException(); + + mnCursor += std::min( nBytesToSkip, available() ); +} + +sal_Int32 SAL_CALL UNOMemoryStream::available() throw (NotConnectedException, IOException, RuntimeException) +{ + return static_cast< sal_Int32 >( maData.size() ) - mnCursor; +} + +void SAL_CALL UNOMemoryStream::closeInput() throw (NotConnectedException, IOException, RuntimeException) +{ + mnCursor = 0; +} + +// XSeekable +void SAL_CALL UNOMemoryStream::seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException) +{ + if( (location < 0) || (location > SAL_MAX_INT32) ) + throw IllegalArgumentException( OUString(RTL_CONSTASCII_USTRINGPARAM("this implementation does not support more than 2GB!")), Reference< XInterface >(static_cast<OWeakObject*>(this)), 0 ); + + // seek operation should be able to resize the stream + if ( location > static_cast< sal_Int64 >( maData.size() ) ) + maData.resize( static_cast< sal_Int32 >( location ) ); + + if ( location > static_cast< sal_Int64 >( maData.size() ) ) + maData.resize( static_cast< sal_Int32 >( location ) ); + + mnCursor = static_cast< sal_Int32 >( location ); +} + +sal_Int64 SAL_CALL UNOMemoryStream::getPosition() throw (IOException, RuntimeException) +{ + return static_cast< sal_Int64 >( mnCursor ); +} + +sal_Int64 SAL_CALL UNOMemoryStream::getLength() throw (IOException, RuntimeException) +{ + return static_cast< sal_Int64 >( maData.size() ); +} + +// XOutputStream +void SAL_CALL UNOMemoryStream::writeBytes( const Sequence< sal_Int8 >& aData ) throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + const sal_Int32 nBytesToWrite( aData.getLength() ); + if( nBytesToWrite ) + { + sal_Int64 nNewSize = static_cast< sal_Int64 >( mnCursor + nBytesToWrite ); + if( nNewSize > SAL_MAX_INT32 ) + { + OSL_ASSERT(false); + throw IOException( OUString(RTL_CONSTASCII_USTRINGPARAM("this implementation does not support more than 2GB!")), Reference< XInterface >(static_cast<OWeakObject*>(this)) ); + } + + if( static_cast< sal_Int32 >( nNewSize ) > static_cast< sal_Int32 >( maData.size() ) ) + maData.resize( static_cast< sal_Int32 >( nNewSize ) ); + + sal_Int8* pData = static_cast<sal_Int8*>(&(*maData.begin())); + sal_Int8* pCursor = &(pData[mnCursor]); + memcpy( (void*)pCursor, (void*)aData.getConstArray(), nBytesToWrite ); + + mnCursor += nBytesToWrite; + } +} + +void SAL_CALL UNOMemoryStream::flush() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ +} + +void SAL_CALL UNOMemoryStream::closeOutput() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + mnCursor = 0; +} + +//XTruncate +void SAL_CALL UNOMemoryStream::truncate() throw (IOException, RuntimeException) +{ + maData.resize( 0 ); + mnCursor = 0; +} + +::rtl::OUString SAL_CALL UNOMemoryStream::getImplementationName_static() +{ + static const OUString sImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.MemoryStream" ) ); + return sImplName; +} + +Sequence< ::rtl::OUString > SAL_CALL UNOMemoryStream::getSupportedServiceNames_static() +{ + Sequence< OUString > aSeq(1); + aSeq[0] = getImplementationName_static(); + return aSeq; +} + +Reference< XInterface > SAL_CALL UNOMemoryStream::Create( + const Reference< XComponentContext >& ) +{ + return static_cast<OWeakObject*>(new UNOMemoryStream()); +} + +} // namespace comphelper + +void createRegistryInfo_UNOMemoryStream() +{ + static ::comphelper::module::OAutoRegistration< ::comphelper::UNOMemoryStream > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/oslfile2streamwrap.cxx b/comphelper/source/streaming/oslfile2streamwrap.cxx new file mode 100644 index 000000000000..68af33298336 --- /dev/null +++ b/comphelper/source/streaming/oslfile2streamwrap.cxx @@ -0,0 +1,200 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/oslfile2streamwrap.hxx> + +#include <algorithm> + +namespace comphelper +{ + using namespace osl; + +//------------------------------------------------------------------ +OSLInputStreamWrapper::OSLInputStreamWrapper( File& _rFile ) + :m_pFile(&_rFile) + ,m_bFileOwner(sal_False) +{ +} + +//------------------------------------------------------------------ +OSLInputStreamWrapper::OSLInputStreamWrapper( File* pStream, sal_Bool bOwner ) + :m_pFile( pStream ) + ,m_bFileOwner( bOwner ) +{ +} + +//------------------------------------------------------------------ +OSLInputStreamWrapper::~OSLInputStreamWrapper() +{ + if( m_bFileOwner ) + delete m_pFile; +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OSLInputStreamWrapper::readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) + throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + if (!m_pFile) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + if (nBytesToRead < 0) + throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + + ::osl::MutexGuard aGuard( m_aMutex ); + + aData.realloc(nBytesToRead); + + sal_uInt64 nRead = 0; + FileBase::RC eError = m_pFile->read((void*)aData.getArray(), nBytesToRead, nRead); + if (eError != FileBase::E_None) + throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + + // Wenn gelesene Zeichen < MaxLength, staruno::Sequence anpassen + if (nRead < (sal_uInt32)nBytesToRead) + aData.realloc( sal::static_int_cast< sal_Int32 >(nRead) ); + + return sal::static_int_cast< sal_Int32 >(nRead); +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OSLInputStreamWrapper::readSomeBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + if (!m_pFile) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + if (nMaxBytesToRead < 0) + throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + + /* + if (m_pFile->IsEof()) + { + aData.realloc(0); + return 0; + } + else + */ + return readBytes(aData, nMaxBytesToRead); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OSLInputStreamWrapper::skipBytes(sal_Int32 nBytesToSkip) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_pFile) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + sal_uInt64 nCurrentPos; + m_pFile->getPos(nCurrentPos); + + sal_uInt64 nNewPos = nCurrentPos + nBytesToSkip; + FileBase::RC eError = m_pFile->setPos(osl_Pos_Absolut, nNewPos); + if (eError != FileBase::E_None) + { + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + } + +#ifdef DBG_UTIL + m_pFile->getPos(nCurrentPos); +// volatile int dummy = 0; // to take a look at last changes ;-) +#endif +} + +//------------------------------------------------------------------------------ +sal_Int32 SAL_CALL OSLInputStreamWrapper::available() throw( stario::NotConnectedException, staruno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (!m_pFile) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + sal_uInt64 nPos; + FileBase::RC eError = m_pFile->getPos(nPos); + if (eError != FileBase::E_None) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + sal_uInt64 nDummy = 0; + eError = m_pFile->setPos(osl_Pos_End, nDummy); + if (eError != FileBase::E_None) + throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + + sal_uInt64 nAvailable; + eError = m_pFile->getPos(nAvailable); + if (eError != FileBase::E_None) + throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + + nAvailable = nAvailable - nPos; + eError = m_pFile->setPos(osl_Pos_Absolut, nPos); + if (eError != FileBase::E_None) + throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + return sal::static_int_cast< sal_Int32 >( + std::max(nAvailable, sal::static_int_cast< sal_uInt64 >(SAL_MAX_INT32))); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OSLInputStreamWrapper::closeInput() throw( stario::NotConnectedException, staruno::RuntimeException ) +{ + if (!m_pFile) + throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this)); + + m_pFile->close(); + if (m_bFileOwner) + delete m_pFile; + + m_pFile = NULL; +} + +/*************************************************************************/ +// stario::XOutputStream +//------------------------------------------------------------------------------ +void SAL_CALL OSLOutputStreamWrapper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + sal_uInt64 nWritten; + FileBase::RC eError = rFile.write(aData.getConstArray(),aData.getLength(), nWritten); + if (eError != FileBase::E_None + || nWritten != sal::static_int_cast< sal_uInt32 >(aData.getLength())) + { + throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this)); + } +} + +//------------------------------------------------------------------ +void SAL_CALL OSLOutputStreamWrapper::flush() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ +} + +//------------------------------------------------------------------ +void SAL_CALL OSLOutputStreamWrapper::closeOutput() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException ) +{ + rFile.close(); +} + +} // namespace comphelper + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/otransactedfilestream.cxx b/comphelper/source/streaming/otransactedfilestream.cxx new file mode 100644 index 000000000000..9bcfac5fb66b --- /dev/null +++ b/comphelper/source/streaming/otransactedfilestream.cxx @@ -0,0 +1,826 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <osl/diagnose.h> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/io/XAsyncOutputMonitor.hpp> +#include <com/sun/star/embed/UseBackupException.hpp> + +#include <comphelper/otransactedfilestream.hxx> +#include <comphelper/storagehelper.hxx> +#include <cppuhelper/implbase1.hxx> + +using namespace ::com::sun::star; + +namespace comphelper +{ + +// ======================================================================== +class OTransactionHelper : public ::cppu::WeakImplHelper1 < embed::XTransactedObject > +{ + OTruncatedTransactedFileStream* m_pFileStream; + uno::Reference< io::XStream > m_xStreamHolder; + +public: + OTransactionHelper( OTruncatedTransactedFileStream* pStream ) + : m_pFileStream( pStream ) + { + m_xStreamHolder = static_cast< io::XStream* >( pStream ); + if ( !m_xStreamHolder.is() ) + throw uno::RuntimeException(); + } + + virtual void SAL_CALL commit( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException); + virtual void SAL_CALL revert( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException); +}; + +// ------------------------------------------------------------------------ +void SAL_CALL OTransactionHelper::commit( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException) +{ + m_pFileStream->Commit_Impl(); +} + +// ------------------------------------------------------------------------ +void SAL_CALL OTransactionHelper::revert( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException) +{ + m_pFileStream->Revert_Impl(); +} + +// ======================================================================== +struct TTFileStreamData_Impl +{ + uno::Reference< ucb::XSimpleFileAccess > m_xFileAccess; + sal_Bool m_bDelete; + ::rtl::OUString m_aURL; + + // the streams below are not visible from outside so there is no need to remember position + + // original stream related members + uno::Reference< io::XStream > m_xOrigStream; + uno::Reference< io::XTruncate > m_xOrigTruncate; + uno::Reference< io::XSeekable > m_xOrigSeekable; + uno::Reference< io::XInputStream > m_xOrigInStream; + uno::Reference< io::XOutputStream > m_xOrigOutStream; + + // temporary stream related members + uno::Reference< io::XStream > m_xTempStream; + uno::Reference< io::XTruncate > m_xTempTruncate; + uno::Reference< io::XSeekable > m_xTempSeekable; + uno::Reference< io::XInputStream > m_xTempInStream; + uno::Reference< io::XOutputStream > m_xTempOutStream; + + sal_Bool m_bInOpen; + sal_Bool m_bOutOpen; + + sal_Bool m_bTransacted; + + + TTFileStreamData_Impl( + const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess, + sal_Bool bDelete, + const ::rtl::OUString& aURL, + const uno::Reference< io::XStream >& xOrigStream, + const uno::Reference< io::XTruncate >& xOrigTruncate, + const uno::Reference< io::XSeekable >& xOrigSeekable, + const uno::Reference< io::XInputStream >& xOrigInStream, + const uno::Reference< io::XOutputStream >& xOrigOutStream, + const uno::Reference< io::XStream >& xTempStream, + const uno::Reference< io::XTruncate >& xTempTruncate, + const uno::Reference< io::XSeekable >& xTempSeekable, + const uno::Reference< io::XInputStream >& xTempInStream, + const uno::Reference< io::XOutputStream >& xTempOutStream ) + : m_xFileAccess( xFileAccess ) + , m_bDelete( bDelete ) + , m_aURL( aURL ) + , m_xOrigStream( xOrigStream ) + , m_xOrigTruncate( xOrigTruncate ) + , m_xOrigSeekable( xOrigSeekable ) + , m_xOrigInStream( xOrigInStream ) + , m_xOrigOutStream( xOrigOutStream ) + , m_xTempStream( xTempStream ) + , m_xTempTruncate( xTempTruncate ) + , m_xTempSeekable( xTempSeekable ) + , m_xTempInStream( xTempInStream ) + , m_xTempOutStream( xTempOutStream ) + , m_bInOpen( sal_False ) + , m_bOutOpen( sal_False ) + , m_bTransacted( sal_True ) + {} + + void NoTransaction() + { + m_bDelete = sal_False; + m_bTransacted = sal_False; + m_xTempStream = uno::Reference< io::XStream >(); + m_xTempTruncate = uno::Reference< io::XTruncate >(); + m_xTempSeekable = uno::Reference< io::XSeekable >(); + m_xTempInStream = uno::Reference< io::XInputStream >(); + m_xTempOutStream = uno::Reference< io::XOutputStream >(); + } + + void FreeOriginal() + { + m_bDelete = sal_False; + m_bTransacted = sal_False; + + m_xOrigStream = m_xTempStream; + m_xTempStream = uno::Reference< io::XStream >(); + + m_xOrigTruncate = m_xTempTruncate; + m_xTempTruncate = uno::Reference< io::XTruncate >(); + + m_xOrigSeekable = m_xTempSeekable; + m_xTempSeekable = uno::Reference< io::XSeekable >(); + + m_xOrigInStream = m_xTempInStream; + m_xTempInStream = uno::Reference< io::XInputStream >(); + + m_xOrigOutStream = m_xTempOutStream; + m_xTempOutStream = uno::Reference< io::XOutputStream >(); + } +}; + +// ======================================================================== +// ------------------------------------------------------------------------ +OTruncatedTransactedFileStream::OTruncatedTransactedFileStream( + const ::rtl::OUString& aURL, + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +: m_pStreamData( NULL ) +{ + uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( + xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ), + uno::UNO_QUERY_THROW ); + + CommonInit_Impl( aURL, xSimpleFileAccess, xFactory, sal_False ); +} + +// ------------------------------------------------------------------------ +OTruncatedTransactedFileStream::OTruncatedTransactedFileStream( + const ::rtl::OUString& aURL, + const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess, + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +: m_pStreamData( NULL ) +{ + CommonInit_Impl( aURL, xFileAccess, xFactory, sal_False ); +} + +// ------------------------------------------------------------------------ +OTruncatedTransactedFileStream::OTruncatedTransactedFileStream( + const ::rtl::OUString& aURL, + const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess, + const uno::Reference< lang::XMultiServiceFactory >& xFactory, + sal_Bool bDeleteIfNotCommited ) +: m_pStreamData( NULL ) +{ + CommonInit_Impl( aURL, xFileAccess, xFactory, sal_True ); + if ( m_pStreamData ) + m_pStreamData->m_bDelete = bDeleteIfNotCommited; +} + +// ------------------------------------------------------------------------ +OTruncatedTransactedFileStream::~OTruncatedTransactedFileStream() +{ + CloseAll_Impl(); +} + +// ------------------------------------------------------------------------ +void OTruncatedTransactedFileStream::CloseAll_Impl() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pStreamData ) + { + sal_Bool bDelete = m_pStreamData->m_bDelete; + ::rtl::OUString aURL = m_pStreamData->m_aURL; + uno::Reference< ucb::XSimpleFileAccess > xFileAccess = m_pStreamData->m_xFileAccess; + + delete m_pStreamData; + m_pStreamData = NULL; + + if ( bDelete && xFileAccess.is() && aURL.getLength() ) + { + // delete the file + try + { + xFileAccess->kill( aURL ); + } catch( uno::Exception& ) + { + OSL_FAIL( "Could not remove the file!" ); + } + } + } +} + +// ------------------------------------------------------------------------ +void OTruncatedTransactedFileStream::CommonInit_Impl( + const ::rtl::OUString& aURL, + const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess, + const uno::Reference< lang::XMultiServiceFactory >& xFactory, + sal_Bool bDeleteOptionIsProvided ) +{ + sal_Bool bDelete = sal_False; + if ( !bDeleteOptionIsProvided ) + bDelete = !xFileAccess->exists( aURL ); + + uno::Reference< io::XStream > xOrigStream = xFileAccess->openFileReadWrite( aURL ); + uno::Reference< io::XTruncate > xOrigTruncate( xOrigStream, uno::UNO_QUERY_THROW ); + uno::Reference< io::XSeekable > xOrigSeekable( xOrigStream, uno::UNO_QUERY_THROW ); + uno::Reference< io::XInputStream > xOrigInStream = xOrigStream->getInputStream(); + uno::Reference< io::XOutputStream > xOrigOutStream = xOrigStream->getOutputStream(); + if ( !xOrigInStream.is() || !xOrigOutStream.is() ) + throw uno::RuntimeException(); + + // temporary stream related members + uno::Reference< io::XStream > xTempStream( xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< io::XTruncate > xTempTruncate( xTempStream, uno::UNO_QUERY_THROW ); + uno::Reference< io::XSeekable > xTempSeekable( xTempStream, uno::UNO_QUERY_THROW ); + uno::Reference< io::XInputStream > xTempInStream = xTempStream->getInputStream(); + uno::Reference< io::XOutputStream > xTempOutStream = xTempStream->getOutputStream(); + if ( !xTempInStream.is() || !xTempOutStream.is() ) + throw uno::RuntimeException(); + + m_pStreamData = new TTFileStreamData_Impl( xFileAccess, bDelete, aURL, + xOrigStream, xOrigTruncate, xOrigSeekable, xOrigInStream, xOrigOutStream, + xTempStream, xTempTruncate, xTempSeekable, xTempInStream, xTempOutStream ); +} + +// ------------------------------------------------------------------------ +void OTruncatedTransactedFileStream::Commit_Impl() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + sal_Int64 nPos = m_pStreamData->m_xTempSeekable->getPosition(); + m_pStreamData->m_xTempSeekable->seek( 0 ); + + // after the following step fails the information might be lost, throw an exception with URL of temporary file + try + { + m_pStreamData->m_xOrigTruncate->truncate(); + OStorageHelper::CopyInputToOutput( m_pStreamData->m_xTempInStream, m_pStreamData->m_xOrigOutStream ); + m_pStreamData->m_xOrigOutStream->flush(); + + // in case the stream is based on a file it will implement the following interface + // the call should be used to be sure that the contents are written to the file system + uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor( m_pStreamData->m_xOrigOutStream, uno::UNO_QUERY ); + if ( asyncOutputMonitor.is() ) + asyncOutputMonitor->waitForCompletion(); + } + catch( uno::Exception& ) + { + ::rtl::OUString aTempURL; + try { + uno::Reference< beans::XPropertySet > xTempFile( m_pStreamData->m_xTempStream, uno::UNO_QUERY_THROW ); + uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Uri")) ); + aUrl >>= aTempURL; + xTempFile->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RemoveFile")), + uno::makeAny( sal_False ) ); + + m_pStreamData->m_xTempSeekable->seek( nPos ); + } + catch( uno::Exception& ) + { + OSL_FAIL( "These calls are pretty simple, they should not fail!\n" ); + } + + m_pStreamData->FreeOriginal(); + + ::rtl::OUString aErrTxt( RTL_CONSTASCII_USTRINGPARAM ( "Writing file failed!" ) ); + embed::UseBackupException aException( aErrTxt, uno::Reference< uno::XInterface >(), aTempURL ); + throw lang::WrappedTargetException( aErrTxt, + static_cast < OWeakObject * > ( this ), + uno::makeAny ( aException ) ); + } + + m_pStreamData->m_xOrigSeekable->seek( nPos ); + m_pStreamData->NoTransaction(); + } + else + throw io::NotConnectedException(); +} + +// ------------------------------------------------------------------------ +void OTruncatedTransactedFileStream::Revert_Impl() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + m_pStreamData->m_xTempTruncate->truncate(); + else + throw io::NotConnectedException(); +} + +// com::sun::star::io::XStream +// ------------------------------------------------------------------------ +uno::Reference< io::XInputStream > SAL_CALL OTruncatedTransactedFileStream::getInputStream( ) + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pStreamData ) + m_pStreamData->m_bInOpen = sal_True; + return static_cast< io::XInputStream* >( this ); +} + + +// ------------------------------------------------------------------------ +uno::Reference< io::XOutputStream > SAL_CALL OTruncatedTransactedFileStream::getOutputStream( ) + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pStreamData ) + m_pStreamData->m_bOutOpen = sal_True; + return static_cast< io::XOutputStream* >( this ); +} + + + +// com::sun::star::io::XInputStream +// ------------------------------------------------------------------------ +::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) + throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempInStream.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xTempInStream->readBytes( aData, nBytesToRead ); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigInStream.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xOrigInStream->readBytes( aData, nBytesToRead ); + } +} + + +// ------------------------------------------------------------------------ +::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) + throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempInStream.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xTempInStream->readSomeBytes( aData, nMaxBytesToRead ); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigInStream.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xOrigInStream->readSomeBytes( aData, nMaxBytesToRead ); + } +} + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::skipBytes( ::sal_Int32 nBytesToSkip ) + throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempInStream.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xTempInStream->skipBytes( nBytesToSkip ); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigInStream.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xOrigInStream->skipBytes( nBytesToSkip ); + } +} + + +// ------------------------------------------------------------------------ +::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::available( ) + throw (io::NotConnectedException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempInStream.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xTempInStream->available(); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigInStream.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xOrigInStream->available(); + } +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::closeInput() + throw (io::NotConnectedException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + m_pStreamData->m_bInOpen = sal_False; + if ( !m_pStreamData->m_bOutOpen ) + CloseAll_Impl(); +} + + + +// com::sun::star::io::XOutputStream +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::writeBytes( const uno::Sequence< ::sal_Int8 >& aData ) + throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempOutStream.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xTempOutStream->writeBytes( aData ); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigOutStream.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xOrigOutStream->writeBytes( aData ); + } +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::flush( ) + throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + { + OSL_FAIL( "flush() call on closed stream!\n" ); + return; + // in future throw exception, for now some code might call flush() on closed stream + // since file ucp implementation allows it + // throw io::NotConnectedException(); + } + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempOutStream.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xTempOutStream->flush(); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigOutStream.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xOrigOutStream->flush(); + } +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::closeOutput( ) + throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + m_pStreamData->m_bOutOpen = sal_False; + if ( !m_pStreamData->m_bInOpen ) + CloseAll_Impl(); +} + + + +// com::sun::star::io::XTruncate +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::truncate( ) + throw (io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempTruncate.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xTempTruncate->truncate(); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigTruncate.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xOrigTruncate->truncate(); + } +} + + + +// com::sun::star::io::XSeekable +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::seek( ::sal_Int64 location ) + throw (lang::IllegalArgumentException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempSeekable.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xTempSeekable->seek( location ); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigSeekable.is() ) + throw uno::RuntimeException(); + + m_pStreamData->m_xOrigSeekable->seek( location ); + } +} + + +// ------------------------------------------------------------------------ +::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getPosition( ) + throw (io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempSeekable.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xTempSeekable->getPosition(); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigSeekable.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xOrigSeekable->getPosition(); + } +} + + +// ------------------------------------------------------------------------ +::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getLength( ) + throw (io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + if ( m_pStreamData->m_bTransacted ) + { + // temporary stream data should be provided + if ( !m_pStreamData->m_xTempSeekable.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xTempSeekable->getLength(); + } + else + { + // the original stream data should be provided + if ( !m_pStreamData->m_xOrigSeekable.is() ) + throw uno::RuntimeException(); + + return m_pStreamData->m_xOrigSeekable->getLength(); + } +} + +// com::sun::star::beans::XPropertySetInfo +// ------------------------------------------------------------------------ +uno::Sequence< beans::Property > SAL_CALL OTruncatedTransactedFileStream::getProperties() + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Sequence< beans::Property > aProps( 1 ); + aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); + aProps[0].Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) ); + aProps[0].Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY; + + return aProps; +} + + +// ------------------------------------------------------------------------ +beans::Property SAL_CALL OTruncatedTransactedFileStream::getPropertyByName( const ::rtl::OUString& aName ) + throw (beans::UnknownPropertyException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); + + if ( !aName.equals( aTransactionPropName ) ) + throw beans::UnknownPropertyException(); + + beans::Property aProp; + aProp.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); + aProp.Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) ); + aProp.Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY; + + return aProp; +} + + +// ------------------------------------------------------------------------ +::sal_Bool SAL_CALL OTruncatedTransactedFileStream::hasPropertyByName( const ::rtl::OUString& Name ) + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); + return ( Name.equals( aTransactionPropName ) ); +} + + + +// com::sun::star::beans::XPropertySet +// ------------------------------------------------------------------------ +uno::Reference< beans::XPropertySetInfo > SAL_CALL OTruncatedTransactedFileStream::getPropertySetInfo() + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + return static_cast< beans::XPropertySetInfo* >( this ); +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& ) + throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); + if ( aPropertyName.equals( aTransactionPropName ) ) + throw beans::PropertyVetoException(); + + throw beans::UnknownPropertyException(); +} + + +// ------------------------------------------------------------------------ +uno::Any SAL_CALL OTruncatedTransactedFileStream::getPropertyValue( const ::rtl::OUString& PropertyName ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pStreamData ) + throw io::NotConnectedException(); + + ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) ); + if ( PropertyName.equals( aTransactionPropName ) ) + { + uno::Reference< embed::XTransactedObject > xObj; + if ( m_pStreamData->m_bTransacted ) + xObj = static_cast< embed::XTransactedObject* >( new OTransactionHelper( this ) ); + + return uno::makeAny( xObj ); + } + + throw beans::UnknownPropertyException(); +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::addPropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + // not implemented +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::removePropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + // not implemented +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::addVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + // not implemented +} + + +// ------------------------------------------------------------------------ +void SAL_CALL OTruncatedTransactedFileStream::removeVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + // not implemented +} + + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/seekableinput.cxx b/comphelper/source/streaming/seekableinput.cxx new file mode 100644 index 000000000000..f20153ee0aaf --- /dev/null +++ b/comphelper/source/streaming/seekableinput.cxx @@ -0,0 +1,269 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <com/sun/star/io/XOutputStream.hpp> + + +#include <comphelper/seekableinput.hxx> + +using namespace ::com::sun::star; + +namespace comphelper +{ + +const sal_Int32 nConstBufferSize = 32000; + +//--------------------------------------------------------------------------- +void copyInputToOutput_Impl( const uno::Reference< io::XInputStream >& xIn, + const uno::Reference< io::XOutputStream >& xOut ) +{ + sal_Int32 nRead; + uno::Sequence< sal_Int8 > aSequence( nConstBufferSize ); + + do + { + nRead = xIn->readBytes( aSequence, nConstBufferSize ); + if ( nRead < nConstBufferSize ) + { + uno::Sequence< sal_Int8 > aTempBuf( aSequence.getConstArray(), nRead ); + xOut->writeBytes( aTempBuf ); + } + else + xOut->writeBytes( aSequence ); + } + while ( nRead == nConstBufferSize ); +} + +//--------------------------------------------------------------------------- +OSeekableInputWrapper::OSeekableInputWrapper( + const uno::Reference< io::XInputStream >& xInStream, + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +: m_xFactory( xFactory ) +, m_xOriginalStream( xInStream ) +{ + if ( !m_xFactory.is() ) + throw uno::RuntimeException(); +} + +//--------------------------------------------------------------------------- +OSeekableInputWrapper::~OSeekableInputWrapper() +{ +} + +//--------------------------------------------------------------------------- +uno::Reference< io::XInputStream > OSeekableInputWrapper::CheckSeekableCanWrap( + const uno::Reference< io::XInputStream >& xInStream, + const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +{ + // check that the stream is seekable and just wrap it if it is not + uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY ); + if ( xSeek.is() ) + return xInStream; + + uno::Reference< io::XInputStream > xNewStream( + static_cast< io::XInputStream* >( + new OSeekableInputWrapper( xInStream, xFactory ) ) ); + return xNewStream; +} + +//--------------------------------------------------------------------------- +void OSeekableInputWrapper::PrepareCopy_Impl() +{ + if ( !m_xCopyInput.is() ) + { + if ( !m_xFactory.is() ) + throw uno::RuntimeException(); + + uno::Reference< io::XOutputStream > xTempOut( + m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.TempFile")) ), + uno::UNO_QUERY ); + + if ( xTempOut.is() ) + { + copyInputToOutput_Impl( m_xOriginalStream, xTempOut ); + xTempOut->closeOutput(); + + uno::Reference< io::XSeekable > xTempSeek( xTempOut, uno::UNO_QUERY ); + if ( xTempSeek.is() ) + { + xTempSeek->seek( 0 ); + m_xCopyInput = uno::Reference< io::XInputStream >( xTempOut, uno::UNO_QUERY ); + if ( m_xCopyInput.is() ) + m_xCopySeek = xTempSeek; + } + } + } + + if ( !m_xCopyInput.is() ) + throw io::IOException(); +} + +// XInputStream +//--------------------------------------------------------------------------- +sal_Int32 SAL_CALL OSeekableInputWrapper::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xOriginalStream.is() ) + throw io::NotConnectedException(); + + PrepareCopy_Impl(); + + return m_xCopyInput->readBytes( aData, nBytesToRead ); +} + +//--------------------------------------------------------------------------- +sal_Int32 SAL_CALL OSeekableInputWrapper::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xOriginalStream.is() ) + throw io::NotConnectedException(); + + PrepareCopy_Impl(); + + return m_xCopyInput->readSomeBytes( aData, nMaxBytesToRead ); +} + +//--------------------------------------------------------------------------- +void SAL_CALL OSeekableInputWrapper::skipBytes( sal_Int32 nBytesToSkip ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xOriginalStream.is() ) + throw io::NotConnectedException(); + + PrepareCopy_Impl(); + + m_xCopyInput->skipBytes( nBytesToSkip ); +} + +//--------------------------------------------------------------------------- +sal_Int32 SAL_CALL OSeekableInputWrapper::available() + throw ( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xOriginalStream.is() ) + throw io::NotConnectedException(); + + PrepareCopy_Impl(); + + return m_xCopyInput->available(); +} + +//--------------------------------------------------------------------------- +void SAL_CALL OSeekableInputWrapper::closeInput() + throw ( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xOriginalStream.is() ) + throw io::NotConnectedException(); + + m_xOriginalStream->closeInput(); + m_xOriginalStream = uno::Reference< io::XInputStream >(); + + if ( m_xCopyInput.is() ) + { + m_xCopyInput->closeInput(); + m_xCopyInput = uno::Reference< io::XInputStream >(); + } + + m_xCopySeek = uno::Reference< io::XSeekable >(); +} + + +// XSeekable +//--------------------------------------------------------------------------- +void SAL_CALL OSeekableInputWrapper::seek( sal_Int64 location ) + throw ( lang::IllegalArgumentException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xOriginalStream.is() ) + throw io::NotConnectedException(); + + PrepareCopy_Impl(); + + m_xCopySeek->seek( location ); +} + +//--------------------------------------------------------------------------- +sal_Int64 SAL_CALL OSeekableInputWrapper::getPosition() + throw ( io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xOriginalStream.is() ) + throw io::NotConnectedException(); + + PrepareCopy_Impl(); + + return m_xCopySeek->getPosition(); +} + +//--------------------------------------------------------------------------- +sal_Int64 SAL_CALL OSeekableInputWrapper::getLength() + throw ( io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xOriginalStream.is() ) + throw io::NotConnectedException(); + + PrepareCopy_Impl(); + + return m_xCopySeek->getLength(); +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/seqinputstreamserv.cxx b/comphelper/source/streaming/seqinputstreamserv.cxx new file mode 100644 index 000000000000..4e1cc7ade660 --- /dev/null +++ b/comphelper/source/streaming/seqinputstreamserv.cxx @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +#include <sal/config.h> +#include <osl/mutex.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/implbase3.hxx> +#include <comphelper/seqstream.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/io/XSeekableInputStream.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/frame/DoubleInitializationException.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + + +using namespace ::com::sun::star; + +namespace { + +class SequenceInputStreamService: + public ::cppu::WeakImplHelper3< + lang::XServiceInfo, + io::XSeekableInputStream, + lang::XInitialization> +{ +public: + explicit SequenceInputStreamService(); + + // ::com::sun::star::lang::XServiceInfo: + virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( uno::RuntimeException ); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString & ServiceName ) throw ( uno::RuntimeException ); + virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( uno::RuntimeException ); + + // XServiceInfo - static versions (used for component registration) + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static uno::Reference< uno::XInterface > SAL_CALL Create( const uno::Reference< uno::XComponentContext >& ); + + // ::com::sun::star::io::XInputStream: + virtual ::sal_Int32 SAL_CALL readBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ); + virtual ::sal_Int32 SAL_CALL readSomeBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nMaxBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ); + virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ); + virtual ::sal_Int32 SAL_CALL available() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException ); + virtual void SAL_CALL closeInput() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException ); + + // ::com::sun::star::io::XSeekable: + virtual void SAL_CALL seek( ::sal_Int64 location ) throw ( uno::RuntimeException, lang::IllegalArgumentException, io::IOException ); + virtual ::sal_Int64 SAL_CALL getPosition() throw ( uno::RuntimeException, io::IOException ); + virtual ::sal_Int64 SAL_CALL getLength() throw ( uno::RuntimeException, io::IOException ); + + // ::com::sun::star::lang::XInitialization: + virtual void SAL_CALL initialize( const uno::Sequence< ::com::sun::star::uno::Any > & aArguments ) throw ( uno::RuntimeException, uno::Exception ); + +private: + SequenceInputStreamService( SequenceInputStreamService & ); // not defined + void operator =( SequenceInputStreamService & ); // not defined + + virtual ~SequenceInputStreamService() {} + + + ::osl::Mutex m_aMutex; + sal_Bool m_bInitialized; + uno::Reference< io::XInputStream > m_xInputStream; + uno::Reference< io::XSeekable > m_xSeekable; +}; + +SequenceInputStreamService::SequenceInputStreamService() +: m_bInitialized( sal_False ) +{} + +// com.sun.star.uno.XServiceInfo: +::rtl::OUString SAL_CALL SequenceInputStreamService::getImplementationName() throw ( uno::RuntimeException ) +{ + return getImplementationName_static(); +} + +::rtl::OUString SAL_CALL SequenceInputStreamService::getImplementationName_static() +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.SequenceInputStreamService" ) ); +} + +::sal_Bool SAL_CALL SequenceInputStreamService::supportsService( ::rtl::OUString const & serviceName ) throw ( uno::RuntimeException ) +{ + uno::Sequence< ::rtl::OUString > serviceNames = getSupportedServiceNames(); + for ( ::sal_Int32 i = 0; i < serviceNames.getLength(); ++i ) { + if ( serviceNames[i] == serviceName ) + return sal_True; + } + return sal_False; +} + +uno::Sequence< ::rtl::OUString > SAL_CALL SequenceInputStreamService::getSupportedServiceNames() throw ( uno::RuntimeException ) +{ + return getSupportedServiceNames_static(); +} + +uno::Sequence< ::rtl::OUString > SAL_CALL SequenceInputStreamService::getSupportedServiceNames_static() +{ + uno::Sequence< ::rtl::OUString > s( 1 ); + s[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.io.SequenceInputStream" ) ); + return s; +} + +uno::Reference< uno::XInterface > SAL_CALL SequenceInputStreamService::Create( + const uno::Reference< uno::XComponentContext >& ) +{ + return static_cast< ::cppu::OWeakObject * >( new SequenceInputStreamService() ); +} + +// ::com::sun::star::io::XInputStream: +::sal_Int32 SAL_CALL SequenceInputStreamService::readBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xInputStream.is() ) + throw io::NotConnectedException(); + + return m_xInputStream->readBytes( aData, nBytesToRead ); +} + +::sal_Int32 SAL_CALL SequenceInputStreamService::readSomeBytes( uno::Sequence< ::sal_Int8 > & aData, ::sal_Int32 nMaxBytesToRead ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xInputStream.is() ) + throw io::NotConnectedException(); + + return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead ); +} + +void SAL_CALL SequenceInputStreamService::skipBytes( ::sal_Int32 nBytesToSkip ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xInputStream.is() ) + throw io::NotConnectedException(); + + return m_xInputStream->skipBytes( nBytesToSkip ); +} + +::sal_Int32 SAL_CALL SequenceInputStreamService::available() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xInputStream.is() ) + throw io::NotConnectedException(); + + return m_xInputStream->available(); +} + +void SAL_CALL SequenceInputStreamService::closeInput() throw ( uno::RuntimeException, io::NotConnectedException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xInputStream.is() ) + throw io::NotConnectedException(); + + m_xInputStream->closeInput(); + m_xInputStream = uno::Reference< io::XInputStream >(); + m_xSeekable = uno::Reference< io::XSeekable >(); +} + +// ::com::sun::star::io::XSeekable: +void SAL_CALL SequenceInputStreamService::seek( ::sal_Int64 location ) throw ( uno::RuntimeException, lang::IllegalArgumentException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xSeekable.is() ) + throw io::NotConnectedException(); + + m_xSeekable->seek( location ); +} + +::sal_Int64 SAL_CALL SequenceInputStreamService::getPosition() throw ( uno::RuntimeException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xSeekable.is() ) + throw io::NotConnectedException(); + + return m_xSeekable->getPosition(); +} + +::sal_Int64 SAL_CALL SequenceInputStreamService::getLength() throw ( uno::RuntimeException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xSeekable.is() ) + throw io::NotConnectedException(); + + return m_xSeekable->getLength(); +} + +// ::com::sun::star::lang::XInitialization: +void SAL_CALL SequenceInputStreamService::initialize( const uno::Sequence< ::com::sun::star::uno::Any > & aArguments ) throw ( uno::RuntimeException, uno::Exception ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bInitialized ) + throw frame::DoubleInitializationException(); + + if ( aArguments.getLength() != 1 ) + throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wrong number of arguments!\n")), + uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), + 1 ); + + uno::Sequence< sal_Int8 > aSeq; + if ( aArguments[0] >>= aSeq ) + { + uno::Reference< io::XInputStream > xInputStream( + static_cast< ::cppu::OWeakObject* >( new ::comphelper::SequenceInputStream( aSeq ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< io::XSeekable > xSeekable( xInputStream, uno::UNO_QUERY_THROW ); + m_xInputStream = xInputStream; + m_xSeekable = xSeekable; + m_bInitialized = sal_True; + } + else + throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unexpected type of argument!\n")), + uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), + 1 ); +} + +} // anonymous namespace + +void createRegistryInfo_SequenceInputStream() +{ + static ::comphelper::module::OAutoRegistration< SequenceInputStreamService > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/seqoutputstreamserv.cxx b/comphelper/source/streaming/seqoutputstreamserv.cxx new file mode 100644 index 000000000000..02cfd2fe7bc6 --- /dev/null +++ b/comphelper/source/streaming/seqoutputstreamserv.cxx @@ -0,0 +1,175 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include "comphelper_module.hxx" + +#include <sal/config.h> +#include <osl/mutex.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/implbase2.hxx> +#include <comphelper/seqstream.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/io/XSequenceOutputStream.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +using namespace ::com::sun::star; + + +namespace { + +class SequenceOutputStreamService: +public ::cppu::WeakImplHelper2 < lang::XServiceInfo, io::XSequenceOutputStream > +{ +public: + explicit SequenceOutputStreamService(); + + // ::com::sun::star::lang::XServiceInfo: + virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( uno::RuntimeException ); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString & ServiceName ) throw ( uno::RuntimeException ); + virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( uno::RuntimeException ); + + // XServiceInfo - static versions (used for component registration) + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static uno::Reference< uno::XInterface > SAL_CALL Create( const uno::Reference< uno::XComponentContext >& ); + + // ::com::sun::star::io::XOutputStream: + virtual void SAL_CALL writeBytes( const uno::Sequence< ::sal_Int8 > & aData ) throw ( io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException ); + virtual void SAL_CALL flush() throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ); + virtual void SAL_CALL closeOutput() throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ); + + // ::com::sun::star::io::XSequenceOutputStream: + virtual uno::Sequence< ::sal_Int8 > SAL_CALL getWrittenBytes( ) throw ( io::NotConnectedException, io::IOException, uno::RuntimeException); + +private: + SequenceOutputStreamService( SequenceOutputStreamService & ); //not defined + void operator =( SequenceOutputStreamService & ); //not defined + + virtual ~SequenceOutputStreamService() {}; + + + ::osl::Mutex m_aMutex; + uno::Reference< io::XOutputStream > m_xOutputStream; + uno::Sequence< ::sal_Int8 > m_aSequence; +}; +SequenceOutputStreamService::SequenceOutputStreamService() +{ + m_xOutputStream.set( static_cast < ::cppu::OWeakObject* >( new ::comphelper::OSequenceOutputStream( m_aSequence ) ), uno::UNO_QUERY_THROW ); +} + +// com.sun.star.uno.XServiceInfo: +::rtl::OUString SAL_CALL SequenceOutputStreamService::getImplementationName() throw ( uno::RuntimeException ) +{ + return getImplementationName_static(); +} + +::rtl::OUString SAL_CALL SequenceOutputStreamService::getImplementationName_static() +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.SequenceOutputStreamService" ) ); +} + +::sal_Bool SAL_CALL SequenceOutputStreamService::supportsService( ::rtl::OUString const & serviceName ) throw ( uno::RuntimeException ) +{ + uno::Sequence< ::rtl::OUString > serviceNames = getSupportedServiceNames(); + for ( ::sal_Int32 i = 0; i < serviceNames.getLength(); ++i ) { + if ( serviceNames[i] == serviceName ) + return sal_True; + } + return sal_False; +} + +uno::Sequence< ::rtl::OUString > SAL_CALL SequenceOutputStreamService::getSupportedServiceNames() throw ( uno::RuntimeException ) +{ + return getSupportedServiceNames_static(); +} + +uno::Sequence< ::rtl::OUString > SAL_CALL SequenceOutputStreamService::getSupportedServiceNames_static() +{ + uno::Sequence< ::rtl::OUString > s( 1 ); + s[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.SequenceOutputStream" ) ); + return s; +} + +uno::Reference< uno::XInterface > SAL_CALL SequenceOutputStreamService::Create( + const uno::Reference< uno::XComponentContext >& ) +{ + return static_cast< ::cppu::OWeakObject * >( new SequenceOutputStreamService()); +} + +// ::com::sun::star::io::XOutputStream: +void SAL_CALL SequenceOutputStreamService::writeBytes( const uno::Sequence< ::sal_Int8 > & aData ) throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xOutputStream.is() ) + throw io::NotConnectedException(); + + m_xOutputStream->writeBytes( aData ); + m_aSequence = aData; +} + +void SAL_CALL SequenceOutputStreamService::flush() throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xOutputStream.is() ) + throw io::NotConnectedException(); + + m_xOutputStream->flush(); +}; + +void SAL_CALL SequenceOutputStreamService::closeOutput() throw ( uno::RuntimeException, io::NotConnectedException, io::BufferSizeExceededException, io::IOException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xOutputStream.is() ) + throw io::NotConnectedException(); + + m_xOutputStream->closeOutput(); + m_xOutputStream = uno::Reference< io::XOutputStream >(); +} + +// ::com::sun::star::io::XSequenceOutputStream: +uno::Sequence< ::sal_Int8 > SAL_CALL SequenceOutputStreamService::getWrittenBytes() throw ( io::NotConnectedException, io::IOException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_xOutputStream.is() ) + throw io::NotConnectedException(); + + m_xOutputStream->flush(); + return m_aSequence; +} + +} // anonymous namespace + +void createRegistryInfo_SequenceOutputStream() +{ + static ::comphelper::module::OAutoRegistration< SequenceOutputStreamService > aAutoRegistration; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx new file mode 100644 index 000000000000..d2852b70a901 --- /dev/null +++ b/comphelper/source/streaming/seqstream.cxx @@ -0,0 +1,246 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/seqstream.hxx> + +#include <memory.h> // for memcpy + +namespace comphelper +{ +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; +using namespace ::osl; + +//--------------------------------------------------------------------------------------------- +// class SequenceInputStream +//--------------------------------------------------------------------------------------------- + +//------------------------------------------------------------------ +SequenceInputStream::SequenceInputStream(const ByteSequence& rData) +: m_aData(rData) +, m_nPos(0) +{ +} + +// checks if closed, returns available size, not mutex-protected +//------------------------------------------------------------------ +inline sal_Int32 SequenceInputStream::avail() +{ + if (m_nPos == -1) + throw NotConnectedException(::rtl::OUString(), *this); + + return m_aData.getLength() - m_nPos; +} + +// com::sun::star::io::XInputStream +//------------------------------------------------------------------ +sal_Int32 SAL_CALL SequenceInputStream::readBytes( Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead ) + throw(NotConnectedException, BufferSizeExceededException, + IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nAvail = avail(); + + if (nBytesToRead < 0) + throw BufferSizeExceededException(::rtl::OUString(),*this); + + if (nAvail < nBytesToRead) + nBytesToRead = nAvail; + + aData.realloc(nBytesToRead); + memcpy(aData.getArray(), m_aData.getConstArray() + m_nPos, nBytesToRead); + m_nPos += nBytesToRead; + + return nBytesToRead; +} + +//------------------------------------------------------------------ +sal_Int32 SAL_CALL SequenceInputStream::readSomeBytes( Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead ) + throw(NotConnectedException, BufferSizeExceededException, + IOException, RuntimeException) +{ + // all data is available at once + return readBytes(aData, nMaxBytesToRead); +} + +//------------------------------------------------------------------ +void SAL_CALL SequenceInputStream::skipBytes( sal_Int32 nBytesToSkip ) + throw(NotConnectedException, BufferSizeExceededException, + IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + sal_Int32 nAvail = avail(); + + if (nBytesToSkip < 0) + throw BufferSizeExceededException(::rtl::OUString(),*this); + + if (nAvail < nBytesToSkip) + nBytesToSkip = nAvail; + + m_nPos += nBytesToSkip; +} + +//------------------------------------------------------------------ +sal_Int32 SAL_CALL SequenceInputStream::available( ) + throw(NotConnectedException, IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + return avail(); +} + +//------------------------------------------------------------------ +void SAL_CALL SequenceInputStream::closeInput( ) + throw(NotConnectedException, IOException, RuntimeException) +{ + if (m_nPos == -1) + throw NotConnectedException(::rtl::OUString(), *this); + + m_nPos = -1; +} + +void SAL_CALL SequenceInputStream::seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException) +{ + if ( location > m_aData.getLength() || location < 0 || location > SAL_MAX_INT32 ) + throw IllegalArgumentException(); + m_nPos = (sal_Int32) location; +} + +sal_Int64 SAL_CALL SequenceInputStream::getPosition() throw (IOException, RuntimeException) +{ + return m_nPos; +} + +sal_Int64 SAL_CALL SequenceInputStream::getLength( ) throw (IOException, RuntimeException) +{ + return m_aData.getLength(); +} + +//-------------------------------------------------------------------------- +OSequenceOutputStream::OSequenceOutputStream(Sequence< sal_Int8 >& _rSeq, double _nResizeFactor, sal_Int32 _nMinimumResize, sal_Int32 _nMaximumResize) + :m_rSequence(_rSeq) + ,m_nResizeFactor(_nResizeFactor) + ,m_nMinimumResize(_nMinimumResize) + ,m_nMaximumResize(_nMaximumResize) + ,m_nSize(0) // starting at position 0 + ,m_bConnected(sal_True) +{ + OSL_ENSURE(m_nResizeFactor > 1, "OSequenceOutputStream::OSequenceOutputStream : invalid resize factor !"); + OSL_ENSURE((m_nMaximumResize < 0) || (m_nMaximumResize > m_nMinimumResize), + "OSequenceOutputStream::OSequenceOutputStream : these limits don't make any sense !"); + + if (m_nResizeFactor <= 1) + m_nResizeFactor = 1.3; + if ((m_nMaximumResize >= 0) && (m_nMaximumResize <= m_nMinimumResize)) + m_nMaximumResize = m_nMinimumResize * 2; + // this heuristic is as good as any other ... supply better parameters if you don't like it :) +} + +//-------------------------------------------------------------------------- +void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rData ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + MutexGuard aGuard(m_aMutex); + if (!m_bConnected) + throw NotConnectedException(); + + // ensure the sequence has enoungh space left + if (m_nSize + _rData.getLength() > m_rSequence.getLength()) + { + sal_Int32 nCurrentLength = m_rSequence.getLength(); + sal_Int32 nNewLength = static_cast< sal_Int32 >( + nCurrentLength * m_nResizeFactor); + + if (m_nMinimumResize > nNewLength - nCurrentLength) + // we have a minimum so it's not too inefficient for small sequences and small write requests + nNewLength = nCurrentLength + m_nMinimumResize; + + if ((m_nMaximumResize > 0) && (nNewLength - nCurrentLength > m_nMaximumResize)) + // such a large step is not allowed + nNewLength = nCurrentLength + m_nMaximumResize; + + if (nNewLength < m_nSize + _rData.getLength()) + { // it's not enough .... the data would not fit + + // let's take the double amount of the length of the data to be written, as the next write + // request could be as large as this one + sal_Int32 nNewGrowth = _rData.getLength() * 2; + if ((m_nMaximumResize > 0) && (nNewGrowth > m_nMaximumResize)) + { // we came to the limit, again ... + nNewGrowth = m_nMaximumResize; + if (nNewGrowth + nCurrentLength < m_nSize + _rData.getLength()) + // but it would not fit if we respect the limit + nNewGrowth = m_nSize + _rData.getLength() - nCurrentLength; + } + nNewLength = nCurrentLength + nNewGrowth; + } + + // round it off to the next multiple of 4 ... + nNewLength = (nNewLength + 3) / 4 * 4; + + m_rSequence.realloc(nNewLength); + } + + OSL_ENSURE(m_rSequence.getLength() >= m_nSize + _rData.getLength(), + "ooops ... the realloc algorithm seems to be wrong :( !"); + + memcpy(m_rSequence.getArray() + m_nSize, _rData.getConstArray(), _rData.getLength()); + m_nSize += _rData.getLength(); +} + +//-------------------------------------------------------------------------- +void SAL_CALL OSequenceOutputStream::flush( ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + MutexGuard aGuard(m_aMutex); + if (!m_bConnected) + throw NotConnectedException(); + + // cut the sequence to the real size + m_rSequence.realloc(m_nSize); +} + +//-------------------------------------------------------------------------- +void SAL_CALL OSequenceOutputStream::closeOutput( ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + MutexGuard aGuard(m_aMutex); + if (!m_bConnected) + throw NotConnectedException(); + + // cut the sequence to the real size + m_rSequence.realloc(m_nSize); + // and don't allow any further accesses + m_bConnected = sal_False; +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/streaming/streamsection.cxx b/comphelper/source/streaming/streamsection.cxx new file mode 100644 index 000000000000..1fa71fd42682 --- /dev/null +++ b/comphelper/source/streaming/streamsection.cxx @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/streamsection.hxx> +#include <osl/diagnose.h> + +namespace comphelper +{ + +//------------------------------------------------------------------------- +OStreamSection::OStreamSection(const staruno::Reference< stario::XDataInputStream >& _rxInput) + :m_xMarkStream(_rxInput, ::com::sun::star::uno::UNO_QUERY) + ,m_xInStream(_rxInput) + ,m_nBlockStart(-1) + ,m_nBlockLen(-1) +{ + OSL_ENSURE(m_xInStream.is() && m_xMarkStream.is(), "OStreamSection::OStreamSection : invalid argument !"); + if (m_xInStream.is() && m_xMarkStream.is()) + { + m_nBlockLen = _rxInput->readLong(); + m_nBlockStart = m_xMarkStream->createMark(); + } +} + +//------------------------------------------------------------------------- +OStreamSection::OStreamSection(const staruno::Reference< stario::XDataOutputStream >& _rxOutput, sal_Int32 _nPresumedLength) + :m_xMarkStream(_rxOutput, ::com::sun::star::uno::UNO_QUERY) + ,m_xOutStream(_rxOutput) + ,m_nBlockStart(-1) + ,m_nBlockLen(-1) +{ + OSL_ENSURE(m_xOutStream.is() && m_xMarkStream.is(), "OStreamSection::OStreamSection : invalid argument !"); + if (m_xOutStream.is() && m_xMarkStream.is()) + { + m_nBlockStart = m_xMarkStream->createMark(); + // a placeholder where we will write the overall length (within the destructor) + if (_nPresumedLength > 0) + m_nBlockLen = _nPresumedLength + sizeof(m_nBlockLen); + // as the caller did not consider - of course - the placeholder we are going to write + else + m_nBlockLen = 0; + m_xOutStream->writeLong(m_nBlockLen); + } +} + +//------------------------------------------------------------------------- +OStreamSection::~OStreamSection() +{ + try + { // don't allow any exceptions to leave this block, this may be called during the stack unwinding of an exception + // handling routing + if (m_xInStream.is() && m_xMarkStream.is()) + { // we're working on an input stream + m_xMarkStream->jumpToMark(m_nBlockStart); + m_xInStream->skipBytes(m_nBlockLen); + m_xMarkStream->deleteMark(m_nBlockStart); + } + else if (m_xOutStream.is() && m_xMarkStream.is()) + { + sal_Int32 nRealBlockLength = m_xMarkStream->offsetToMark(m_nBlockStart) - sizeof(m_nBlockLen); + if (m_nBlockLen && (m_nBlockLen == nRealBlockLength)) + // nothing to do : the estimation the caller gave us (in the ctor) was correct + m_xMarkStream->deleteMark(m_nBlockStart); + else + { // the estimation was wrong (or we didn't get one) + m_nBlockLen = nRealBlockLength; + m_xMarkStream->jumpToMark(m_nBlockStart); + m_xOutStream->writeLong(m_nBlockLen); + m_xMarkStream->jumpToFurthest(); + m_xMarkStream->deleteMark(m_nBlockStart); + } + } + } + catch(const staruno::Exception&) + { + } +} +// ----------------------------------------------------------------------------- +sal_Int32 OStreamSection::available() +{ + sal_Int32 nBytes = 0; + try + { // don't allow any exceptions to leave this block, this may be called during the stack unwinding of an exception + if (m_xInStream.is() && m_xMarkStream.is()) + nBytes = m_xMarkStream->offsetToMark(m_nBlockStart) - sizeof(m_nBlockLen); + } + catch(const staruno::Exception&) + { + } + return nBytes; +} +// ----------------------------------------------------------------------------- + +} // namespace comphelper + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/xml/attributelist.cxx b/comphelper/source/xml/attributelist.cxx new file mode 100644 index 000000000000..2442fd69f106 --- /dev/null +++ b/comphelper/source/xml/attributelist.cxx @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" +#include <comphelper/attributelist.hxx> +#include <osl/diagnose.h> + +#include <vector> + +using namespace osl; +using namespace com::sun::star; + +using ::rtl::OUString; + +namespace comphelper { + +struct TagAttribute_Impl +{ + TagAttribute_Impl(){} + TagAttribute_Impl( const OUString &aName, const OUString &aType, + const OUString &aValue ) + { + this->sName = aName; + this->sType = aType; + this->sValue = aValue; + } + + OUString sName; + OUString sType; + OUString sValue; +}; + +struct AttributeList_Impl +{ + AttributeList_Impl() + { + // performance improvement during adding + vecAttribute.reserve(20); + } + ::std::vector<struct TagAttribute_Impl> vecAttribute; +}; + +sal_Int16 SAL_CALL AttributeList::getLength(void) throw( ::com::sun::star::uno::RuntimeException ) +{ + return (sal_Int16)(m_pImpl->vecAttribute.size()); +} + +OUString SAL_CALL AttributeList::getNameByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException ) +{ + return ( i < static_cast < sal_Int16 > (m_pImpl->vecAttribute.size()) ) ? m_pImpl->vecAttribute[i].sName : OUString(); +} + +OUString SAL_CALL AttributeList::getTypeByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException ) +{ + if( i < static_cast < sal_Int16 > (m_pImpl->vecAttribute.size() ) ) { + return m_pImpl->vecAttribute[i].sType; + } + return OUString(); +} + +OUString SAL_CALL AttributeList::getValueByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException ) +{ + return ( i < static_cast < sal_Int16 > (m_pImpl->vecAttribute.size() ) ) ? m_pImpl->vecAttribute[i].sValue : OUString(); +} + +OUString SAL_CALL AttributeList::getTypeByName( const OUString& sName ) throw( ::com::sun::star::uno::RuntimeException ) +{ + ::std::vector<struct TagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin(); + + for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) { + if( (*ii).sName == sName ) { + return (*ii).sType; + } + } + return OUString(); +} + +OUString SAL_CALL AttributeList::getValueByName(const OUString& sName) throw( ::com::sun::star::uno::RuntimeException ) +{ + ::std::vector<struct TagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin(); + + for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) { + if( (*ii).sName == sName ) { + return (*ii).sValue; + } + } + return OUString(); +} + + +AttributeList::AttributeList() +{ + m_pImpl = new AttributeList_Impl; +} + + + +AttributeList::~AttributeList() +{ + delete m_pImpl; +} + +void AttributeList::AddAttribute( const OUString &sName , + const OUString &sType , + const OUString &sValue ) +{ + m_pImpl->vecAttribute.push_back( TagAttribute_Impl( sName , sType , sValue ) ); +} + +void AttributeList::Clear() +{ + m_pImpl->vecAttribute.clear(); + + OSL_ENSURE( ! getLength(), "Length > 0 after AttributeList::Clear!"); +} + +void AttributeList::RemoveAttribute( const OUString sName ) +{ + ::std::vector<struct TagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin(); + + for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) { + if( (*ii).sName == sName ) { + m_pImpl->vecAttribute.erase( ii ); + break; + } + } +} + + +void AttributeList::SetAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList > &r ) +{ + Clear(); + AppendAttributeList( r ); +} + +void AttributeList::AppendAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList > &r ) +{ + OSL_ENSURE( r.is(), "r isn't!" ); + + sal_Int32 nMax = r->getLength(); + sal_Int32 nTotalSize = m_pImpl->vecAttribute.size() + nMax; + m_pImpl->vecAttribute.reserve( nTotalSize ); + + for( sal_Int16 i = 0 ; i < nMax ; i ++ ) { + m_pImpl->vecAttribute.push_back( TagAttribute_Impl( + r->getNameByIndex( i ) , + r->getTypeByIndex( i ) , + r->getValueByIndex( i ))); + } + + OSL_ENSURE( nTotalSize == getLength(), "nTotalSize != getLength()"); +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/xml/ofopxmlhelper.cxx b/comphelper/source/xml/ofopxmlhelper.cxx new file mode 100644 index 000000000000..9df5977efb04 --- /dev/null +++ b/comphelper/source/xml/ofopxmlhelper.cxx @@ -0,0 +1,457 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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_comphelper.hxx" + +#include <com/sun/star/beans/StringPair.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +#include <comphelper/ofopxmlhelper.hxx> +#include <comphelper/attributelist.hxx> + +#define RELATIONINFO_FORMAT 0 +#define CONTENTTYPE_FORMAT 1 +#define FORMAT_MAX_ID CONTENTTYPE_FORMAT + +using namespace ::com::sun::star; + +namespace comphelper { + +// ----------------------------------- +uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadRelationsInfoSequence( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString aStreamName, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + ::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/" ) ); + aStringID += aStreamName; + return ReadSequence_Impl( xInStream, aStringID, RELATIONINFO_FORMAT, xFactory ); +} + +// ----------------------------------- +uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadContentTypeSequence( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + ::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[Content_Types].xml" ) ); + return ReadSequence_Impl( xInStream, aStringID, CONTENTTYPE_FORMAT, xFactory ); +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::WriteRelationsInfoSequence( const uno::Reference< io::XOutputStream >& xOutStream, const uno::Sequence< uno::Sequence< beans::StringPair > >& aSequence, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + if ( !xOutStream.is() ) + throw uno::RuntimeException(); + + uno::Reference< io::XActiveDataSource > xWriterSource( + xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< xml::sax::XDocumentHandler > xWriterHandler( xWriterSource, uno::UNO_QUERY_THROW ); + + xWriterSource->setOutputStream( xOutStream ); + + ::rtl::OUString aRelListElement( RTL_CONSTASCII_USTRINGPARAM( "Relationships" ) ); + ::rtl::OUString aRelElement( RTL_CONSTASCII_USTRINGPARAM( "Relationship" ) ); + ::rtl::OUString aIDAttr( RTL_CONSTASCII_USTRINGPARAM( "Id" ) ); + ::rtl::OUString aTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ); + ::rtl::OUString aTargetModeAttr( RTL_CONSTASCII_USTRINGPARAM( "TargetMode" ) ); + ::rtl::OUString aTargetAttr( RTL_CONSTASCII_USTRINGPARAM( "Target" ) ); + ::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) ); + ::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) ); + + // write the namespace + AttributeList* pRootAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList ); + pRootAttrList->AddAttribute( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ), + aCDATAString, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://schemas.openxmlformats.org/package/2006/relationships" ) ) ); + + xWriterHandler->startDocument(); + xWriterHandler->startElement( aRelListElement, xRootAttrList ); + + for ( sal_Int32 nInd = 0; nInd < aSequence.getLength(); nInd++ ) + { + AttributeList *pAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList ); + for( sal_Int32 nSecInd = 0; nSecInd < aSequence[nInd].getLength(); nSecInd++ ) + { + if ( aSequence[nInd][nSecInd].First.equals( aIDAttr ) + || aSequence[nInd][nSecInd].First.equals( aTypeAttr ) + || aSequence[nInd][nSecInd].First.equals( aTargetModeAttr ) + || aSequence[nInd][nSecInd].First.equals( aTargetAttr ) ) + { + pAttrList->AddAttribute( aSequence[nInd][nSecInd].First, aCDATAString, aSequence[nInd][nSecInd].Second ); + } + else + { + // TODO/LATER: should the extensions be allowed? + throw lang::IllegalArgumentException(); + } + } + + xWriterHandler->startElement( aRelElement, xAttrList ); + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aRelElement ); + } + + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aRelListElement ); + xWriterHandler->endDocument(); +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::WriteContentSequence( const uno::Reference< io::XOutputStream >& xOutStream, const uno::Sequence< beans::StringPair >& aDefaultsSequence, const uno::Sequence< beans::StringPair >& aOverridesSequence, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + if ( !xOutStream.is() ) + throw uno::RuntimeException(); + + uno::Reference< io::XActiveDataSource > xWriterSource( + xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< xml::sax::XDocumentHandler > xWriterHandler( xWriterSource, uno::UNO_QUERY_THROW ); + + xWriterSource->setOutputStream( xOutStream ); + + ::rtl::OUString aTypesElement( RTL_CONSTASCII_USTRINGPARAM( "Types" ) ); + ::rtl::OUString aDefaultElement( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ); + ::rtl::OUString aOverrideElement( RTL_CONSTASCII_USTRINGPARAM( "Override" ) ); + ::rtl::OUString aExtensionAttr( RTL_CONSTASCII_USTRINGPARAM( "Extension" ) ); + ::rtl::OUString aPartNameAttr( RTL_CONSTASCII_USTRINGPARAM( "PartName" ) ); + ::rtl::OUString aContentTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ); + ::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) ); + ::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) ); + + // write the namespace + AttributeList* pRootAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList ); + pRootAttrList->AddAttribute( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ), + aCDATAString, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://schemas.openxmlformats.org/package/2006/content-types" ) ) ); + + xWriterHandler->startDocument(); + xWriterHandler->startElement( aTypesElement, xRootAttrList ); + + for ( sal_Int32 nInd = 0; nInd < aDefaultsSequence.getLength(); nInd++ ) + { + AttributeList *pAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList ); + pAttrList->AddAttribute( aExtensionAttr, aCDATAString, aDefaultsSequence[nInd].First ); + pAttrList->AddAttribute( aContentTypeAttr, aCDATAString, aDefaultsSequence[nInd].Second ); + + xWriterHandler->startElement( aDefaultElement, xAttrList ); + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aDefaultElement ); + } + + for ( sal_Int32 nInd = 0; nInd < aOverridesSequence.getLength(); nInd++ ) + { + AttributeList *pAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList ); + pAttrList->AddAttribute( aPartNameAttr, aCDATAString, aOverridesSequence[nInd].First ); + pAttrList->AddAttribute( aContentTypeAttr, aCDATAString, aOverridesSequence[nInd].Second ); + + xWriterHandler->startElement( aOverrideElement, xAttrList ); + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aOverrideElement ); + } + + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aTypesElement ); + xWriterHandler->endDocument(); + +} + +// ================================================================================== + +// ----------------------------------- +uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadSequence_Impl( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString& aStringID, sal_uInt16 nFormat, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + if ( !xFactory.is() || !xInStream.is() || nFormat > FORMAT_MAX_ID ) + throw uno::RuntimeException(); + + uno::Sequence< uno::Sequence< beans::StringPair > > aResult; + + uno::Reference< xml::sax::XParser > xParser( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ) ) ), uno::UNO_QUERY_THROW ); + + OFOPXMLHelper* pHelper = new OFOPXMLHelper( nFormat ); + uno::Reference< xml::sax::XDocumentHandler > xHelper( static_cast< xml::sax::XDocumentHandler* >( pHelper ) ); + xml::sax::InputSource aParserInput; + aParserInput.aInputStream = xInStream; + aParserInput.sSystemId = aStringID; + xParser->setDocumentHandler( xHelper ); + xParser->parseStream( aParserInput ); + xParser->setDocumentHandler( uno::Reference < xml::sax::XDocumentHandler > () ); + + return pHelper->GetParsingResult(); +} + +// ----------------------------------- +OFOPXMLHelper::OFOPXMLHelper( sal_uInt16 nFormat ) +: m_nFormat( nFormat ) +, m_aRelListElement( RTL_CONSTASCII_USTRINGPARAM( "Relationships" ) ) +, m_aRelElement( RTL_CONSTASCII_USTRINGPARAM( "Relationship" ) ) +, m_aIDAttr( RTL_CONSTASCII_USTRINGPARAM( "Id" ) ) +, m_aTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) +, m_aTargetModeAttr( RTL_CONSTASCII_USTRINGPARAM( "TargetMode" ) ) +, m_aTargetAttr( RTL_CONSTASCII_USTRINGPARAM( "Target" ) ) +, m_aTypesElement( RTL_CONSTASCII_USTRINGPARAM( "Types" ) ) +, m_aDefaultElement( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ) +, m_aOverrideElement( RTL_CONSTASCII_USTRINGPARAM( "Override" ) ) +, m_aExtensionAttr( RTL_CONSTASCII_USTRINGPARAM( "Extension" ) ) +, m_aPartNameAttr( RTL_CONSTASCII_USTRINGPARAM( "PartName" ) ) +, m_aContentTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ) +{ +} + +// ----------------------------------- +OFOPXMLHelper::~OFOPXMLHelper() +{ +} + +// ----------------------------------- +uno::Sequence< uno::Sequence< beans::StringPair > > OFOPXMLHelper::GetParsingResult() +{ + if ( m_aElementsSeq.getLength() ) + throw uno::RuntimeException(); // the parsing has still not finished! + + return m_aResultSeq; +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::startDocument() + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::endDocument() + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) + throw( xml::sax::SAXException, uno::RuntimeException ) +{ + if ( m_nFormat == RELATIONINFO_FORMAT ) + { + if ( aName == m_aRelListElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + + if ( nNewLength != 1 ) + throw xml::sax::SAXException(); // TODO: this element must be the first level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + return; // nothing to do + } + else if ( aName == m_aRelElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + if ( nNewLength != 2 ) + throw xml::sax::SAXException(); // TODO: this element must be the second level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + sal_Int32 nNewEntryNum = m_aResultSeq.getLength() + 1; + m_aResultSeq.realloc( nNewEntryNum ); + sal_Int32 nAttrNum = 0; + m_aResultSeq[nNewEntryNum-1].realloc( 4 ); // the maximal expected number of arguments is 4 + + ::rtl::OUString aIDValue = xAttribs->getValueByName( m_aIDAttr ); + if ( !aIDValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the ID value must present + + ::rtl::OUString aTypeValue = xAttribs->getValueByName( m_aTypeAttr ); + ::rtl::OUString aTargetValue = xAttribs->getValueByName( m_aTargetAttr ); + ::rtl::OUString aTargetModeValue = xAttribs->getValueByName( m_aTargetModeAttr ); + + m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aIDAttr; + m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aIDValue; + + if ( aTypeValue.getLength() ) + { + m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTypeAttr; + m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTypeValue; + } + + if ( aTargetValue.getLength() ) + { + m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTargetAttr; + m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTargetValue; + } + + if ( aTargetModeValue.getLength() ) + { + m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTargetModeAttr; + m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTargetModeValue; + } + + m_aResultSeq[nNewEntryNum-1].realloc( nAttrNum ); + } + else + throw xml::sax::SAXException(); // TODO: no other elements expected! + } + else if ( m_nFormat == CONTENTTYPE_FORMAT ) + { + if ( aName == m_aTypesElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + + if ( nNewLength != 1 ) + throw xml::sax::SAXException(); // TODO: this element must be the first level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + if ( !m_aResultSeq.getLength() ) + m_aResultSeq.realloc( 2 ); + + return; // nothing to do + } + else if ( aName == m_aDefaultElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + if ( nNewLength != 2 ) + throw xml::sax::SAXException(); // TODO: this element must be the second level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + if ( !m_aResultSeq.getLength() ) + m_aResultSeq.realloc( 2 ); + + if ( m_aResultSeq.getLength() != 2 ) + throw uno::RuntimeException(); + + ::rtl::OUString aExtensionValue = xAttribs->getValueByName( m_aExtensionAttr ); + if ( !aExtensionValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the Extension value must present + + ::rtl::OUString aContentTypeValue = xAttribs->getValueByName( m_aContentTypeAttr ); + if ( !aContentTypeValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the ContentType value must present + + sal_Int32 nNewResultLen = m_aResultSeq[0].getLength() + 1; + m_aResultSeq[0].realloc( nNewResultLen ); + + m_aResultSeq[0][nNewResultLen-1].First = aExtensionValue; + m_aResultSeq[0][nNewResultLen-1].Second = aContentTypeValue; + } + else if ( aName == m_aOverrideElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + if ( nNewLength != 2 ) + throw xml::sax::SAXException(); // TODO: this element must be the second level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + if ( !m_aResultSeq.getLength() ) + m_aResultSeq.realloc( 2 ); + + if ( m_aResultSeq.getLength() != 2 ) + throw uno::RuntimeException(); + + ::rtl::OUString aPartNameValue = xAttribs->getValueByName( m_aPartNameAttr ); + if ( !aPartNameValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the PartName value must present + + ::rtl::OUString aContentTypeValue = xAttribs->getValueByName( m_aContentTypeAttr ); + if ( !aContentTypeValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the ContentType value must present + + sal_Int32 nNewResultLen = m_aResultSeq[1].getLength() + 1; + m_aResultSeq[1].realloc( nNewResultLen ); + + m_aResultSeq[1][nNewResultLen-1].First = aPartNameValue; + m_aResultSeq[1][nNewResultLen-1].Second = aContentTypeValue; + } + else + throw xml::sax::SAXException(); // TODO: no other elements expected! + } + else + throw xml::sax::SAXException(); // TODO: no other elements expected! +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::endElement( const ::rtl::OUString& aName ) + throw( xml::sax::SAXException, uno::RuntimeException ) +{ + if ( m_nFormat == RELATIONINFO_FORMAT || m_nFormat == CONTENTTYPE_FORMAT ) + { + sal_Int32 nLength = m_aElementsSeq.getLength(); + if ( nLength <= 0 ) + throw xml::sax::SAXException(); // TODO: no other end elements expected! + + if ( !m_aElementsSeq[nLength-1].equals( aName ) ) + throw xml::sax::SAXException(); // TODO: unexpected element ended + + m_aElementsSeq.realloc( nLength - 1 ); + } +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::characters( const ::rtl::OUString& /*aChars*/ ) + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ ) + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ ) + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/test/uno_iterators/uno_iterators.cxx b/comphelper/test/uno_iterators/uno_iterators.cxx new file mode 100644 index 000000000000..a242c614b508 --- /dev/null +++ b/comphelper/test/uno_iterators/uno_iterators.cxx @@ -0,0 +1,221 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General 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 <algorithm> +#include <comphelper/stlunosequence.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <iostream> +#include <list> +#include <rtl/textenc.h> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> +#include <vector> + +using namespace ::comphelper; +using namespace ::com::sun::star::uno; +using namespace ::rtl; +using namespace ::std; + +// some helpers for testing (imperative) +void fill_testdata(Sequence<OUString>& seq) +{ + OUStringBuffer buf; + for(sal_Int32 i=0; i<seq.getLength(); i++) + { + buf.appendAscii("Sampletext "); + buf.append(i); + seq[i] = buf.makeStringAndClear(); + } +} + +void print_oustring(const OUString& ustr) +{ cout << OUStringToOString(ustr, RTL_TEXTENCODING_ASCII_US).getStr() << endl; } + +void print_sequence(const Sequence<OUString>& seq) +{ + cout << "Sequence of " << seq.getLength() << " OUStrings: " << endl; + for(sal_Int32 i=0; i<seq.getLength(); i++) + print_oustring(seq[i]); + cout << endl; +} + +// some helpers for testing (functional) +class TestdataGenerator +{ + public: + TestdataGenerator() : m_Index(0) {}; + OUString operator()() { return m_Buf.appendAscii("Sampletext ").append(m_Index++).makeStringAndClear(); }; + OUStringBuffer m_Buf; + sal_Int32 m_Index; +}; + +void fill_testdata_stl(StlUnoSequence<OUString>& stl_seq) +{ + generate(stl_seq.begin(), stl_seq.end(), TestdataGenerator()); +} + +void print_sequence_stl(const StlUnoSequence<OUString>& stl_seq) +{ + cout << "Sequence of " << stl_seq.size() << " OUStrings: " << endl; + for_each(stl_seq.begin(), stl_seq.end(), &print_oustring); + cout << endl; +} + + +// code samples + +// imperative loops (just to show they work, using for_each would be better most of the time +void classic_loops() +{ + Sequence<OUString> s(10); + fill_testdata(s); + StlUnoSequence<OUString>::iterator stl_s_it; + + cout << "for iteration" << endl; + for(stl_s_it = stl_begin(s); stl_s_it != stl_end(s); ++stl_s_it) + cout << OUStringToOString(*stl_s_it, RTL_TEXTENCODING_ASCII_US).getStr() << endl; + + cout << "reverse for iteration" << endl; + for(stl_s_it = stl_end(s); stl_s_it != stl_begin(s); --stl_s_it) + cout << OUStringToOString(*(stl_s_it-1), RTL_TEXTENCODING_ASCII_US).getStr() << endl; + + cout << "skipping for iteration" << endl; + for(stl_s_it = stl_begin(s); stl_s_it != stl_end(s); stl_s_it+=2) + cout << OUStringToOString(*stl_s_it, RTL_TEXTENCODING_ASCII_US).getStr() << endl; + + cout << "skipping reverse for iteration" << endl; + for(stl_s_it = stl_end(s); stl_s_it != stl_begin(s); stl_s_it-=2) + std::cout << OUStringToOString(*(stl_s_it-1), RTL_TEXTENCODING_ASCII_US).getStr() << endl; +} + +void stl_algos() +{ + Sequence<OUString> s(10); + fill_testdata(s); + + random_shuffle(stl_begin(s), stl_end(s)); + cout << "shuffed" << std::endl; + print_sequence(s); + + sort(stl_begin(s), stl_end(s)); + cout << "sorted" << std::endl; + print_sequence(s); +} + +void stl_conversions() +{ + Sequence<OUString> s(10); + fill_testdata(s); + StlUnoSequence<OUString> stl_s = StlUnoSequence<OUString>::createInstance(s); + + // convert to stl::vector, modify in vector, copy back, print + cout << "vector conversion" << endl; + vector<OUString> vec(stl_s.begin(), stl_s.end()); + vec[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( "changed in vector" )); + copy(vec.begin(), vec.end(), stl_s.begin()); + print_sequence(s); + + // convert to stl::list, modify in list, copy back, print + cout << "list conversion" << endl; + list<OUString> l(stl_s.begin(), stl_s.end()); + l.pop_back(); + l.push_back(OUString( RTL_CONSTASCII_USTRINGPARAM( "changed in list" ))); + copy(l.begin(), l.end(), stl_s.begin()); + print_sequence(s); +} + +// inserts the second half of the second sequence after the first element of the first sequence +void stl_inserting() +{ + Sequence<OUString> s1(10); + Sequence<OUString> s2(10); + Sequence<OUString> result(15); + StlUnoSequence<OUString> stl_s1 = StlUnoSequence<OUString>::createInstance(s1); + StlUnoSequence<OUString> stl_s2 = StlUnoSequence<OUString>::createInstance(s2); + StlUnoSequence<OUString> stl_result = StlUnoSequence<OUString>::createInstance(result); + fill_testdata(s1); + fill_testdata(s2); + + list<OUString> temp(stl_s1.begin(), stl_s1.end()); + copy(stl_s2.begin()+5, stl_s2.end(), insert_iterator<list<OUString> >(temp, ++temp.begin())); + copy(temp.begin(), temp.end(), stl_result.begin()); + print_sequence(result); +} + +void stl_compare() +{ + Sequence<OUString> s1(10); + Sequence<OUString> s2(10); + StlUnoSequence<OUString> stl_s1 = StlUnoSequence<OUString>::createInstance(s1); + StlUnoSequence<OUString> stl_s2 = StlUnoSequence<OUString>::createInstance(s2); + if (stl_s1 == stl_s2) + cout << "sequences are equal." << endl; + s2[9] = OUString( RTL_CONSTASCII_USTRINGPARAM( "ZZZZZ" )); + if(stl_s1 < stl_s2) + cout << "first sequence is smaller." << endl; +} + +void stl_const_sequence() +{ + const Sequence<OUString> s(10); + for(StlUnoSequence<OUString>::const_iterator stl_s_it = stl_begin(s); stl_s_it != stl_end(s); ++stl_s_it) + cout << OUStringToOString(*stl_s_it, RTL_TEXTENCODING_ASCII_US).getStr() << endl; +} + +void stl_helpers() +{ + Sequence<OUString> s(10); + StlUnoSequence<OUString> stl_s = StlUnoSequence<OUString>::createInstance(s); + fill_testdata_stl(stl_s); + print_sequence_stl(stl_s); +} + +int main() +{ + cout << "--- CLASSIC LOOPS" << endl; + classic_loops(); + + cout << "--- SOME STL ALGORITHMS" << endl; + stl_algos(); + + cout << "--- SOME STL CONVERSIONS" << endl; + stl_conversions(); + + cout << "--- INSERTING IN SEQUENCE" << endl; + stl_inserting(); + + cout << "--- COMPARING" << endl; + stl_compare(); + + cout << "--- CONST SEQUENCE" << endl; + stl_const_sequence(); + + cout << "--- HELPERS IN STL-STYLE" << endl; + stl_helpers(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/util/comphelp.component b/comphelper/util/comphelp.component new file mode 100644 index 000000000000..d29468bfe459 --- /dev/null +++ b/comphelper/util/comphelp.component @@ -0,0 +1,70 @@ +<?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. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" prefix="comphelp" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="AnyCompareFactory"> + <service name="com.sun.star.ucb.AnyCompareFactory"/> + </implementation> + <implementation name="IndexedPropertyValuesContainer"> + <service name="com.sun.star.document.IndexedPropertyValues"/> + </implementation> + <implementation name="NamedPropertyValuesContainer"> + <service name="com.sun.star.document.NamedPropertyValues"/> + </implementation> + <implementation name="com.sun.star.comp.MemoryStream"> + <service name="com.sun.star.comp.MemoryStream"/> + </implementation> + <implementation name="com.sun.star.comp.SequenceInputStreamService"> + <service name="com.sun.star.io.SequenceInputStream"/> + </implementation> + <implementation name="com.sun.star.comp.SequenceOutputStreamService"> + <service name="com.sun.star.io.SequenceOutputStream"/> + </implementation> + <implementation name="com.sun.star.comp.comphelper.OPropertyBag"> + <service name="com.sun.star.beans.PropertyBag"/> + </implementation> + <implementation name="com.sun.star.comp.embed.InstanceLocker"> + <service name="com.sun.star.embed.InstanceLocker"/> + </implementation> + <implementation name="com.sun.star.comp.logging.SimpleLogRing"> + <service name="com.sun.star.logging.SimpleLogRing"/> + <singleton name="com.sun.star.logging.DocumentIOLogRing"/> + </implementation> + <implementation name="com.sun.star.comp.task.OfficeRestartManager"> + <service name="com.sun.star.comp.task.OfficeRestartManager"/> + <singleton name="com.sun.star.task.OfficeRestartManager"/> + </implementation> + <implementation name="com.sun.star.comp.util.OfficeInstallationDirectories"> + <service name="com.sun.star.util.OfficeInstallationDirectories"/> + <singleton name="com.sun.star.util.theOfficeInstallationDirectories"/> + </implementation> + <implementation name="org.openoffice.comp.comphelper.EnumerableMap"> + <service name="com.sun.star.container.EnumerableMap"/> + </implementation> +</component> |