summaryrefslogtreecommitdiff
path: root/sfx2/source/doc
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/doc')
-rw-r--r--sfx2/source/doc/DocumentMetadataAccess.cxx1411
-rw-r--r--sfx2/source/doc/Metadatable.cxx1703
-rw-r--r--sfx2/source/doc/QuerySaveDocument.cxx50
-rw-r--r--sfx2/source/doc/SfxDocumentMetaData.cxx2391
-rw-r--r--sfx2/source/doc/applet.cxx383
-rw-r--r--sfx2/source/doc/doc.hrc222
-rw-r--r--sfx2/source/doc/doc.src536
-rw-r--r--sfx2/source/doc/docfac.cxx474
-rw-r--r--sfx2/source/doc/docfile.cxx3978
-rw-r--r--sfx2/source/doc/docfilt.cxx251
-rw-r--r--sfx2/source/doc/docinf.cxx309
-rw-r--r--sfx2/source/doc/docinsert.cxx305
-rw-r--r--sfx2/source/doc/docmacromode.cxx436
-rw-r--r--sfx2/source/doc/docstoragemodifylistener.cxx96
-rw-r--r--sfx2/source/doc/doctdlg.cxx238
-rw-r--r--sfx2/source/doc/doctdlg.hrc42
-rw-r--r--sfx2/source/doc/doctdlg.src146
-rw-r--r--sfx2/source/doc/doctempl.cxx2735
-rw-r--r--sfx2/source/doc/doctempl.src106
-rw-r--r--sfx2/source/doc/doctemplates.cxx2898
-rw-r--r--sfx2/source/doc/doctemplateslocal.cxx263
-rw-r--r--sfx2/source/doc/doctemplateslocal.hxx88
-rw-r--r--sfx2/source/doc/docvor.cxx2466
-rw-r--r--sfx2/source/doc/docvor.hrc75
-rw-r--r--sfx2/source/doc/docvor.src315
-rw-r--r--sfx2/source/doc/frmdescr.cxx329
-rw-r--r--sfx2/source/doc/graphhelp.cxx529
-rw-r--r--sfx2/source/doc/graphhelp.hxx75
-rw-r--r--sfx2/source/doc/graphhelp.src59
-rw-r--r--sfx2/source/doc/guisaveas.cxx1842
-rw-r--r--sfx2/source/doc/iframe.cxx397
-rw-r--r--sfx2/source/doc/makefile.mk105
-rw-r--r--sfx2/source/doc/new.cxx745
-rw-r--r--sfx2/source/doc/new.hrc57
-rw-r--r--sfx2/source/doc/new.src259
-rw-r--r--sfx2/source/doc/objcont.cxx1292
-rw-r--r--sfx2/source/doc/objembed.cxx317
-rw-r--r--sfx2/source/doc/objitem.cxx135
-rwxr-xr-xsfx2/source/doc/objmisc.cxx2590
-rw-r--r--sfx2/source/doc/objserv.cxx1502
-rw-r--r--sfx2/source/doc/objstor.cxx3702
-rw-r--r--sfx2/source/doc/objuno.cxx1350
-rwxr-xr-xsfx2/source/doc/objxtor.cxx1118
-rwxr-xr-xsfx2/source/doc/oleprops.cxx1227
-rwxr-xr-xsfx2/source/doc/oleprops.hxx404
-rw-r--r--sfx2/source/doc/ownsubfilterservice.cxx165
-rw-r--r--sfx2/source/doc/plugin.cxx266
-rwxr-xr-xsfx2/source/doc/printhelper.cxx906
-rwxr-xr-xsfx2/source/doc/printhelper.hxx69
-rw-r--r--sfx2/source/doc/querytemplate.cxx52
-rw-r--r--sfx2/source/doc/querytemplate.hxx44
-rw-r--r--sfx2/source/doc/sfxacldetect.cxx105
-rw-r--r--sfx2/source/doc/sfxbasemodel.cxx4302
-rw-r--r--sfx2/source/doc/sfxmodelfactory.cxx239
-rwxr-xr-xsfx2/source/doc/syspath.cxx48
-rw-r--r--sfx2/source/doc/syspath.hxx44
-rw-r--r--sfx2/source/doc/syspathw32.cxx83
57 files changed, 46274 insertions, 0 deletions
diff --git a/sfx2/source/doc/DocumentMetadataAccess.cxx b/sfx2/source/doc/DocumentMetadataAccess.cxx
new file mode 100644
index 000000000000..9625ea958830
--- /dev/null
+++ b/sfx2/source/doc/DocumentMetadataAccess.cxx
@@ -0,0 +1,1411 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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_sfx2.hxx"
+
+#include <sfx2/DocumentMetadataAccess.hxx>
+
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/task/ErrorCodeIOException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/rdf/FileFormat.hpp>
+#include <com/sun/star/rdf/URIs.hpp>
+#include <com/sun/star/rdf/Statement.hpp>
+#include <com/sun/star/rdf/Literal.hpp>
+#include <com/sun/star/rdf/URI.hpp>
+#include <com/sun/star/rdf/Repository.hpp>
+
+#include <rtl/uuid.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <comphelper/interaction.hxx>
+#include <comphelper/makesequence.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/sequenceasvector.hxx>
+#include <comphelper/storagehelper.hxx>
+
+#include <sfx2/docfile.hxx>
+#include <sfx2/XmlIdRegistry.hxx>
+
+#include <libxml/tree.h> // for xmlValidateNCName
+
+#include <boost/bind.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <vector>
+#include <set>
+#include <map>
+#include <functional>
+#include <algorithm>
+
+#include <unotools/ucbhelper.hxx>
+#include <com/sun/star/uri/XUriReference.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/uri/XVndSunStarPkgUrlReferenceFactory.hpp>
+
+
+/*
+ Note: in the context of this implementation, all rdf.QueryExceptions and
+ rdf.RepositoryExceptions are RuntimeExceptions, and will be reported as such.
+
+ This implementation assumes that it is only used with ODF documents, not mere
+ ODF packages. In other words, we enforce that metadata files must not be
+ called reserved names.
+ */
+
+using namespace ::com::sun::star;
+
+namespace sfx2 {
+
+
+bool isValidNCName(::rtl::OUString const & i_rIdref)
+{
+ const ::rtl::OString id(
+ ::rtl::OUStringToOString(i_rIdref, RTL_TEXTENCODING_UTF8) );
+ return !(xmlValidateNCName(
+ reinterpret_cast<const unsigned char*>(id.getStr()), 0));
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+static const char s_content [] = "content.xml";
+static const char s_styles [] = "styles.xml";
+static const char s_meta [] = "meta.xml";
+static const char s_settings[] = "settings.xml";
+static const char s_manifest[] = "manifest.rdf";
+static const char s_rdfxml [] = "application/rdf+xml";
+static const char s_odfmime [] = "application/vnd.oasis.opendocument.";
+
+////////////////////////////////////////////////////////////////////////////
+
+static bool isContentFile(::rtl::OUString const & i_rPath)
+{
+ return i_rPath.equalsAscii(s_content);
+}
+
+static bool isStylesFile (::rtl::OUString const & i_rPath)
+{
+ return i_rPath.equalsAscii(s_styles);
+}
+
+static bool isReservedFile(::rtl::OUString const & i_rPath)
+{
+ return isContentFile(i_rPath)
+ || isStylesFile(i_rPath)
+ || i_rPath.equalsAscii(s_meta)
+ || i_rPath.equalsAscii(s_settings);
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+uno::Reference<rdf::XURI> createBaseURI(
+ uno::Reference<uno::XComponentContext> const & i_xContext,
+ uno::Reference<embed::XStorage> const & i_xStorage,
+ ::rtl::OUString const & i_rPkgURI, ::rtl::OUString const & i_rSubDocument)
+{
+ if (!i_xContext.is() || !i_xStorage.is() || !i_rPkgURI.getLength()) {
+ throw uno::RuntimeException();
+ }
+
+ const uno::Reference<lang::XMultiComponentFactory> xServiceFactory(
+ i_xContext->getServiceManager(), uno::UNO_SET_THROW);
+ const uno::Reference<uri::XUriReferenceFactory> xUriFactory(
+ xServiceFactory->createInstanceWithContext(
+ ::rtl::OUString::createFromAscii(
+ "com.sun.star.uri.UriReferenceFactory"), i_xContext),
+ uno::UNO_QUERY_THROW);
+ uno::Reference< uri::XUriReference > xBaseURI;
+
+ const uno::Reference< uri::XUriReference > xPkgURI(
+ xUriFactory->parse(i_rPkgURI), uno::UNO_SET_THROW );
+ xPkgURI->clearFragment();
+ // need to know whether the storage is a FileSystemStorage
+ // XServiceInfo would be better, but it is not implemented
+// if ( i_rPkgURI.getLength() && ::utl::UCBContentHelper::IsFolder(i_rPkgURI) )
+ if (true) {
+ xBaseURI.set( xPkgURI, uno::UNO_SET_THROW );
+#if 0
+ } else {
+ const uno::Reference<uri::XVndSunStarPkgUrlReferenceFactory>
+ xPkgUriFactory( xServiceFactory->createInstanceWithContext(
+ ::rtl::OUString::createFromAscii(
+ "com.sun.star.uri.VndSunStarPkgUrlReferenceFactory"),
+ i_xContext),
+ uno::UNO_QUERY_THROW);
+ xBaseURI.set( xPkgUriFactory->createVndSunStarPkgUrlReference(xPkgURI),
+ uno::UNO_SET_THROW );
+#endif
+ }
+ ::rtl::OUStringBuffer buf;
+ if (!xBaseURI->getUriReference().endsWithAsciiL("/", 1))
+ {
+ const sal_Int32 count( xBaseURI->getPathSegmentCount() );
+ if (count > 0)
+ {
+ const ::rtl::OUString last( xBaseURI->getPathSegment(count - 1) );
+ buf.append(last);
+ }
+ buf.append(static_cast<sal_Unicode>('/'));
+ }
+ if (i_rSubDocument.getLength())
+ {
+ buf.append(i_rSubDocument);
+ buf.append(static_cast<sal_Unicode>('/'));
+ }
+ const ::rtl::OUString Path(buf.makeStringAndClear());
+ if (Path.getLength())
+ {
+ const uno::Reference< uri::XUriReference > xPathURI(
+ xUriFactory->parse(Path), uno::UNO_SET_THROW );
+ xBaseURI.set(
+ xUriFactory->makeAbsolute(xBaseURI, xPathURI,
+ true, uri::RelativeUriExcessParentSegments_ERROR),
+ uno::UNO_SET_THROW);
+ }
+
+ return rdf::URI::create(i_xContext, xBaseURI->getUriReference());
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+struct DocumentMetadataAccess_Impl
+{
+ // note: these are all initialized in constructor, and loadFromStorage
+ const uno::Reference<uno::XComponentContext> m_xContext;
+ const IXmlIdRegistrySupplier & m_rXmlIdRegistrySupplier;
+ uno::Reference<rdf::XURI> m_xBaseURI;
+ uno::Reference<rdf::XRepository> m_xRepository;
+ uno::Reference<rdf::XNamedGraph> m_xManifest;
+ DocumentMetadataAccess_Impl(
+ uno::Reference<uno::XComponentContext> const& i_xContext,
+ IXmlIdRegistrySupplier const & i_rRegistrySupplier)
+ : m_xContext(i_xContext)
+ , m_rXmlIdRegistrySupplier(i_rRegistrySupplier)
+ , m_xBaseURI()
+ , m_xRepository()
+ , m_xManifest()
+ {
+ OSL_ENSURE(m_xContext.is(), "context null");
+ }
+};
+
+// this is... a hack.
+template<sal_Int16 Constant>
+/*static*/ uno::Reference<rdf::XURI>
+getURI(uno::Reference< uno::XComponentContext > const & i_xContext)
+{
+ static uno::Reference< rdf::XURI > xURI(
+ rdf::URI::createKnown(i_xContext, Constant), uno::UNO_QUERY_THROW);
+ return xURI;
+}
+
+
+/** would storing the file to a XStorage succeed? */
+static bool isFileNameValid(const ::rtl::OUString & i_rFileName)
+{
+ if (i_rFileName.getLength() <= 0) return false;
+ if (i_rFileName[0] == '/') return false; // no absolute paths!
+ sal_Int32 idx(0);
+ do {
+ const ::rtl::OUString segment(
+ i_rFileName.getToken(0, static_cast<sal_Unicode> ('/'), idx) );
+ if (!segment.getLength() || // no empty segments
+ segment.equalsAscii(".") || // no . segments
+ segment.equalsAscii("..") || // no .. segments
+ !::comphelper::OStorageHelper::IsValidZipEntryFileName(
+ segment, sal_False)) // no invalid characters
+ return false;
+ } while (idx >= 0);
+ return true;
+}
+
+/** split a uri hierarchy into first segment and rest */
+static bool
+splitPath(::rtl::OUString const & i_rPath,
+ ::rtl::OUString & o_rDir, ::rtl::OUString& o_rRest)
+{
+ const sal_Int32 idx(i_rPath.indexOf(static_cast<sal_Unicode>('/')));
+ if (idx < 0 || idx >= i_rPath.getLength()) {
+ o_rDir = ::rtl::OUString();
+ o_rRest = i_rPath;
+ return true;
+ } else if (idx == 0 || idx == i_rPath.getLength() - 1) {
+ // input must not start or end with '/'
+ return false;
+ } else {
+ o_rDir = (i_rPath.copy(0, idx));
+ o_rRest = (i_rPath.copy(idx+1));
+ return true;
+ }
+}
+
+static bool
+splitXmlId(::rtl::OUString const & i_XmlId,
+ ::rtl::OUString & o_StreamName, ::rtl::OUString& o_Idref )
+{
+ const sal_Int32 idx(i_XmlId.indexOf(static_cast<sal_Unicode>('#')));
+ if ((idx <= 0) || (idx >= i_XmlId.getLength() - 1)) {
+ return false;
+ } else {
+ o_StreamName = (i_XmlId.copy(0, idx));
+ o_Idref = (i_XmlId.copy(idx+1));
+ return isValidXmlId(o_StreamName, o_Idref);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+static uno::Reference<rdf::XURI>
+getURIForStream(struct DocumentMetadataAccess_Impl& i_rImpl,
+ ::rtl::OUString const& i_rPath)
+{
+ const uno::Reference<rdf::XURI> xURI(
+ rdf::URI::createNS( i_rImpl.m_xContext,
+ i_rImpl.m_xBaseURI->getStringValue(), i_rPath),
+ uno::UNO_SET_THROW);
+ return xURI;
+}
+
+/** add statements declaring i_xResource to be a file of type i_xType with
+ path i_rPath to manifest, with optional additional types i_pTypes */
+static void
+addFile(struct DocumentMetadataAccess_Impl & i_rImpl,
+ uno::Reference<rdf::XURI> const& i_xType,
+ ::rtl::OUString const & i_rPath,
+ const uno::Sequence < uno::Reference< rdf::XURI > > * i_pTypes = 0)
+{
+ try {
+ const uno::Reference<rdf::XURI> xURI( getURIForStream(
+ i_rImpl, i_rPath) );
+
+ i_rImpl.m_xManifest->addStatement(i_rImpl.m_xBaseURI.get(),
+ getURI<rdf::URIs::PKG_HASPART>(i_rImpl.m_xContext),
+ xURI.get());
+ i_rImpl.m_xManifest->addStatement(xURI.get(),
+ getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext),
+ i_xType.get());
+ if (i_pTypes) {
+ for (sal_Int32 i = 0; i < i_pTypes->getLength(); ++i) {
+ i_rImpl.m_xManifest->addStatement(xURI.get(),
+ getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext),
+ (*i_pTypes)[i].get());
+ }
+ }
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "addFile: exception"), /*this*/0, uno::makeAny(e));
+ }
+}
+
+/** add content.xml or styles.xml to manifest */
+static bool
+addContentOrStylesFileImpl(struct DocumentMetadataAccess_Impl & i_rImpl,
+ const ::rtl::OUString & i_rPath)
+{
+ uno::Reference<rdf::XURI> xType;
+ if (isContentFile(i_rPath)) {
+ xType.set(getURI<rdf::URIs::ODF_CONTENTFILE>(i_rImpl.m_xContext));
+ } else if (isStylesFile(i_rPath)) {
+ xType.set(getURI<rdf::URIs::ODF_STYLESFILE>(i_rImpl.m_xContext));
+ } else {
+ return false;
+ }
+ addFile(i_rImpl, xType.get(), i_rPath);
+ return true;
+}
+
+/** add metadata file to manifest */
+static void
+addMetadataFileImpl(struct DocumentMetadataAccess_Impl & i_rImpl,
+ const ::rtl::OUString & i_rPath,
+ const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
+{
+ addFile(i_rImpl,
+ getURI<rdf::URIs::PKG_METADATAFILE>(i_rImpl.m_xContext),
+ i_rPath, &i_rTypes);
+}
+
+/** remove a file from the manifest */
+static void
+removeFile(struct DocumentMetadataAccess_Impl & i_rImpl,
+ uno::Reference<rdf::XURI> const& i_xPart)
+{
+ if (!i_xPart.is()) throw uno::RuntimeException();
+ try {
+ i_rImpl.m_xManifest->removeStatements(i_rImpl.m_xBaseURI.get(),
+ getURI<rdf::URIs::PKG_HASPART>(i_rImpl.m_xContext),
+ i_xPart.get());
+ i_rImpl.m_xManifest->removeStatements(i_xPart.get(),
+ getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext), 0);
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii("removeFile: exception"),
+ 0, uno::makeAny(e));
+ }
+}
+
+static ::std::vector< uno::Reference< rdf::XURI > >
+getAllParts(struct DocumentMetadataAccess_Impl & i_rImpl)
+{
+ ::std::vector< uno::Reference< rdf::XURI > > ret;
+ try {
+ const uno::Reference<container::XEnumeration> xEnum(
+ i_rImpl.m_xManifest->getStatements( i_rImpl.m_xBaseURI.get(),
+ getURI<rdf::URIs::PKG_HASPART>(i_rImpl.m_xContext), 0),
+ uno::UNO_SET_THROW);
+ while (xEnum->hasMoreElements()) {
+ rdf::Statement stmt;
+ if (!(xEnum->nextElement() >>= stmt)) {
+ throw uno::RuntimeException();
+ }
+ const uno::Reference<rdf::XURI> xPart(stmt.Object,
+ uno::UNO_QUERY);
+ if (!xPart.is()) continue;
+ ret.push_back(xPart);
+ }
+ return ret;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii("getAllParts: exception"),
+ 0, uno::makeAny(e));
+ }
+}
+
+static bool
+isPartOfType(struct DocumentMetadataAccess_Impl & i_rImpl,
+ uno::Reference<rdf::XURI> const & i_xPart,
+ uno::Reference<rdf::XURI> const & i_xType)
+{
+ if (!i_xPart.is() || !i_xType.is()) throw uno::RuntimeException();
+ try {
+ const uno::Reference<container::XEnumeration> xEnum(
+ i_rImpl.m_xManifest->getStatements(i_xPart.get(),
+ getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext),
+ i_xType.get()),
+ uno::UNO_SET_THROW);
+ return (xEnum->hasMoreElements());
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii("isPartOfType: exception"),
+ 0, uno::makeAny(e));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+static ucb::InteractiveAugmentedIOException
+mkException( ::rtl::OUString const & i_rMessage,
+ ucb::IOErrorCode const i_ErrorCode,
+ ::rtl::OUString const & i_rUri, ::rtl::OUString const & i_rResource)
+{
+ ucb::InteractiveAugmentedIOException iaioe;
+ iaioe.Message = i_rMessage;
+ iaioe.Classification = task::InteractionClassification_ERROR;
+ iaioe.Code = i_ErrorCode;
+
+ const beans::PropertyValue uriProp(::rtl::OUString::createFromAscii("Uri"),
+ -1, uno::makeAny(i_rUri), static_cast<beans::PropertyState>(0));
+ const beans::PropertyValue rnProp(
+ ::rtl::OUString::createFromAscii("ResourceName"),
+ -1, uno::makeAny(i_rResource), static_cast<beans::PropertyState>(0));
+ iaioe.Arguments = ::comphelper::makeSequence(
+ uno::makeAny(uriProp), uno::makeAny(rnProp));
+ return iaioe;
+}
+
+/** error handling policy.
+ <p>If a handler is given, ask it how to proceed:
+ <ul><li>(default:) cancel import, raise exception</li>
+ <li>ignore the error and continue</li>
+ <li>retry the action that led to the error</li></ul></p>
+ N.B.: must not be called before DMA is fully initalized!
+ @returns true iff caller should retry
+ */
+static bool
+handleError( ucb::InteractiveAugmentedIOException const & i_rException,
+ const uno::Reference<task::XInteractionHandler> & i_xHandler)
+{
+ if (!i_xHandler.is()) {
+ throw lang::WrappedTargetException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromStorage: exception"),
+ /* *this*/ 0, uno::makeAny(i_rException));
+ }
+
+ ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest(
+ new ::comphelper::OInteractionRequest(uno::makeAny(i_rException)) );
+ ::rtl::Reference< ::comphelper::OInteractionRetry > pRetry(
+ new ::comphelper::OInteractionRetry );
+ ::rtl::Reference< ::comphelper::OInteractionApprove > pApprove(
+ new ::comphelper::OInteractionApprove );
+ ::rtl::Reference< ::comphelper::OInteractionAbort > pAbort(
+ new ::comphelper::OInteractionAbort );
+ /* this does not seem to work
+ if (i_rException.Code != ucb::IOErrorCode_WRONG_FORMAT) {
+ pRequest->addContinuation( pRetry.get() );
+ }
+ */
+ pRequest->addContinuation( pApprove.get() );
+ pRequest->addContinuation( pAbort.get() );
+ // actually call the handler
+ i_xHandler->handle( pRequest.get() );
+ if (pRetry->wasSelected()) {
+ return true;
+ } else if (pApprove->wasSelected()) {
+ return false;
+ } else {
+ OSL_ENSURE(pAbort->wasSelected(), "no continuation selected?");
+ throw lang::WrappedTargetException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromStorage: exception"),
+ /* *this*/ 0, uno::makeAny(i_rException));
+ }
+}
+
+/** check if storage has content.xml/styles.xml;
+ e.g. ODB files seem to only have content.xml */
+static void
+collectFilesFromStorage(uno::Reference<embed::XStorage> const& i_xStorage,
+ ::rtl::OUString i_Path,
+ std::set< ::rtl::OUString > & o_rFiles)
+{
+ static ::rtl::OUString content(::rtl::OUString::createFromAscii(s_content));
+ static ::rtl::OUString styles (::rtl::OUString::createFromAscii(s_styles ));
+ try {
+ if (i_xStorage->hasByName(content) &&
+ i_xStorage->isStreamElement(content))
+ {
+ o_rFiles.insert(i_Path + content);
+ }
+ if (i_xStorage->hasByName(styles) &&
+ i_xStorage->isStreamElement(styles))
+ {
+ o_rFiles.insert(i_Path + styles);
+ }
+ } catch (uno::Exception &) {
+ OSL_TRACE("collectFilesFromStorage: exception?");
+ }
+}
+
+/** import a metadata file into repository */
+static void
+readStream(struct DocumentMetadataAccess_Impl & i_rImpl,
+ uno::Reference< embed::XStorage > const & i_xStorage,
+ ::rtl::OUString const & i_rPath,
+ ::rtl::OUString const & i_rBaseURI)
+{
+ ::rtl::OUString dir;
+ ::rtl::OUString rest;
+ try {
+ if (!splitPath(i_rPath, dir, rest)) throw uno::RuntimeException();
+ if (dir.equalsAscii("")) {
+ if (i_xStorage->isStreamElement(i_rPath)) {
+ const uno::Reference<io::XStream> xStream(
+ i_xStorage->openStreamElement(i_rPath,
+ embed::ElementModes::READ), uno::UNO_SET_THROW);
+ const uno::Reference<io::XInputStream> xInStream(
+ xStream->getInputStream(), uno::UNO_SET_THROW );
+ const uno::Reference<rdf::XURI> xBaseURI(
+ rdf::URI::create(i_rImpl.m_xContext, i_rBaseURI));
+ const uno::Reference<rdf::XURI> xURI(
+ rdf::URI::createNS(i_rImpl.m_xContext,
+ i_rBaseURI, i_rPath));
+ i_rImpl.m_xRepository->importGraph(rdf::FileFormat::RDF_XML,
+ xInStream, xURI, xBaseURI);
+ } else {
+ throw mkException(::rtl::OUString::createFromAscii(
+ "readStream: is not a stream"),
+ ucb::IOErrorCode_NO_FILE, i_rBaseURI + i_rPath, i_rPath);
+ }
+ } else {
+ if (i_xStorage->isStorageElement(dir)) {
+ const uno::Reference<embed::XStorage> xDir(
+ i_xStorage->openStorageElement(dir,
+ embed::ElementModes::READ));
+ const uno::Reference< beans::XPropertySet > xDirProps(xDir,
+ uno::UNO_QUERY_THROW);
+ try {
+ ::rtl::OUString mimeType;
+ xDirProps->getPropertyValue(
+ ::comphelper::MediaDescriptor::PROP_MEDIATYPE() )
+ >>= mimeType;
+ if (mimeType.matchAsciiL(s_odfmime, sizeof(s_odfmime) - 1))
+ {
+ OSL_TRACE("readStream: "
+ "refusing to recurse into embedded document");
+ return;
+ }
+ } catch (uno::Exception &) { }
+ ::rtl::OUStringBuffer buf(i_rBaseURI);
+ buf.append(dir).append(static_cast<sal_Unicode>('/'));
+ readStream(i_rImpl, xDir, rest, buf.makeStringAndClear() );
+ } else {
+ throw mkException(::rtl::OUString::createFromAscii(
+ "readStream: is not a directory"),
+ ucb::IOErrorCode_NO_DIRECTORY, i_rBaseURI + dir, dir);
+ }
+ }
+ } catch (container::NoSuchElementException & e) {
+ throw mkException(e.Message, ucb::IOErrorCode_NOT_EXISTING_PATH,
+ i_rBaseURI + i_rPath, i_rPath);
+ } catch (io::IOException & e) {
+ throw mkException(e.Message, ucb::IOErrorCode_CANT_READ,
+ i_rBaseURI + i_rPath, i_rPath);
+ } catch (rdf::ParseException & e) {
+ throw mkException(e.Message, ucb::IOErrorCode_WRONG_FORMAT,
+ i_rBaseURI + i_rPath, i_rPath);
+ }
+}
+
+/** import a metadata file into repository */
+static void
+importFile(struct DocumentMetadataAccess_Impl & i_rImpl,
+ uno::Reference<embed::XStorage> const & i_xStorage,
+ ::rtl::OUString const & i_rBaseURI,
+ uno::Reference<task::XInteractionHandler> const & i_xHandler,
+ ::rtl::OUString i_rPath)
+{
+retry:
+ try {
+ readStream(i_rImpl, i_xStorage, i_rPath, i_rBaseURI);
+ } catch (ucb::InteractiveAugmentedIOException & e) {
+ if (handleError(e, i_xHandler)) goto retry;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii("importFile: exception"),
+ 0, uno::makeAny(e));
+ }
+}
+
+/** actually write a metadata file to the storage */
+static void
+exportStream(struct DocumentMetadataAccess_Impl & i_rImpl,
+ uno::Reference< embed::XStorage > const & i_xStorage,
+ uno::Reference<rdf::XURI> const & i_xGraphName,
+ ::rtl::OUString const & i_rFileName,
+ ::rtl::OUString const & i_rBaseURI)
+{
+ const uno::Reference<io::XStream> xStream(
+ i_xStorage->openStreamElement(i_rFileName,
+ embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE),
+ uno::UNO_SET_THROW);
+ const uno::Reference< beans::XPropertySet > xStreamProps(xStream,
+ uno::UNO_QUERY);
+ if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage
+ xStreamProps->setPropertyValue(
+ ::rtl::OUString::createFromAscii("MediaType"),
+ uno::makeAny(::rtl::OUString::createFromAscii(s_rdfxml)));
+ }
+ const uno::Reference<io::XOutputStream> xOutStream(
+ xStream->getOutputStream(), uno::UNO_SET_THROW );
+ const uno::Reference<rdf::XURI> xBaseURI(
+ rdf::URI::create(i_rImpl.m_xContext, i_rBaseURI));
+ i_rImpl.m_xRepository->exportGraph(rdf::FileFormat::RDF_XML,
+ xOutStream, i_xGraphName, xBaseURI);
+}
+
+/** write a metadata file to the storage */
+static void
+writeStream(struct DocumentMetadataAccess_Impl & i_rImpl,
+ uno::Reference< embed::XStorage > const & i_xStorage,
+ uno::Reference<rdf::XURI> const & i_xGraphName,
+ ::rtl::OUString const & i_rPath,
+ ::rtl::OUString const & i_rBaseURI)
+{
+ ::rtl::OUString dir;
+ ::rtl::OUString rest;
+ if (!splitPath(i_rPath, dir, rest)) throw uno::RuntimeException();
+ try {
+ if (dir.equalsAscii("")) {
+ exportStream(i_rImpl, i_xStorage, i_xGraphName, i_rPath,
+ i_rBaseURI);
+ } else {
+ const uno::Reference<embed::XStorage> xDir(
+ i_xStorage->openStorageElement(dir,
+ embed::ElementModes::WRITE));
+ const uno::Reference< beans::XPropertySet > xDirProps(xDir,
+ uno::UNO_QUERY_THROW);
+ try {
+ ::rtl::OUString mimeType;
+ xDirProps->getPropertyValue(
+ ::comphelper::MediaDescriptor::PROP_MEDIATYPE() )
+ >>= mimeType;
+ if (mimeType.matchAsciiL(s_odfmime, sizeof(s_odfmime) - 1)) {
+ OSL_TRACE("writeStream: "
+ "refusing to recurse into embedded document");
+ return;
+ }
+ } catch (uno::Exception &) { }
+ ::rtl::OUStringBuffer buf(i_rBaseURI);
+ buf.append(dir).append(static_cast<sal_Unicode>('/'));
+ writeStream(i_rImpl, xDir, i_xGraphName, rest,
+ buf.makeStringAndClear());
+ }
+ const uno::Reference<embed::XTransactedObject> xTransaction(
+ i_xStorage, uno::UNO_QUERY);
+ if (xTransaction.is()) {
+ xTransaction->commit();
+ }
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (io::IOException &) {
+ throw;
+ }
+}
+
+static void
+initLoading(struct DocumentMetadataAccess_Impl & i_rImpl,
+ const uno::Reference< embed::XStorage > & i_xStorage,
+ const uno::Reference<rdf::XURI> & i_xBaseURI,
+ const uno::Reference<task::XInteractionHandler> & i_xHandler)
+{
+retry:
+ // clear old data
+ i_rImpl.m_xManifest.clear();
+ // init BaseURI
+ i_rImpl.m_xBaseURI = i_xBaseURI;
+
+ // create repository
+ i_rImpl.m_xRepository.clear();
+ i_rImpl.m_xRepository.set(rdf::Repository::create(i_rImpl.m_xContext),
+ uno::UNO_SET_THROW);
+
+ const ::rtl::OUString manifest (
+ ::rtl::OUString::createFromAscii(s_manifest));
+ const ::rtl::OUString baseURI( i_xBaseURI->getStringValue() );
+ // try to delay raising errors until after initialization is done
+ uno::Any rterr;
+ ucb::InteractiveAugmentedIOException iaioe;
+ bool err(false);
+
+ const uno::Reference <rdf::XURI> xManifest(
+ getURIForStream(i_rImpl, manifest));
+ try {
+ readStream(i_rImpl, i_xStorage, manifest, baseURI);
+ } catch (ucb::InteractiveAugmentedIOException & e) {
+ // no manifest.rdf: this is not an error in ODF < 1.2
+ if (!(ucb::IOErrorCode_NOT_EXISTING_PATH == e.Code)) {
+ iaioe = e;
+ err = true;
+ }
+ } catch (uno::Exception & e) {
+ rterr <<= e;
+ }
+
+ // init manifest graph
+ const uno::Reference<rdf::XNamedGraph> xManifestGraph(
+ i_rImpl.m_xRepository->getGraph(xManifest));
+ i_rImpl.m_xManifest.set(xManifestGraph.is() ? xManifestGraph :
+ i_rImpl.m_xRepository->createGraph(xManifest), uno::UNO_SET_THROW);
+ const uno::Reference<container::XEnumeration> xEnum(
+ i_rImpl.m_xManifest->getStatements(0,
+ getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext),
+ getURI<rdf::URIs::PKG_DOCUMENT>(i_rImpl.m_xContext).get()));
+
+ // document statement
+ i_rImpl.m_xManifest->addStatement(i_rImpl.m_xBaseURI.get(),
+ getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext),
+ getURI<rdf::URIs::PKG_DOCUMENT>(i_rImpl.m_xContext).get());
+
+ OSL_ENSURE(i_rImpl.m_xBaseURI.is(), "base URI is null");
+ OSL_ENSURE(i_rImpl.m_xRepository.is(), "repository is null");
+ OSL_ENSURE(i_rImpl.m_xManifest.is(), "manifest is null");
+
+ if (rterr.hasValue()) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromStorage: "
+ "exception"), 0, rterr);
+ }
+
+ if (err) {
+ if (handleError(iaioe, i_xHandler)) goto retry;
+ }
+}
+
+/** init Impl struct */
+static void init(struct DocumentMetadataAccess_Impl & i_rImpl)
+{
+ try {
+
+ i_rImpl.m_xManifest.set(i_rImpl.m_xRepository->createGraph(
+ getURIForStream(i_rImpl,
+ ::rtl::OUString::createFromAscii(s_manifest))),
+ uno::UNO_SET_THROW);
+
+ // insert the document statement
+ i_rImpl.m_xManifest->addStatement(i_rImpl.m_xBaseURI.get(),
+ getURI<rdf::URIs::RDF_TYPE>(i_rImpl.m_xContext),
+ getURI<rdf::URIs::PKG_DOCUMENT>(i_rImpl.m_xContext).get());
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii("init: unexpected exception"), 0,
+ uno::makeAny(e));
+ }
+
+ // add top-level content files
+ if (!addContentOrStylesFileImpl(i_rImpl,
+ ::rtl::OUString::createFromAscii(s_content))) {
+ throw uno::RuntimeException();
+ }
+ if (!addContentOrStylesFileImpl(i_rImpl,
+ ::rtl::OUString::createFromAscii(s_styles))) {
+ throw uno::RuntimeException();
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+DocumentMetadataAccess::DocumentMetadataAccess(
+ uno::Reference< uno::XComponentContext > const & i_xContext,
+ const IXmlIdRegistrySupplier & i_rRegistrySupplier)
+ : m_pImpl(new DocumentMetadataAccess_Impl(i_xContext, i_rRegistrySupplier))
+{
+ // no initalization: must call loadFrom...
+}
+
+DocumentMetadataAccess::DocumentMetadataAccess(
+ uno::Reference< uno::XComponentContext > const & i_xContext,
+ const IXmlIdRegistrySupplier & i_rRegistrySupplier,
+ ::rtl::OUString const & i_rURI)
+ : m_pImpl(new DocumentMetadataAccess_Impl(i_xContext, i_rRegistrySupplier))
+{
+ OSL_ENSURE(i_rURI.getLength(), "DMA::DMA: no URI given!");
+ OSL_ENSURE(i_rURI.endsWithAsciiL("/", 1), "DMA::DMA: URI without / given!");
+ if (!i_rURI.endsWithAsciiL("/", 1)) throw uno::RuntimeException();
+ m_pImpl->m_xBaseURI.set(rdf::URI::create(m_pImpl->m_xContext, i_rURI));
+ m_pImpl->m_xRepository.set(rdf::Repository::create(m_pImpl->m_xContext),
+ uno::UNO_SET_THROW);
+
+ // init repository
+ init(*m_pImpl);
+
+ OSL_ENSURE(m_pImpl->m_xBaseURI.is(), "base URI is null");
+ OSL_ENSURE(m_pImpl->m_xRepository.is(), "repository is null");
+ OSL_ENSURE(m_pImpl->m_xManifest.is(), "manifest is null");
+}
+
+DocumentMetadataAccess::~DocumentMetadataAccess()
+{
+}
+
+
+// ::com::sun::star::rdf::XRepositorySupplier:
+uno::Reference< rdf::XRepository > SAL_CALL
+DocumentMetadataAccess::getRDFRepository() throw (uno::RuntimeException)
+{
+ OSL_ENSURE(m_pImpl->m_xRepository.is(), "repository not initialized");
+ return m_pImpl->m_xRepository;
+}
+
+// ::com::sun::star::rdf::XNode:
+::rtl::OUString SAL_CALL
+DocumentMetadataAccess::getStringValue() throw (uno::RuntimeException)
+{
+ return m_pImpl->m_xBaseURI->getStringValue();
+}
+
+// ::com::sun::star::rdf::XURI:
+::rtl::OUString SAL_CALL
+DocumentMetadataAccess::getNamespace() throw (uno::RuntimeException)
+{
+ return m_pImpl->m_xBaseURI->getNamespace();
+}
+
+::rtl::OUString SAL_CALL
+DocumentMetadataAccess::getLocalName() throw (uno::RuntimeException)
+{
+ return m_pImpl->m_xBaseURI->getLocalName();
+}
+
+// ::com::sun::star::rdf::XDocumentMetadataAccess:
+uno::Reference< rdf::XMetadatable > SAL_CALL
+DocumentMetadataAccess::getElementByMetadataReference(
+ const ::com::sun::star::beans::StringPair & i_rReference)
+throw (uno::RuntimeException)
+{
+ const IXmlIdRegistry * pReg(
+ m_pImpl->m_rXmlIdRegistrySupplier.GetXmlIdRegistry() );
+ if (!pReg) {
+ throw uno::RuntimeException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::getElementByXmlId: no registry"), *this);
+ }
+ return pReg->GetElementByMetadataReference(i_rReference);
+}
+
+uno::Reference< rdf::XMetadatable > SAL_CALL
+DocumentMetadataAccess::getElementByURI(
+ const uno::Reference< rdf::XURI > & i_xURI )
+throw (uno::RuntimeException, lang::IllegalArgumentException)
+{
+ if (!i_xURI.is()) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::getElementByURI: URI is null"), *this, 0);
+ }
+
+ const ::rtl::OUString baseURI( m_pImpl->m_xBaseURI->getStringValue() );
+ const ::rtl::OUString name( i_xURI->getStringValue() );
+ if (!name.match(baseURI)) {
+ return 0;
+ }
+ const ::rtl::OUString relName( name.copy(baseURI.getLength()) );
+ ::rtl::OUString path;
+ ::rtl::OUString idref;
+ if (!splitXmlId(relName, path, idref)) {
+ return 0;
+ }
+
+ return getElementByMetadataReference( beans::StringPair(path, idref) );
+}
+
+
+uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL
+DocumentMetadataAccess::getMetadataGraphsWithType(
+ const uno::Reference<rdf::XURI> & i_xType)
+throw (uno::RuntimeException, lang::IllegalArgumentException)
+{
+ if (!i_xType.is()) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::getMetadataGraphsWithType: "
+ "type is null"), *this, 0);
+ }
+
+ ::comphelper::SequenceAsVector< uno::Reference< rdf::XURI > > ret;
+ const ::std::vector< uno::Reference< rdf::XURI > > parts(
+ getAllParts(*m_pImpl) );
+ ::std::remove_copy_if(parts.begin(), parts.end(),
+ ::std::back_inserter(ret),
+ ::boost::bind(
+ ::std::logical_not<bool>(),
+ ::boost::bind(&isPartOfType, ::boost::ref(*m_pImpl), _1, i_xType) ));
+ return ret.getAsConstList();
+}
+
+uno::Reference<rdf::XURI> SAL_CALL
+DocumentMetadataAccess::addMetadataFile(const ::rtl::OUString & i_rFileName,
+ const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ container::ElementExistException)
+{
+ if (!isFileNameValid(i_rFileName)) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::addMetadataFile: invalid FileName"),
+ *this, 0);
+ }
+ if (isReservedFile(i_rFileName)) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::addMetadataFile:"
+ "invalid FileName: reserved"), *this, 0);
+ }
+ for (sal_Int32 i = 0; i < i_rTypes.getLength(); ++i) {
+ if (!i_rTypes[i].is()) {
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::addMetadataFile: "
+ "null type"), *this, 2);
+ }
+ }
+
+ const uno::Reference<rdf::XURI> xGraphName(
+ getURIForStream(*m_pImpl, i_rFileName) );
+
+ try {
+ m_pImpl->m_xRepository->createGraph(xGraphName);
+ } catch (rdf::RepositoryException & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::addMetadataFile: exception"),
+ *this, uno::makeAny(e));
+ // note: all other exceptions are propagated
+ }
+
+ addMetadataFileImpl(*m_pImpl, i_rFileName, i_rTypes);
+ return xGraphName;
+}
+
+uno::Reference<rdf::XURI> SAL_CALL
+DocumentMetadataAccess::importMetadataFile(::sal_Int16 i_Format,
+ const uno::Reference< io::XInputStream > & i_xInStream,
+ const ::rtl::OUString & i_rFileName,
+ const uno::Reference< rdf::XURI > & i_xBaseURI,
+ const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ datatransfer::UnsupportedFlavorException,
+ container::ElementExistException, rdf::ParseException, io::IOException)
+{
+ if (!isFileNameValid(i_rFileName)) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::importMetadataFile: invalid FileName"),
+ *this, 0);
+ }
+ if (isReservedFile(i_rFileName)) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::importMetadataFile:"
+ "invalid FileName: reserved"), *this, 0);
+ }
+ for (sal_Int32 i = 0; i < i_rTypes.getLength(); ++i) {
+ if (!i_rTypes[i].is()) {
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::importMetadataFile: null type"),
+ *this, 5);
+ }
+ }
+
+ const uno::Reference<rdf::XURI> xGraphName(
+ getURIForStream(*m_pImpl, i_rFileName) );
+
+ try {
+ m_pImpl->m_xRepository->importGraph(
+ i_Format, i_xInStream, xGraphName, i_xBaseURI);
+ } catch (rdf::RepositoryException & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::importMetadataFile: "
+ "RepositoryException"), *this, uno::makeAny(e));
+ // note: all other exceptions are propagated
+ }
+
+ // add to manifest
+ addMetadataFileImpl(*m_pImpl, i_rFileName, i_rTypes);
+ return xGraphName;
+}
+
+void SAL_CALL
+DocumentMetadataAccess::removeMetadataFile(
+ const uno::Reference< rdf::XURI > & i_xGraphName)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ container::NoSuchElementException)
+{
+ try {
+ m_pImpl->m_xRepository->destroyGraph(i_xGraphName);
+ } catch (rdf::RepositoryException & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::removeMetadataFile: "
+ "RepositoryException"), *this, uno::makeAny(e));
+ // note: all other exceptions are propagated
+ }
+
+ // remove file from manifest
+ removeFile(*m_pImpl, i_xGraphName.get());
+}
+
+void SAL_CALL
+DocumentMetadataAccess::addContentOrStylesFile(
+ const ::rtl::OUString & i_rFileName)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ container::ElementExistException)
+{
+ if (!isFileNameValid(i_rFileName)) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::addContentOrStylesFile: "
+ "invalid FileName"), *this, 0);
+ }
+
+ if (!addContentOrStylesFileImpl(*m_pImpl, i_rFileName)) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::addContentOrStylesFile: "
+ "invalid FileName: must end with content.xml or styles.xml"),
+ *this, 0);
+ }
+}
+
+void SAL_CALL
+DocumentMetadataAccess::removeContentOrStylesFile(
+ const ::rtl::OUString & i_rFileName)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ container::NoSuchElementException)
+{
+ if (!isFileNameValid(i_rFileName)) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::removeContentOrStylesFile: "
+ "invalid FileName"), *this, 0);
+ }
+
+ try {
+ const uno::Reference<rdf::XURI> xPart(
+ getURIForStream(*m_pImpl, i_rFileName) );
+ const uno::Reference<container::XEnumeration> xEnum(
+ m_pImpl->m_xManifest->getStatements( m_pImpl->m_xBaseURI.get(),
+ getURI<rdf::URIs::PKG_HASPART>(m_pImpl->m_xContext),
+ xPart.get()),
+ uno::UNO_SET_THROW);
+ if (!xEnum->hasMoreElements()) {
+ throw container::NoSuchElementException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::removeContentOrStylesFile: "
+ "cannot find stream in manifest graph: ") + i_rFileName,
+ *this);
+ }
+
+ // remove file from manifest
+ removeFile(*m_pImpl, xPart);
+
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::removeContentOrStylesFile: exception"),
+ *this, uno::makeAny(e));
+ }
+}
+
+void SAL_CALL DocumentMetadataAccess::loadMetadataFromStorage(
+ const uno::Reference< embed::XStorage > & i_xStorage,
+ const uno::Reference<rdf::XURI> & i_xBaseURI,
+ const uno::Reference<task::XInteractionHandler> & i_xHandler)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ if (!i_xStorage.is()) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromStorage: "
+ "storage is null"), *this, 0);
+ }
+ if (!i_xBaseURI.is()) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromStorage: "
+ "base URI is null"), *this, 1);
+ }
+ const ::rtl::OUString baseURI( i_xBaseURI->getStringValue());
+ if (baseURI.indexOf('#') >= 0) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromStorage: "
+ "base URI not absolute"), *this, 1);
+ }
+ if (!baseURI.getLength() || !baseURI.endsWithAsciiL("/", 1)) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromStorage: "
+ "base URI does not end with slash"), *this, 1);
+ }
+
+ initLoading(*m_pImpl, i_xStorage, i_xBaseURI, i_xHandler);
+
+ std::set< ::rtl::OUString > StgFiles;
+ collectFilesFromStorage(i_xStorage,
+ ::rtl::OUString::createFromAscii(""), StgFiles);
+
+ std::vector< ::rtl::OUString > MfstMetadataFiles;
+
+ try {
+ const ::std::vector< uno::Reference< rdf::XURI > > parts(
+ getAllParts(*m_pImpl) );
+ const uno::Reference<rdf::XURI> xContentFile(
+ getURI<rdf::URIs::ODF_CONTENTFILE>(m_pImpl->m_xContext));
+ const uno::Reference<rdf::XURI> xStylesFile(
+ getURI<rdf::URIs::ODF_STYLESFILE>(m_pImpl->m_xContext));
+ const uno::Reference<rdf::XURI> xMetadataFile(
+ getURI<rdf::URIs::PKG_METADATAFILE>(m_pImpl->m_xContext));
+ const sal_Int32 len( baseURI.getLength() );
+ const ::rtl::OUString manifest (
+ ::rtl::OUString::createFromAscii(s_manifest));
+ for (::std::vector< uno::Reference< rdf::XURI > >::const_iterator it
+ = parts.begin();
+ it != parts.end(); ++it) {
+ const ::rtl::OUString name((*it)->getStringValue());
+ if (!name.match(baseURI)) {
+ OSL_TRACE("loadMetadataFromStorage: graph not in document: %s",
+ ::rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8)
+ .getStr());
+ continue;
+ }
+ const ::rtl::OUString relName( name.copy(len) );
+ if (relName == manifest) {
+ OSL_TRACE("loadMetadataFromStorage: "
+ "found ourselves a recursive manifest!");
+ continue;
+ }
+ // remove found items from StgFiles
+ StgFiles.erase(relName);
+ if (isContentFile(relName)) {
+ if (!isPartOfType(*m_pImpl, *it, xContentFile)) {
+ const uno::Reference <rdf::XURI> xName(
+ getURIForStream(*m_pImpl, relName) );
+ // add missing type statement
+ m_pImpl->m_xManifest->addStatement(xName.get(),
+ getURI<rdf::URIs::RDF_TYPE>(m_pImpl->m_xContext),
+ xContentFile.get());
+ }
+ } else if (isStylesFile(relName)) {
+ if (!isPartOfType(*m_pImpl, *it, xStylesFile)) {
+ const uno::Reference <rdf::XURI> xName(
+ getURIForStream(*m_pImpl, relName) );
+ // add missing type statement
+ m_pImpl->m_xManifest->addStatement(xName.get(),
+ getURI<rdf::URIs::RDF_TYPE>(m_pImpl->m_xContext),
+ xStylesFile.get());
+ }
+ } else if (isReservedFile(relName)) {
+ OSL_TRACE("loadMetadataFromStorage: "
+ "reserved file name in manifest");
+ } else {
+ if (isPartOfType(*m_pImpl, *it, xMetadataFile)) {
+ MfstMetadataFiles.push_back(relName);
+ }
+ // do not add statement for MetadataFile; it could be
+ // something else! just ignore it...
+ }
+ }
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromStorage: "
+ "exception"), *this, uno::makeAny(e));
+ }
+
+ std::for_each(StgFiles.begin(), StgFiles.end(),
+ boost::bind(addContentOrStylesFileImpl, boost::ref(*m_pImpl), _1));
+
+ std::for_each(MfstMetadataFiles.begin(), MfstMetadataFiles.end(),
+ boost::bind(importFile, boost::ref(*m_pImpl),
+ i_xStorage, baseURI, i_xHandler, _1));
+}
+
+void SAL_CALL DocumentMetadataAccess::storeMetadataToStorage(
+ const uno::Reference< embed::XStorage > & i_xStorage)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ if (!i_xStorage.is()) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::storeMetadataToStorage: "
+ "storage is null"), *this, 0);
+ }
+
+ // export manifest
+ const ::rtl::OUString manifest (
+ ::rtl::OUString::createFromAscii(s_manifest));
+ const uno::Reference <rdf::XURI> xManifest(
+ getURIForStream(*m_pImpl, manifest) );
+ const ::rtl::OUString baseURI( m_pImpl->m_xBaseURI->getStringValue() );
+ try {
+ writeStream(*m_pImpl, i_xStorage, xManifest, manifest, baseURI);
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (io::IOException & e) {
+ throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii(
+ "storeMetadataToStorage: IO exception"), *this, uno::makeAny(e));
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "storeMetadataToStorage: exception"), *this, uno::makeAny(e));
+ }
+
+ // export metadata streams
+ try {
+ const uno::Sequence<uno::Reference<rdf::XURI> > graphs(
+ m_pImpl->m_xRepository->getGraphNames());
+ const sal_Int32 len( baseURI.getLength() );
+ for (sal_Int32 i = 0; i < graphs.getLength(); ++i) {
+ const uno::Reference<rdf::XURI> xName(graphs[i]);
+ const ::rtl::OUString name(xName->getStringValue());
+ if (!name.match(baseURI)) {
+ OSL_TRACE("storeMetadataToStorage: graph not in document: %s",
+ ::rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8)
+ .getStr());
+ continue;
+ }
+ const ::rtl::OUString relName( name.copy(len) );
+ if (relName == manifest) {
+ continue;
+ }
+ if (!isFileNameValid(relName) || isReservedFile(relName)) {
+ OSL_TRACE("storeMetadataToStorage: invalid file name: %s",
+ ::rtl::OUStringToOString(relName, RTL_TEXTENCODING_UTF8)
+ .getStr());
+ continue;
+ }
+ try {
+ writeStream(*m_pImpl, i_xStorage, xName, relName, baseURI);
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (io::IOException & e) {
+ throw lang::WrappedTargetException(
+ ::rtl::OUString::createFromAscii(
+ "storeMetadataToStorage: IO exception"),
+ *this, uno::makeAny(e));
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "storeMetadataToStorage: exception"),
+ *this, uno::makeAny(e));
+ }
+ }
+ } catch (rdf::RepositoryException & e) {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "storeMetadataToStorage: exception"), *this, uno::makeAny(e));
+ }
+}
+
+void SAL_CALL
+DocumentMetadataAccess::loadMetadataFromMedium(
+ const uno::Sequence< beans::PropertyValue > & i_rMedium)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ uno::Reference<io::XInputStream> xIn;
+ ::comphelper::MediaDescriptor md(i_rMedium);
+ ::rtl::OUString URL;
+ md[ ::comphelper::MediaDescriptor::PROP_URL() ] >>= URL;
+ ::rtl::OUString BaseURL;
+ md[ ::comphelper::MediaDescriptor::PROP_DOCUMENTBASEURL() ] >>= BaseURL;
+ if (md.addInputStream()) {
+ md[ ::comphelper::MediaDescriptor::PROP_INPUTSTREAM() ] >>= xIn;
+ }
+ if (!xIn.is() && URL.equalsAscii("")) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromMedium: "
+ "inalid medium: no URL, no input stream"), *this, 0);
+ }
+ uno::Reference<embed::XStorage> xStorage;
+ try {
+ const uno::Reference<lang::XMultiServiceFactory> xMsf (
+ m_pImpl->m_xContext->getServiceManager(), uno::UNO_QUERY_THROW);
+ if (xIn.is()) {
+ xStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream(
+ xIn, xMsf);
+ } else { // fallback to url
+ xStorage = ::comphelper::OStorageHelper::GetStorageFromURL2(
+ URL, embed::ElementModes::READ, xMsf);
+ }
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (io::IOException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetException(
+ ::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromMedium: "
+ "exception"), *this, uno::makeAny(e));
+ }
+ if (!xStorage.is()) {
+ throw uno::RuntimeException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::loadMetadataFromMedium: "
+ "cannot get Storage"), *this);
+ }
+ uno::Reference<rdf::XURI> xBaseURI;
+ try {
+ xBaseURI = createBaseURI(m_pImpl->m_xContext, xStorage, BaseURL);
+ } catch (uno::Exception &) {
+ // fall back to URL
+ try {
+ xBaseURI = createBaseURI(m_pImpl->m_xContext, xStorage, URL);
+ } catch (uno::Exception &) {
+ OSL_ENSURE(false, "cannot create base URI");
+ }
+ }
+ uno::Reference<task::XInteractionHandler> xIH;
+ md[ ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER() ] >>= xIH;
+ loadMetadataFromStorage(xStorage, xBaseURI, xIH);
+}
+
+void SAL_CALL
+DocumentMetadataAccess::storeMetadataToMedium(
+ const uno::Sequence< beans::PropertyValue > & i_rMedium)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ ::comphelper::MediaDescriptor md(i_rMedium);
+ ::rtl::OUString URL;
+ md[ ::comphelper::MediaDescriptor::PROP_URL() ] >>= URL;
+ if (URL.equalsAscii("")) {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::storeMetadataToMedium: "
+ "invalid medium: no URL"), *this, 0);
+ }
+
+ SfxMedium aMedium(i_rMedium);
+ uno::Reference<embed::XStorage> xStorage(aMedium.GetOutputStorage());
+
+ bool sfx(false);
+ if (xStorage.is()) {
+ sfx = true;
+ } else {
+ const uno::Reference<lang::XMultiServiceFactory> xMsf (
+ m_pImpl->m_xContext->getServiceManager(), uno::UNO_QUERY_THROW);
+ xStorage = ::comphelper::OStorageHelper::GetStorageFromURL2(
+ URL, embed::ElementModes::WRITE, xMsf);
+ }
+
+ if (!xStorage.is()) {
+ throw uno::RuntimeException(::rtl::OUString::createFromAscii(
+ "DocumentMetadataAccess::storeMetadataToMedium: "
+ "cannot get Storage"), *this);
+ }
+ // set MIME type of the storage
+ ::comphelper::MediaDescriptor::const_iterator iter
+ = md.find(::comphelper::MediaDescriptor::PROP_MEDIATYPE());
+ if (iter != md.end()) {
+ uno::Reference< beans::XPropertySet > xProps(xStorage,
+ uno::UNO_QUERY_THROW);
+ try {
+ // this is NOT supported in FileSystemStorage
+ xProps->setPropertyValue(
+ ::comphelper::MediaDescriptor::PROP_MEDIATYPE(),
+ iter->second);
+ } catch (uno::Exception &) { }
+ }
+ storeMetadataToStorage(xStorage);
+
+ if (sfx) {
+ const sal_Bool bOk = aMedium.Commit();
+ aMedium.Close();
+ if ( !bOk ) {
+ sal_uInt32 nError = aMedium.GetError();
+ if ( nError == ERRCODE_NONE ) {
+ nError = ERRCODE_IO_GENERAL;
+ }
+ task::ErrorCodeIOException ex( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(), nError);
+ throw lang::WrappedTargetException(::rtl::OUString(), *this,
+ uno::makeAny(ex));
+ }
+ }
+}
+
+} // namespace sfx2
+
diff --git a/sfx2/source/doc/Metadatable.cxx b/sfx2/source/doc/Metadatable.cxx
new file mode 100644
index 000000000000..94c5826569f2
--- /dev/null
+++ b/sfx2/source/doc/Metadatable.cxx
@@ -0,0 +1,1703 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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_sfx2.hxx"
+
+#include <sfx2/Metadatable.hxx>
+#include <sfx2/XmlIdRegistry.hxx>
+
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx> // solarmutex
+
+#include <rtl/random.h>
+
+#include <boost/bind.hpp>
+
+#include <memory>
+#include <hash_map>
+#include <list>
+#include <algorithm>
+#if OSL_DEBUG_LEVEL > 0
+#include <typeinfo>
+#endif
+
+
+/** XML ID handling.
+
+ There is an abstract base class <type>XmlIdRegistry</type>, with
+ 2 subclasses <type>XmlIdRegistryDocument</type> for "normal" documents,
+ and <type>XmlIdRegistryClipboard</type> for clipboard documents.
+ These classes are responsible for managing XML IDs for all elements
+ of the model. Only the implementation of the <type>Metadatable</type>
+ base class needs to know the registries, so they are not in the header.
+
+ The handling of XML IDs differs between clipboard and non-clipboard
+ documents in several aspects. Most importantly, non-clipboard documents
+ can have several elements associated with one XML ID.
+ This is necessary because of the weird undo implementation:
+ deleting a text node moves the deleted node to the undo array, but
+ executing undo will then create a <em>copy</em> of that node in the
+ document array. These 2 nodes must have the same XML ID, because
+ we cannot know whether the user will do a redo next, or something else.
+
+ Because we need to have a mechanism for several objects per XML ID anyway,
+ we use that also to enable some usability features:
+ The document registry has a list of Metadatables per XML ID.
+ This list is sorted by priority, i.e., the first element has highest
+ priority. When inserting copies, care must be taken that they are inserted
+ at the right position: either before or after the source.
+ This is done by <method>Metadatable::RegisterAsCopyOf</method>.
+ When a text node is split, then both resulting text nodes are inserted
+ into the list. If the user then deletes one text node, the other one
+ will have the XML ID.
+ Also, when a Metadatable is copied to the clipboard and then pasted,
+ the copy is inserted into the list. If the user then deletes the source,
+ the XML ID is not lost.
+ The goal is that it should be hard to lose an XML ID by accident, which
+ is especially important as long as we do not have an UI that displays them.
+
+ There are two subclasses of <type>Metadatable</type>:
+ <ul><li><type>MetadatableClipboard</type>: for copies in the clipboard</li>
+ <li><type>MetadatableUndo</type>: for undo, because a Metadatable
+ may be destroyed on delete and a new one created on undo.</li></ul>
+ These serve only to track the position in an XML ID list in a document
+ registry, so that future actions can insert objects at the right position.
+ Unfortunately, inserting dummy objects seems to be necessary:
+ <ul><li>it is not sufficent to just remember the saved id, because then
+ the relative priorities might change when executing the undo</li>
+ <li>it is not sufficient to record the position as an integer, because
+ if we delete a text node and then undo, the node will be copied(!),
+ and we will have one more node in the list.<li>
+ <li>it is not sufficient to record the pointer of the previous/next
+ Metadatable, because if we delete a text node, undo, and then
+ do something to clear the redo array, the original text node is
+ destroyed, and is replaced by the copy created by undo</li></ul>
+
+ If content from a non-clipboard document is copied into a clipboard
+ document, a dummy <type>MetadatableClipboard</type> is inserted into the
+ non-clipboard document registry in order to track the position of the
+ source element. When the clipboard content is pasted back into the source
+ document, this dummy object is used to associate the pasted element with
+ that same XML ID.
+
+ If a <type>Metadatable</type> is deleted or merged,
+ <method>Metadatable::CreateUndo</method> is called, and returns a
+ <type>MetadatableUndo<type> instance, which can be used to undo the action
+ by passing it to <method>Metadatable::RestoreMetadata</method>.
+
+ @author mst
+ */
+
+
+using namespace ::com::sun::star;
+
+using ::sfx2::isValidXmlId;
+
+
+namespace sfx2 {
+
+static const char s_content [] = "content.xml";
+static const char s_styles [] = "styles.xml";
+static const char s_prefix [] = "id"; // prefix for generated xml:id
+
+static bool isContentFile(::rtl::OUString const & i_rPath)
+{
+ return i_rPath.equalsAscii(s_content);
+}
+
+static bool isStylesFile (::rtl::OUString const & i_rPath)
+{
+ return i_rPath.equalsAscii(s_styles);
+}
+
+
+//=============================================================================
+// XML ID handling ---------------------------------------------------
+
+/** handles registration of XMetadatable.
+
+ This class is responsible for guaranteeing that XMetadatable objects
+ always have XML IDs that are unique within a stream.
+
+ This is an abstract base class; see subclasses XmlIdRegistryDocument and
+ XmlIdRegistryClipboard.
+
+ @see SwDoc::GetXmlIdRegistry
+ @see SwDocShell::GetXmlIdRegistry
+ */
+class XmlIdRegistry : public sfx2::IXmlIdRegistry
+{
+
+public:
+ XmlIdRegistry();
+
+ virtual ~XmlIdRegistry();
+
+ /** get the ODF element with the given metadata reference. */
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::rdf::XMetadatable > SAL_CALL
+ GetElementByMetadataReference(
+ const ::com::sun::star::beans::StringPair & i_rReference) const;
+
+ /** register an ODF element at a newly generated, unique metadata reference.
+
+ <p>
+ Find a fresh XML ID, and register it for the element.
+ The generated ID does not occur in any stream of the document.
+ </p>
+ */
+ virtual void RegisterMetadatableAndCreateID(Metadatable& i_xObject) = 0;
+
+ /** try to register an ODF element at a given XML ID, or update its
+ registation to a different XML ID.
+
+ <p>
+ If the given new metadata reference is not already occupied in the
+ document, unregister the element at its old metadata reference if
+ it has one, and register the new metadata reference for the element.
+ Note that this method only ensures that XML IDs are unique per stream,
+ so using the same XML ID in both content.xml and styles.xml is allowed.
+ </p>
+
+ @returns
+ true iff the element has successfully been registered
+ */
+ virtual bool TryRegisterMetadatable(Metadatable& i_xObject,
+ ::rtl::OUString const& i_rStreamName, ::rtl::OUString const& i_rIdref)
+ = 0;
+
+ /** unregister an ODF element.
+
+ <p>
+ Unregister the element at its metadata reference.
+ Does not remove the metadata reference from the element.
+ </p>
+
+ @see RemoveXmlIdForElement
+ */
+ virtual void UnregisterMetadatable(Metadatable const&) = 0;
+
+ /** get the metadata reference for the given element. */
+ ::com::sun::star::beans::StringPair
+ GetXmlIdForElement(Metadatable const&) const;
+
+ /** remove the metadata reference for the given element. */
+ virtual void RemoveXmlIdForElement(Metadatable const&) = 0;
+
+protected:
+
+ virtual bool LookupXmlId(const Metadatable& i_xObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref) const = 0;
+
+ virtual Metadatable* LookupElement(const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const = 0;
+};
+
+// XmlIdRegistryDocument ---------------------------------------------
+
+/** non-clipboard documents */
+class XmlIdRegistryDocument : public XmlIdRegistry
+{
+
+public:
+ XmlIdRegistryDocument();
+
+ virtual ~XmlIdRegistryDocument();
+
+ virtual void RegisterMetadatableAndCreateID(Metadatable& i_xObject);
+
+ virtual bool TryRegisterMetadatable(Metadatable& i_xObject,
+ ::rtl::OUString const& i_rStreamName, ::rtl::OUString const& i_rIdref);
+
+ virtual void UnregisterMetadatable(Metadatable const&);
+
+ virtual void RemoveXmlIdForElement(Metadatable const&);
+
+ /** register i_rCopy as a copy of i_rSource,
+ with precedence iff i_bCopyPrecedesSource is true */
+ void RegisterCopy(Metadatable const& i_rSource, Metadatable & i_rCopy,
+ const bool i_bCopyPrecedesSource);
+
+ /** create a Undo Metadatable for i_rObject. */
+ ::boost::shared_ptr<MetadatableUndo> CreateUndo(
+ Metadatable const& i_rObject);
+
+ /** merge i_rMerged and i_rOther into i_rMerged. */
+ void JoinMetadatables(Metadatable & i_rMerged, Metadatable const& i_rOther);
+
+ // unfortunately public, Metadatable::RegisterAsCopyOf needs this
+ virtual bool LookupXmlId(const Metadatable& i_xObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref) const;
+
+private:
+
+ virtual Metadatable* LookupElement(const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const;
+
+ struct XmlIdRegistry_Impl;
+ ::std::auto_ptr<XmlIdRegistry_Impl> m_pImpl;
+};
+
+// MetadatableUndo ---------------------------------------------------
+
+/** the horrible Undo Metadatable: is inserted into lists to track position */
+class MetadatableUndo : public Metadatable
+{
+ /// as determined by the stream of the source in original document
+ const bool m_isInContent;
+public:
+ MetadatableUndo(const bool i_isInContent)
+ : m_isInContent(i_isInContent) { }
+ virtual ::sfx2::XmlIdRegistry& GetRegistry()
+ {
+ // N.B. for Undo, m_pReg is initialized by registering this as copy in
+ // CreateUndo; it is never cleared
+ OSL_ENSURE(m_pReg, "no m_pReg in MetadatableUndo ?");
+ return *m_pReg;
+ }
+ virtual bool IsInClipboard() const { return false; }
+ virtual bool IsInUndo() const { return true; }
+ virtual bool IsInContent() const { return m_isInContent; }
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::rdf::XMetadatable > MakeUnoObject()
+ { OSL_ENSURE(false, "MetadatableUndo::MakeUnoObject"); throw; }
+};
+
+// MetadatableClipboard ----------------------------------------------
+
+/** the horrible Clipboard Metadatable: inserted into lists to track position */
+class MetadatableClipboard : public Metadatable
+{
+ /// as determined by the stream of the source in original document
+ const bool m_isInContent;
+public:
+ MetadatableClipboard(const bool i_isInContent)
+ : m_isInContent(i_isInContent) { }
+ virtual ::sfx2::XmlIdRegistry& GetRegistry()
+ {
+ // N.B. for Clipboard, m_pReg is initialized by registering this as copy in
+ // RegisterAsCopyOf; it is only cleared by OriginNoLongerInBusinessAnymore
+ OSL_ENSURE(m_pReg, "no m_pReg in MetadatableClipboard ?");
+ return *m_pReg;
+ }
+ virtual bool IsInClipboard() const { return true; }
+ virtual bool IsInUndo() const { return false; }
+ virtual bool IsInContent() const { return m_isInContent; }
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::rdf::XMetadatable > MakeUnoObject()
+ { OSL_ENSURE(false, "MetadatableClipboard::MakeUnoObject"); throw; }
+ void OriginNoLongerInBusinessAnymore() { m_pReg = 0; }
+};
+
+// XmlIdRegistryClipboard --------------------------------------------
+
+class XmlIdRegistryClipboard : public XmlIdRegistry
+{
+
+public:
+ XmlIdRegistryClipboard();
+ virtual ~XmlIdRegistryClipboard();
+
+ virtual void RegisterMetadatableAndCreateID(Metadatable& i_xObject);
+
+ virtual bool TryRegisterMetadatable(Metadatable& i_xObject,
+ ::rtl::OUString const& i_rStreamName, ::rtl::OUString const& i_rIdref);
+
+ virtual void UnregisterMetadatable(Metadatable const&);
+
+ virtual void RemoveXmlIdForElement(Metadatable const&);
+
+ /** register i_rCopy as a copy of i_rSource */
+ MetadatableClipboard & RegisterCopyClipboard(Metadatable & i_rCopy,
+ beans::StringPair const & i_rReference,
+ const bool i_isLatent);
+
+ /** get the Metadatable that links i_rObject to its origin registry */
+ MetadatableClipboard const* SourceLink(Metadatable const& i_rObject);
+
+private:
+ virtual bool LookupXmlId(const Metadatable& i_xObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref) const;
+
+ virtual Metadatable* LookupElement(const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const;
+
+ /** create a Clipboard Metadatable for i_rObject. */
+ ::boost::shared_ptr<MetadatableClipboard> CreateClipboard(
+ const bool i_isInContent);
+
+ struct XmlIdRegistry_Impl;
+ ::std::auto_ptr<XmlIdRegistry_Impl> m_pImpl;
+};
+
+
+//=============================================================================
+// XmlIdRegistry
+
+::sfx2::IXmlIdRegistry * createXmlIdRegistry(const bool i_DocIsClipboard)
+{
+ return i_DocIsClipboard
+ ? static_cast<XmlIdRegistry*>( new XmlIdRegistryClipboard )
+ : static_cast<XmlIdRegistry*>( new XmlIdRegistryDocument );
+}
+
+XmlIdRegistry::XmlIdRegistry()
+{
+}
+
+XmlIdRegistry::~XmlIdRegistry()
+{
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::rdf::XMetadatable > SAL_CALL
+XmlIdRegistry::GetElementByMetadataReference(
+ const beans::StringPair & i_rReference) const
+{
+ Metadatable* pObject( LookupElement(i_rReference.First,
+ i_rReference.Second) );
+ return pObject ? pObject->MakeUnoObject() : 0;
+}
+
+beans::StringPair
+XmlIdRegistry::GetXmlIdForElement(const Metadatable& i_rObject) const
+{
+ ::rtl::OUString path;
+ ::rtl::OUString idref;
+ if (LookupXmlId(i_rObject, path, idref))
+ {
+ if (LookupElement(path, idref) == &i_rObject)
+ {
+ return beans::StringPair(path, idref);
+ }
+ }
+ return beans::StringPair();
+}
+
+
+/// generate unique xml:id
+template< typename T >
+/*static*/ ::rtl::OUString create_id(const
+ ::std::hash_map< ::rtl::OUString, T, ::rtl::OUStringHash > & i_rXmlIdMap)
+{
+ static rtlRandomPool s_Pool( rtl_random_createPool() );
+ const ::rtl::OUString prefix( ::rtl::OUString::createFromAscii(s_prefix) );
+ typename ::std::hash_map< ::rtl::OUString, T, ::rtl::OUStringHash >
+ ::const_iterator iter;
+ ::rtl::OUString id;
+ do
+ {
+ sal_Int32 n;
+ rtl_random_getBytes(s_Pool, & n, sizeof(n));
+ id = prefix + ::rtl::OUString::valueOf(static_cast<sal_Int32>(abs(n)));
+ iter = i_rXmlIdMap.find(id);
+ }
+ while (iter != i_rXmlIdMap.end());
+ return id;
+}
+
+//=============================================================================
+// Document XML ID Registry (_Impl)
+
+/// element list
+typedef ::std::list< Metadatable* > XmlIdList_t;
+
+/// Idref -> (content.xml element list, styles.xml element list)
+typedef ::std::hash_map< ::rtl::OUString,
+ ::std::pair< XmlIdList_t, XmlIdList_t >, ::rtl::OUStringHash > XmlIdMap_t;
+
+/// pointer hash template
+template<typename T> struct PtrHash
+{
+ size_t operator() (T const * i_pT) const
+ {
+ return reinterpret_cast<size_t>(i_pT);
+ }
+};
+
+/// element -> (stream name, idref)
+typedef ::std::hash_map< const Metadatable*,
+ ::std::pair< ::rtl::OUString, ::rtl::OUString>, PtrHash<Metadatable> >
+ XmlIdReverseMap_t;
+
+struct XmlIdRegistryDocument::XmlIdRegistry_Impl
+{
+ XmlIdRegistry_Impl()
+ : m_XmlIdMap(), m_XmlIdReverseMap() { }
+
+ bool TryInsertMetadatable(Metadatable& i_xObject,
+ const ::rtl::OUString & i_rStream, const ::rtl::OUString & i_rIdref);
+
+ bool LookupXmlId(const Metadatable& i_xObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref) const;
+
+ Metadatable* LookupElement(const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const;
+
+ const XmlIdList_t * LookupElementList(
+ const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const;
+
+ XmlIdList_t * LookupElementList(
+ const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref)
+ {
+ return const_cast<XmlIdList_t*>(
+ const_cast<const XmlIdRegistry_Impl*>(this)
+ ->LookupElementList(i_rStreamName, i_rIdref));
+ }
+
+ XmlIdMap_t m_XmlIdMap;
+ XmlIdReverseMap_t m_XmlIdReverseMap;
+};
+
+// -------------------------------------------------------------------
+
+static void
+rmIter(XmlIdMap_t & i_rXmlIdMap, XmlIdMap_t::iterator const& i_rIter,
+ ::rtl::OUString const & i_rStream, Metadatable const& i_rObject)
+{
+ if (i_rIter != i_rXmlIdMap.end())
+ {
+ XmlIdList_t & rList( isContentFile(i_rStream)
+ ? i_rIter->second.first : i_rIter->second.second );
+ rList.remove(&const_cast<Metadatable&>(i_rObject));
+ if (i_rIter->second.first.empty() && i_rIter->second.second.empty())
+ {
+ i_rXmlIdMap.erase(i_rIter);
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+
+const XmlIdList_t *
+XmlIdRegistryDocument::XmlIdRegistry_Impl::LookupElementList(
+ const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const
+{
+ const XmlIdMap_t::const_iterator iter( m_XmlIdMap.find(i_rIdref) );
+ if (iter != m_XmlIdMap.end())
+ {
+ OSL_ENSURE(!iter->second.first.empty() || !iter->second.second.empty(),
+ "null entry in m_XmlIdMap");
+ return (isContentFile(i_rStreamName))
+ ? &iter->second.first
+ : &iter->second.second;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+Metadatable*
+XmlIdRegistryDocument::XmlIdRegistry_Impl::LookupElement(
+ const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const
+{
+ if (!isValidXmlId(i_rStreamName, i_rIdref))
+ {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "illegal XmlId"), 0, 0);
+ }
+
+ const XmlIdList_t * pList( LookupElementList(i_rStreamName, i_rIdref) );
+ if (pList)
+ {
+ const XmlIdList_t::const_iterator iter(
+ ::std::find_if(pList->begin(), pList->end(),
+ ::boost::bind(
+ ::std::logical_not<bool>(),
+ ::boost::bind(
+ ::std::logical_or<bool>(),
+ ::boost::bind( &Metadatable::IsInUndo, _1 ),
+ ::boost::bind( &Metadatable::IsInClipboard, _1 )
+ ) ) ) );
+ if (iter != pList->end())
+ {
+ return *iter;
+ }
+ }
+ return 0;
+}
+
+bool
+XmlIdRegistryDocument::XmlIdRegistry_Impl::LookupXmlId(
+ const Metadatable& i_rObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref) const
+{
+ const XmlIdReverseMap_t::const_iterator iter(
+ m_XmlIdReverseMap.find(&i_rObject) );
+ if (iter != m_XmlIdReverseMap.end())
+ {
+ OSL_ENSURE(!iter->second.first.equalsAscii(""),
+ "null stream in m_XmlIdReverseMap");
+ OSL_ENSURE(!iter->second.second.equalsAscii(""),
+ "null id in m_XmlIdReverseMap");
+ o_rStream = iter->second.first;
+ o_rIdref = iter->second.second;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool
+XmlIdRegistryDocument::XmlIdRegistry_Impl::TryInsertMetadatable(
+ Metadatable & i_rObject,
+ const ::rtl::OUString & i_rStreamName, const ::rtl::OUString & i_rIdref)
+{
+ const bool bContent( isContentFile(i_rStreamName) );
+ OSL_ENSURE(isContentFile(i_rStreamName) || isStylesFile(i_rStreamName),
+ "invalid stream");
+
+ XmlIdList_t * pList( LookupElementList(i_rStreamName, i_rIdref) );
+ if (pList)
+ {
+ if (pList->empty())
+ {
+ pList->push_back( &i_rObject );
+ return true;
+ }
+ else
+ {
+ // this is only called from TryRegister now, so check
+ // if all elements in the list are deleted (in undo) or
+ // placeholders, then "steal" the id from them
+ if ( pList->end() == ::std::find_if(pList->begin(), pList->end(),
+ ::boost::bind(
+ ::std::logical_not<bool>(),
+ ::boost::bind(
+ ::std::logical_or<bool>(),
+ ::boost::bind( &Metadatable::IsInUndo, _1 ),
+ ::boost::bind( &Metadatable::IsInClipboard, _1 )
+ ) ) ) )
+ {
+// ??? this is not undoable
+// pList->clear();
+// pList->push_back( &i_rObject );
+ pList->push_front( &i_rObject );
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ m_XmlIdMap.insert(::std::make_pair(i_rIdref, bContent
+ ? ::std::make_pair( XmlIdList_t( 1, &i_rObject ), XmlIdList_t() )
+ : ::std::make_pair( XmlIdList_t(), XmlIdList_t( 1, &i_rObject ) )));
+ return true;
+ }
+}
+
+//=============================================================================
+// Document XML ID Registry
+
+
+XmlIdRegistryDocument::XmlIdRegistryDocument()
+ : m_pImpl( new XmlIdRegistry_Impl )
+{
+}
+
+static void
+removeLink(Metadatable* i_pObject)
+{
+ OSL_ENSURE(i_pObject, "null in list ???");
+ if (!i_pObject) return;
+ if (i_pObject->IsInClipboard())
+ {
+ MetadatableClipboard* pLink(
+ dynamic_cast<MetadatableClipboard*>( i_pObject ) );
+ OSL_ENSURE(pLink, "IsInClipboard, but no MetadatableClipboard ?");
+ if (pLink)
+ {
+ pLink->OriginNoLongerInBusinessAnymore();
+ }
+ }
+}
+
+XmlIdRegistryDocument::~XmlIdRegistryDocument()
+{
+ // notify all list elements that are actually in the clipboard
+ for (XmlIdMap_t::iterator iter(m_pImpl->m_XmlIdMap.begin());
+ iter != m_pImpl->m_XmlIdMap.end(); ++iter)
+ {
+ ::std::for_each(iter->second.first.begin(), iter->second.first.end(),
+ removeLink);
+ ::std::for_each(iter->second.second.begin(), iter->second.second.end(),
+ removeLink);
+ }
+}
+
+bool
+XmlIdRegistryDocument::LookupXmlId(
+ const Metadatable& i_rObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref) const
+{
+ return m_pImpl->LookupXmlId(i_rObject, o_rStream, o_rIdref);
+}
+
+Metadatable*
+XmlIdRegistryDocument::LookupElement(
+ const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const
+{
+ return m_pImpl->LookupElement(i_rStreamName, i_rIdref);
+}
+
+bool
+XmlIdRegistryDocument::TryRegisterMetadatable(Metadatable & i_rObject,
+ ::rtl::OUString const& i_rStreamName, ::rtl::OUString const& i_rIdref)
+{
+ OSL_TRACE("TryRegisterMetadatable: %p (%s#%s)\n", &i_rObject,
+ ::rtl::OUStringToOString(i_rStreamName, RTL_TEXTENCODING_UTF8).getStr(),
+ ::rtl::OUStringToOString(i_rIdref, RTL_TEXTENCODING_UTF8).getStr());
+
+ OSL_ENSURE(!dynamic_cast<MetadatableUndo*>(&i_rObject),
+ "TryRegisterMetadatable called for MetadatableUndo?");
+ OSL_ENSURE(!dynamic_cast<MetadatableClipboard*>(&i_rObject),
+ "TryRegisterMetadatable called for MetadatableClipboard?");
+
+ if (!isValidXmlId(i_rStreamName, i_rIdref))
+ {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "illegal XmlId"), 0, 0);
+ }
+ if (i_rObject.IsInContent()
+ ? !isContentFile(i_rStreamName)
+ : !isStylesFile(i_rStreamName))
+ {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "illegal XmlId: wrong stream"), 0, 0);
+ }
+
+ ::rtl::OUString old_path;
+ ::rtl::OUString old_idref;
+ m_pImpl->LookupXmlId(i_rObject, old_path, old_idref);
+ if (old_path == i_rStreamName && old_idref == i_rIdref)
+ {
+ return (m_pImpl->LookupElement(old_path, old_idref) == &i_rObject);
+ }
+ XmlIdMap_t::iterator old_id( m_pImpl->m_XmlIdMap.end() );
+ if (!old_idref.equalsAscii(""))
+ {
+ old_id = m_pImpl->m_XmlIdMap.find(old_idref);
+ OSL_ENSURE(old_id != m_pImpl->m_XmlIdMap.end(), "old id not found");
+ }
+ if (m_pImpl->TryInsertMetadatable(i_rObject, i_rStreamName, i_rIdref))
+ {
+ rmIter(m_pImpl->m_XmlIdMap, old_id, old_path, i_rObject);
+ m_pImpl->m_XmlIdReverseMap[&i_rObject] =
+ ::std::make_pair(i_rStreamName, i_rIdref);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void
+XmlIdRegistryDocument::RegisterMetadatableAndCreateID(Metadatable & i_rObject)
+{
+ OSL_TRACE("RegisterMetadatableAndCreateID: %p\n", &i_rObject);
+
+ OSL_ENSURE(!dynamic_cast<MetadatableUndo*>(&i_rObject),
+ "RegisterMetadatableAndCreateID called for MetadatableUndo?");
+ OSL_ENSURE(!dynamic_cast<MetadatableClipboard*>(&i_rObject),
+ "RegisterMetadatableAndCreateID called for MetadatableClipboard?");
+
+ const bool isInContent( i_rObject.IsInContent() );
+ const ::rtl::OUString stream( ::rtl::OUString::createFromAscii(
+ isInContent ? s_content : s_styles ) );
+ // check if we have a latent xmlid, and if yes, remove it
+ ::rtl::OUString old_path;
+ ::rtl::OUString old_idref;
+ m_pImpl->LookupXmlId(i_rObject, old_path, old_idref);
+
+ XmlIdMap_t::iterator old_id( m_pImpl->m_XmlIdMap.end() );
+ if (!old_idref.equalsAscii(""))
+ {
+ old_id = m_pImpl->m_XmlIdMap.find(old_idref);
+ OSL_ENSURE(old_id != m_pImpl->m_XmlIdMap.end(), "old id not found");
+ if (m_pImpl->LookupElement(old_path, old_idref) == &i_rObject)
+ {
+ return;
+ }
+ else
+ {
+ // remove latent xmlid
+ rmIter(m_pImpl->m_XmlIdMap, old_id, old_path, i_rObject);
+ }
+ }
+
+ // create id
+ const ::rtl::OUString id( create_id(m_pImpl->m_XmlIdMap) );
+ OSL_ENSURE(m_pImpl->m_XmlIdMap.find(id) == m_pImpl->m_XmlIdMap.end(),
+ "created id is in use");
+ m_pImpl->m_XmlIdMap.insert(::std::make_pair(id, isInContent
+ ? ::std::make_pair( XmlIdList_t( 1, &i_rObject ), XmlIdList_t() )
+ : ::std::make_pair( XmlIdList_t(), XmlIdList_t( 1, &i_rObject ) )));
+ m_pImpl->m_XmlIdReverseMap[&i_rObject] = ::std::make_pair(stream, id);
+}
+
+void XmlIdRegistryDocument::UnregisterMetadatable(const Metadatable& i_rObject)
+{
+ OSL_TRACE("UnregisterMetadatable: %p\n", &i_rObject);
+
+ ::rtl::OUString path;
+ ::rtl::OUString idref;
+ if (!m_pImpl->LookupXmlId(i_rObject, path, idref))
+ {
+ OSL_ENSURE(false, "unregister: no xml id?");
+ return;
+ }
+ const XmlIdMap_t::iterator iter( m_pImpl->m_XmlIdMap.find(idref) );
+ if (iter != m_pImpl->m_XmlIdMap.end())
+ {
+ rmIter(m_pImpl->m_XmlIdMap, iter, path, i_rObject);
+ }
+}
+
+void XmlIdRegistryDocument::RemoveXmlIdForElement(const Metadatable& i_rObject)
+{
+ OSL_TRACE("RemoveXmlIdForElement: %p\n", &i_rObject);
+
+ const XmlIdReverseMap_t::iterator iter(
+ m_pImpl->m_XmlIdReverseMap.find(&i_rObject) );
+ if (iter != m_pImpl->m_XmlIdReverseMap.end())
+ {
+ OSL_ENSURE(!iter->second.second.equalsAscii(""),
+ "null id in m_XmlIdReverseMap");
+ m_pImpl->m_XmlIdReverseMap.erase(iter);
+ }
+}
+
+// -------------------------------------------------------------------
+
+void XmlIdRegistryDocument::RegisterCopy(Metadatable const& i_rSource,
+ Metadatable & i_rCopy, const bool i_bCopyPrecedesSource)
+{
+ OSL_TRACE("RegisterCopy: %p -> %p (%d)\n",
+ &i_rSource, &i_rCopy, i_bCopyPrecedesSource);
+
+ // potential sources: clipboard, undo array, splitNode
+ // assumption: stream change can only happen via clipboard, and is handled
+ // by Metadatable::RegisterAsCopyOf
+ OSL_ENSURE(i_rSource.IsInUndo() || i_rCopy.IsInUndo() ||
+ (i_rSource.IsInContent() == i_rCopy.IsInContent()),
+ "RegisterCopy: not in same stream?");
+
+ ::rtl::OUString path;
+ ::rtl::OUString idref;
+ if (!m_pImpl->LookupXmlId( i_rSource, path, idref ))
+ {
+ OSL_ENSURE(false, "no xml id?");
+ return;
+ }
+ XmlIdList_t * pList ( m_pImpl->LookupElementList(path, idref) );
+ OSL_ENSURE( ::std::find( pList->begin(), pList->end(), &i_rCopy )
+ == pList->end(), "copy already registered???");
+ XmlIdList_t::iterator srcpos(
+ ::std::find( pList->begin(), pList->end(), &i_rSource ) );
+ OSL_ENSURE(srcpos != pList->end(), "source not in list???");
+ if (srcpos == pList->end())
+ {
+ return;
+ }
+ if (i_bCopyPrecedesSource)
+ {
+ pList->insert( srcpos, &i_rCopy );
+ }
+ else
+ {
+ // for undo push_back does not work! must insert right after source
+ pList->insert( ++srcpos, &i_rCopy );
+ }
+ m_pImpl->m_XmlIdReverseMap.insert(::std::make_pair(&i_rCopy,
+ ::std::make_pair(path, idref)));
+}
+
+::boost::shared_ptr<MetadatableUndo>
+XmlIdRegistryDocument::CreateUndo(Metadatable const& i_rObject)
+{
+ OSL_TRACE("CreateUndo: %p\n", &i_rObject);
+
+ return ::boost::shared_ptr<MetadatableUndo>(
+ new MetadatableUndo(i_rObject.IsInContent()) );
+}
+
+/*
+i_rMerged is both a source and the target node of the merge
+i_rOther is the other source, and will be deleted after the merge
+
+dimensions: none|latent|actual empty|nonempty
+i_rMerged(1) i_rOther(2) result
+ *|empty *|empty => 1|2 (arbitrary)
+ *|empty *|nonempty => 2
+ *|nonempty *|empty => 1
+ none|nonempty none|nonempty => none
+ none|nonempty latent|nonempty => 2
+latent|nonempty none|nonempty => 1
+latent|nonempty latent|nonempty => 1|2
+ *|nonempty actual|nonempty => 2
+actual|nonempty *|nonempty => 1
+actual|nonempty actual|nonempty => 1|2
+*/
+void
+XmlIdRegistryDocument::JoinMetadatables(
+ Metadatable & i_rMerged, Metadatable const & i_rOther)
+{
+ OSL_TRACE("JoinMetadatables: %p <- %p\n", &i_rMerged, &i_rOther);
+
+ bool mergedOwnsRef;
+ ::rtl::OUString path;
+ ::rtl::OUString idref;
+ if (m_pImpl->LookupXmlId(i_rMerged, path, idref))
+ {
+ mergedOwnsRef = (m_pImpl->LookupElement(path, idref) == &i_rMerged);
+ }
+ else
+ {
+ OSL_ENSURE(false, "JoinMetadatables: no xmlid?");
+ return;
+ }
+ if (!mergedOwnsRef)
+ {
+ i_rMerged.RemoveMetadataReference();
+ i_rMerged.RegisterAsCopyOf(i_rOther, true);
+ return;
+ }
+ // other cases: merged has actual ref and is nonempty,
+ // other has latent/actual ref and is nonempty: other loses => nothing to do
+}
+
+
+//=============================================================================
+// Clipboard XML ID Registry (_Impl)
+
+struct RMapEntry
+{
+ RMapEntry() : m_pLink() { }
+ RMapEntry(::rtl::OUString const& i_rStream,
+ ::rtl::OUString const& i_rXmlId,
+ ::boost::shared_ptr<MetadatableClipboard> const& i_pLink
+ = ::boost::shared_ptr<MetadatableClipboard>())
+ : m_Stream(i_rStream), m_XmlId(i_rXmlId), m_pLink(i_pLink)
+ {}
+ ::rtl::OUString m_Stream;
+ ::rtl::OUString m_XmlId;
+ // this would have been an auto_ptr, if only that would have compiled...
+ ::boost::shared_ptr<MetadatableClipboard> m_pLink;
+};
+
+/// element -> (stream name, idref, source)
+typedef ::std::hash_map< const Metadatable*,
+ struct RMapEntry,
+ PtrHash<Metadatable> >
+ ClipboardXmlIdReverseMap_t;
+
+/// Idref -> (content.xml element, styles.xml element)
+typedef ::std::hash_map< ::rtl::OUString,
+ ::std::pair< Metadatable*, Metadatable* >, ::rtl::OUStringHash >
+ ClipboardXmlIdMap_t;
+
+struct XmlIdRegistryClipboard::XmlIdRegistry_Impl
+{
+ XmlIdRegistry_Impl()
+ : m_XmlIdMap(), m_XmlIdReverseMap() { }
+
+ bool TryInsertMetadatable(Metadatable& i_xObject,
+ const ::rtl::OUString & i_rStream, const ::rtl::OUString & i_rIdref);
+
+ bool LookupXmlId(const Metadatable& i_xObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref,
+ MetadatableClipboard const* &o_rpLink) const;
+
+ Metadatable* LookupElement(const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const;
+
+ Metadatable* const* LookupEntry(const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const;
+
+ Metadatable* * LookupEntry(const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref)
+ {
+ return const_cast<Metadatable**>(
+ const_cast<const XmlIdRegistry_Impl*>(this)
+ ->LookupEntry(i_rStreamName, i_rIdref));
+ }
+
+ ClipboardXmlIdMap_t m_XmlIdMap;
+ ClipboardXmlIdReverseMap_t m_XmlIdReverseMap;
+};
+
+// -------------------------------------------------------------------
+
+static void
+rmIter(ClipboardXmlIdMap_t & i_rXmlIdMap,
+ ClipboardXmlIdMap_t::iterator const& i_rIter,
+ ::rtl::OUString const & i_rStream, Metadatable const& i_rObject)
+{
+ if (i_rIter != i_rXmlIdMap.end())
+ {
+ Metadatable *& rMeta = isContentFile(i_rStream)
+ ? i_rIter->second.first : i_rIter->second.second;
+ if (rMeta == &i_rObject)
+ {
+ rMeta = 0;
+ }
+ if (!i_rIter->second.first && !i_rIter->second.second)
+ {
+ i_rXmlIdMap.erase(i_rIter);
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+
+Metadatable* const*
+XmlIdRegistryClipboard::XmlIdRegistry_Impl::LookupEntry(
+ const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const
+{
+ if (!isValidXmlId(i_rStreamName, i_rIdref))
+ {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "illegal XmlId"), 0, 0);
+ }
+
+ const ClipboardXmlIdMap_t::const_iterator iter( m_XmlIdMap.find(i_rIdref) );
+ if (iter != m_XmlIdMap.end())
+ {
+ OSL_ENSURE(iter->second.first || iter->second.second,
+ "null entry in m_XmlIdMap");
+ return (isContentFile(i_rStreamName))
+ ? &iter->second.first
+ : &iter->second.second;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+Metadatable*
+XmlIdRegistryClipboard::XmlIdRegistry_Impl::LookupElement(
+ const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const
+{
+ Metadatable * const * ppEntry = LookupEntry(i_rStreamName, i_rIdref);
+ return ppEntry ? *ppEntry : 0;
+}
+
+bool
+XmlIdRegistryClipboard::XmlIdRegistry_Impl::LookupXmlId(
+ const Metadatable& i_rObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref,
+ MetadatableClipboard const* &o_rpLink) const
+{
+ const ClipboardXmlIdReverseMap_t::const_iterator iter(
+ m_XmlIdReverseMap.find(&i_rObject) );
+ if (iter != m_XmlIdReverseMap.end())
+ {
+ OSL_ENSURE(!iter->second.m_Stream.equalsAscii(""),
+ "null stream in m_XmlIdReverseMap");
+ OSL_ENSURE(!iter->second.m_XmlId.equalsAscii(""),
+ "null id in m_XmlIdReverseMap");
+ o_rStream = iter->second.m_Stream;
+ o_rIdref = iter->second.m_XmlId;
+ o_rpLink = iter->second.m_pLink.get();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool
+XmlIdRegistryClipboard::XmlIdRegistry_Impl::TryInsertMetadatable(
+ Metadatable & i_rObject,
+ const ::rtl::OUString & i_rStreamName, const ::rtl::OUString & i_rIdref)
+{
+ bool bContent( isContentFile(i_rStreamName) );
+ OSL_ENSURE(isContentFile(i_rStreamName) || isStylesFile(i_rStreamName),
+ "invalid stream");
+
+ //wntmsci12 won't parse this:
+// Metadatable ** ppEntry( LookupEntry(i_rStreamName, i_rIdref) );
+ Metadatable ** ppEntry = LookupEntry(i_rStreamName, i_rIdref);
+ if (ppEntry)
+ {
+ if (*ppEntry)
+ {
+ return false;
+ }
+ else
+ {
+ *ppEntry = &i_rObject;
+ return true;
+ }
+ }
+ else
+ {
+ m_XmlIdMap.insert(::std::make_pair(i_rIdref, bContent
+ ? ::std::make_pair( &i_rObject, static_cast<Metadatable*>(0) )
+ : ::std::make_pair( static_cast<Metadatable*>(0), &i_rObject )));
+ return true;
+ }
+}
+
+//=============================================================================
+// Clipboard XML ID Registry
+
+
+XmlIdRegistryClipboard::XmlIdRegistryClipboard()
+ : m_pImpl( new XmlIdRegistry_Impl )
+{
+}
+
+XmlIdRegistryClipboard::~XmlIdRegistryClipboard()
+{
+}
+
+bool
+XmlIdRegistryClipboard::LookupXmlId(
+ const Metadatable& i_rObject,
+ ::rtl::OUString & o_rStream, ::rtl::OUString & o_rIdref) const
+{
+ const MetadatableClipboard * pLink;
+ return m_pImpl->LookupXmlId(i_rObject, o_rStream, o_rIdref, pLink);
+}
+
+Metadatable*
+XmlIdRegistryClipboard::LookupElement(
+ const ::rtl::OUString & i_rStreamName,
+ const ::rtl::OUString & i_rIdref) const
+{
+ return m_pImpl->LookupElement(i_rStreamName, i_rIdref);
+}
+
+bool
+XmlIdRegistryClipboard::TryRegisterMetadatable(Metadatable & i_rObject,
+ ::rtl::OUString const& i_rStreamName, ::rtl::OUString const& i_rIdref)
+{
+ OSL_TRACE("TryRegisterMetadatable: %p (%s#%s)\n", &i_rObject,
+ ::rtl::OUStringToOString(i_rStreamName, RTL_TEXTENCODING_UTF8).getStr(),
+ ::rtl::OUStringToOString(i_rIdref, RTL_TEXTENCODING_UTF8).getStr());
+
+ OSL_ENSURE(!dynamic_cast<MetadatableUndo*>(&i_rObject),
+ "TryRegisterMetadatable called for MetadatableUndo?");
+ OSL_ENSURE(!dynamic_cast<MetadatableClipboard*>(&i_rObject),
+ "TryRegisterMetadatable called for MetadatableClipboard?");
+
+ if (!isValidXmlId(i_rStreamName, i_rIdref))
+ {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "illegal XmlId"), 0, 0);
+ }
+ if (i_rObject.IsInContent()
+ ? !isContentFile(i_rStreamName)
+ : !isStylesFile(i_rStreamName))
+ {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "illegal XmlId: wrong stream"), 0, 0);
+ }
+
+ ::rtl::OUString old_path;
+ ::rtl::OUString old_idref;
+ const MetadatableClipboard * pLink;
+ m_pImpl->LookupXmlId(i_rObject, old_path, old_idref, pLink);
+ if (old_path == i_rStreamName && old_idref == i_rIdref)
+ {
+ return (m_pImpl->LookupElement(old_path, old_idref) == &i_rObject);
+ }
+ ClipboardXmlIdMap_t::iterator old_id( m_pImpl->m_XmlIdMap.end() );
+ if (!old_idref.equalsAscii(""))
+ {
+ old_id = m_pImpl->m_XmlIdMap.find(old_idref);
+ OSL_ENSURE(old_id != m_pImpl->m_XmlIdMap.end(), "old id not found");
+ }
+ if (m_pImpl->TryInsertMetadatable(i_rObject, i_rStreamName, i_rIdref))
+ {
+ rmIter(m_pImpl->m_XmlIdMap, old_id, old_path, i_rObject);
+ m_pImpl->m_XmlIdReverseMap[&i_rObject] =
+ RMapEntry(i_rStreamName, i_rIdref);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void
+XmlIdRegistryClipboard::RegisterMetadatableAndCreateID(Metadatable & i_rObject)
+{
+ OSL_TRACE("RegisterMetadatableAndCreateID: %p\n", &i_rObject);
+
+ OSL_ENSURE(!dynamic_cast<MetadatableUndo*>(&i_rObject),
+ "RegisterMetadatableAndCreateID called for MetadatableUndo?");
+ OSL_ENSURE(!dynamic_cast<MetadatableClipboard*>(&i_rObject),
+ "RegisterMetadatableAndCreateID called for MetadatableClipboard?");
+
+ bool isInContent( i_rObject.IsInContent() );
+ ::rtl::OUString stream( ::rtl::OUString::createFromAscii(
+ isInContent ? s_content : s_styles ) );
+
+ ::rtl::OUString old_path;
+ ::rtl::OUString old_idref;
+ LookupXmlId(i_rObject, old_path, old_idref);
+ if (!old_idref.equalsAscii("") &&
+ (m_pImpl->LookupElement(old_path, old_idref) == &i_rObject))
+ {
+ return;
+ }
+
+ // create id
+ const ::rtl::OUString id( create_id(m_pImpl->m_XmlIdMap) );
+ OSL_ENSURE(m_pImpl->m_XmlIdMap.find(id) == m_pImpl->m_XmlIdMap.end(),
+ "created id is in use");
+ m_pImpl->m_XmlIdMap.insert(::std::make_pair(id, isInContent
+ ? ::std::make_pair( &i_rObject, static_cast<Metadatable*>(0) )
+ : ::std::make_pair( static_cast<Metadatable*>(0), &i_rObject )));
+ // N.B.: if i_rObject had a latent XmlId, then we implicitly delete the
+ // MetadatableClipboard and thus the latent XmlId here
+ m_pImpl->m_XmlIdReverseMap[&i_rObject] = RMapEntry(stream, id);
+}
+
+void XmlIdRegistryClipboard::UnregisterMetadatable(const Metadatable& i_rObject)
+{
+ OSL_TRACE("UnregisterMetadatable: %p\n", &i_rObject);
+
+ ::rtl::OUString path;
+ ::rtl::OUString idref;
+ const MetadatableClipboard * pLink;
+ if (!m_pImpl->LookupXmlId(i_rObject, path, idref, pLink))
+ {
+ OSL_ENSURE(false, "unregister: no xml id?");
+ return;
+ }
+ const ClipboardXmlIdMap_t::iterator iter( m_pImpl->m_XmlIdMap.find(idref) );
+ if (iter != m_pImpl->m_XmlIdMap.end())
+ {
+ rmIter(m_pImpl->m_XmlIdMap, iter, path, i_rObject);
+ }
+}
+
+
+void XmlIdRegistryClipboard::RemoveXmlIdForElement(const Metadatable& i_rObject)
+{
+ OSL_TRACE("RemoveXmlIdForElement: %p\n", &i_rObject);
+
+ ClipboardXmlIdReverseMap_t::iterator iter(
+ m_pImpl->m_XmlIdReverseMap.find(&i_rObject) );
+ if (iter != m_pImpl->m_XmlIdReverseMap.end())
+ {
+ OSL_ENSURE(!iter->second.m_XmlId.equalsAscii(""),
+ "null id in m_XmlIdReverseMap");
+ m_pImpl->m_XmlIdReverseMap.erase(iter);
+ }
+}
+
+// -------------------------------------------------------------------
+
+::boost::shared_ptr<MetadatableClipboard>
+XmlIdRegistryClipboard::CreateClipboard(const bool i_isInContent)
+{
+ OSL_TRACE("CreateClipboard: \n");
+
+ return ::boost::shared_ptr<MetadatableClipboard>(
+ new MetadatableClipboard(i_isInContent) );
+}
+
+MetadatableClipboard &
+XmlIdRegistryClipboard::RegisterCopyClipboard(Metadatable & i_rCopy,
+ beans::StringPair const & i_rReference,
+ const bool i_isLatent)
+{
+ OSL_TRACE("RegisterCopyClipboard: %p -> "/*"%p"*/"(%s#%s) (%d)\n",
+ /*&i_rSource,*/ &i_rCopy,
+ ::rtl::OUStringToOString(i_rReference.First,
+ RTL_TEXTENCODING_UTF8).getStr(),
+ ::rtl::OUStringToOString(i_rReference.Second,
+ RTL_TEXTENCODING_UTF8).getStr(),
+ i_isLatent);
+
+ // N.B.: when copying to the clipboard, the selection is always inserted
+ // into the body, even if the source is a header/footer!
+ // so we do not check whether the stream is right in this function
+
+ if (!isValidXmlId(i_rReference.First, i_rReference.Second))
+ {
+ throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii(
+ "illegal XmlId"), 0, 0);
+ }
+
+ if (!i_isLatent)
+ {
+ // this should succeed assuming clipboard has a single source document
+ const bool success( m_pImpl->TryInsertMetadatable(i_rCopy,
+ i_rReference.First, i_rReference.Second) );
+ OSL_ENSURE(success, "RegisterCopyClipboard: TryInsert failed?");
+ (void) success;
+ }
+ const ::boost::shared_ptr<MetadatableClipboard> pLink(
+ CreateClipboard( isContentFile(i_rReference.First)) );
+ m_pImpl->m_XmlIdReverseMap.insert(::std::make_pair(&i_rCopy,
+ RMapEntry(i_rReference.First, i_rReference.Second, pLink)));
+ return *pLink.get();
+}
+
+MetadatableClipboard const*
+XmlIdRegistryClipboard::SourceLink(Metadatable const& i_rObject)
+{
+ ::rtl::OUString path;
+ ::rtl::OUString idref;
+ const MetadatableClipboard * pLink( 0 );
+ m_pImpl->LookupXmlId(i_rObject, path, idref, pLink);
+ return pLink;
+}
+
+
+//=============================================================================
+// Metadatable mixin
+
+
+Metadatable::~Metadatable()
+{
+ RemoveMetadataReference();
+}
+
+void Metadatable::RemoveMetadataReference()
+{
+ try
+ {
+ if (m_pReg)
+ {
+ m_pReg->UnregisterMetadatable( *this );
+ m_pReg->RemoveXmlIdForElement( *this );
+ m_pReg = 0;
+ }
+ }
+ catch (uno::Exception &)
+ {
+ OSL_ENSURE(false, "Metadatable::RemoveMetadataReference: exception");
+ }
+}
+
+// ::com::sun::star::rdf::XMetadatable:
+beans::StringPair
+Metadatable::GetMetadataReference() const
+{
+ if (m_pReg)
+ {
+ return m_pReg->GetXmlIdForElement(*this);
+ }
+ return beans::StringPair();
+}
+
+void
+Metadatable::SetMetadataReference(
+ const ::com::sun::star::beans::StringPair & i_rReference)
+{
+ if (i_rReference.Second.equalsAscii(""))
+ {
+ RemoveMetadataReference();
+ }
+ else
+ {
+ ::rtl::OUString streamName( i_rReference.First );
+ if (streamName.equalsAscii(""))
+ {
+ // handle empty stream name as auto-detect.
+ // necessary for importing flat file format.
+ streamName = ::rtl::OUString::createFromAscii(
+ IsInContent() ? s_content : s_styles );
+ }
+ XmlIdRegistry & rReg( dynamic_cast<XmlIdRegistry&>( GetRegistry() ) );
+ if (rReg.TryRegisterMetadatable(*this, streamName, i_rReference.Second))
+ {
+ m_pReg = &rReg;
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("Metadatable::"
+ "SetMetadataReference: argument is invalid"), /*this*/0, 0);
+ }
+ }
+}
+
+void Metadatable::EnsureMetadataReference()
+{
+ XmlIdRegistry& rReg(
+ m_pReg ? *m_pReg : dynamic_cast<XmlIdRegistry&>( GetRegistry() ) );
+ rReg.RegisterMetadatableAndCreateID( *this );
+ m_pReg = &rReg;
+}
+
+const ::sfx2::IXmlIdRegistry& GetRegistryConst(Metadatable const& i_rObject)
+{
+ return const_cast< Metadatable& >( i_rObject ).GetRegistry();
+}
+
+void
+Metadatable::RegisterAsCopyOf(Metadatable const & i_rSource,
+ const bool i_bCopyPrecedesSource)
+{
+ OSL_ENSURE(typeid(*this) == typeid(i_rSource)
+ || typeid(i_rSource) == typeid(MetadatableUndo)
+ || typeid(*this) == typeid(MetadatableUndo)
+ || typeid(i_rSource) == typeid(MetadatableClipboard)
+ || typeid(*this) == typeid(MetadatableClipboard),
+ "RegisterAsCopyOf element with different class?");
+ OSL_ENSURE(!this->m_pReg, "RegisterAsCopyOf called on element with XmlId?");
+
+ if (this->m_pReg)
+ {
+ RemoveMetadataReference();
+ }
+
+ try
+ {
+ if (i_rSource.m_pReg)
+ {
+ XmlIdRegistry & rReg(
+ dynamic_cast<XmlIdRegistry&>( GetRegistry() ) );
+ if (i_rSource.m_pReg == &rReg)
+ {
+ OSL_ENSURE(!IsInClipboard(),
+ "RegisterAsCopy: both in clipboard?");
+ if (!IsInClipboard())
+ {
+ XmlIdRegistryDocument & rRegDoc(
+ dynamic_cast<XmlIdRegistryDocument&>( rReg ) );
+ rRegDoc.RegisterCopy(i_rSource, *this,
+ i_bCopyPrecedesSource);
+ this->m_pReg = &rRegDoc;
+ }
+ return;
+ }
+ // source is in different document
+ XmlIdRegistryDocument * pRegDoc(
+ dynamic_cast<XmlIdRegistryDocument *>(&rReg) );
+ XmlIdRegistryClipboard * pRegClp(
+ dynamic_cast<XmlIdRegistryClipboard*>(&rReg) );
+
+ if (pRegClp)
+ {
+ beans::StringPair SourceRef(
+ i_rSource.m_pReg->GetXmlIdForElement(i_rSource) );
+ bool isLatent( SourceRef.Second.equalsAscii("") );
+ XmlIdRegistryDocument * pSourceRegDoc(
+ dynamic_cast<XmlIdRegistryDocument*>(i_rSource.m_pReg) );
+ OSL_ENSURE(pSourceRegDoc, "RegisterAsCopyOf: 2 clipboards?");
+ if (!pSourceRegDoc) return;
+ // this is a copy _to_ the clipboard
+ if (isLatent)
+ {
+ pSourceRegDoc->LookupXmlId(i_rSource,
+ SourceRef.First, SourceRef.Second);
+ }
+ Metadatable & rLink(
+ pRegClp->RegisterCopyClipboard(*this, SourceRef, isLatent));
+ this->m_pReg = pRegClp;
+ // register as copy in the non-clipboard registry
+ pSourceRegDoc->RegisterCopy(i_rSource, rLink,
+ false); // i_bCopyPrecedesSource);
+ rLink.m_pReg = pSourceRegDoc;
+ }
+ else if (pRegDoc)
+ {
+ XmlIdRegistryClipboard * pSourceRegClp(
+ dynamic_cast<XmlIdRegistryClipboard*>(i_rSource.m_pReg) );
+ OSL_ENSURE(pSourceRegClp,
+ "RegisterAsCopyOf: 2 non-clipboards?");
+ if (!pSourceRegClp) return;
+ const MetadatableClipboard * pLink(
+ pSourceRegClp->SourceLink(i_rSource) );
+ // may happen if src got its id via UNO call
+ if (!pLink) return;
+ // only register copy if clipboard content is from this SwDoc!
+ if (pLink && (&GetRegistryConst(*pLink) == pRegDoc))
+ {
+ // this is a copy _from_ the clipboard; check if the
+ // element is still in the same stream
+ // N.B.: we check the stream of pLink, not of i_rSource!
+ bool srcInContent( pLink->IsInContent() );
+ bool tgtInContent( this->IsInContent() );
+ if (srcInContent == tgtInContent)
+ {
+ pRegDoc->RegisterCopy(*pLink, *this,
+ true); // i_bCopyPrecedesSource);
+ this->m_pReg = pRegDoc;
+ }
+ // otherwise: stream change! do not register!
+ }
+ }
+ else
+ {
+ OSL_ENSURE(false, "neither RegDoc nor RegClp cannot happen");
+ }
+#if 0
+ {
+ //FIXME: do we need this at all???
+ XmlIdRegistryDocument & rRegDoc(
+ dynamic_cast<XmlIdRegistryDocument&>( rReg ) );
+ {
+ if (rRegDoc.TryRegisterMetadatable(*this, SourceRef))
+ {
+ this->m_pReg = &rRegDoc;
+ }
+ }
+ }
+#endif
+ }
+ }
+ catch (uno::Exception &)
+ {
+ OSL_ENSURE(false, "Metadatable::RegisterAsCopyOf: exception");
+ }
+}
+
+::boost::shared_ptr<MetadatableUndo> Metadatable::CreateUndo() const
+{
+ OSL_ENSURE(!IsInUndo(), "CreateUndo called for object in undo?");
+ OSL_ENSURE(!IsInClipboard(), "CreateUndo called for object in clipboard?");
+ try
+ {
+ if (!IsInClipboard() && !IsInUndo() && m_pReg)
+ {
+ XmlIdRegistryDocument * pRegDoc(
+ dynamic_cast<XmlIdRegistryDocument*>( m_pReg ) );
+ ::boost::shared_ptr<MetadatableUndo> pUndo(
+ pRegDoc->CreateUndo(*this) );
+ pRegDoc->RegisterCopy(*this, *pUndo, false);
+ pUndo->m_pReg = pRegDoc;
+ return pUndo;
+ }
+ }
+ catch (uno::Exception &)
+ {
+ OSL_ENSURE(false, "Metadatable::CreateUndo: exception");
+ }
+ return ::boost::shared_ptr<MetadatableUndo>();
+}
+
+::boost::shared_ptr<MetadatableUndo> Metadatable::CreateUndoForDelete()
+{
+ ::boost::shared_ptr<MetadatableUndo> const pUndo( CreateUndo() );
+ RemoveMetadataReference();
+ return pUndo;
+}
+
+void Metadatable::RestoreMetadata(
+ ::boost::shared_ptr<MetadatableUndo> const& i_pUndo)
+{
+ OSL_ENSURE(!IsInUndo(), "RestoreMetadata called for object in undo?");
+ OSL_ENSURE(!IsInClipboard(),
+ "RestoreMetadata called for object in clipboard?");
+ if (IsInClipboard() || IsInUndo()) return;
+ RemoveMetadataReference();
+ if (i_pUndo)
+ {
+ this->RegisterAsCopyOf(*i_pUndo, true);
+ }
+}
+
+void
+Metadatable::JoinMetadatable(Metadatable const & i_rOther,
+ const bool i_isMergedEmpty, const bool i_isOtherEmpty)
+{
+ OSL_ENSURE(!IsInUndo(), "JoinMetadatables called for object in undo?");
+ OSL_ENSURE(!IsInClipboard(),
+ "JoinMetadatables called for object in clipboard?");
+ if (IsInClipboard() || IsInUndo()) return;
+
+ if (i_isOtherEmpty && !i_isMergedEmpty)
+ {
+ // other is empty, thus loses => nothing to do
+ return;
+ }
+ if (i_isMergedEmpty && !i_isOtherEmpty)
+ {
+ this->RemoveMetadataReference();
+ this->RegisterAsCopyOf(i_rOther, true);
+ return;
+ }
+
+ if (!i_rOther.m_pReg)
+ {
+ // other doesn't have xmlid, thus loses => nothing to do
+ return;
+ }
+ if (!m_pReg)
+ {
+ this->RegisterAsCopyOf(i_rOther, true);
+ // assumption: i_rOther will be deleted, so don't unregister it here
+ return;
+ }
+ try
+ {
+ XmlIdRegistryDocument * pRegDoc(
+ dynamic_cast<XmlIdRegistryDocument*>( m_pReg ) );
+ OSL_ENSURE(pRegDoc, "JoinMetadatable: no pRegDoc?");
+ if (pRegDoc)
+ {
+ pRegDoc->JoinMetadatables(*this, i_rOther);
+ }
+ }
+ catch (uno::Exception &)
+ {
+ OSL_ENSURE(false, "Metadatable::JoinMetadatable: exception");
+ }
+}
+
+
+//=============================================================================
+// XMetadatable mixin
+
+// ::com::sun::star::rdf::XNode:
+::rtl::OUString SAL_CALL MetadatableMixin::getStringValue()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return getNamespace() + getLocalName();
+}
+
+// ::com::sun::star::rdf::XURI:
+::rtl::OUString SAL_CALL MetadatableMixin::getLocalName()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ beans::StringPair mdref( getMetadataReference() );
+ if (!mdref.Second.getLength())
+ {
+ ensureMetadataReference(); // N.B.: side effect!
+ mdref = getMetadataReference();
+ }
+ ::rtl::OUStringBuffer buf;
+ buf.append(mdref.First);
+ buf.append(static_cast<sal_Unicode>('#'));
+ buf.append(mdref.Second);
+ return buf.makeStringAndClear();
+}
+
+::rtl::OUString SAL_CALL MetadatableMixin::getNamespace()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ const uno::Reference< frame::XModel > xModel( GetModel() );
+ const uno::Reference< rdf::XURI > xDMA( xModel, uno::UNO_QUERY_THROW );
+ return xDMA->getStringValue();
+}
+
+// ::com::sun::star::rdf::XMetadatable:
+beans::StringPair SAL_CALL
+MetadatableMixin::getMetadataReference()
+throw (uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ Metadatable *const pObject( GetCoreObject() );
+ if (!pObject)
+ {
+ throw uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MetadatableMixin: cannot get core object; not inserted?")),
+ *this);
+ }
+ return pObject->GetMetadataReference();
+}
+
+void SAL_CALL
+MetadatableMixin::setMetadataReference(
+ const beans::StringPair & i_rReference)
+throw (uno::RuntimeException, lang::IllegalArgumentException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ Metadatable *const pObject( GetCoreObject() );
+ if (!pObject)
+ {
+ throw uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MetadatableMixin: cannot get core object; not inserted?")),
+ *this);
+ }
+ return pObject->SetMetadataReference(i_rReference);
+}
+
+void SAL_CALL MetadatableMixin::ensureMetadataReference()
+throw (uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ Metadatable *const pObject( GetCoreObject() );
+ if (!pObject)
+ {
+ throw uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MetadatableMixin: cannot get core object; not inserted?")),
+ *this);
+ }
+ return pObject->EnsureMetadataReference();
+}
+
+} // namespace sfx2
+
+
+//=============================================================================
+
+#if OSL_DEBUG_LEVEL > 1
+
+#include <stdio.h>
+
+static void dump(sfx2::XmlIdList_t * pList)
+#ifdef GCC
+__attribute__ ((unused))
+#endif
+;
+static void dump(sfx2::XmlIdList_t * pList)
+{
+ fprintf(stderr, "\nXmlIdList(%p): ", pList);
+ for (sfx2::XmlIdList_t::iterator i = pList->begin(); i != pList->end(); ++i)
+ {
+ fprintf(stderr, "%p ", *i);
+ }
+ fprintf(stderr, "\n");
+}
+
+#endif
+
diff --git a/sfx2/source/doc/QuerySaveDocument.cxx b/sfx2/source/doc/QuerySaveDocument.cxx
new file mode 100644
index 000000000000..642fe3c21af8
--- /dev/null
+++ b/sfx2/source/doc/QuerySaveDocument.cxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include "QuerySaveDocument.hxx"
+
+#include <sfx2/sfx.hrc>
+#include "sfxresid.hxx"
+#include <sfx2/sfxuno.hxx>
+#include "doc.hrc"
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+// -----------------------------------------------------------------------------
+short ExecuteQuerySaveDocument(Window* _pParent,const String& _rTitle)
+{
+ String aText( SfxResId( STR_QUERY_SAVE_DOCUMENT ) );
+ aText.SearchAndReplace( DEFINE_CONST_UNICODE( "$(DOC)" ),
+ _rTitle );
+ QueryBox aQBox( _pParent, WB_YES_NO_CANCEL | WB_DEF_YES, aText );
+ aQBox.SetButtonText( BUTTONID_NO, SfxResId( STR_NOSAVEANDCLOSE ) );
+ aQBox.SetButtonText( BUTTONID_YES, SfxResId( STR_SAVEDOC ) );
+ return aQBox.Execute();
+}
+// -----------------------------------------------------------------------------
diff --git a/sfx2/source/doc/SfxDocumentMetaData.cxx b/sfx2/source/doc/SfxDocumentMetaData.cxx
new file mode 100644
index 000000000000..14474dd2904d
--- /dev/null
+++ b/sfx2/source/doc/SfxDocumentMetaData.cxx
@@ -0,0 +1,2391 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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_sfx2.hxx"
+
+#include "sal/config.h"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/compbase6.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/document/XDocumentProperties.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/util/XCloneable.hpp"
+#include "com/sun/star/util/XModifiable.hpp"
+#include "com/sun/star/xml/sax/XSAXSerializable.hpp"
+
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/lang/EventObject.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/beans/XPropertySetInfo.hpp"
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/task/ErrorCodeIOException.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/embed/XTransactedObject.hpp"
+#include "com/sun/star/embed/ElementModes.hpp"
+#include "com/sun/star/io/XActiveDataControl.hpp"
+#include "com/sun/star/io/XActiveDataSource.hpp"
+#include "com/sun/star/io/XStream.hpp"
+#include "com/sun/star/document/XImporter.hpp"
+#include "com/sun/star/document/XExporter.hpp"
+#include "com/sun/star/document/XFilter.hpp"
+#include "com/sun/star/xml/sax/XParser.hpp"
+#include "com/sun/star/xml/dom/XDocument.hpp"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/dom/XSAXDocumentBuilder.hpp"
+#include "com/sun/star/xml/dom/NodeType.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "com/sun/star/util/Date.hpp"
+#include "com/sun/star/util/Time.hpp"
+#include "com/sun/star/util/Duration.hpp"
+
+#include "SfxDocumentMetaData.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "tools/debug.hxx"
+#include "tools/string.hxx" // for DBG
+#include "tools/datetime.hxx"
+#include "tools/urlobj.hxx"
+#include "osl/mutex.hxx"
+#include "cppuhelper/basemutex.hxx"
+#include "cppuhelper/interfacecontainer.hxx"
+#include "comphelper/storagehelper.hxx"
+#include "comphelper/mediadescriptor.hxx"
+#include "comphelper/sequenceasvector.hxx"
+#include "comphelper/stlunosequence.hxx"
+#include "sot/storage.hxx"
+#include "sfx2/docfile.hxx"
+#include "sax/tools/converter.hxx"
+
+#include <utility>
+#include <vector>
+#include <map>
+#include <cstring>
+#include <limits>
+
+/**
+ * This file contains the implementation of the service
+ * com.sun.star.document.DocumentProperties.
+ * This service enables access to the meta-data stored in documents.
+ * Currently, this service only handles documents in ODF format.
+ *
+ * The implementation uses an XML DOM to store the properties.
+ * This approach was taken because it allows for preserving arbitrary XML data
+ * in loaded documents, which will be stored unmodified when saving the
+ * document again.
+ *
+ * Upon access, some properties are directly read from and updated in the DOM.
+ * Exception: it seems impossible to get notified upon addition of a property
+ * to a com.sun.star.beans.PropertyBag, which is used for storing user-defined
+ * properties; because of this, user-defined properties are updated in the
+ * XML DOM only when storing the document.
+ * Exception 2: when setting certain properties which correspond to attributes
+ * in the XML DOM, we want to remove the corresponding XML element. Detecting
+ * this condition can get messy, so we store all such properties as members,
+ * and update the DOM tree only when storing the document (in
+ * <method>updateUserDefinedAndAttributes</method>).
+ *
+ * @author mst
+ */
+
+/// anonymous implementation namespace
+namespace {
+
+namespace css = ::com::sun::star;
+
+
+/// a list of attribute-lists, where attribute means name and content
+typedef std::vector<std::vector<std::pair<const char*, ::rtl::OUString> > >
+ AttrVector;
+
+typedef ::cppu::WeakComponentImplHelper6<
+ css::lang::XServiceInfo,
+ css::document::XDocumentProperties,
+ css::lang::XInitialization,
+ css::util::XCloneable,
+ css::util::XModifiable,
+ css::xml::sax::XSAXSerializable>
+ SfxDocumentMetaData_Base;
+
+class SfxDocumentMetaData:
+ private ::cppu::BaseMutex,
+ public SfxDocumentMetaData_Base
+{
+public:
+ explicit SfxDocumentMetaData(
+ css::uno::Reference< css::uno::XComponentContext > const & context);
+
+ // ::com::sun::star::lang::XServiceInfo:
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService(
+ const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ // ::com::sun::star::lang::XComponent:
+ virtual void SAL_CALL dispose() throw (css::uno::RuntimeException);
+
+ // ::com::sun::star::document::XDocumentProperties:
+ virtual ::rtl::OUString SAL_CALL getAuthor()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setAuthor(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getGenerator()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setGenerator(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual css::util::DateTime SAL_CALL getCreationDate()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setCreationDate(const css::util::DateTime & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTitle()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setTitle(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getSubject()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setSubject(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDescription()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDescription(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getKeywords()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setKeywords(
+ const css::uno::Sequence< ::rtl::OUString > & the_value)
+ throw (css::uno::RuntimeException);
+ virtual css::lang::Locale SAL_CALL getLanguage()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setLanguage(const css::lang::Locale & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getModifiedBy()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setModifiedBy(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual css::util::DateTime SAL_CALL getModificationDate()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setModificationDate(
+ const css::util::DateTime & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getPrintedBy()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPrintedBy(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual css::util::DateTime SAL_CALL getPrintDate()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setPrintDate(const css::util::DateTime & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTemplateName()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setTemplateName(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTemplateURL()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setTemplateURL(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual css::util::DateTime SAL_CALL getTemplateDate()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setTemplateDate(const css::util::DateTime & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAutoloadURL()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setAutoloadURL(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getAutoloadSecs()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setAutoloadSecs(::sal_Int32 the_value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
+ virtual ::rtl::OUString SAL_CALL getDefaultTarget()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDefaultTarget(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< css::beans::NamedValue > SAL_CALL
+ getDocumentStatistics() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setDocumentStatistics(
+ const css::uno::Sequence< css::beans::NamedValue > & the_value)
+ throw (css::uno::RuntimeException);
+ virtual ::sal_Int16 SAL_CALL getEditingCycles()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setEditingCycles(::sal_Int16 the_value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
+ virtual ::sal_Int32 SAL_CALL getEditingDuration()
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setEditingDuration(::sal_Int32 the_value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
+ virtual void SAL_CALL resetUserData(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::beans::XPropertyContainer > SAL_CALL
+ getUserDefinedProperties() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL loadFromStorage(
+ const css::uno::Reference< css::embed::XStorage > & Storage,
+ const css::uno::Sequence< css::beans::PropertyValue > & Medium)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException,
+ css::io::WrongFormatException,
+ css::lang::WrappedTargetException, css::io::IOException);
+ virtual void SAL_CALL loadFromMedium(const ::rtl::OUString & URL,
+ const css::uno::Sequence< css::beans::PropertyValue > & Medium)
+ throw (css::uno::RuntimeException,
+ css::io::WrongFormatException,
+ css::lang::WrappedTargetException, css::io::IOException);
+ virtual void SAL_CALL storeToStorage(
+ const css::uno::Reference< css::embed::XStorage > & Storage,
+ const css::uno::Sequence< css::beans::PropertyValue > & Medium)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException,
+ css::lang::WrappedTargetException, css::io::IOException);
+ virtual void SAL_CALL storeToMedium(const ::rtl::OUString & URL,
+ const css::uno::Sequence< css::beans::PropertyValue > & Medium)
+ throw (css::uno::RuntimeException,
+ css::lang::WrappedTargetException, css::io::IOException);
+
+ // ::com::sun::star::lang::XInitialization:
+ virtual void SAL_CALL initialize(
+ const css::uno::Sequence< css::uno::Any > & aArguments)
+ throw (css::uno::RuntimeException, css::uno::Exception);
+
+ // ::com::sun::star::util::XCloneable:
+ virtual css::uno::Reference<css::util::XCloneable> SAL_CALL createClone()
+ throw (css::uno::RuntimeException);
+
+ // ::com::sun::star::util::XModifiable:
+ virtual ::sal_Bool SAL_CALL isModified( )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL setModified( ::sal_Bool bModified )
+ throw (css::beans::PropertyVetoException, css::uno::RuntimeException);
+
+ // ::com::sun::star::util::XModifyBroadcaster:
+ virtual void SAL_CALL addModifyListener(
+ const css::uno::Reference< css::util::XModifyListener > & xListener)
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener(
+ const css::uno::Reference< css::util::XModifyListener > & xListener)
+ throw (css::uno::RuntimeException);
+
+ // ::com::sun::star::xml::sax::XSAXSerializable
+ virtual void SAL_CALL serialize(
+ const css::uno::Reference<css::xml::sax::XDocumentHandler>& i_xHandler,
+ const css::uno::Sequence< css::beans::StringPair >& i_rNamespaces)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException);
+
+private:
+ SfxDocumentMetaData(SfxDocumentMetaData &); // not defined
+ SfxDocumentMetaData& operator =(SfxDocumentMetaData &); // not defined
+
+ virtual ~SfxDocumentMetaData() {}
+
+ const css::uno::Reference< css::uno::XComponentContext > m_xContext;
+
+ /// for notification
+ ::cppu::OInterfaceContainerHelper m_NotifyListeners;
+ /// flag: false means not initialized yet, or disposed
+ bool m_isInitialized;
+ /// flag
+ bool m_isModified;
+ /// meta-data DOM tree
+ css::uno::Reference< css::xml::dom::XDocument > m_xDoc;
+ /// meta-data super node in the meta-data DOM tree
+ css::uno::Reference< css::xml::dom::XNode> m_xParent;
+ /// standard meta data (single occurrence)
+ std::map< ::rtl::OUString, css::uno::Reference<css::xml::dom::XNode> >
+ m_meta;
+ /// standard meta data (multiple occurrences)
+ std::map< ::rtl::OUString,
+ std::vector<css::uno::Reference<css::xml::dom::XNode> > > m_metaList;
+ /// user-defined meta data (meta:user-defined) @ATTENTION may be null!
+ css::uno::Reference<css::beans::XPropertyContainer> m_xUserDefined;
+ // now for some meta-data attributes; these are not updated directly in the
+ // DOM because updates (detecting "empty" elements) would be quite messy
+ ::rtl::OUString m_TemplateName;
+ ::rtl::OUString m_TemplateURL;
+ css::util::DateTime m_TemplateDate;
+ ::rtl::OUString m_AutoloadURL;
+ sal_Int32 m_AutoloadSecs;
+ ::rtl::OUString m_DefaultTarget;
+
+ /// check if we are initialized properly
+ void SAL_CALL checkInit() const;
+ // throw (css::uno::RuntimeException);
+ /// initialize state from given DOM tree
+ void SAL_CALL init(css::uno::Reference<css::xml::dom::XDocument> i_xDom);
+ // throw (css::uno::RuntimeException, css::io::WrongFormatException,
+ // css::uno::Exception);
+ /// update element in DOM tree
+ void SAL_CALL updateElement(const char *i_name,
+ std::vector<std::pair<const char *, ::rtl::OUString> >* i_pAttrs = 0);
+ /// update user-defined meta data and attributes in DOM tree
+ void SAL_CALL updateUserDefinedAndAttributes();
+ /// create empty DOM tree (XDocument)
+ css::uno::Reference<css::xml::dom::XDocument> SAL_CALL createDOM() const;
+ /// extract base URL (necessary for converting relative links)
+ css::uno::Reference<css::beans::XPropertySet> SAL_CALL getURLProperties(
+ const css::uno::Sequence<css::beans::PropertyValue> & i_rMedium) const;
+ // throw (css::uno::RuntimeException);
+ /// get text of standard meta data element
+ ::rtl::OUString SAL_CALL getMetaText(const char* i_name) const;
+ // throw (css::uno::RuntimeException);
+ /// set text of standard meta data element iff not equal to existing text
+ bool SAL_CALL setMetaText(const char* i_name,
+ const ::rtl::OUString & i_rValue);
+ // throw (css::uno::RuntimeException);
+ /// set text of standard meta data element iff not equal to existing text
+ void SAL_CALL setMetaTextAndNotify(const char* i_name,
+ const ::rtl::OUString & i_rValue);
+ // throw (css::uno::RuntimeException);
+ /// get text of standard meta data element's attribute
+ ::rtl::OUString SAL_CALL getMetaAttr(const char* i_name,
+ const char* i_attr) const;
+ // throw (css::uno::RuntimeException);
+ /// get text of a list of standard meta data elements (multiple occ.)
+ css::uno::Sequence< ::rtl::OUString > SAL_CALL getMetaList(
+ const char* i_name) const;
+ // throw (css::uno::RuntimeException);
+ /// set text of a list of standard meta data elements (multiple occ.)
+ bool SAL_CALL setMetaList(const char* i_name,
+ const css::uno::Sequence< ::rtl::OUString > & i_rValue,
+ AttrVector const* = 0);
+ // throw (css::uno::RuntimeException);
+ void createUserDefined();
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+bool operator== (const css::util::DateTime &i_rLeft,
+ const css::util::DateTime &i_rRight)
+{
+ return i_rLeft.Year == i_rRight.Year
+ && i_rLeft.Month == i_rRight.Month
+ && i_rLeft.Day == i_rRight.Day
+ && i_rLeft.Hours == i_rRight.Hours
+ && i_rLeft.Minutes == i_rRight.Minutes
+ && i_rLeft.Seconds == i_rRight.Seconds
+ && i_rLeft.HundredthSeconds == i_rRight.HundredthSeconds;
+}
+
+// NB: keep these two arrays in sync!
+const char* s_stdStatAttrs[] = {
+ "meta:page-count",
+ "meta:table-count",
+ "meta:draw-count",
+ "meta:image-count",
+ "meta:object-count",
+ "meta:ole-object-count",
+ "meta:paragraph-count",
+ "meta:word-count",
+ "meta:character-count",
+ "meta:row-count",
+ "meta:frame-count",
+ "meta:sentence-count",
+ "meta:syllable-count",
+ "meta:non-whitespace-character-count",
+ "meta:cell-count",
+ 0
+};
+
+// NB: keep these two arrays in sync!
+const char* s_stdStats[] = {
+ "PageCount",
+ "TableCount",
+ "DrawCount",
+ "ImageCount",
+ "ObjectCount",
+ "OLEObjectCount",
+ "ParagraphCount",
+ "WordCount",
+ "CharacterCount",
+ "RowCount",
+ "FrameCount",
+ "SentenceCount",
+ "SyllableCount",
+ "NonWhitespaceCharacterCount",
+ "CellCount",
+ 0
+};
+
+const char* s_stdMeta[] = {
+ "meta:generator", // string
+ "dc:title", // string
+ "dc:description", // string
+ "dc:subject", // string
+ "meta:initial-creator", // string
+ "dc:creator", // string
+ "meta:printed-by", // string
+ "meta:creation-date", // dateTime
+ "dc:date", // dateTime
+ "meta:print-date", // dateTime
+ "meta:template", // XLink
+ "meta:auto-reload", // ...
+ "meta:hyperlink-behaviour", // ...
+ "dc:language", // language
+ "meta:editing-cycles", // nonNegativeInteger
+ "meta:editing-duration", // duration
+ "meta:document-statistic", // ... // note: statistic is singular, no s!
+ 0
+};
+
+const char* s_stdMetaList[] = {
+ "meta:keyword", // string*
+ "meta:user-defined", // ...*
+ 0
+};
+
+const char* s_nsXLink = "http://www.w3.org/1999/xlink";
+const char* s_nsDC = "http://purl.org/dc/elements/1.1/";
+const char* s_nsODF = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
+const char* s_nsODFMeta = "urn:oasis:names:tc:opendocument:xmlns:meta:1.0";
+// const char* s_nsOOo = "http://openoffice.org/2004/office"; // not used (yet?)
+
+const char* s_metaXml = "meta.xml";
+
+
+bool isValidDate(const css::util::Date & i_rDate)
+{
+ return i_rDate.Month > 0;
+}
+
+bool isValidDateTime(const css::util::DateTime & i_rDateTime)
+{
+ return i_rDateTime.Month > 0;
+}
+
+std::pair< ::rtl::OUString, ::rtl::OUString > SAL_CALL
+getQualifier(const char* i_name) {
+ ::rtl::OUString nm = ::rtl::OUString::createFromAscii(i_name);
+ sal_Int32 ix = nm.indexOf(static_cast<sal_Unicode> (':'));
+ if (ix == -1) {
+ return std::make_pair(::rtl::OUString(), nm);
+ } else {
+ return std::make_pair(nm.copy(0,ix), nm.copy(ix+1));
+ }
+}
+
+// get namespace for standard qualified names
+// NB: only call this with statically known strings!
+::rtl::OUString SAL_CALL getNameSpace(const char* i_qname) throw ()
+{
+ DBG_ASSERT(i_qname, "SfxDocumentMetaData: getNameSpace: argument is null");
+ const char * ns = "";
+ ::rtl::OUString n = getQualifier(i_qname).first;
+ if (n.equalsAscii("xlink" )) ns = s_nsXLink;
+ if (n.equalsAscii("dc" )) ns = s_nsDC;
+ if (n.equalsAscii("office")) ns = s_nsODF;
+ if (n.equalsAscii("meta" )) ns = s_nsODFMeta;
+ DBG_ASSERT(*ns, "SfxDocumentMetaData: unknown namespace prefix");
+ return ::rtl::OUString::createFromAscii(ns);
+}
+
+bool SAL_CALL
+textToDateOrDateTime(css::util::Date & io_rd, css::util::DateTime & io_rdt,
+ bool & o_rIsDateTime, ::rtl::OUString i_text) throw ()
+{
+ if (::sax::Converter::convertDateOrDateTime(
+ io_rd, io_rdt, o_rIsDateTime, i_text)) {
+ return true;
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
+ OUStringToOString(i_text, RTL_TEXTENCODING_UTF8).getStr());
+ return false;
+ }
+}
+
+// convert string to date/time
+bool SAL_CALL
+textToDateTime(css::util::DateTime & io_rdt, ::rtl::OUString i_text) throw ()
+{
+ if (::sax::Converter::convertDateTime(io_rdt, i_text)) {
+ return true;
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
+ OUStringToOString(i_text, RTL_TEXTENCODING_UTF8).getStr());
+ return false;
+ }
+}
+
+// convert string to date/time with default return value
+css::util::DateTime SAL_CALL
+textToDateTimeDefault(::rtl::OUString i_text) throw ()
+{
+ css::util::DateTime dt;
+ static_cast<void> (textToDateTime(dt, i_text));
+ // on conversion error: return default value (unchanged)
+ return dt;
+}
+
+// convert date to string
+::rtl::OUString SAL_CALL
+dateToText(css::util::Date const& i_rd) throw ()
+{
+ if (isValidDate(i_rd)) {
+ ::rtl::OUStringBuffer buf;
+ ::sax::Converter::convertDate(buf, i_rd);
+ return buf.makeStringAndClear();
+ } else {
+ return ::rtl::OUString();
+ }
+}
+
+
+// convert date/time to string
+::rtl::OUString SAL_CALL
+dateTimeToText(css::util::DateTime const& i_rdt) throw ()
+{
+ if (isValidDateTime(i_rdt)) {
+ ::rtl::OUStringBuffer buf;
+ ::sax::Converter::convertDateTime(buf, i_rdt, true);
+ return buf.makeStringAndClear();
+ } else {
+ return ::rtl::OUString();
+ }
+}
+
+// convert string to duration
+bool
+textToDuration(css::util::Duration& io_rDur, ::rtl::OUString const& i_rText)
+throw ()
+{
+ if (::sax::Converter::convertDuration(io_rDur, i_rText)) {
+ return true;
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid duration: %s",
+ OUStringToOString(i_rText, RTL_TEXTENCODING_UTF8).getStr());
+ return false;
+ }
+}
+
+sal_Int32 textToDuration(::rtl::OUString const& i_rText) throw ()
+{
+ css::util::Duration d;
+ if (textToDuration(d, i_rText)) {
+ // #i107372#: approximate years/months
+ const sal_Int32 days( (d.Years * 365) + (d.Months * 30) + d.Days );
+ return (days * (24*3600))
+ + (d.Hours * 3600) + (d.Minutes * 60) + d.Seconds;
+ } else {
+ return 0; // default
+ }
+}
+
+// convert duration to string
+::rtl::OUString durationToText(css::util::Duration const& i_rDur) throw ()
+{
+ ::rtl::OUStringBuffer buf;
+ ::sax::Converter::convertDuration(buf, i_rDur);
+ return buf.makeStringAndClear();
+}
+
+// convert duration to string
+::rtl::OUString SAL_CALL durationToText(sal_Int32 i_value) throw ()
+{
+ css::util::Duration ud;
+ ud.Days = static_cast<sal_Int16>(i_value / (24 * 3600));
+ ud.Hours = static_cast<sal_Int16>((i_value % (24 * 3600)) / 3600);
+ ud.Minutes = static_cast<sal_Int16>((i_value % 3600) / 60);
+ ud.Seconds = static_cast<sal_Int16>(i_value % 60);
+ ud.MilliSeconds = 0;
+ return durationToText(ud);
+}
+
+// extract base URL (necessary for converting relative links)
+css::uno::Reference< css::beans::XPropertySet > SAL_CALL
+SfxDocumentMetaData::getURLProperties(
+ const css::uno::Sequence< css::beans::PropertyValue > & i_rMedium) const
+{
+ css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
+ m_xContext->getServiceManager());
+ css::uno::Reference< css::beans::XPropertyContainer> xPropArg(
+ xMsf->createInstanceWithContext(::rtl::OUString::createFromAscii(
+ "com.sun.star.beans.PropertyBag"), m_xContext),
+ css::uno::UNO_QUERY_THROW);
+ try {
+ ::rtl::OUString dburl =
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentBaseURL"));
+ ::rtl::OUString hdn =
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HierarchicalDocumentName"));
+ for (sal_Int32 i = 0; i < i_rMedium.getLength(); ++i) {
+ if (i_rMedium[i].Name.equals(dburl)) {
+ xPropArg->addProperty(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI")),
+ css::beans::PropertyAttribute::MAYBEVOID,
+ i_rMedium[i].Value);
+ } else if (i_rMedium[i].Name.equals(hdn)) {
+ xPropArg->addProperty(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath")),
+ css::beans::PropertyAttribute::MAYBEVOID,
+ i_rMedium[i].Value);
+ }
+ }
+ xPropArg->addProperty(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")),
+ css::beans::PropertyAttribute::MAYBEVOID,
+ css::uno::makeAny(::rtl::OUString::createFromAscii(s_metaXml)));
+ } catch (css::uno::Exception &) {
+ // ignore
+ }
+ return css::uno::Reference< css::beans::XPropertySet>(xPropArg,
+ css::uno::UNO_QUERY_THROW);
+}
+
+// return the text of the (hopefully unique, i.e., normalize first!) text
+// node _below_ the given node
+::rtl::OUString SAL_CALL
+getNodeText(css::uno::Reference<css::xml::dom::XNode> i_xNode)
+ throw (css::uno::RuntimeException)
+{
+ if (!i_xNode.is()) throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::getNodeText: argument is null"), i_xNode);
+ for (css::uno::Reference<css::xml::dom::XNode> c = i_xNode->getFirstChild();
+ c.is();
+ c = c->getNextSibling()) {
+ if (c->getNodeType() == css::xml::dom::NodeType_TEXT_NODE) {
+ try {
+ return c->getNodeValue();
+ } catch (css::xml::dom::DOMException &) { // too big?
+ return ::rtl::OUString();
+ }
+ }
+ }
+ return ::rtl::OUString();
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getMetaText(const char* i_name) const
+// throw (css::uno::RuntimeException)
+{
+ checkInit();
+
+ const ::rtl::OUString name( ::rtl::OUString::createFromAscii(i_name) );
+ DBG_ASSERT(m_meta.find(name) != m_meta.end(),
+ "SfxDocumentMetaData::getMetaText: not found");
+ css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
+ return (xNode.is()) ? getNodeText(xNode) : ::rtl::OUString();
+}
+
+bool SAL_CALL
+SfxDocumentMetaData::setMetaText(const char* i_name,
+ const ::rtl::OUString & i_rValue)
+ // throw (css::uno::RuntimeException)
+{
+ checkInit();
+
+ const ::rtl::OUString name( ::rtl::OUString::createFromAscii(i_name) );
+ DBG_ASSERT(m_meta.find(name) != m_meta.end(),
+ "SfxDocumentMetaData::setMetaText: not found");
+ css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
+
+ try {
+ if (i_rValue.equalsAscii("")) {
+ if (xNode.is()) { // delete
+ m_xParent->removeChild(xNode);
+ xNode.clear();
+ m_meta[name] = xNode;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if (xNode.is()) { // update
+ for (css::uno::Reference<css::xml::dom::XNode> c =
+ xNode->getFirstChild();
+ c.is();
+ c = c->getNextSibling()) {
+ if (c->getNodeType() == css::xml::dom::NodeType_TEXT_NODE) {
+ if (!c->getNodeValue().equals(i_rValue)) {
+ c->setNodeValue(i_rValue);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ } else { // insert
+ xNode.set(m_xDoc->createElementNS(getNameSpace(i_name), name),
+ css::uno::UNO_QUERY_THROW);
+ m_xParent->appendChild(xNode);
+ m_meta[name] = xNode;
+ }
+ css::uno::Reference<css::xml::dom::XNode> xTextNode(
+ m_xDoc->createTextNode(i_rValue), css::uno::UNO_QUERY_THROW);
+ xNode->appendChild(xTextNode);
+ return true;
+ }
+ } catch (css::xml::dom::DOMException & e) {
+ css::uno::Any a(e);
+ throw css::lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::setMetaText: DOM exception"),
+ css::uno::Reference<css::uno::XInterface>(*this), a);
+ }
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setMetaTextAndNotify(const char* i_name,
+ const ::rtl::OUString & i_rValue)
+ // throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ if (setMetaText(i_name, i_rValue)) {
+ g.clear();
+ setModified(true);
+ }
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getMetaAttr(const char* i_name, const char* i_attr) const
+// throw (css::uno::RuntimeException)
+{
+// checkInit();
+ ::rtl::OUString name = ::rtl::OUString::createFromAscii(i_name);
+ DBG_ASSERT(m_meta.find(name) != m_meta.end(),
+ "SfxDocumentMetaData::getMetaAttr: not found");
+ css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
+ if (xNode.is()) {
+ css::uno::Reference<css::xml::dom::XElement> xElem(xNode,
+ css::uno::UNO_QUERY_THROW);
+ return xElem->getAttributeNS(getNameSpace(i_attr),
+ getQualifier(i_attr).second);
+ } else {
+ return ::rtl::OUString();
+ }
+}
+
+css::uno::Sequence< ::rtl::OUString> SAL_CALL
+SfxDocumentMetaData::getMetaList(const char* i_name) const
+// throw (css::uno::RuntimeException)
+{
+ checkInit();
+ ::rtl::OUString name = ::rtl::OUString::createFromAscii(i_name);
+ DBG_ASSERT(m_metaList.find(name) != m_metaList.end(),
+ "SfxDocumentMetaData::getMetaList: not found");
+ std::vector<css::uno::Reference<css::xml::dom::XNode> > const & vec =
+ m_metaList.find(name)->second;
+ css::uno::Sequence< ::rtl::OUString> ret(vec.size());
+ for (size_t i = 0; i < vec.size(); ++i) {
+ ret[i] = getNodeText(vec.at(i));
+ }
+ return ret;
+}
+
+bool SAL_CALL
+SfxDocumentMetaData::setMetaList(const char* i_name,
+ const css::uno::Sequence< ::rtl::OUString> & i_rValue,
+ AttrVector const* i_pAttrs)
+ // throw (css::uno::RuntimeException)
+{
+ checkInit();
+ DBG_ASSERT((i_pAttrs == 0) ||
+ (static_cast<size_t>(i_rValue.getLength()) == i_pAttrs->size()),
+ "SfxDocumentMetaData::setMetaList: invalid args");
+
+ try {
+ ::rtl::OUString name = ::rtl::OUString::createFromAscii(i_name);
+ DBG_ASSERT(m_metaList.find(name) != m_metaList.end(),
+ "SfxDocumentMetaData::setMetaList: not found");
+ std::vector<css::uno::Reference<css::xml::dom::XNode> > & vec =
+ m_metaList[name];
+
+ // if nothing changed, do nothing
+ // alas, this does not check for permutations, or attributes...
+ if ((0 == i_pAttrs)) {
+ if (static_cast<size_t>(i_rValue.getLength()) == vec.size()) {
+ bool isEqual(true);
+ for (sal_Int32 i = 0; i < i_rValue.getLength(); ++i) {
+ css::uno::Reference<css::xml::dom::XNode> xNode(vec.at(i));
+ if (xNode.is()) {
+ ::rtl::OUString val = getNodeText(xNode);
+ if (!val.equals(i_rValue[i])) {
+ isEqual = false;
+ break;
+ }
+ }
+ }
+ if (isEqual) return false;
+ }
+ }
+
+ // remove old meta data nodes
+ {
+ std::vector<css::uno::Reference<css::xml::dom::XNode> >
+ ::reverse_iterator it(vec.rbegin());
+ try {
+ for ( ;it != vec.rend(); ++it)
+ {
+ m_xParent->removeChild(*it);
+ }
+ }
+ catch (...)
+ {
+ // Clean up already removed nodes
+ vec.erase(it.base(), vec.end());
+ throw;
+ }
+ vec.clear();
+ }
+
+ // insert new meta data nodes into DOM tree
+ for (sal_Int32 i = 0; i < i_rValue.getLength(); ++i) {
+ css::uno::Reference<css::xml::dom::XElement> xElem(
+ m_xDoc->createElementNS(getNameSpace(i_name), name),
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::xml::dom::XNode> xNode(xElem,
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::xml::dom::XNode> xTextNode(
+ m_xDoc->createTextNode(i_rValue[i]), css::uno::UNO_QUERY_THROW);
+ // set attributes
+ if (i_pAttrs != 0) {
+ for (std::vector<std::pair<const char*, ::rtl::OUString> >
+ ::const_iterator it = (*i_pAttrs)[i].begin();
+ it != (*i_pAttrs)[i].end(); ++it) {
+ xElem->setAttributeNS(getNameSpace(it->first),
+ ::rtl::OUString::createFromAscii(it->first),
+ it->second);
+ }
+ }
+ xNode->appendChild(xTextNode);
+ m_xParent->appendChild(xNode);
+ vec.push_back(xNode);
+ }
+
+ return true;
+ } catch (css::xml::dom::DOMException & e) {
+ css::uno::Any a(e);
+ throw css::lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::setMetaList: DOM exception"),
+ css::uno::Reference<css::uno::XInterface>(*this), a);
+ }
+}
+
+// convert property list to string list and attribute list
+std::pair<css::uno::Sequence< ::rtl::OUString>, AttrVector> SAL_CALL
+propsToStrings(css::uno::Reference<css::beans::XPropertySet> const & i_xPropSet)
+{
+ ::comphelper::SequenceAsVector< ::rtl::OUString > values;
+ AttrVector attrs;
+
+ css::uno::Reference<css::beans::XPropertySetInfo> xSetInfo
+ = i_xPropSet->getPropertySetInfo();
+ css::uno::Sequence<css::beans::Property> props = xSetInfo->getProperties();
+
+ for (sal_Int32 i = 0; i < props.getLength(); ++i) {
+ if (props[i].Attributes & css::beans::PropertyAttribute::TRANSIENT) {
+ continue;
+ }
+ const ::rtl::OUString name = props[i].Name;
+ css::uno::Any any;
+ try {
+ any = i_xPropSet->getPropertyValue(name);
+ } catch (css::uno::Exception &) {
+ // ignore
+ }
+ const css::uno::Type & type = any.getValueType();
+ std::vector<std::pair<const char*, ::rtl::OUString> > as;
+ as.push_back(std::make_pair(static_cast<const char*>("meta:name"),
+ name));
+ const char* vt = "meta:value-type";
+
+ // convert according to type
+ if (type == ::cppu::UnoType<bool>::get()) {
+ bool b = false;
+ any >>= b;
+ ::rtl::OUStringBuffer buf;
+ ::sax::Converter::convertBool(buf, b);
+ values.push_back(buf.makeStringAndClear());
+ as.push_back(std::make_pair(vt,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("boolean"))));
+ } else if (type == ::cppu::UnoType< ::rtl::OUString>::get()) {
+ ::rtl::OUString s;
+ any >>= s;
+ values.push_back(s);
+// #i90847# OOo 2.x does stupid things if value-type="string";
+// fortunately string is default anyway, so we can just omit it
+// #i107502#: however, OOo 2.x only reads 4 user-defined without @value-type
+// => best backward compatibility: first 4 without @value-type, rest with
+ if (4 <= i)
+ {
+ as.push_back(std::make_pair(vt,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("string"))));
+ }
+ } else if (type == ::cppu::UnoType<css::util::DateTime>::get()) {
+ css::util::DateTime dt;
+ any >>= dt;
+ values.push_back(dateTimeToText(dt));
+ as.push_back(std::make_pair(vt,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date"))));
+ } else if (type == ::cppu::UnoType<css::util::Date>::get()) {
+ css::util::Date d;
+ any >>= d;
+ values.push_back(dateToText(d));
+ as.push_back(std::make_pair(vt,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date"))));
+ } else if (type == ::cppu::UnoType<css::util::Time>::get()) {
+ // #i97029#: replaced by Duration
+ // Time is supported for backward compatibility with OOo 3.x, x<=2
+ css::util::Time ut;
+ any >>= ut;
+ css::util::Duration ud;
+ ud.Hours = ut.Hours;
+ ud.Minutes = ut.Minutes;
+ ud.Seconds = ut.Seconds;
+ ud.MilliSeconds = 10 * ut.HundredthSeconds;
+ values.push_back(durationToText(ud));
+ as.push_back(std::make_pair(vt,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time"))));
+ } else if (type == ::cppu::UnoType<css::util::Duration>::get()) {
+ css::util::Duration ud;
+ any >>= ud;
+ values.push_back(durationToText(ud));
+ as.push_back(std::make_pair(vt,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time"))));
+ } else if (::cppu::UnoType<double>::get().isAssignableFrom(type)) {
+ // support not just double, but anything that can be converted
+ double d = 0;
+ any >>= d;
+ ::rtl::OUStringBuffer buf;
+ ::sax::Converter::convertDouble(buf, d);
+ values.push_back(buf.makeStringAndClear());
+ as.push_back(std::make_pair(vt,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("float"))));
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: unsupported property type: %s",
+ OUStringToOString(any.getValueTypeName(),
+ RTL_TEXTENCODING_UTF8).getStr());
+ continue;
+ }
+ attrs.push_back(as);
+ }
+
+ return std::make_pair(values.getAsConstList(), attrs);
+}
+
+// remove the given element from the DOM, and iff i_pAttrs != 0 insert new one
+void SAL_CALL
+SfxDocumentMetaData::updateElement(const char *i_name,
+ std::vector<std::pair<const char *, ::rtl::OUString> >* i_pAttrs)
+{
+ ::rtl::OUString name = ::rtl::OUString::createFromAscii(i_name);
+ try {
+ // remove old element
+ css::uno::Reference<css::xml::dom::XNode> xNode =
+ m_meta.find(name)->second;
+ if (xNode.is()) {
+ m_xParent->removeChild(xNode);
+ xNode.clear();
+ }
+ // add new element
+ if (0 != i_pAttrs) {
+ css::uno::Reference<css::xml::dom::XElement> xElem(
+ m_xDoc->createElementNS(getNameSpace(i_name), name),
+ css::uno::UNO_QUERY_THROW);
+ xNode.set(xElem, css::uno::UNO_QUERY_THROW);
+ // set attributes
+ for (std::vector<std::pair<const char *, ::rtl::OUString> >
+ ::const_iterator it = i_pAttrs->begin();
+ it != i_pAttrs->end(); ++it) {
+ xElem->setAttributeNS(getNameSpace(it->first),
+ ::rtl::OUString::createFromAscii(it->first), it->second);
+ }
+ m_xParent->appendChild(xNode);
+ }
+ m_meta[name] = xNode;
+ } catch (css::xml::dom::DOMException & e) {
+ css::uno::Any a(e);
+ throw css::lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::updateElement: DOM exception"),
+ css::uno::Reference<css::uno::XInterface>(*this), a);
+ }
+}
+
+// update user-defined meta data in DOM tree
+void SAL_CALL SfxDocumentMetaData::updateUserDefinedAndAttributes()
+{
+ createUserDefined();
+ const css::uno::Reference<css::beans::XPropertySet> xPSet(m_xUserDefined,
+ css::uno::UNO_QUERY_THROW);
+ const std::pair<css::uno::Sequence< ::rtl::OUString>, AttrVector>
+ udStringsAttrs( propsToStrings(xPSet) );
+ (void) setMetaList("meta:user-defined", udStringsAttrs.first,
+ &udStringsAttrs.second);
+
+ // update elements with attributes
+ std::vector<std::pair<const char *, ::rtl::OUString> > attributes;
+ if (!m_TemplateName.equalsAscii("") || !m_TemplateURL.equalsAscii("")
+ || isValidDateTime(m_TemplateDate)) {
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("xlink:type"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simple"))));
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("xlink:actuate"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("onRequest"))));
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("xlink:title"), m_TemplateName));
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("xlink:href" ), m_TemplateURL ));
+ if (isValidDateTime(m_TemplateDate)) {
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("meta:date" ),
+ dateTimeToText(m_TemplateDate)));
+ }
+ updateElement("meta:template", &attributes);
+ } else {
+ updateElement("meta:template");
+ }
+ attributes.clear();
+
+ if (!m_AutoloadURL.equalsAscii("") || (0 != m_AutoloadSecs)) {
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("xlink:href" ), m_AutoloadURL ));
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("meta:delay" ),
+ durationToText(m_AutoloadSecs)));
+ updateElement("meta:auto-reload", &attributes);
+ } else {
+ updateElement("meta:auto-reload");
+ }
+ attributes.clear();
+
+ if (!m_DefaultTarget.equalsAscii("")) {
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("office:target-frame-name"),
+ m_DefaultTarget));
+ // xlink:show: _blank -> new, any other value -> replace
+ const sal_Char* show = m_DefaultTarget.equalsAscii("_blank")
+ ? "new" : "replace";
+ attributes.push_back(std::make_pair(
+ static_cast<const char*>("xlink:show"),
+ ::rtl::OUString::createFromAscii(show)));
+ updateElement("meta:hyperlink-behaviour", &attributes);
+ } else {
+ updateElement("meta:hyperlink-behaviour");
+ }
+ attributes.clear();
+}
+
+// create empty DOM tree (XDocument)
+css::uno::Reference<css::xml::dom::XDocument> SAL_CALL
+SfxDocumentMetaData::createDOM() const // throw (css::uno::RuntimeException)
+{
+ css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
+ m_xContext->getServiceManager());
+ css::uno::Reference<css::xml::dom::XDocumentBuilder> xBuilder(
+ xMsf->createInstanceWithContext(::rtl::OUString::createFromAscii(
+ "com.sun.star.xml.dom.DocumentBuilder"), m_xContext),
+ css::uno::UNO_QUERY_THROW );
+ if (!xBuilder.is()) throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::createDOM: "
+ "cannot create DocumentBuilder service"),
+ *const_cast<SfxDocumentMetaData*>(this));
+ css::uno::Reference<css::xml::dom::XDocument> xDoc =
+ xBuilder->newDocument();
+ if (!xDoc.is()) throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::createDOM: "
+ "cannot create new document"),
+ *const_cast<SfxDocumentMetaData*>(this));
+ return xDoc;
+}
+
+void SAL_CALL
+SfxDocumentMetaData::checkInit() const // throw (css::uno::RuntimeException)
+{
+ if (!m_isInitialized) {
+ throw css::uno::RuntimeException(::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::checkInit: not initialized"),
+ *const_cast<SfxDocumentMetaData*>(this));
+ }
+ DBG_ASSERT((m_xDoc.is() && m_xParent.is() ),
+ "SfxDocumentMetaData::checkInit: reference is null");
+}
+
+// initialize state from DOM tree
+void SAL_CALL SfxDocumentMetaData::init(
+ css::uno::Reference<css::xml::dom::XDocument> i_xDoc)
+// throw (css::uno::RuntimeException, css::io::WrongFormatException,
+// css::uno::Exception)
+{
+ if (!i_xDoc.is()) throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::init: no DOM tree given"), *this);
+
+ css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
+ m_xContext->getServiceManager());
+ css::uno::Reference<css::xml::xpath::XXPathAPI> xPath(
+ xMsf->createInstanceWithContext(::rtl::OUString::createFromAscii(
+ "com.sun.star.xml.xpath.XPathAPI"), m_xContext),
+ css::uno::UNO_QUERY_THROW );
+ if (!xPath.is()) throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::init:"
+ " cannot create XPathAPI service"), *this);
+
+ m_isInitialized = false;
+ m_xDoc = i_xDoc;
+ m_xDoc->normalize();
+
+ // select nodes for standard meta data stuff
+ xPath->registerNS(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xlink")),
+ ::rtl::OUString::createFromAscii(s_nsXLink));
+ xPath->registerNS(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("dc")),
+ ::rtl::OUString::createFromAscii(s_nsDC));
+ xPath->registerNS(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("office")),
+ ::rtl::OUString::createFromAscii(s_nsODF));
+ xPath->registerNS(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta")),
+ ::rtl::OUString::createFromAscii(s_nsODFMeta));
+ // NB: we do not handle the single-XML-file ODF variant, which would
+ // have the root element office:document.
+ // The root of such documents must be converted in the importer!
+ ::rtl::OUString prefix = ::rtl::OUString::createFromAscii(
+ "/child::office:document-meta/child::office:meta");
+ css::uno::Reference<css::xml::dom::XNode> xDocNode(
+ m_xDoc, css::uno::UNO_QUERY_THROW);
+ m_xParent.clear();
+ try {
+ m_xParent = xPath->selectSingleNode(xDocNode, prefix);
+ } catch (com::sun::star::uno::Exception &) {
+// DBG_WARNING("SfxDocumentMetaData::init: "
+// "caught RuntimeException from libxml!");
+ }
+
+ if (!m_xParent.is()) {
+ // all this create/append stuff may throw DOMException
+ try {
+ css::uno::Reference<css::xml::dom::XElement> xRElem(
+ i_xDoc->createElementNS(
+ ::rtl::OUString::createFromAscii(s_nsODF),
+ ::rtl::OUString::createFromAscii("office:document-meta")));
+ css::uno::Reference<css::xml::dom::XNode> xRNode(xRElem,
+ css::uno::UNO_QUERY_THROW);
+ // NB: the following is a _bad_idea_ with our DOM implementation
+ // do _not_ create attributes with xmlns prefix!
+// xRElem->setAttribute(::rtl::OUString::createFromAscii("xmlns:office"),
+// ::rtl::OUString::createFromAscii(s_nsODF));
+ xRElem->setAttributeNS(::rtl::OUString::createFromAscii(s_nsODF),
+ ::rtl::OUString::createFromAscii("office:version"),
+ ::rtl::OUString::createFromAscii("1.0"));
+ i_xDoc->appendChild(xRNode);
+ css::uno::Reference<css::xml::dom::XNode> xParent (
+ i_xDoc->createElementNS(
+ ::rtl::OUString::createFromAscii(s_nsODF),
+ ::rtl::OUString::createFromAscii("office:meta")),
+ css::uno::UNO_QUERY_THROW);
+ xRNode->appendChild(xParent);
+ m_xParent = xParent;
+ } catch (css::xml::dom::DOMException & e) {
+ css::uno::Any a(e);
+ throw css::lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::init: DOM exception"),
+ css::uno::Reference<css::uno::XInterface>(*this), a);
+ }
+ }
+
+
+ // select nodes for elements of which we only handle one occurrence
+ for (const char **pName = s_stdMeta; *pName != 0; ++pName) {
+ ::rtl::OUString name = ::rtl::OUString::createFromAscii(*pName);
+ // NB: If a document contains more than one occurrence of a
+ // meta-data element, we arbitrarily pick one of them here.
+ // We do not remove the others, i.e., when we write the
+ // document, it will contain the duplicates unchanged.
+ // The ODF spec says that handling multiple occurrences is
+ // application-specific.
+ css::uno::Reference<css::xml::dom::XNode> xNode =
+ xPath->selectSingleNode(m_xParent,
+ ::rtl::OUString::createFromAscii("child::") + name);
+ // Do not create an empty element if it is missing;
+ // for certain elements, such as dateTime, this would be invalid
+ m_meta[name] = xNode;
+ }
+
+ // select nodes for elements of which we handle all occurrences
+ for (const char **pName = s_stdMetaList; *pName != 0; ++pName) {
+ ::rtl::OUString name = ::rtl::OUString::createFromAscii(*pName);
+ css::uno::Reference<css::xml::dom::XNodeList> nodes =
+ xPath->selectNodeList(m_xParent,
+ ::rtl::OUString::createFromAscii("child::") + name);
+ std::vector<css::uno::Reference<css::xml::dom::XNode> > v;
+ for (sal_Int32 i = 0; i < nodes->getLength(); ++i) {
+ v.push_back(nodes->item(i));
+ }
+ m_metaList[name] = v;
+ }
+
+ // initialize members corresponding to attributes from DOM nodes
+ m_TemplateName = getMetaAttr("meta:template", "xlink:title");
+ m_TemplateURL = getMetaAttr("meta:template", "xlink:href");
+ m_TemplateDate =
+ textToDateTimeDefault(getMetaAttr("meta:template", "meta:date"));
+ m_AutoloadURL = getMetaAttr("meta:auto-reload", "xlink:href");
+ m_AutoloadSecs =
+ textToDuration(getMetaAttr("meta:auto-reload", "meta:delay"));
+ m_DefaultTarget =
+ getMetaAttr("meta:hyperlink-behaviour", "office:target-frame-name");
+
+
+ std::vector<css::uno::Reference<css::xml::dom::XNode> > & vec =
+ m_metaList[::rtl::OUString::createFromAscii("meta:user-defined")];
+ m_xUserDefined.clear(); // #i105826#: reset (may be re-initialization)
+ if ( !vec.empty() )
+ {
+ createUserDefined();
+ }
+
+ // user-defined meta data: initialize PropertySet from DOM nodes
+ for (std::vector<css::uno::Reference<css::xml::dom::XNode> >::iterator
+ it = vec.begin(); it != vec.end(); ++it) {
+ css::uno::Reference<css::xml::dom::XElement> xElem(*it,
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Any any;
+ ::rtl::OUString name = xElem->getAttributeNS(
+ ::rtl::OUString::createFromAscii(s_nsODFMeta),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name")));
+ ::rtl::OUString type = xElem->getAttributeNS(
+ ::rtl::OUString::createFromAscii(s_nsODFMeta),
+ ::rtl::OUString::createFromAscii("value-type"));
+ ::rtl::OUString text = getNodeText(*it);
+ if (type.equalsAscii("float")) {
+ double d;
+ if (::sax::Converter::convertDouble(d, text)) {
+ any <<= d;
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid float: %s",
+ OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
+ continue;
+ }
+ } else if (type.equalsAscii("date")) {
+ bool isDateTime;
+ css::util::Date d;
+ css::util::DateTime dt;
+ if (textToDateOrDateTime(d, dt, isDateTime, text)) {
+ if (isDateTime) {
+ any <<= dt;
+ } else {
+ any <<= d;
+ }
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
+ OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
+ continue;
+ }
+ } else if (type.equalsAscii("time")) {
+ css::util::Duration ud;
+ if (textToDuration(ud, text)) {
+ any <<= ud;
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid time: %s",
+ OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
+ continue;
+ }
+ } else if (type.equalsAscii("boolean")) {
+ bool b;
+ if (::sax::Converter::convertBool(b, text)) {
+ any <<= b;
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid boolean: %s",
+ OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
+ continue;
+ }
+ } else if (type.equalsAscii("string") || true) { // default
+ any <<= text;
+ }
+ try {
+ m_xUserDefined->addProperty(name,
+ css::beans::PropertyAttribute::REMOVEABLE, any);
+ } catch (css::beans::PropertyExistException &) {
+ DBG_WARNING1("SfxDocumentMetaData: duplicate: %s",
+ OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr());
+ // ignore; duplicate
+ } catch (css::beans::IllegalTypeException &) {
+ DBG_ERROR1("SfxDocumentMetaData: illegal type: %s",
+ OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr());
+ } catch (css::lang::IllegalArgumentException &) {
+ DBG_ERROR1("SfxDocumentMetaData: illegal arg: %s",
+ OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+
+ m_isModified = false;
+ m_isInitialized = true;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+SfxDocumentMetaData::SfxDocumentMetaData(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ : BaseMutex()
+ , SfxDocumentMetaData_Base(m_aMutex)
+ , m_xContext(context)
+ , m_NotifyListeners(m_aMutex)
+ , m_isInitialized(false)
+ , m_isModified(false)
+ , m_AutoloadSecs(0)
+{
+ DBG_ASSERT(context.is(), "SfxDocumentMetaData: context is null");
+ DBG_ASSERT(context->getServiceManager().is(),
+ "SfxDocumentMetaData: context has no service manager");
+ init(createDOM());
+}
+
+// com.sun.star.uno.XServiceInfo:
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getImplementationName() throw (css::uno::RuntimeException)
+{
+ return comp_SfxDocumentMetaData::_getImplementationName();
+}
+
+::sal_Bool SAL_CALL
+SfxDocumentMetaData::supportsService(::rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< ::rtl::OUString > serviceNames =
+ comp_SfxDocumentMetaData::_getSupportedServiceNames();
+ for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
+ if (serviceNames[i] == serviceName)
+ return sal_True;
+ }
+ return sal_False;
+}
+
+css::uno::Sequence< ::rtl::OUString > SAL_CALL
+SfxDocumentMetaData::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return comp_SfxDocumentMetaData::_getSupportedServiceNames();
+}
+
+
+// ::com::sun::star::lang::XComponent:
+void SAL_CALL SfxDocumentMetaData::dispose() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ if (!m_isInitialized) {
+ return;
+ }
+ WeakComponentImplHelperBase::dispose(); // superclass
+ m_NotifyListeners.disposeAndClear(css::lang::EventObject(
+ static_cast< ::cppu::OWeakObject* >(this)));
+ m_isInitialized = false;
+ m_meta.clear();
+ m_metaList.clear();
+ m_xParent.clear();
+ m_xDoc.clear();
+ m_xUserDefined.clear();
+}
+
+
+// ::com::sun::star::document::XDocumentProperties:
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getAuthor() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return getMetaText("meta:initial-creator");
+}
+
+void SAL_CALL SfxDocumentMetaData::setAuthor(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("meta:initial-creator", the_value);
+}
+
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getGenerator() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return getMetaText("meta:generator");
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setGenerator(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("meta:generator", the_value);
+}
+
+css::util::DateTime SAL_CALL
+SfxDocumentMetaData::getCreationDate() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return textToDateTimeDefault(getMetaText("meta:creation-date"));
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setCreationDate(const css::util::DateTime & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("meta:creation-date", dateTimeToText(the_value));
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getTitle() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return getMetaText("dc:title");
+}
+
+void SAL_CALL SfxDocumentMetaData::setTitle(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("dc:title", the_value);
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getSubject() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return getMetaText("dc:subject");
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setSubject(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("dc:subject", the_value);
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getDescription() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return getMetaText("dc:description");
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setDescription(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("dc:description", the_value);
+}
+
+css::uno::Sequence< ::rtl::OUString >
+SAL_CALL SfxDocumentMetaData::getKeywords() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return getMetaList("meta:keyword");
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setKeywords(
+ const css::uno::Sequence< ::rtl::OUString > & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ if (setMetaList("meta:keyword", the_value)) {
+ g.clear();
+ setModified(true);
+ }
+}
+
+css::lang::Locale SAL_CALL
+ SfxDocumentMetaData::getLanguage() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ css::lang::Locale loc;
+ ::rtl::OUString text = getMetaText("dc:language");
+ sal_Int32 ix = text.indexOf(static_cast<sal_Unicode> ('-'));
+ if (ix == -1) {
+ loc.Language = text;
+ } else {
+ loc.Language = text.copy(0, ix);
+ loc.Country = text.copy(ix+1);
+ }
+ return loc;
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setLanguage(const css::lang::Locale & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::rtl::OUString text = the_value.Language;
+ if (the_value.Country.getLength() > 0) {
+ text += ::rtl::OUString::createFromAscii("-").concat(the_value.Country);
+ }
+ setMetaTextAndNotify("dc:language", text);
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getModifiedBy() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return getMetaText("dc:creator");
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setModifiedBy(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("dc:creator", the_value);
+}
+
+css::util::DateTime SAL_CALL
+SfxDocumentMetaData::getModificationDate() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return textToDateTimeDefault(getMetaText("dc:date"));
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setModificationDate(const css::util::DateTime & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("dc:date", dateTimeToText(the_value));
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getPrintedBy() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return getMetaText("meta:printed-by");
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setPrintedBy(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("meta:printed-by", the_value);
+}
+
+css::util::DateTime SAL_CALL
+SfxDocumentMetaData::getPrintDate() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return textToDateTimeDefault(getMetaText("meta:print-date"));
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setPrintDate(const css::util::DateTime & the_value)
+ throw (css::uno::RuntimeException)
+{
+ setMetaTextAndNotify("meta:print-date", dateTimeToText(the_value));
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getTemplateName() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ return m_TemplateName;
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setTemplateName(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ checkInit();
+ if (m_TemplateName != the_value) {
+ m_TemplateName = the_value;
+ g.clear();
+ setModified(true);
+ }
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getTemplateURL() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ return m_TemplateURL;
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setTemplateURL(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ checkInit();
+ if (m_TemplateURL != the_value) {
+ m_TemplateURL = the_value;
+ g.clear();
+ setModified(true);
+ }
+}
+
+css::util::DateTime SAL_CALL
+SfxDocumentMetaData::getTemplateDate() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ return m_TemplateDate;
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setTemplateDate(const css::util::DateTime & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ checkInit();
+ if (!(m_TemplateDate == the_value)) {
+ m_TemplateDate = the_value;
+ g.clear();
+ setModified(true);
+ }
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getAutoloadURL() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ return m_AutoloadURL;
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setAutoloadURL(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ checkInit();
+ if (m_AutoloadURL != the_value) {
+ m_AutoloadURL = the_value;
+ g.clear();
+ setModified(true);
+ }
+}
+
+::sal_Int32 SAL_CALL
+SfxDocumentMetaData::getAutoloadSecs() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ return m_AutoloadSecs;
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setAutoloadSecs(::sal_Int32 the_value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
+{
+ if (the_value < 0) throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::setAutoloadSecs: argument is negative"),
+ *this, 0);
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ checkInit();
+ if (m_AutoloadSecs != the_value) {
+ m_AutoloadSecs = the_value;
+ g.clear();
+ setModified(true);
+ }
+}
+
+::rtl::OUString SAL_CALL
+SfxDocumentMetaData::getDefaultTarget() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ return m_DefaultTarget;
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setDefaultTarget(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ checkInit();
+ if (m_DefaultTarget != the_value) {
+ m_DefaultTarget = the_value;
+ g.clear();
+ setModified(true);
+ }
+}
+
+css::uno::Sequence< css::beans::NamedValue > SAL_CALL
+SfxDocumentMetaData::getDocumentStatistics() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ ::comphelper::SequenceAsVector<css::beans::NamedValue> stats;
+ for (size_t i = 0; s_stdStats[i] != 0; ++i) {
+ const char * aName = s_stdStatAttrs[i];
+ ::rtl::OUString text = getMetaAttr("meta:document-statistic", aName);
+ if (text.equalsAscii("")) continue;
+ css::beans::NamedValue stat;
+ stat.Name = ::rtl::OUString::createFromAscii(s_stdStats[i]);
+ sal_Int32 val;
+ css::uno::Any any;
+ if (!::sax::Converter::convertNumber(val, text, 0,
+ std::numeric_limits<sal_Int32>::max()) || (val < 0)) {
+ val = 0;
+ DBG_WARNING1("SfxDocumentMetaData: invalid number: %s",
+ OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ any <<= val;
+ stat.Value = any;
+ stats.push_back(stat);
+ }
+
+ return stats.getAsConstList();
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setDocumentStatistics(
+ const css::uno::Sequence< css::beans::NamedValue > & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+ checkInit();
+ std::vector<std::pair<const char *, ::rtl::OUString> > attributes;
+ for (sal_Int32 i = 0; i < the_value.getLength(); ++i) {
+ const ::rtl::OUString name = the_value[i].Name;
+ // inefficently search for matching attribute
+ for (size_t j = 0; s_stdStats[j] != 0; ++j) {
+ if (name.equalsAscii(s_stdStats[j])) {
+ const css::uno::Any any = the_value[i].Value;
+ sal_Int32 val = 0;
+ if (any >>= val) {
+ ::rtl::OUStringBuffer buf;
+ ::sax::Converter::convertNumber(buf, val);
+ attributes.push_back(std::make_pair(s_stdStatAttrs[j],
+ buf.makeStringAndClear()));
+ } else {
+ DBG_WARNING1("SfxDocumentMetaData: invalid statistic: %s",
+ OUStringToOString(name, RTL_TEXTENCODING_UTF8)
+ .getStr());
+ }
+ break;
+ }
+ }
+ }
+ updateElement("meta:document-statistic", &attributes);
+ g.clear();
+ setModified(true);
+}
+
+::sal_Int16 SAL_CALL
+SfxDocumentMetaData::getEditingCycles() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ ::rtl::OUString text = getMetaText("meta:editing-cycles");
+ sal_Int32 ret;
+ if (::sax::Converter::convertNumber(ret, text,
+ 0, std::numeric_limits<sal_Int16>::max())) {
+ return static_cast<sal_Int16>(ret);
+ } else {
+ return 0;
+ }
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setEditingCycles(::sal_Int16 the_value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
+{
+ if (the_value < 0) throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::setEditingCycles: argument is negative"),
+ *this, 0);
+ ::rtl::OUStringBuffer buf;
+ ::sax::Converter::convertNumber(buf, the_value);
+ setMetaTextAndNotify("meta:editing-cycles", buf.makeStringAndClear());
+}
+
+::sal_Int32 SAL_CALL
+SfxDocumentMetaData::getEditingDuration() throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ return textToDuration(getMetaText("meta:editing-duration"));
+}
+
+void SAL_CALL
+SfxDocumentMetaData::setEditingDuration(::sal_Int32 the_value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
+{
+ if (the_value < 0) throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::setEditingDuration: argument is negative"),
+ *this, 0);
+ setMetaTextAndNotify("meta:editing-duration", durationToText(the_value));
+}
+
+void SAL_CALL
+SfxDocumentMetaData::resetUserData(const ::rtl::OUString & the_value)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::ClearableMutexGuard g(m_aMutex);
+
+ bool bModified( false );
+ bModified |= setMetaText("meta:initial-creator", the_value);
+ ::DateTime now = DateTime();
+ css::util::DateTime uDT(now.Get100Sec(), now.GetSec(), now.GetMin(),
+ now.GetHour(), now.GetDay(), now.GetMonth(), now.GetYear());
+ bModified |= setMetaText("meta:creation-date", dateTimeToText(uDT));
+ bModified |= setMetaText("dc:creator", ::rtl::OUString());
+ bModified |= setMetaText("meta:printed-by", ::rtl::OUString());
+ bModified |= setMetaText("dc:date", dateTimeToText(css::util::DateTime()));
+ bModified |= setMetaText("meta:print-date",
+ dateTimeToText(css::util::DateTime()));
+ bModified |= setMetaText("meta:editing-duration", durationToText(0));
+ bModified |= setMetaText("meta:editing-cycles",
+ ::rtl::OUString::createFromAscii("1"));
+
+ if (bModified) {
+ g.clear();
+ setModified(true);
+ }
+}
+
+
+css::uno::Reference< css::beans::XPropertyContainer > SAL_CALL
+SfxDocumentMetaData::getUserDefinedProperties()
+ throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ createUserDefined();
+ return m_xUserDefined;
+}
+
+
+void SAL_CALL
+SfxDocumentMetaData::loadFromStorage(
+ const css::uno::Reference< css::embed::XStorage > & xStorage,
+ const css::uno::Sequence< css::beans::PropertyValue > & Medium)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException,
+ css::io::WrongFormatException,
+ css::lang::WrappedTargetException, css::io::IOException)
+{
+ if (!xStorage.is()) throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::loadFromStorage:"
+ " argument is null"), *this, 0);
+ ::osl::MutexGuard g(m_aMutex);
+
+ // open meta data file
+ css::uno::Reference<css::io::XStream> xStream(
+ xStorage->openStreamElement(
+ ::rtl::OUString::createFromAscii(s_metaXml),
+ css::embed::ElementModes::READ) );
+ if (!xStream.is()) throw css::uno::RuntimeException();
+ css::uno::Reference<css::io::XInputStream> xInStream =
+ xStream->getInputStream();
+ if (!xInStream.is()) throw css::uno::RuntimeException();
+
+ // create DOM parser service
+ css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
+ m_xContext->getServiceManager());
+ css::uno::Reference<css::xml::sax::XParser> xParser (
+ xMsf->createInstanceWithContext(::rtl::OUString::createFromAscii(
+ "com.sun.star.xml.sax.Parser"), m_xContext),
+ css::uno::UNO_QUERY_THROW);
+ if (!xParser.is()) throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::loadFromStorage:"
+ " cannot create Parser service"), *this);
+ css::xml::sax::InputSource input;
+ input.aInputStream = xInStream;
+
+ sal_uInt64 version = SotStorage::GetVersion( xStorage );
+ // Oasis is also the default (0)
+ sal_Bool bOasis = ( version > SOFFICE_FILEFORMAT_60 || version == 0 );
+ const sal_Char *pServiceName = bOasis
+ ? "com.sun.star.document.XMLOasisMetaImporter"
+ : "com.sun.star.document.XMLMetaImporter";
+
+ // set base URL
+ css::uno::Reference<css::beans::XPropertySet> xPropArg =
+ getURLProperties(Medium);
+ try {
+ xPropArg->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI")))
+ >>= input.sSystemId;
+ input.sSystemId += ::rtl::OUString::createFromAscii("/").concat(
+ ::rtl::OUString::createFromAscii(s_metaXml));
+ } catch (css::uno::Exception &) {
+ input.sSystemId = ::rtl::OUString::createFromAscii(s_metaXml);
+ }
+ css::uno::Sequence< css::uno::Any > args(1);
+ args[0] <<= xPropArg;
+
+ css::uno::Reference<css::xml::sax::XDocumentHandler> xDocHandler (
+ xMsf->createInstanceWithArgumentsAndContext(
+ ::rtl::OUString::createFromAscii(pServiceName), args, m_xContext),
+ css::uno::UNO_QUERY_THROW);
+ if (!xDocHandler.is()) throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::loadFromStorage:"
+ " cannot create XMLOasisMetaImporter service"), *this);
+ css::uno::Reference<css::document::XImporter> xImp (xDocHandler,
+ css::uno::UNO_QUERY_THROW);
+ xImp->setTargetDocument(css::uno::Reference<css::lang::XComponent>(this));
+ xParser->setDocumentHandler(xDocHandler);
+ try {
+ xParser->parseStream(input);
+ } catch (css::xml::sax::SAXException &) {
+ throw css::io::WrongFormatException(::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::loadFromStorage:"
+ " XML parsing exception"), *this);
+ }
+ // NB: the implementation of XMLOasisMetaImporter calls initialize
+// init(xDocBuilder->getDocument());
+ checkInit();
+}
+
+void SAL_CALL
+SfxDocumentMetaData::storeToStorage(
+ const css::uno::Reference< css::embed::XStorage > & xStorage,
+ const css::uno::Sequence< css::beans::PropertyValue > & Medium)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException,
+ css::lang::WrappedTargetException, css::io::IOException)
+{
+ if (!xStorage.is()) throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::storeToStorage:"
+ " argument is null"), *this, 0);
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+
+ // update user-defined meta data in DOM tree
+// updateUserDefinedAndAttributes(); // this will be done in serialize!
+
+ // write into storage
+ css::uno::Reference<css::io::XStream> xStream =
+ xStorage->openStreamElement(::rtl::OUString::createFromAscii(s_metaXml),
+ css::embed::ElementModes::WRITE
+ | css::embed::ElementModes::TRUNCATE);
+ if (!xStream.is()) throw css::uno::RuntimeException();
+ css::uno::Reference< css::beans::XPropertySet > xStreamProps(xStream,
+ css::uno::UNO_QUERY_THROW);
+ xStreamProps->setPropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")),
+ css::uno::makeAny(::rtl::OUString::createFromAscii("text/xml")));
+ xStreamProps->setPropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")),
+ css::uno::makeAny(static_cast<sal_Bool> (sal_False)));
+ xStreamProps->setPropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption")),
+ css::uno::makeAny(static_cast<sal_Bool> (sal_False)));
+ css::uno::Reference<css::io::XOutputStream> xOutStream =
+ xStream->getOutputStream();
+ if (!xOutStream.is()) throw css::uno::RuntimeException();
+ css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
+ m_xContext->getServiceManager());
+ css::uno::Reference<css::io::XActiveDataSource> xSaxWriter(
+ xMsf->createInstanceWithContext(::rtl::OUString::createFromAscii(
+ "com.sun.star.xml.sax.Writer"), m_xContext),
+ css::uno::UNO_QUERY_THROW);
+ xSaxWriter->setOutputStream(xOutStream);
+ css::uno::Reference<css::xml::sax::XDocumentHandler> xDocHandler (
+ xSaxWriter, css::uno::UNO_QUERY_THROW);
+
+ const sal_uInt64 version = SotStorage::GetVersion( xStorage );
+ // Oasis is also the default (0)
+ const sal_Bool bOasis = ( version > SOFFICE_FILEFORMAT_60 || version == 0 );
+ const sal_Char *pServiceName = bOasis
+ ? "com.sun.star.document.XMLOasisMetaExporter"
+ : "com.sun.star.document.XMLMetaExporter";
+
+ // set base URL
+ css::uno::Reference<css::beans::XPropertySet> xPropArg =
+ getURLProperties(Medium);
+ css::uno::Sequence< css::uno::Any > args(2);
+ args[0] <<= xDocHandler;
+ args[1] <<= xPropArg;
+
+ css::uno::Reference<css::document::XExporter> xExp(
+ xMsf->createInstanceWithArgumentsAndContext(
+ ::rtl::OUString::createFromAscii(pServiceName), args, m_xContext),
+ css::uno::UNO_QUERY_THROW);
+ xExp->setSourceDocument(css::uno::Reference<css::lang::XComponent>(this));
+ css::uno::Reference<css::document::XFilter> xFilter(xExp,
+ css::uno::UNO_QUERY_THROW);
+ if (xFilter->filter(css::uno::Sequence< css::beans::PropertyValue >())) {
+ css::uno::Reference<css::embed::XTransactedObject> xTransaction(
+ xStorage, css::uno::UNO_QUERY);
+ if (xTransaction.is()) {
+ xTransaction->commit();
+ }
+ } else {
+ throw css::io::IOException(::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::storeToStorage: cannot filter"), *this);
+ }
+}
+
+void SAL_CALL
+SfxDocumentMetaData::loadFromMedium(const ::rtl::OUString & URL,
+ const css::uno::Sequence< css::beans::PropertyValue > & Medium)
+ throw (css::uno::RuntimeException, css::io::WrongFormatException,
+ css::lang::WrappedTargetException, css::io::IOException)
+{
+ css::uno::Reference<css::io::XInputStream> xIn;
+ ::comphelper::MediaDescriptor md(Medium);
+ // if we have an URL parameter, it replaces the one in the media descriptor
+ if (!URL.equalsAscii("")) {
+ md[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= URL;
+ }
+ if (sal_True == md.addInputStream()) {
+ md[ ::comphelper::MediaDescriptor::PROP_INPUTSTREAM() ] >>= xIn;
+ }
+ css::uno::Reference<css::embed::XStorage> xStorage;
+ css::uno::Reference<css::lang::XMultiServiceFactory> xMsf (
+ m_xContext->getServiceManager(), css::uno::UNO_QUERY_THROW);
+ try {
+ if (xIn.is()) {
+ xStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream(
+ xIn, xMsf);
+ } else { // fallback to url parameter
+ xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
+ URL, css::embed::ElementModes::READ, xMsf);
+ }
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::io::IOException &) {
+ throw;
+ } catch (css::uno::Exception & e) {
+ throw css::lang::WrappedTargetException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::loadFromMedium: exception"),
+ css::uno::Reference<css::uno::XInterface>(*this),
+ css::uno::makeAny(e));
+ }
+ if (!xStorage.is()) {
+ throw css::uno::RuntimeException(::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::loadFromMedium: cannot get Storage"),
+ *this);
+ }
+ loadFromStorage(xStorage, md.getAsConstPropertyValueList());
+}
+
+void SAL_CALL
+SfxDocumentMetaData::storeToMedium(const ::rtl::OUString & URL,
+ const css::uno::Sequence< css::beans::PropertyValue > & Medium)
+ throw (css::uno::RuntimeException,
+ css::lang::WrappedTargetException, css::io::IOException)
+{
+ ::comphelper::MediaDescriptor md(Medium);
+ if (!URL.equalsAscii("")) {
+ md[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= URL;
+ }
+ SfxMedium aMedium(md.getAsConstPropertyValueList());
+ css::uno::Reference<css::embed::XStorage> xStorage
+ = aMedium.GetOutputStorage();
+
+
+ if (!xStorage.is()) {
+ throw css::uno::RuntimeException(::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::storeToMedium: cannot get Storage"),
+ *this);
+ }
+ // set MIME type of the storage
+ ::comphelper::MediaDescriptor::const_iterator iter
+ = md.find(::comphelper::MediaDescriptor::PROP_MEDIATYPE());
+ if (iter != md.end()) {
+ css::uno::Reference< css::beans::XPropertySet > xProps(xStorage,
+ css::uno::UNO_QUERY_THROW);
+ xProps->setPropertyValue(
+ ::comphelper::MediaDescriptor::PROP_MEDIATYPE(),
+ iter->second);
+ }
+ storeToStorage(xStorage, md.getAsConstPropertyValueList());
+
+
+ const sal_Bool bOk = aMedium.Commit();
+ aMedium.Close();
+ if ( !bOk ) {
+ sal_uInt32 nError = aMedium.GetError();
+ if ( nError == ERRCODE_NONE ) {
+ nError = ERRCODE_IO_GENERAL;
+ }
+
+ throw css::task::ErrorCodeIOException( ::rtl::OUString(),
+ css::uno::Reference< css::uno::XInterface >(), nError);
+
+ }
+}
+
+// ::com::sun::star::lang::XInitialization:
+void SAL_CALL
+SfxDocumentMetaData::initialize(
+ const css::uno::Sequence< ::com::sun::star::uno::Any > & aArguments)
+ throw (css::uno::RuntimeException, css::uno::Exception)
+{
+ // possible arguments:
+ // - no argument: default initialization (empty DOM)
+ // - 1 argument, XDocument: initialize with given DOM and empty base URL
+ // NB: links in document must be absolute
+
+ ::osl::MutexGuard g(m_aMutex);
+ css::uno::Reference<css::xml::dom::XDocument> xDoc;
+
+ for (sal_Int32 i = 0; i < aArguments.getLength(); ++i) {
+ const css::uno::Any any = aArguments[i];
+ if (any >>= xDoc) {
+ if (!xDoc.is()) {
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::"
+ "initialize: argument is null"),
+ *this, static_cast<sal_Int16>(i));
+ }
+ } else {
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("SfxDocumentMetaData::"
+ "initialize: argument must be XDocument"),
+ *this, static_cast<sal_Int16>(i));
+ }
+ }
+
+ if (!xDoc.is()) {
+ // For a new document, we create a new DOM tree here.
+ xDoc = createDOM();
+ }
+
+ init(xDoc);
+}
+
+// ::com::sun::star::util::XCloneable:
+css::uno::Reference<css::util::XCloneable> SAL_CALL
+SfxDocumentMetaData::createClone()
+ throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+
+ SfxDocumentMetaData *pNew = new SfxDocumentMetaData(m_xContext);
+
+ // NB: do not copy the modification listeners, only DOM
+ css::uno::Reference<css::xml::dom::XDocument> xDoc = createDOM();
+ try {
+ updateUserDefinedAndAttributes();
+ // deep copy of root node
+ css::uno::Reference<css::xml::dom::XNode> xRoot(
+ m_xDoc->getDocumentElement(), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::xml::dom::XNode> xRootNew(
+ xDoc->importNode(xRoot, true));
+ xDoc->appendChild(xRootNew);
+ pNew->init(xDoc);
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::uno::Exception & e) {
+ css::uno::Any a(e);
+ throw css::lang::WrappedTargetRuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentMetaData::createClone: exception"),
+ css::uno::Reference<css::uno::XInterface>(*this), a);
+ }
+// return static_cast< ::cppu::OWeakObject * > (pNew);
+ return css::uno::Reference<css::util::XCloneable> (pNew);
+}
+
+// ::com::sun::star::util::XModifiable:
+::sal_Bool SAL_CALL SfxDocumentMetaData::isModified( )
+ throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ css::uno::Reference<css::util::XModifiable> xMB(m_xUserDefined,
+ css::uno::UNO_QUERY);
+ return m_isModified || (xMB.is() ? xMB->isModified() : sal_False);
+}
+
+void SAL_CALL SfxDocumentMetaData::setModified( ::sal_Bool bModified )
+ throw (css::beans::PropertyVetoException, css::uno::RuntimeException)
+{
+ css::uno::Reference<css::util::XModifiable> xMB;
+ { // do not lock mutex while notifying (#i93514#) to prevent deadlock
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ m_isModified = bModified;
+ if ( !bModified && m_xUserDefined.is() )
+ {
+ xMB.set(m_xUserDefined, css::uno::UNO_QUERY);
+ DBG_ASSERT(xMB.is(),
+ "SfxDocumentMetaData::setModified: PropertyBag not Modifiable?");
+ }
+ }
+ if (bModified) {
+ try {
+ css::uno::Reference<css::uno::XInterface> xThis(*this);
+ css::lang::EventObject event(xThis);
+ m_NotifyListeners.notifyEach(&css::util::XModifyListener::modified,
+ event);
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::uno::Exception & e) {
+ // ignore
+ DBG_WARNING1("SfxDocumentMetaData::setModified: exception:\n%s",
+ OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
+ (void) e;
+ }
+ } else {
+ if (xMB.is()) {
+ xMB->setModified(false);
+ }
+ }
+}
+
+// ::com::sun::star::util::XModifyBroadcaster:
+void SAL_CALL SfxDocumentMetaData::addModifyListener(
+ const css::uno::Reference< css::util::XModifyListener > & xListener)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ m_NotifyListeners.addInterface(xListener);
+ css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,
+ css::uno::UNO_QUERY);
+ if (xMB.is()) {
+ xMB->addModifyListener(xListener);
+ }
+}
+
+void SAL_CALL SfxDocumentMetaData::removeModifyListener(
+ const css::uno::Reference< css::util::XModifyListener > & xListener)
+ throw (css::uno::RuntimeException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ m_NotifyListeners.removeInterface(xListener);
+ css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,
+ css::uno::UNO_QUERY);
+ if (xMB.is()) {
+ xMB->removeModifyListener(xListener);
+ }
+}
+
+// ::com::sun::star::xml::sax::XSAXSerializable
+void SAL_CALL SfxDocumentMetaData::serialize(
+ const css::uno::Reference<css::xml::sax::XDocumentHandler>& i_xHandler,
+ const css::uno::Sequence< css::beans::StringPair >& i_rNamespaces)
+ throw (css::uno::RuntimeException, css::xml::sax::SAXException)
+{
+ ::osl::MutexGuard g(m_aMutex);
+ checkInit();
+ updateUserDefinedAndAttributes();
+ css::uno::Reference<css::xml::sax::XSAXSerializable> xSAXable(m_xDoc,
+ css::uno::UNO_QUERY_THROW);
+ xSAXable->serialize(i_xHandler, i_rNamespaces);
+}
+
+void SfxDocumentMetaData::createUserDefined()
+{
+ // user-defined meta data: create PropertyBag which only accepts property
+ // values of allowed types
+ if ( !m_xUserDefined.is() )
+ {
+ css::uno::Sequence<css::uno::Type> types(11);
+ types[0] = ::cppu::UnoType<bool>::get();
+ types[1] = ::cppu::UnoType< ::rtl::OUString>::get();
+ types[2] = ::cppu::UnoType<css::util::DateTime>::get();
+ types[3] = ::cppu::UnoType<css::util::Date>::get();
+ types[4] = ::cppu::UnoType<css::util::Duration>::get();
+ types[5] = ::cppu::UnoType<float>::get();
+ types[6] = ::cppu::UnoType<double>::get();
+ types[7] = ::cppu::UnoType<sal_Int16>::get();
+ types[8] = ::cppu::UnoType<sal_Int32>::get();
+ types[9] = ::cppu::UnoType<sal_Int64>::get();
+ // Time is supported for backward compatibility with OOo 3.x, x<=2
+ types[10] = ::cppu::UnoType<css::util::Time>::get();
+ css::uno::Sequence<css::uno::Any> args(2);
+ args[0] <<= css::beans::NamedValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowedTypes")),
+ css::uno::makeAny(types));
+ // #i94175#: ODF allows empty user-defined property names!
+ args[1] <<= css::beans::NamedValue( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("AllowEmptyPropertyName")),
+ css::uno::makeAny(sal_True));
+
+ const css::uno::Reference<css::lang::XMultiComponentFactory> xMsf(
+ m_xContext->getServiceManager());
+ m_xUserDefined.set(
+ xMsf->createInstanceWithContext(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.beans.PropertyBag")), m_xContext),
+ css::uno::UNO_QUERY_THROW);
+ const css::uno::Reference<css::lang::XInitialization> xInit(
+ m_xUserDefined, css::uno::UNO_QUERY);
+ if (xInit.is()) {
+ xInit->initialize(args);
+ }
+
+ const css::uno::Reference<css::util::XModifyBroadcaster> xMB(
+ m_xUserDefined, css::uno::UNO_QUERY);
+ if (xMB.is())
+ {
+ const css::uno::Sequence<css::uno::Reference<css::uno::XInterface> >
+ listeners(m_NotifyListeners.getElements());
+ for (css::uno::Reference< css::uno::XInterface > const * iter =
+ ::comphelper::stl_begin(listeners);
+ iter != ::comphelper::stl_end(listeners); ++iter) {
+ xMB->addModifyListener(
+ css::uno::Reference< css::util::XModifyListener >(*iter,
+ css::uno::UNO_QUERY));
+ }
+ }
+ }
+}
+
+} // closing anonymous implementation namespace
+
+
+// component helper namespace
+namespace comp_SfxDocumentMetaData {
+
+::rtl::OUString SAL_CALL _getImplementationName() {
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SfxDocumentMetaData"));
+}
+
+css::uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames()
+{
+ css::uno::Sequence< ::rtl::OUString > s(1);
+ s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.document.DocumentProperties"));
+ return s;
+}
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL _create(
+ const css::uno::Reference< css::uno::XComponentContext > & context)
+ SAL_THROW((css::uno::Exception))
+{
+ return static_cast< ::cppu::OWeakObject * >
+ (new SfxDocumentMetaData(context));
+}
+
+} // closing component helper namespace
+
+static ::cppu::ImplementationEntry const entries[] = {
+ { &comp_SfxDocumentMetaData::_create,
+ &comp_SfxDocumentMetaData::_getImplementationName,
+ &comp_SfxDocumentMetaData::_getSupportedServiceNames,
+ &::cppu::createSingleComponentFactory, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+#if 0
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const char ** envTypeName, uno_Environment **)
+{
+ *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" void * SAL_CALL component_getFactory(
+ const char * implName, void * serviceManager, void * registryKey)
+{
+ return ::cppu::component_getFactoryHelper(
+ implName, serviceManager, registryKey, entries);
+}
+
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * serviceManager, void * registryKey)
+{
+ return ::cppu::component_writeInfoHelper(serviceManager, registryKey,
+ entries);
+}
+#endif
+
diff --git a/sfx2/source/doc/applet.cxx b/sfx2/source/doc/applet.cxx
new file mode 100644
index 000000000000..844eb5726b1a
--- /dev/null
+++ b/sfx2/source/doc/applet.cxx
@@ -0,0 +1,383 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "applet.hxx"
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/sfxsids.hrc>
+
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "cppuhelper/factory.hxx"
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <sj2/sjapplet.hxx>
+#include <vcl/syschild.hxx>
+#include <rtl/ustring.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <unotools/javaoptions.hxx>
+#include <svtools/miscopt.hxx>
+#include <comphelper/TypeGeneration.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::comphelper;
+
+namespace sfx2
+{
+class AppletWindow_Impl : public SystemChildWindow
+{
+public:
+ SjApplet2* pApplet;
+ AppletWindow_Impl( Window* pParent, SjApplet2* pApp )
+ : SystemChildWindow( pParent, WB_CLIPCHILDREN )
+ , pApplet(pApp)
+ {}
+
+ virtual void Resize();
+};
+
+void AppletWindow_Impl::Resize()
+{
+ Size aSize( GetOutputSizePixel() );
+ if ( pApplet )
+ pApplet->setSizePixel( aSize );
+}
+
+class AppletWrapper_Impl : public SjApplet2
+{
+ virtual void appletResize( const Size & );
+ virtual void showDocument( const INetURLObject &, const XubString & );
+ virtual void showStatus( const XubString & );
+};
+
+void AppletWrapper_Impl::appletResize( const Size & ) {}
+void AppletWrapper_Impl::showDocument( const INetURLObject &, const XubString & ) {}
+void AppletWrapper_Impl::showStatus( const XubString & ) {}
+
+#define PROPERTY_UNBOUND 0
+#define PROPERTY_MAYBEVOID ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
+
+#define WID_APPLET_CODE 1
+#define WID_APPLET_CODEBASE 2
+#define WID_APPLET_COMMANDS 3
+#define WID_APPLET_DOCBASE 4
+#define WID_APPLET_ISSCRIPT 5
+#define WID_APPLET_NAME 6
+const SfxItemPropertyMapEntry* lcl_GetAppletPropertyMap_Impl()
+{
+ static SfxItemPropertyMapEntry aAppletPropertyMap_Impl[] =
+ {
+ { MAP_CHAR_LEN("AppletCode") , WID_APPLET_CODE , CPPU_E2T(CPPUTYPE_OUSTRING), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("AppletCodeBase"), WID_APPLET_CODEBASE , CPPU_E2T(CPPUTYPE_OUSTRING), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("AppletCommands"), WID_APPLET_COMMANDS , CPPU_E2T(CPPUTYPE_PROPERTYVALUE), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("AppletDocBase"), WID_APPLET_DOCBASE , CPPU_E2T(CPPUTYPE_OUSTRING), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("AppletIsScript"), WID_APPLET_ISSCRIPT , CPPU_E2T(CPPUTYPE_BOOLEAN), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("AppletName") , WID_APPLET_NAME , CPPU_E2T(CPPUTYPE_OUSTRING), PROPERTY_UNBOUND, 0 },
+ {0,0,0,0,0,0}
+ };
+return aAppletPropertyMap_Impl;
+}
+
+::rtl::OUString AppletObject::getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ return impl_getStaticImplementationName();
+}
+
+::sal_Bool AppletObject::supportsService( const ::rtl::OUString& sServiceName )
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > seqServiceNames =
+ getSupportedServiceNames();
+ const ::rtl::OUString* pArray = seqServiceNames.getConstArray();
+ for ( ::sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength();
+ nCounter++ )
+ {
+ if ( pArray[nCounter] == sServiceName )
+ {
+ return sal_True ;
+ }
+ }
+ return sal_False ;
+}
+
+::com::sun::star::uno::Sequence< ::rtl::OUString >
+AppletObject::getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ return impl_getStaticSupportedServiceNames();
+}
+
+::com::sun::star::uno::Sequence< ::rtl::OUString >
+AppletObject::impl_getStaticSupportedServiceNames()
+{
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > seqServiceNames( 1 );
+ seqServiceNames.getArray() [0] = ::rtl::OUString::createFromAscii(
+ "com.sun.star.embed.SpecialEmbeddedObject" );
+ return seqServiceNames ;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+AppletObject::impl_createInstance(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext >& xContext )
+ throw( ::com::sun::star::uno::Exception )
+{
+ return static_cast< ::cppu::OWeakObject * >( new AppletObject( xContext ) );
+}
+
+::rtl::OUString AppletObject::impl_getStaticImplementationName()
+{
+ return ::rtl::OUString::createFromAscii(
+ "com.sun.star.comp.sfx2.AppletObject" );
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+AppletObject::impl_createFactory()
+{
+ return uno::Reference< uno::XInterface >(
+ cppu::createSingleComponentFactory(
+ impl_createInstance, impl_getStaticImplementationName(),
+ impl_getStaticSupportedServiceNames() ),
+ uno::UNO_QUERY_THROW );
+}
+
+AppletObject::AppletObject(
+ const uno::Reference < uno::XComponentContext >& rContext )
+ : mxContext( rContext )
+ , maPropMap( lcl_GetAppletPropertyMap_Impl() )
+ , mpApplet( NULL )
+ , mbMayScript( FALSE )
+{
+}
+
+AppletObject::~AppletObject()
+{
+}
+
+void SAL_CALL AppletObject::initialize( const uno::Sequence< uno::Any >& aArguments ) throw ( uno::Exception, uno::RuntimeException )
+{
+ if ( aArguments.getLength() )
+ aArguments[0] >>= mxObj;
+}
+
+sal_Bool SAL_CALL AppletObject::load(
+ const uno::Sequence < com::sun::star::beans::PropertyValue >& /*lDescriptor*/,
+ const uno::Reference < frame::XFrame >& xFrame )
+throw( uno::RuntimeException )
+{
+ if ( SvtJavaOptions().IsExecuteApplets() && SvtMiscOptions().IsPluginsEnabled() )
+ {
+ mpApplet = new AppletWrapper_Impl;
+
+ Window* pParent = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ Window* pWin = new AppletWindow_Impl( pParent, mpApplet );
+ pWin->SetBackground();
+ pWin->Show();
+
+ // aCmdList.Append( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "width" ) ), String( aPosSize.GetWidth() ) );
+ // aCmdList.Append( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "height" ) ), String( aPosSize.GetHeight() ) );
+
+ if( maName.getLength() )
+ maCmdList.Append( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "name" ) ), maName );
+
+ if( maCodeBase.getLength() )
+ {
+ for ( sal_uInt32 nParams=0; nParams<maCmdList.Count(); nParams++ )
+ {
+ if ( maCmdList[nParams].GetCommand().EqualsAscii("codebase") )
+ {
+ maCmdList.Remove(nParams);
+ break;
+ }
+ }
+
+ maCmdList.Append( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "codebase" ) ), maCodeBase );
+ }
+
+ if( maClass.getLength() )
+ maCmdList.Append( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "code" ) ), maClass );
+
+ if( mbMayScript )
+ maCmdList.Append( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "mayscript" ) ), String() );
+
+ INetURLObject aDocBase( maDocBase );
+ mpApplet->Init( mxContext, pWin, aDocBase, maCmdList );
+ uno::Reference < awt::XWindow > xWindow( pWin->GetComponentInterface(), uno::UNO_QUERY );
+
+ // we must destroy the applet before the parent is destroyed
+ xWindow->addEventListener( this );
+
+ xFrame->setComponent( xWindow, uno::Reference < frame::XController >() );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void SAL_CALL AppletObject::cancel() throw( com::sun::star::uno::RuntimeException )
+{
+ if ( mpApplet )
+ {
+ mpApplet->appletClose(); // reparenting window
+ DELETEZ( mpApplet );
+ }
+}
+
+void SAL_CALL AppletObject::close( sal_Bool /*bDeliverOwnership*/ ) throw( com::sun::star::util::CloseVetoException, com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL AppletObject::addCloseListener( const com::sun::star::uno::Reference < com::sun::star::util::XCloseListener >& ) throw( com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL AppletObject::removeCloseListener( const com::sun::star::uno::Reference < com::sun::star::util::XCloseListener >& ) throw( com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL AppletObject::disposing( const com::sun::star::lang::EventObject& ) throw (com::sun::star::uno::RuntimeException)
+{
+ cancel();
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL AppletObject::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException )
+{
+ static uno::Reference< beans::XPropertySetInfo > xInfo = new SfxItemPropertySetInfo( &maPropMap );
+ return xInfo;
+}
+
+void SAL_CALL AppletObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aAny)
+ throw ( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+
+ const SfxItemPropertySimpleEntry* pEntry = maPropMap.getByName( aPropertyName );
+ if( !pEntry )
+ throw beans::UnknownPropertyException();
+ switch( pEntry->nWID )
+ {
+ case WID_APPLET_CODE :
+ aAny >>= maClass;
+ break;
+ case WID_APPLET_CODEBASE :
+ //pImpl->aCodeBase = rURL.GetMainURL( INetURLObject::NO_DECODE );
+ //if( rURL.GetProtocol() == INET_PROT_FILE
+ // && pImpl->aCodeBase.GetChar( 9 ) == INET_ENC_DELIM_TOKEN )
+ // // Laufwerksbuchstabe auf ':' patchen
+ // pImpl->aCodeBase.SetChar( 9, INET_DELIM_TOKEN );
+
+ aAny >>= maCodeBase;
+ break;
+ case WID_APPLET_COMMANDS :
+ {
+ maCmdList.Clear();
+ uno::Sequence < beans::PropertyValue > aCommandSequence;
+ if( aAny >>= aCommandSequence )
+ maCmdList.FillFromSequence( aCommandSequence );
+ }
+ break;
+ case WID_APPLET_DOCBASE :
+ aAny >>= maDocBase;
+ break;
+ case WID_APPLET_ISSCRIPT :
+ aAny >>= mbMayScript;
+ break;
+ case WID_APPLET_NAME :
+ aAny >>= maName;
+ break;
+ default:;
+
+ }
+}
+
+uno::Any SAL_CALL AppletObject::getPropertyValue(const ::rtl::OUString& aPropertyName) throw ( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aAny;
+ const SfxItemPropertySimpleEntry* pEntry = maPropMap.getByName( aPropertyName );
+ if( !pEntry )
+ throw beans::UnknownPropertyException();
+ switch( pEntry->nWID )
+ {
+ case WID_APPLET_CODE :
+ aAny <<= maClass;
+ break;
+ case WID_APPLET_CODEBASE :
+ aAny <<= maCodeBase;
+ break;
+ case WID_APPLET_COMMANDS :
+ {
+ uno::Sequence< beans::PropertyValue > aCommandSequence;
+ maCmdList.FillSequence( aCommandSequence );
+ aAny <<= aCommandSequence;
+ }
+ break;
+ case WID_APPLET_DOCBASE :
+ break;
+ case WID_APPLET_ISSCRIPT :
+ aAny <<= mbMayScript;
+ break;
+ case WID_APPLET_NAME :
+ aAny <<= maName;
+ break;
+ default:;
+
+ }
+ return aAny;
+}
+
+void SAL_CALL AppletObject::addPropertyChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL AppletObject::removePropertyChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL AppletObject::addVetoableChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL AppletObject::removeVetoableChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+::sal_Int16 SAL_CALL AppletObject::execute() throw (::com::sun::star::uno::RuntimeException)
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ uno::Reference < beans::XPropertySet > xSet( this );
+ VclAbstractDialog* pDlg = pFact->CreateEditObjectDialog( NULL, SID_INSERT_APPLET, mxObj );
+ if ( pDlg )
+ pDlg->Execute();
+ return 0;
+}
+
+void SAL_CALL AppletObject::setTitle( const ::rtl::OUString& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+}
diff --git a/sfx2/source/doc/doc.hrc b/sfx2/source/doc/doc.hrc
new file mode 100644
index 000000000000..838168e64526
--- /dev/null
+++ b/sfx2/source/doc/doc.hrc
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 _SFX_DOC_HRC
+#define _SFX_DOC_HRC
+
+#include <sfx2/sfx.hrc>
+
+// #defines *****************************************************************
+
+#define RID_SFX_DOC_END (RID_SFX_DIALOG_START-1)
+
+#define STR_NODEFPRINTER (RID_SFX_DOC_START+ 0)
+#define STR_PRINTER_NOTAVAIL_1 (RID_SFX_DOC_START+ 1)
+#define STR_PRINTER_NOTAVAIL_2 (RID_SFX_DOC_START+ 2)
+#define STR_PRINTER_NOTAVAIL_3 (RID_SFX_DOC_START+ 3)
+#define STR_PRINTER_NOTAVAIL_4 (RID_SFX_DOC_START+ 4)
+#define STR_PRINTER_NOTAVAIL_5 (RID_SFX_DOC_START+ 5)
+#define STR_PRINT_OPTIONS (RID_SFX_DOC_START+ 6)
+#define STR_ERROR_PRINTER_BUSY (RID_SFX_DOC_START+ 7)
+#define STR_NOSTARTPRINTER (RID_SFX_DOC_START+ 8)
+#define MSG_CONFIRM_FILTER (RID_SFX_DOC_START+11)
+#define MSG_CONFIRM_OVERWRITE_TEMPLATE (RID_SFX_DOC_START+12)
+#define MSG_QUERY_LOAD_TEMPLATE (RID_SFX_DOC_START+13)
+
+#define STR_DELETE_REGION (RID_SFX_DOC_START+14)
+#define STR_DELETE_TEMPLATE (RID_SFX_DOC_START+15)
+#define MSG_REGION_NOTEMPTY (RID_SFX_DOC_START+17)
+
+#define DLG_NEW_FILE (RID_SFX_DOC_START+1)
+#define DLG_DOC_TEMPLATE (RID_SFX_DOC_START+2)
+#define DLG_ORGANIZE (RID_SFX_DOC_START+3)
+
+#define BMP_STYLES_CLOSED (RID_SFX_DOC_START+ 0)
+#define BMP_STYLES_OPENED (RID_SFX_DOC_START+ 1)
+
+#define BMP_STYLES_FAMILY1 (RID_SFX_DOC_START+ 2)
+#define BMP_STYLES_FAMILY2 (RID_SFX_DOC_START+ 3)
+#define BMP_STYLES_FAMILY3 (RID_SFX_DOC_START+ 4)
+#define BMP_STYLES_FAMILY4 (RID_SFX_DOC_START+ 5)
+
+#define BMP_STYLES_CLOSED_HC (RID_SFX_DOC_START+ 6)
+#define BMP_STYLES_OPENED_HC (RID_SFX_DOC_START+ 7)
+
+#define BMP_STYLES_FAMILY1_HC (RID_SFX_DOC_START+ 8)
+#define BMP_STYLES_FAMILY2_HC (RID_SFX_DOC_START+ 9)
+#define BMP_STYLES_FAMILY3_HC (RID_SFX_DOC_START+ 10)
+#define BMP_STYLES_FAMILY4_HC (RID_SFX_DOC_START+ 11)
+
+#define STR_STYLES (RID_SFX_DOC_START+ 18)
+#define STR_MACROS (RID_SFX_DOC_START+ 19)
+
+#define STR_PRINT_STYLES (RID_SFX_DOC_START+ 20)
+#define STR_PRINT_STYLES_HEADER (RID_SFX_DOC_START+ 21)
+#define MSG_PRINT_ERROR (RID_SFX_DOC_START+ 22)
+#define STR_BACKUP_COPY (RID_SFX_DOC_START+ 23)
+// #define MSG_WARNING_BACKUP (RID_SFX_DOC_START+ 24)
+#define MSG_CANT_OPEN_TEMPLATE (RID_SFX_DOC_START+ 25)
+#define MSG_VIEW_OPEN_CANT_SAVE (RID_SFX_DOC_START+ 26)
+#define STR_ERROR_SAVE (RID_SFX_DOC_START+ 27)
+#define STR_TEMPLATE_FILTER (RID_SFX_DOC_START+ 28)
+#define STR_ERROR_COPY_TEMPLATE (RID_SFX_DOC_START+ 29)
+
+#define STR_ERROR_DELETE_TEMPLATE (RID_SFX_DOC_START+ 30)
+#define STR_ERROR_MOVE_TEMPLATE (RID_SFX_DOC_START+ 32)
+#define MSG_ERROR_RESCAN (RID_SFX_DOC_START+ 33)
+#define STR_ERROR_SAVE_TEMPLATE (RID_SFX_DOC_START+ 34)
+#define MSG_ERROR_RENAME_TEMPLATE (RID_SFX_DOC_START+ 34)
+#define MSG_ERROR_RENAME_TEMPLATE_REGION (RID_SFX_DOC_START+ 35)
+#define STR_CONFIG (RID_SFX_DOC_START+ 37)
+#define MSG_ERROR_EMPTY_NAME (RID_SFX_DOC_START+ 37)
+#define MSG_ERROR_UNIQ_NAME (RID_SFX_DOC_START+ 38)
+#define STR_QUERY_DEFAULT_TEMPLATE (RID_SFX_DOC_START+ 39)
+#define MSG_QUERY_RESET_DEFAULT_TEMPLATE (RID_SFX_DOC_START+ 39)
+#define MSG_TEMPLATE_DIR_NOT_EXIST (RID_SFX_DOC_START+ 40)
+#define MSG_DOCINFO_CANTREAD (RID_SFX_DOC_START+ 41)
+#define STR_ERROR_NOSTORAGE (RID_SFX_DOC_START+ 42)
+// #define STR_QUERY_SAVEOWNFORMAT (RID_SFX_DOC_START+ 43)
+#define STR_QUERY_MUSTOWNFORMAT (RID_SFX_DOC_START+ 44)
+#define STR_SAVEDOC (RID_SFX_DOC_START+ 45)
+#define STR_UPDATEDOC (RID_SFX_DOC_START+ 46)
+#define STR_SAVEASDOC (RID_SFX_DOC_START+ 47)
+#define STR_SAVECOPYDOC (RID_SFX_DOC_START+ 48)
+#define STR_CLOSEDOC (RID_SFX_DOC_START+ 49)
+#define STR_CLOSEDOC_ANDRETURN (RID_SFX_DOC_START+ 50)
+#define STR_WIZARD (RID_SFX_DOC_START+ 51)
+#define RID_STR_FILTCONFIG (RID_SFX_DOC_START+ 52)
+#define RID_STR_FILTBASIC (RID_SFX_DOC_START+ 53)
+#define RID_STR_WARNSTYLEOVERWRITE (RID_SFX_DOC_START+ 54)
+#define RID_DLSTATUS (RID_SFX_DOC_START+ 55)
+
+#define STR_DOC_LOADING (RID_SFX_DOC_START+ 57)
+#define MSG_OPEN_READONLY (RID_SFX_DOC_START+ 58)
+
+#define RID_OFFICEFILTER (RID_SFX_DOC_START+ 59)
+#define RID_OFFICEFILTER_WILDCARD (RID_SFX_DOC_START+ 60)
+#define RID_OFFICEFILTER_MACTYPE (RID_SFX_DOC_START+ 61)
+#define RID_OFFICEFILTER_OS2TYPE (RID_SFX_DOC_START+ 62)
+#define STR_FRAMEOBJECT_PROPERTIES (RID_SFX_DOC_START+ 63)
+
+#define STR_FSET_FILTERNAME0 (RID_SFX_DOC_START+ 64)
+#define STR_FSET_FILTERNAME1 (RID_SFX_DOC_START+ 65)
+
+#define STR_TEMPL_MOVED (RID_SFX_DOC_START+ 66)
+#define STR_TEMPL_RESET (RID_SFX_DOC_START+ 67)
+#define STR_AUTOMATICVERSION (RID_SFX_DOC_START+ 68)
+
+#define STR_DOCTYPENAME_SW (RID_SFX_DOC_START+ 69)
+#define STR_DOCTYPENAME_SWWEB (RID_SFX_DOC_START+ 70)
+#define STR_DOCTYPENAME_SWGLOB (RID_SFX_DOC_START+ 71)
+#define STR_DOCTYPENAME_SC (RID_SFX_DOC_START+ 72)
+#define STR_DOCTYPENAME_SI (RID_SFX_DOC_START+ 73)
+#define STR_DOCTYPENAME_SD (RID_SFX_DOC_START+ 74)
+#define STR_DOCTYPENAME_MESSAGE (RID_SFX_DOC_START+ 75)
+#define RID_STR_NEW_TASK (RID_SFX_DOC_START+ 76)
+
+#define STR_SAVEANDCLOSE (RID_SFX_DOC_START+ 77)
+#define STR_NOSAVEANDCLOSE (RID_SFX_DOC_START+ 78)
+#define STR_PACKNGO_NOACCESS (RID_SFX_DOC_START+ 79)
+#define STR_PACKNGO_NEWMEDIUM (RID_SFX_DOC_START+ 80)
+
+#define TEMPLATE_LONG_NAMES_ARY (RID_SFX_DOC_START+ 81)
+#define TEMPLATE_SHORT_NAMES_ARY (RID_SFX_DOC_START+ 82)
+#define RID_CNT_STR_WAITING (RID_SFX_DOC_START+ 83)
+
+#define STR_OBJECT (RID_SFX_DOC_START+ 84)
+#define STR_EDITOBJECT (RID_SFX_DOC_START+ 85)
+// --> PB 2004-08-20 #i33095#
+/* obsolete
+#define STR_OPENOBJECT (RID_SFX_DOC_START+ 86)
+*/
+
+#define DLOAD_URL 1
+#define DLOAD_STATUS 2
+#define DLOAD_NAME 3
+#define DLOAD_TEXT 4
+#define DLOAD_CANCEL 1
+
+#define DLG_MACROQUERY (RID_SFX_DOC_START+87)
+#define BTN_OK (RID_SFX_DOC_START+88)
+#define BTN_CANCEL (RID_SFX_DOC_START+89)
+#define FT_OK (RID_SFX_DOC_START+90)
+#define FT_CANCEL (RID_SFX_DOC_START+91)
+
+#define STR_EXPORTASPDF_TITLE (RID_SFX_DOC_START+92)
+#define STR_EXPORTBUTTON (RID_SFX_DOC_START+93)
+#define STR_EXPORTWITHCFGBUTTON (RID_SFX_DOC_START+94)
+
+#define RID_SVXSTR_SECURITY_ADDPATH (RID_SFX_DOC_START+95)
+
+#define STR_LABEL_FILEFORMAT (RID_SFX_DOC_START+96)
+
+// some icons are commented out since they are removed
+#define BMP_SIGNATURE (RID_SFX_DOC_START+97)
+// #define BMP_128X128_BASE_DOC (RID_SFX_DOC_START+98)
+#define BMP_128X128_CALC_DOC (RID_SFX_DOC_START+99)
+// #define BMP_128X128_CALC_TEMP (RID_SFX_DOC_START+100)
+#define BMP_128X128_CHART_DOC (RID_SFX_DOC_START+101)
+#define BMP_128X128_DRAW_DOC (RID_SFX_DOC_START+102)
+// #define BMP_128X128_DRAW_TEMP (RID_SFX_DOC_START+103)
+#define BMP_128X128_IMPRESS_DOC (RID_SFX_DOC_START+104)
+// #define BMP_128X128_IMPRESS_TEMP (RID_SFX_DOC_START+105)
+// #define BMP_128X128_MASTER_DOC (RID_SFX_DOC_START+106)
+#define BMP_128X128_MATH_DOC (RID_SFX_DOC_START+107)
+#define BMP_128X128_WRITER_DOC (RID_SFX_DOC_START+108)
+// #define BMP_128X128_WRITER_TEMP (RID_SFX_DOC_START+109)
+
+#define STR_HIDDENINFO_CONTAINS (RID_SFX_DOC_START+110)
+#define STR_HIDDENINFO_RECORDCHANGES (RID_SFX_DOC_START+111)
+#define STR_HIDDENINFO_NOTES (RID_SFX_DOC_START+112)
+#define STR_HIDDENINFO_DOCVERSIONS (RID_SFX_DOC_START+113)
+#define STR_HIDDENINFO_FIELDS (RID_SFX_DOC_START+114)
+#define STR_HIDDENINFO_LINKDATA (RID_SFX_DOC_START+115)
+#define STR_HIDDENINFO_CONTINUE_SAVING (RID_SFX_DOC_START+116)
+#define STR_HIDDENINFO_CONTINUE_PRINTING (RID_SFX_DOC_START+117)
+#define STR_HIDDENINFO_CONTINUE_SIGNING (RID_SFX_DOC_START+118)
+#define STR_HIDDENINFO_CONTINUE_CREATEPDF (RID_SFX_DOC_START+119)
+
+// #define MSG_WARNING_MACRO_ISDISABLED (RID_SFX_DOC_START+120)
+#define STR_NEW_FILENAME_SAVE (RID_SFX_DOC_START+121)
+// #define STR_MACROS_DISABLED (RID_SFX_DOC_START+122)
+#define STR_ERROR_DELETE_TEMPLATE_DIR (RID_SFX_DOC_START+123)
+#define STR_DOCINFO_INFOFIELD (RID_SFX_DOC_START+124)
+
+#define MSG_XMLSEC_QUERY_SAVESIGNEDBEFORESIGN (RID_SFX_DOC_START+125)
+#define STR_XMLSEC_ODF12_EXPECTED (RID_SFX_DOC_START+126)
+
+#define STR_QRYTEMPL_MESSAGE (RID_SFX_DOC_START+127)
+#define STR_QRYTEMPL_UPDATE_BTN (RID_SFX_DOC_START+128)
+#define STR_QRYTEMPL_KEEP_BTN (RID_SFX_DOC_START+129)
+
+// please update to the last id
+#define ACT_SFX_DOC_END STR_QRYTEMPL_KEEP_BTN
+#if ACT_SFX_DOC_END > RID_SFX_DOC_END
+#error resource overflow in #line, #file
+#endif
+
+#endif
+
diff --git a/sfx2/source/doc/doc.src b/sfx2/source/doc/doc.src
new file mode 100644
index 000000000000..d17b62c9b52a
--- /dev/null
+++ b/sfx2/source/doc/doc.src
@@ -0,0 +1,536 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <sfx2/sfx.hrc>
+#include "doc.hrc"
+#define __RSC
+#include <svl/inetdef.hxx>
+//#include <so3/so2defs.hxx>
+
+ // -----------------------------------------------------------------------
+QueryBox MSG_CONFIRM_FILTER
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_YES ;
+ Message [ en-US ] = "Saving in external formats may have caused\n information loss. Do you still want to close?" ;
+};
+QueryBox MSG_CONFIRM_OVERWRITE_TEMPLATE
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_NO ;
+ Message [ en-US ] = "Name already in use.\nDo you want to overwrite document template?" ;
+};
+QueryBox MSG_QUERY_LOAD_TEMPLATE
+{
+ BUTTONS = WB_YES_NO ;
+ DEFBUTTON = WB_DEF_NO ;
+ HelpId = MSG_QUERY_LOAD_TEMPLATE;
+
+ Message [ en-US ] = "The Styles in this document do not match your current Styles. Should your current Styles be applied to this document?";
+};
+String STR_DELETE_REGION
+{
+ Text [ en-US ] = "Are you sure you want to delete the region \"$1\"?" ;
+};
+String STR_DELETE_TEMPLATE
+{
+ Text [ en-US ] = "Are you sure you want to delete the entry \"$1\"?" ;
+};
+QueryBox MSG_REGION_NOTEMPTY
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_NO ;
+ Message [ en-US ] = "The category is not empty.\nDelete anyway?" ;
+};
+String STR_QUERY_SAVE_DOCUMENT
+{
+ Text [ en-US ] = "The document \"$(DOC)\" has been modified.\nDo you want to save your changes?" ;
+};
+Bitmap BMP_STYLES_CLOSED { File = "newex.bmp" ; };
+Bitmap BMP_STYLES_OPENED { File = "newex.bmp" ; };
+
+Bitmap BMP_STYLES_CLOSED_HC { File = "newex_h.bmp" ; };
+Bitmap BMP_STYLES_OPENED_HC { File = "newex_h.bmp" ; };
+
+String STR_STYLES
+{
+ Text [ en-US ] = "Styles" ;
+};
+String STR_MACROS
+{
+ Text [ en-US ] = "Macros" ;
+};
+String STR_CONFIG
+{
+ Text [ en-US ] = "Configuration" ;
+};
+String STR_PRINT_STYLES_HEADER
+{
+ Text [ en-US ] = "Styles in " ;
+};
+String STR_PRINT_STYLES
+{
+ Text [ en-US ] = "Printing Styles" ;
+};
+Bitmap BMP_STYLES_FAMILY1 { File = "styfam1.bmp" ; };
+Bitmap BMP_STYLES_FAMILY2 { File = "styfam2.bmp" ; };
+Bitmap BMP_STYLES_FAMILY3 { File = "styfam3.bmp" ; };
+Bitmap BMP_STYLES_FAMILY4 { File = "styfam4.bmp" ; };
+
+Bitmap BMP_STYLES_FAMILY1_HC { File = "styfam1_h.bmp" ; };
+Bitmap BMP_STYLES_FAMILY2_HC { File = "styfam2_h.bmp" ; };
+Bitmap BMP_STYLES_FAMILY3_HC { File = "styfam3_h.bmp" ; };
+Bitmap BMP_STYLES_FAMILY4_HC { File = "styfam4_h.bmp" ; };
+
+ErrorBox MSG_PRINT_ERROR
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+ Message [ en-US ] = "The print job could not be started." ;
+};
+String STR_BACKUP_COPY
+{
+ Text [ en-US ] = "Copy" ;
+};
+InfoBox MSG_CANT_OPEN_TEMPLATE
+{
+ Message [ en-US ] = "The template could not be opened." ;
+};
+InfoBox MSG_VIEW_OPEN_CANT_SAVE
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+ Message [ en-US ] = "Document already open for editing." ;
+};
+String STR_ERROR_SAVE
+{
+ Text [ en-US ] = "Error recording document " ;
+};
+String STR_TEMPLATE_FILTER
+{
+ Text [ en-US ] = "Templates" ;
+};
+String STR_ERROR_COPY_TEMPLATE
+{
+ Text [ en-US ] = "Error copying template \"$1\". \nA template with this name may already exist." ;
+};
+String STR_ERROR_DELETE_TEMPLATE
+{
+ Text [ en-US ] = "The template \"$1\" can not be deleted." ;
+};
+String STR_ERROR_MOVE_TEMPLATE
+{
+ Text [ en-US ] = "Error moving template \"$1\"." ;
+};
+ErrorBox MSG_ERROR_RESCAN
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+ Message [ en-US ] = "The update could not be saved." ;
+};
+String STR_ERROR_SAVE_TEMPLATE
+{
+ Text [ en-US ] = "Error saving template " ;
+};
+ErrorBox MSG_ERROR_RENAME_TEMPLATE
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+ Message [ en-US ] = "Error renaming template." ;
+};
+ErrorBox MSG_ERROR_RENAME_TEMPLATE_REGION
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+ Message [ en-US ] = "Error renaming template category." ;
+};
+ErrorBox MSG_ERROR_EMPTY_NAME
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+ Message [ en-US ] = "Please specify a name." ;
+};
+ErrorBox MSG_ERROR_UNIQ_NAME
+{
+ BUTTONS = WB_OK ;
+ DEFBUTTON = WB_DEF_OK ;
+ Message [ en-US ] = "Please specify a unique name.\nEntries must not be case specific." ;
+};
+String STR_QUERY_DEFAULT_TEMPLATE
+{
+ Text [ en-US ] = "Should the template \"$(TEXT)\" become the default template?" ;
+};
+QueryBox MSG_QUERY_RESET_DEFAULT_TEMPLATE
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_NO ;
+ Message [ en-US ] = "Do you want to reset the default template?" ;
+};
+InfoBox MSG_TEMPLATE_DIR_NOT_EXIST
+{
+ Message [ en-US ] = "Template directory\n$(DIR)\ndoes not exist." ;
+};
+InfoBox MSG_DOCINFO_CANTREAD
+{
+ Message [ en-US ] = "Document info cannot be read." ;
+};
+String STR_ERROR_NOSTORAGE
+{
+ /* ### ACHTUNG: Neuer Text in Resource? Die ausgew�hlte Datei besitzt ein falsches Format. : Die ausgew�hlte Datei besitzt ein falsches Format. */
+ /* ### ACHTUNG: Neuer Text in Resource? Die ausgew�hlte Datei besitzt ein falsches Format. : Die ausgew�hlte Datei besitzt ein falsches Format. */
+ Text [ en-US ] = "The selected file has an incorrect format." ;
+};
+String STR_QUERY_MUSTOWNFORMAT
+{
+ Text [ en-US ] = "Documents cannot be saved in $(FORMAT) format. Do you\nwant to save your changes using the $(OWNFORMAT) format?" ;
+};
+String STR_SAVEDOC
+{
+ Text [ en-US ] = "~Save" ;
+};
+String STR_UPDATEDOC
+{
+ Text [ en-US ] = "~Update" ;
+};
+String STR_SAVEASDOC
+{
+ Text [ en-US ] = "Save ~As..." ;
+};
+String STR_SAVECOPYDOC
+{
+ Text [ en-US ] = "Save Copy ~as..." ;
+};
+String STR_CLOSEDOC
+{
+ Text [ en-US ] = "~Close" ;
+};
+String STR_CLOSEDOC_ANDRETURN
+{
+ /* ### ACHTUNG: Neuer Text in Resource? S~chlie�en & zur�ck zu : S~chlie�en & zur�ck zu */
+ /* ### ACHTUNG: Neuer Text in Resource? S~chlie�en & zur�ck zu : S~chlie�en & zur�ck zu */
+ Text [ en-US ] = "~Close & Return to " ;
+};
+String STR_WIZARD
+{
+ Text [ en-US ] = " AutoPilot" ;
+};
+String RID_STR_FILTCONFIG
+{
+ Text [ en-US ] = "Configurations" ;
+};
+String RID_STR_FILTBASIC
+{
+ Text [ en-US ] = "%PRODUCTNAME Basic libraries" ;
+};
+String RID_STR_WARNSTYLEOVERWRITE
+{
+ Text [ en-US ] = "Should the \"$(ARG1)\" Style be replaced?" ;
+};
+String STR_DOC_LOADING
+{
+ Text [ en-US ] = "Loading Document" ;
+};
+Resource RID_DLSTATUS
+{
+ String INET_NAME_RESOLVE_START
+ {
+ Text [ en-US ] = "Connection to: $(HOST). Waiting for response..." ;
+ };
+ String INET_CONNECT_START
+ {
+ Text [ en-US ] = "Opening $(TARGET) at $(HOST)" ;
+ };
+ String INET_READ_STATUS
+ {
+ Text [ en-US ] = "Loading: $(TARGET) from $(HOST). Loaded: $(BYTE)" ;
+ };
+ String INET_CONNECTION_CLOSED
+ {
+ Text [ en-US ] = "Disconnected" ;
+ };
+};
+QueryBox MSG_OPEN_READONLY
+{
+ BUTTONS = WB_YES_NO ;
+ DEFBUTTON = WB_DEF_YES ;
+ Message [ en-US ] = "Document cannot be opened for editing.\nDo you want to open it as read-only?" ;
+};
+String STR_EDIT
+{
+ Text [ en-US ] = "Edit" ;
+};
+String RID_OFFICEFILTER
+{
+ Text [ en-US ] = "%PRODUCTNAME Documents" ;
+};
+String RID_OFFICEFILTER_WILDCARD
+{
+ Text = "*.sdw;*.sdd;*.sda;*.sdc;*.smf;*.sds;*.sd;*.sdm;*.smd" ;
+};
+String RID_OFFICEFILTER_MACTYPE
+{
+ Text = "SVsd0;SW/\2510;SVsc0;SVsm0;SVsh0;SVsd1;SW/\2511;SVsc1;SVsm1;SVsh1;MAIL" ;
+};
+String RID_OFFICEFILTER_OS2TYPE
+{
+ Text = "StarWriter 4.0;StarWriter 3.0;StarDraw 4.0;StarDraw 3.0;StarCalc 4.0;StarCalc 3.0;StarMath 4.0;StarMath 3.0;StarChart 4.0;StarChart 3.0;StarFrameSet;StarMessage" ;
+};
+String STR_FRAMEOBJECT_PROPERTIES
+{
+ Text [ en-US ] = "Propert~ies..." ;
+};
+String STR_FSET_FILTERNAME0
+{
+ Text [ en-US ] = "HTML (FrameSet)" ;
+};
+String STR_FSET_FILTERNAME1
+{
+ // nur 'Dokument' "ubersetzen - only translate 'Document'
+ Text [ en-US ] = "%PRODUCTNAME Frame Document" ;
+};
+String STR_TEMPL_MOVED
+{
+ Text [ en-US ] = "The template \"$(TEMPLATE)\" was not found at the original location. A template with the same name exists at \"$(FOUND)\". Should this template be used in the future when comparing?" ;
+};
+String STR_TEMPL_RESET
+{
+ Text [ en-US ] = "The template \"$(TEMPLATE)\" has not been found. Should the template be looked for the next time the document is opened ?" ;
+};
+String STR_AUTOMATICVERSION
+{
+ Text [ en-US ] = "Automatically saved version" ;
+};
+
+String STR_DOCTYPENAME_SW
+{
+ Text [ en-US ] = "Text Document";
+};
+
+String STR_DOCTYPENAME_SWWEB
+{
+ Text [ en-US ] = "HTML Document";
+};
+
+String STR_DOCTYPENAME_SWGLOB
+{
+ Text [ en-US ] = "Master Document";
+};
+
+String STR_DOCTYPENAME_SC
+{
+ Text [ en-US ] = "Spreadsheet";
+};
+
+String STR_DOCTYPENAME_SI
+{
+ Text [ en-US ] = "Presentation";
+};
+
+String STR_DOCTYPENAME_SD
+{
+ Text [ en-US ] = "Drawing";
+};
+
+String STR_DOCTYPENAME_MESSAGE
+{
+ Text [ en-US ] = "Message";
+};
+
+String STR_NOSAVEANDCLOSE
+{
+ Text [ en-US ] = "~Discard" ;
+};
+
+String STR_PACKNGO_NOACCESS
+{
+ Text [ en-US ] = "Access to the current data medium not possible." ;
+};
+
+String STR_PACKNGO_NEWMEDIUM
+{
+ Text [ en-US ] = "Insert the next data carrier and click OK." ;
+};
+
+String STR_OBJECT
+{
+ Text [ en-US ] = "Object" ;
+};
+
+String STR_EDITOBJECT
+{
+ Text [ en-US ] = "~Edit";
+};
+
+// --> PB 2004-08-20 #i33095#
+/* obsolete
+String STR_OPENOBJECT
+{
+ Text [ en-US ] = "~Open";
+};
+*/
+
+QueryBox DLG_MACROQUERY
+{
+ Buttons = WB_OK_CANCEL;
+ Title [ en-US ] = "Run Macro" ;
+
+ Message [ en-US ] = "This document contains macros. $(TEXT)";
+};
+
+String BTN_OK
+{
+ Text [ en-US ] = "Run" ;
+};
+String BTN_CANCEL
+{
+ Text [ en-US ] = "Do Not Run" ;
+};
+String FT_CANCEL
+{
+ Text [ en-US ] = "According to the security settings, the macros in this document should not be run. Do you want to run them anyway?";
+};
+String FT_OK
+{
+ Text [ en-US ] = "Do you want to allow these macros to be run?";
+};
+
+String STR_EXPORTASPDF_TITLE
+{
+ Text [ en-US ] = "Export as PDF";
+};
+
+String STR_EXPORTWITHCFGBUTTON
+{
+ Text [ en-US ] = "Export...";
+};
+
+String STR_EXPORTBUTTON
+{
+ Text [ en-US ] = "Export" ;
+};
+
+String RID_SVXSTR_SECURITY_ADDPATH
+{
+ Text [ en-US ] = "Add this directory to the list of secure paths: " ;
+};
+
+String STR_LABEL_FILEFORMAT
+{
+ Text [ en-US ] = "File format:" ;
+};
+
+String STR_HIDDENINFO_CONTAINS
+{
+ Text [ en-US ] = "This document contains:\n\n" ;
+};
+String STR_HIDDENINFO_RECORDCHANGES
+{
+ Text [ en-US ] = "Recorded changes" ;
+};
+String STR_HIDDENINFO_NOTES
+{
+ Text [ en-US ] = "Notes" ;
+};
+String STR_HIDDENINFO_DOCVERSIONS
+{
+ Text [ en-US ] = "Document versions" ;
+};
+String STR_HIDDENINFO_FIELDS
+{
+ Text [ en-US ] = "Fields" ;
+};
+String STR_HIDDENINFO_LINKDATA
+{
+ Text [ en-US ] = "Linked data..." ;
+};
+String STR_HIDDENINFO_CONTINUE_SAVING
+{
+ Text [ en-US ] = "Do you want to continue saving the document?" ;
+};
+String STR_HIDDENINFO_CONTINUE_PRINTING
+{
+ Text [ en-US ] = "Do you want to continue printing the document?" ;
+};
+String STR_HIDDENINFO_CONTINUE_SIGNING
+{
+ Text [ en-US ] = "Do you want to continue signing the document?" ;
+};
+String STR_HIDDENINFO_CONTINUE_CREATEPDF
+{
+ Text [ en-US ] = "Do you want to continue creating a PDF file?" ;
+};
+
+String STR_NEW_FILENAME_SAVE
+{
+ Text [ en-US ] = "If you do not want to overwrite the original document, you should save your work under a new filename." ;
+};
+
+String STR_ERROR_DELETE_TEMPLATE_DIR
+{
+ Text [ en-US ] = "Some template files are protected and can not be deleted.";
+};
+
+String STR_DOCINFO_INFOFIELD
+{
+ Text [ en-US ] = "Info %1";
+ Text [ x-comment ] = "pb: %1 == a number [1-4]";
+};
+
+String STR_SHARED
+{
+ Text [ en-US ] = " (shared)";
+ Text [ x-comment ] = "Used in the title of a shared document.";
+};
+
+String STR_XMLSEC_ODF12_EXPECTED
+{
+ Text [ en-US ] = "The document format version is set to ODF 1.1 (OpenOffice.org 2.x) in Tools-Options-Load/Save-General. Signing documents requires ODF 1.2 (OpenOffice.org 3.x).";
+};
+
+QueryBox MSG_XMLSEC_QUERY_SAVESIGNEDBEFORESIGN
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_YES ;
+ Message [ en-US ] = "The document has to be saved before it can be signed. Saving the document removes all present signatures.\nDo you want to save the document?";
+};
+
+String STR_QRYTEMPL_MESSAGE
+{
+ Text [ en-US ] = "The template '$(ARG1)' on which this document is based, has been modified. Do you want to update style based formattings according to the modified template?";
+};
+
+String STR_QRYTEMPL_UPDATE_BTN
+{
+ Text [ en-US ] = "~Update Styles";
+};
+
+String STR_QRYTEMPL_KEEP_BTN
+{
+ Text [ en-US ] = "~Keep Old Styles";
+};
+
+// ******************************************************************* EOF
+
diff --git a/sfx2/source/doc/docfac.cxx b/sfx2/source/doc/docfac.cxx
new file mode 100644
index 000000000000..bfd67210ec44
--- /dev/null
+++ b/sfx2/source/doc/docfac.cxx
@@ -0,0 +1,474 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <com/sun/star/registry/MergeConflictException.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/frame/XLoadable.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <comphelper/processfactory.hxx>
+#include <tools/config.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/configurationhelper.hxx>
+
+#include <sfx2/sfx.hrc>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfac.hxx>
+#include "viewfac.hxx"
+#include "fltfnc.hxx"
+#include "arrdecl.hxx"
+#include <sfx2/app.hxx>
+#include <sfx2/module.hxx>
+#include <sfx2/mnumgr.hxx>
+#include "sfxresid.hxx"
+#include <sfx2/sfxuno.hxx>
+#include "syspath.hxx"
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include "doc.hrc"
+
+#include <assert.h>
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star;
+
+//========================================================================
+
+DECL_PTRARRAY( SfxViewFactoryArr_Impl, SfxViewFactory*, 2, 2 )
+
+//========================================================================
+
+DBG_NAME(SfxObjectFactory)
+
+//static SfxObjectFactoryArr_Impl* pObjFac = 0;
+
+//========================================================================
+
+struct SfxObjectFactory_Impl
+{
+ SfxViewFactoryArr_Impl aViewFactoryArr;// Liste von <SfxViewFactory>s
+ SfxFilterArr_Impl aFilterArr; // Liste von <SFxFilter>n
+ ResId* pNameResId;
+ ::rtl::OUString aServiceName;
+ SfxFilterContainer* pFilterContainer;
+ SfxModule* pModule;
+ sal_uInt16 nImageId;
+ String aStandardTemplate;
+ sal_Bool bTemplateInitialized;
+ SvGlobalName aClassName;
+
+ SfxObjectFactory_Impl() :
+ pNameResId ( NULL ),
+ pFilterContainer ( NULL ),
+ pModule ( NULL ),
+ nImageId ( 0 ),
+ bTemplateInitialized( sal_False )
+ {}
+};
+
+//========================================================================
+
+SfxFilterContainer* SfxObjectFactory::GetFilterContainer( sal_Bool /*bForceLoad*/ ) const
+{
+ return pImpl->pFilterContainer;
+}
+
+//--------------------------------------------------------------------
+
+SfxObjectFactory::SfxObjectFactory
+(
+ const SvGlobalName& rName,
+ SfxObjectShellFlags nFlagsP,
+ const char* pName
+) : pShortName( pName ),
+ pImpl( new SfxObjectFactory_Impl ),
+ nFlags( nFlagsP )
+{
+ DBG_CTOR(SfxObjectFactory, 0);
+ pImpl->pFilterContainer = new SfxFilterContainer( String::CreateFromAscii( pName ) );
+
+ String aShortName( String::CreateFromAscii( pShortName ) );
+ aShortName.ToLowerAscii();
+ pImpl->aClassName = rName;
+ if ( aShortName.EqualsAscii( "swriter" ) )
+ pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SW );
+ else if ( aShortName.EqualsAscii( "swriter/web" ) )
+ pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SWWEB );
+ else if ( aShortName.EqualsAscii( "swriter/globaldocument" ) )
+ pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SWGLOB );
+ else if ( aShortName.EqualsAscii( "scalc" ) )
+ pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SC );
+ else if ( aShortName.EqualsAscii( "simpress" ) )
+ pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SI );
+ else if ( aShortName.EqualsAscii( "sdraw" ) )
+ pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SD );
+ else if ( aShortName.EqualsAscii( "message" ) )
+ pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_MESSAGE );
+}
+
+//--------------------------------------------------------------------
+
+SfxObjectFactory::~SfxObjectFactory()
+{
+ DBG_DTOR(SfxObjectFactory, 0);
+
+ const sal_uInt16 nCount = pImpl->aFilterArr.Count();
+ for ( sal_uInt16 i = 0; i < nCount; ++i )
+ delete pImpl->aFilterArr[i];
+ delete pImpl->pNameResId;
+ delete pImpl;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectFactory::RegisterViewFactory
+(
+ SfxViewFactory &rFactory
+)
+{
+ sal_uInt16 nPos;
+ for ( nPos = 0;
+ nPos < pImpl->aViewFactoryArr.Count() &&
+ pImpl->aViewFactoryArr[nPos]->GetOrdinal() <= rFactory.GetOrdinal();
+ ++nPos )
+ /* empty loop */;
+ pImpl->aViewFactoryArr.Insert(nPos, &rFactory);
+}
+
+//--------------------------------------------------------------------
+
+sal_uInt16 SfxObjectFactory::GetViewFactoryCount() const
+{
+ return pImpl->aViewFactoryArr.Count();
+}
+
+//--------------------------------------------------------------------
+
+SfxViewFactory& SfxObjectFactory::GetViewFactory(sal_uInt16 i) const
+{
+ return *pImpl->aViewFactoryArr[i];
+}
+
+//--------------------------------------------------------------------
+
+SfxModule* SfxObjectFactory::GetModule() const
+{
+ return pImpl->pModule;
+}
+
+void SfxObjectFactory::SetModule_Impl( SfxModule *pMod )
+{
+ pImpl->pModule = pMod;
+}
+
+void SfxObjectFactory::SetSystemTemplate( const String& rServiceName, const String& rTemplateName )
+{
+ static const int nMaxPathSize = 16000;
+ static ::rtl::OUString SERVICE_FILTER_FACTORY = ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" );
+ static ::rtl::OUString SERVICE_TYPE_DECTECTION = ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" );
+ static ::rtl::OUString SERVICE_SIMPLE_ACCESS = ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" );
+
+ static ::rtl::OUString CONF_ROOT = ::rtl::OUString::createFromAscii( "/org.openoffice.Setup");
+ static ::rtl::OUString CONF_PATH = ::rtl::OUString::createFromAscii( "Office/Factories/" ) + ::rtl::OUString( rServiceName );
+ static ::rtl::OUString PROP_DEF_TEMPL_CHANGED = ::rtl::OUString::createFromAscii( "ooSetupFactorySystemDefaultTemplateChanged" );
+ static ::rtl::OUString PROP_ACTUAL_FILTER = ::rtl::OUString::createFromAscii( "ooSetupFactoryActualFilter" );
+
+ static ::rtl::OUString DEF_TPL_STR = ::rtl::OUString::createFromAscii("/soffice.");
+
+ String sURL;
+ String sPath;
+ sal_Unicode aPathBuffer[nMaxPathSize];
+ if ( SystemPath::GetUserTemplateLocation( aPathBuffer, nMaxPathSize ))
+ sPath = String( aPathBuffer );
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPath, sURL );
+
+ ::rtl::OUString aUserTemplateURL( sURL );
+ if ( aUserTemplateURL.getLength() != 0)
+ {
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ uno::Reference< uno::XInterface > xConfig = ::comphelper::ConfigurationHelper::openConfig(
+ xFactory, CONF_ROOT, ::comphelper::ConfigurationHelper::E_STANDARD );
+
+ ::rtl::OUString aActualFilter;
+ ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, CONF_PATH, PROP_ACTUAL_FILTER ) >>= aActualFilter;
+ sal_Bool bChanged(sal_False);
+ ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED ) >>= bChanged;
+
+ uno::Reference< container::XNameAccess > xFilterFactory(
+ xFactory->createInstance( SERVICE_FILTER_FACTORY ), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xTypeDetection(
+ xFactory->createInstance( SERVICE_TYPE_DECTECTION ), uno::UNO_QUERY_THROW );
+
+ ::rtl::OUString aActualFilterTypeName;
+ uno::Sequence< beans::PropertyValue > aActuralFilterData;
+ xFilterFactory->getByName( aActualFilter ) >>= aActuralFilterData;
+ for ( sal_Int32 nInd = 0; nInd < aActuralFilterData.getLength(); nInd++ )
+ if ( aActuralFilterData[nInd].Name.equalsAscii( "Type" ) )
+ aActuralFilterData[nInd].Value >>= aActualFilterTypeName;
+ ::comphelper::SequenceAsHashMap aProps1( xTypeDetection->getByName( aActualFilterTypeName ) );
+ uno::Sequence< ::rtl::OUString > aAllExt =
+ aProps1.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Extensions" ), uno::Sequence< ::rtl::OUString >() );
+ //To-do: check if aAllExt is empty first
+ ::rtl::OUString aExt = aAllExt[0];
+
+ aUserTemplateURL += DEF_TPL_STR;
+ aUserTemplateURL += aExt;
+
+ uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
+ xFactory->createInstance( SERVICE_SIMPLE_ACCESS ), uno::UNO_QUERY_THROW );
+
+ ::rtl::OUString aBackupURL;
+ ::osl::Security().getConfigDir(aBackupURL);
+ aBackupURL += ::rtl::OUString::createFromAscii( "/temp" );
+
+ if ( !xSimpleFileAccess->exists( aBackupURL ) )
+ xSimpleFileAccess->createFolder( aBackupURL );
+
+ aBackupURL += DEF_TPL_STR;
+ aBackupURL += aExt;
+
+ if ( rTemplateName.Len() != 0 )
+ {
+ if ( xSimpleFileAccess->exists( aUserTemplateURL ) && !bChanged )
+ xSimpleFileAccess->copy( aUserTemplateURL, aBackupURL );
+
+ uno::Reference< document::XTypeDetection > xTypeDetector( xTypeDetection, uno::UNO_QUERY );
+ ::comphelper::SequenceAsHashMap aProps2( xTypeDetection->getByName( xTypeDetector->queryTypeByURL( rTemplateName ) ) );
+ ::rtl::OUString aFilterName =
+ aProps2.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii("PreferredFilter"), ::rtl::OUString() );
+
+ uno::Sequence< beans::PropertyValue > aArgs( 3 );
+ aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
+ aArgs[0].Value <<= aFilterName;
+ aArgs[1].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
+ aArgs[1].Value <<= sal_True;
+ aArgs[2].Name = ::rtl::OUString::createFromAscii( "URL" );
+ aArgs[2].Value <<= ::rtl::OUString( rTemplateName );
+
+ uno::Reference< frame::XLoadable > xLoadable( xFactory->createInstance( ::rtl::OUString( rServiceName ) ), uno::UNO_QUERY );
+ xLoadable->load( aArgs );
+
+ aArgs.realloc( 2 );
+ aArgs[1].Name = ::rtl::OUString::createFromAscii( "Overwrite" );
+ aArgs[1].Value <<= sal_True;
+
+ uno::Reference< frame::XStorable > xStorable( xLoadable, uno::UNO_QUERY );
+ xStorable->storeToURL( aUserTemplateURL, aArgs );
+ ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED, uno::makeAny( sal_True ));
+ ::comphelper::ConfigurationHelper::flush( xConfig );
+ }
+ else
+ {
+ DBG_ASSERT( bChanged, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" );
+
+ xSimpleFileAccess->copy( aBackupURL, aUserTemplateURL );
+ xSimpleFileAccess->kill( aBackupURL );
+ ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED, uno::makeAny( sal_False ));
+ ::comphelper::ConfigurationHelper::flush( xConfig );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+}
+
+void SfxObjectFactory::SetStandardTemplate( const String& rServiceName, const String& rTemplate )
+{
+ SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
+ if (eFac == SvtModuleOptions::E_UNKNOWN_FACTORY)
+ eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
+ if (eFac != SvtModuleOptions::E_UNKNOWN_FACTORY)
+ {
+ SetSystemTemplate( rServiceName, rTemplate );
+ SvtModuleOptions().SetFactoryStandardTemplate(eFac, rTemplate);
+ }
+}
+
+String SfxObjectFactory::GetStandardTemplate( const String& rServiceName )
+{
+ SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
+ if (eFac == SvtModuleOptions::E_UNKNOWN_FACTORY)
+ eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
+
+ String sTemplate;
+ if (eFac != SvtModuleOptions::E_UNKNOWN_FACTORY)
+ sTemplate = SvtModuleOptions().GetFactoryStandardTemplate(eFac);
+
+ return sTemplate;
+}
+
+/*
+const SfxObjectFactory* SfxObjectFactory::GetFactory( const String& rFactoryURL )
+{
+ const SfxObjectFactory* pFactory = 0;
+ String aFact( rFactoryURL );
+ String aPrefix( DEFINE_CONST_UNICODE( "private:factory/" ) );
+ if ( aPrefix.Len() == aFact.Match( aPrefix ) )
+ // Aufruf m"oglich mit z.B. "swriter" oder "private:factory/swriter"
+ aFact.Erase( 0, aPrefix.Len() );
+ sal_uInt16 nPos = aFact.Search( '?' );
+
+ // Etwaige Parameter abschneiden
+ aFact.Erase( nPos, aFact.Len() );
+
+ SfxApplication *pApp = SFX_APP();
+
+ // "swriter4" durch "swriter" ersetzen, zum Vergleichen uppercase verwenden
+ WildCard aSearchedFac( aFact.EraseAllChars('4').ToUpperAscii() );
+ for( sal_uInt16 n = GetObjectFactoryCount_Impl(); !pFactory && n--; )
+ {
+ pFactory = &GetObjectFactory_Impl( n );
+ String aCompareTo = String::CreateFromAscii( pFactory->GetShortName() );
+ aCompareTo.ToUpperAscii();
+ if( !aSearchedFac.Matches( aCompareTo ) )
+ pFactory = 0;
+ }
+
+ return pFactory;
+}
+*/
+
+const SfxFilter* SfxObjectFactory::GetTemplateFilter() const
+{
+ USHORT nVersion=0;
+ SfxFilterMatcher aMatcher ( String::CreateFromAscii( pShortName ) );
+ SfxFilterMatcherIter aIter( &aMatcher );
+ const SfxFilter *pFilter = 0;
+ const SfxFilter *pTemp = aIter.First();
+ while ( pTemp )
+ {
+ if( pTemp->IsOwnFormat() && pTemp->IsOwnTemplateFormat() && ( pTemp->GetVersion() > nVersion ) )
+ {
+ pFilter = pTemp;
+ nVersion = (USHORT) pTemp->GetVersion();
+ }
+
+ pTemp = aIter.Next();
+ }
+
+ return pFilter;
+}
+
+void SfxObjectFactory::SetDocumentTypeNameResource( const ResId& rId )
+{
+ DBG_ASSERT( !pImpl->pNameResId, "UI-Namensresource mehrfach gesetzt!" );
+ pImpl->pNameResId = new ResId( rId );
+}
+
+String SfxObjectFactory::GetDocumentTypeName() const
+{
+ if ( pImpl->pNameResId )
+ return String( *pImpl->pNameResId );
+ return String();
+}
+
+void SfxObjectFactory::SetDocumentServiceName( const ::rtl::OUString& rServiceName )
+{
+ pImpl->aServiceName = rServiceName;
+}
+
+const ::rtl::OUString& SfxObjectFactory::GetDocumentServiceName() const
+{
+ return pImpl->aServiceName;
+}
+
+const SvGlobalName& SfxObjectFactory::GetClassId() const
+{
+ return pImpl->aClassName;
+}
+
+String SfxObjectFactory::GetFactoryURL() const
+{
+ ::rtl::OUStringBuffer aURLComposer;
+ aURLComposer.appendAscii( "private:factory/" );
+ aURLComposer.appendAscii( GetShortName() );
+ return aURLComposer.makeStringAndClear();
+}
+
+String SfxObjectFactory::GetModuleName() const
+{
+ static ::rtl::OUString SERVICENAME_MODULEMANAGER = ::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager");
+ static ::rtl::OUString PROP_MODULEUINAME = ::rtl::OUString::createFromAscii("ooSetupFactoryUIName");
+
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ css::uno::Reference< css::container::XNameAccess > xModuleManager(
+ xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
+ css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sDocService(GetDocumentServiceName());
+ ::comphelper::SequenceAsHashMap aPropSet( xModuleManager->getByName(sDocService) );
+ ::rtl::OUString sModuleName = aPropSet.getUnpackedValueOrDefault(PROP_MODULEUINAME, ::rtl::OUString());
+ return String(sModuleName);
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+
+ return String();
+}
+
+
+sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const sal_uInt16 i_nViewId, const sal_uInt16 i_nFallback ) const
+{
+ for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo )
+ {
+ const sal_uInt16 curViewId = GetViewFactory( curViewNo ).GetOrdinal();
+ if ( i_nViewId == curViewId )
+ return curViewNo;
+ }
+ return i_nFallback;
+}
+
+SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( const String& i_rViewName ) const
+{
+ for ( USHORT nViewNo = 0;
+ nViewNo < GetViewFactoryCount();
+ ++nViewNo
+ )
+ {
+ SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) );
+ if ( rViewFac.GetViewName() == i_rViewName )
+ return &rViewFac;
+ }
+ return NULL;
+}
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
new file mode 100644
index 000000000000..1dea202e0d0e
--- /dev/null
+++ b/sfx2/source/doc/docfile.cxx
@@ -0,0 +1,3978 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <sfx2/docfile.hxx>
+#include "sfx2/signaturestate.hxx"
+
+#include <uno/mapping.hxx>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
+#include <com/sun/star/document/LockedDocumentRequest.hpp>
+#include <com/sun/star/document/OwnLockOnDocumentRequest.hpp>
+#include <com/sun/star/document/LockedOnSavingRequest.hpp>
+#include <com/sun/star/document/LockFileIgnoreRequest.hpp>
+#include <com/sun/star/document/ChangedByOthersRequest.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/UseBackupException.hpp>
+#include <com/sun/star/embed/XOptimizedStorage.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/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/util/XArchiver.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/io/XStreamListener.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/logging/XSimpleLogRing.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#ifndef _COM_SUN_STAR_SECURITY_DOCUMENTSIGNATURESINFORMATION_HPP_
+#include <com/sun/star/security/DocumentSignatureInformation.hpp>
+#endif
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+#include <tools/zcodec.hxx>
+#include <tools/cachestr.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/tempfile.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <framework/interaction.hxx>
+#include <unotools/streamhelper.hxx>
+#include <unotools/localedatawrapper.hxx>
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/lckbitem.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svl/itemset.hxx>
+#include <svl/intitem.hxx>
+#include <svtools/svparser.hxx> // SvKeyValue
+#include <cppuhelper/weakref.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+#define _SVSTDARR_ULONGS
+#define _SVSTDARR_STRINGSDTOR
+#include <svl/svstdarr.hxx>
+
+#include <unotools/streamwrap.hxx>
+
+#include <rtl/logfile.hxx>
+#include <osl/file.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/configurationhelper.hxx>
+#include <comphelper/docpasswordhelper.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/inetmime.hxx>
+#include <unotools/ucblockbytes.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/asynclink.hxx>
+#include <svl/inettype.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/progresshandlerwrap.hxx>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/interactionrequest.hxx>
+#include <sot/stg.hxx>
+#include <unotools/saveopt.hxx>
+#include <svl/documentlockfile.hxx>
+
+#include "helper.hxx"
+#include <sfx2/request.hxx> // SFX_ITEMSET_SET
+#include <sfx2/app.hxx> // GetFilterMatcher
+#include <sfx2/frame.hxx> // LoadTargetFrame
+#include "fltfnc.hxx" // SfxFilterMatcher
+#include <sfx2/docfilt.hxx> // SfxFilter
+#include <sfx2/objsh.hxx> // CheckOpenMode
+#include <sfx2/docfac.hxx> // GetFilterContainer
+#include "doc.hrc"
+#include "openflag.hxx" // SFX_STREAM_READONLY etc.
+#include "sfxresid.hxx"
+#include <sfx2/appuno.hxx>
+
+//#include "xmlversion.hxx"
+
+#define MAX_REDIRECT 5
+
+
+sal_Bool IsReadonlyAccordingACL( const sal_Unicode* pFilePath );
+
+//==========================================================
+namespace {
+
+static const sal_Int8 LOCK_UI_NOLOCK = 0;
+static const sal_Int8 LOCK_UI_SUCCEEDED = 1;
+static const sal_Int8 LOCK_UI_TRY = 2;
+
+//----------------------------------------------------------------
+sal_Bool IsSystemFileLockingUsed()
+{
+ // check whether system file locking has been used, the default value is false
+ sal_Bool bUseSystemLock = sal_False;
+ try
+ {
+
+ uno::Reference< 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 uno::RuntimeException();
+
+ ::comphelper::ConfigurationHelper::readRelativeKey(
+ xCommonConfig,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentSystemFileLocking" ) ) ) >>= bUseSystemLock;
+ }
+ catch( const uno::Exception& )
+ {
+ }
+
+ return bUseSystemLock;
+}
+
+//----------------------------------------------------------------
+sal_Bool IsOOoLockFileUsed()
+{
+ // check whether system file locking has been used, the default value is false
+ sal_Bool bOOoLockFileUsed = sal_False;
+ try
+ {
+
+ uno::Reference< 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 uno::RuntimeException();
+
+ ::comphelper::ConfigurationHelper::readRelativeKey(
+ xCommonConfig,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentOOoLockFile" ) ) ) >>= bOOoLockFileUsed;
+ }
+ catch( const uno::Exception& )
+ {
+ }
+
+ return bOOoLockFileUsed;
+}
+
+} // anonymous namespace
+//==========================================================
+
+
+//----------------------------------------------------------------
+class SfxMediumHandler_Impl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler >
+{
+ com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter;
+
+public:
+ virtual void SAL_CALL handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest )
+ throw( com::sun::star::uno::RuntimeException );
+
+ SfxMediumHandler_Impl( com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteraction )
+ : m_xInter( xInteraction )
+ {}
+
+ ~SfxMediumHandler_Impl();
+};
+
+//----------------------------------------------------------------
+SfxMediumHandler_Impl::~SfxMediumHandler_Impl()
+{
+}
+
+//----------------------------------------------------------------
+void SAL_CALL SfxMediumHandler_Impl::handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ if( !m_xInter.is() )
+ return;
+
+ com::sun::star::uno::Any aRequest = xRequest->getRequest();
+ com::sun::star::ucb::InteractiveIOException aIoException;
+ com::sun::star::ucb::UnsupportedDataSinkException aSinkException;
+ if ( (aRequest >>= aIoException) && ( aIoException.Code == IOErrorCode_ACCESS_DENIED || aIoException.Code == IOErrorCode_LOCKING_VIOLATION ) )
+ return;
+ else
+ if ( aRequest >>= aSinkException )
+ return;
+ else
+ m_xInter->handle( xRequest );
+}
+
+//----------------------------------------------------------------
+class SfxMedium_Impl : public SvCompatWeakBase
+{
+public:
+ ::ucbhelper::Content aContent;
+ sal_Bool bUpdatePickList : 1;
+ sal_Bool bIsTemp : 1;
+ sal_Bool bForceSynchron : 1;
+ sal_Bool bDownloadDone : 1;
+ sal_Bool bDontCallDoneLinkOnSharingError : 1;
+ sal_Bool bIsStorage: 1;
+ sal_Bool bUseInteractionHandler: 1;
+ sal_Bool bAllowDefaultIntHdl: 1;
+ sal_Bool bIsCharsetInitialized: 1;
+ sal_Bool bDisposeStorage: 1;
+ sal_Bool bStorageBasedOnInStream: 1;
+ sal_Bool m_bSalvageMode: 1;
+ sal_Bool m_bVersionsAlreadyLoaded: 1;
+ sal_Bool m_bLocked: 1;
+ sal_Bool m_bGotDateTime: 1;
+
+ uno::Reference < embed::XStorage > xStorage;
+
+ SfxMedium* pAntiImpl;
+
+ long nFileVersion;
+
+ const SfxFilter* pOrigFilter;
+ String aOrigURL;
+ String aPreRedirectionURL;
+ String aReferer;
+ DateTime aExpireTime;
+ SfxFrameWeak wLoadTargetFrame;
+ SvKeyValueIteratorRef xAttributes;
+
+ svtools::AsynchronLink aDoneLink;
+ svtools::AsynchronLink aAvailableLink;
+
+ uno::Sequence < util::RevisionTag > aVersions;
+
+ ::utl::TempFile* pTempFile;
+
+ uno::Reference < embed::XStorage > m_xZipStorage;
+ Reference < XInputStream > xInputStream;
+ Reference < XStream > xStream;
+
+ uno::Reference< io::XStream > m_xLockingStream;
+
+ sal_uInt32 nLastStorageError;
+ ::rtl::OUString aCharset;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > xInteraction;
+
+ sal_Bool m_bRemoveBackup;
+ ::rtl::OUString m_aBackupURL;
+
+ // the following member is changed and makes sence only during saving
+ // TODO/LATER: in future the signature state should be controlled by the medium not by the document
+ // in this case the member will hold this information
+ sal_uInt16 m_nSignatureState;
+
+ util::DateTime m_aDateTime;
+
+ uno::Reference< logging::XSimpleLogRing > m_xLogRing;
+
+ SfxMedium_Impl( SfxMedium* pAntiImplP );
+ ~SfxMedium_Impl();
+};
+
+void SfxMedium::DataAvailable_Impl()
+{
+ pImp->aAvailableLink.ClearPendingCall();
+ pImp->aAvailableLink.Call( NULL );
+}
+
+void SfxMedium::Cancel_Impl()
+{
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+}
+
+//------------------------------------------------------------------
+SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP )
+ : SvCompatWeakBase( pAntiImplP ),
+ bUpdatePickList(sal_True),
+ bIsTemp( sal_False ),
+ bForceSynchron( sal_False ),
+ bDownloadDone( sal_True ),
+ bDontCallDoneLinkOnSharingError( sal_False ),
+ bIsStorage( sal_False ),
+ bUseInteractionHandler( sal_True ),
+ bAllowDefaultIntHdl( sal_False ),
+ bIsCharsetInitialized( sal_False ),
+ bStorageBasedOnInStream( sal_False ),
+ m_bSalvageMode( sal_False ),
+ m_bVersionsAlreadyLoaded( sal_False ),
+ m_bLocked( sal_False ),
+ m_bGotDateTime( sal_False ),
+ pAntiImpl( pAntiImplP ),
+ nFileVersion( 0 ),
+ pOrigFilter( 0 ),
+ aExpireTime( Date() + 10, Time() ),
+ pTempFile( NULL ),
+ nLastStorageError( 0 ),
+ m_bRemoveBackup( sal_False ),
+ m_nSignatureState( SIGNATURESTATE_NOSIGNATURES )
+{
+ aDoneLink.CreateMutex();
+}
+
+//------------------------------------------------------------------
+SfxMedium_Impl::~SfxMedium_Impl()
+{
+
+ aDoneLink.ClearPendingCall();
+ aAvailableLink.ClearPendingCall();
+
+ if ( pTempFile )
+ delete pTempFile;
+}
+
+//================================================================
+
+#define IMPL_CTOR(rootVal,URLVal) \
+ eError( SVSTREAM_OK ), \
+ \
+ bDirect( sal_False ), \
+ bRoot( rootVal ), \
+ bSetFilter( sal_False ), \
+ bTriedStorage( sal_False ), \
+ \
+ nStorOpenMode( SFX_STREAM_READWRITE ), \
+ pURLObj( URLVal ), \
+ pInStream(0), \
+ pOutStream( 0 )
+
+//------------------------------------------------------------------
+void SfxMedium::ResetError()
+{
+ eError = SVSTREAM_OK;
+ if( pInStream )
+ pInStream->ResetError();
+ if( pOutStream )
+ pOutStream->ResetError();
+}
+
+//------------------------------------------------------------------
+sal_uInt32 SfxMedium::GetLastStorageCreationState()
+{
+ return pImp->nLastStorageError;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::AddLog( const ::rtl::OUString& aMessage )
+{
+ if ( !pImp->m_xLogRing.is() )
+ {
+ try
+ {
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ if ( aContext.is() )
+ pImp->m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if ( pImp->m_xLogRing.is() )
+ pImp->m_xLogRing->logString( aMessage );
+}
+
+//------------------------------------------------------------------
+void SfxMedium::SetError( sal_uInt32 nError, const ::rtl::OUString& aLogMessage )
+{
+ eError = nError;
+ if ( eError != ERRCODE_NONE && aLogMessage.getLength() )
+ AddLog( aLogMessage );
+}
+
+//------------------------------------------------------------------
+sal_uInt32 SfxMedium::GetErrorCode() const
+{
+ sal_uInt32 lError=eError;
+ if(!lError && pInStream)
+ lError=pInStream->GetErrorCode();
+ if(!lError && pOutStream)
+ lError=pOutStream->GetErrorCode();
+ return lError;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::CheckFileDate( const util::DateTime& aInitDate )
+{
+ GetInitFileDate( sal_True );
+ if ( pImp->m_aDateTime.Seconds != aInitDate.Seconds
+ || pImp->m_aDateTime.Minutes != aInitDate.Minutes
+ || pImp->m_aDateTime.Hours != aInitDate.Hours
+ || pImp->m_aDateTime.Day != aInitDate.Day
+ || pImp->m_aDateTime.Month != aInitDate.Month
+ || pImp->m_aDateTime.Year != aInitDate.Year )
+ {
+ uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
+
+ if ( xHandler.is() )
+ {
+ try
+ {
+ ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
+ document::ChangedByOthersRequest() ) );
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 );
+ aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() );
+ aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() );
+ xInteractionRequestImpl->setContinuations( aContinuations );
+
+ xHandler->handle( xInteractionRequestImpl.get() );
+
+ ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection();
+ if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() )
+ {
+ SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ catch ( uno::Exception& )
+ {}
+ }
+ }
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::DocNeedsFileDateCheck()
+{
+ return ( !IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) );
+}
+
+//------------------------------------------------------------------
+util::DateTime SfxMedium::GetInitFileDate( sal_Bool bIgnoreOldValue )
+{
+ if ( ( bIgnoreOldValue || !pImp->m_bGotDateTime ) && aLogicName.Len() )
+ {
+ try
+ {
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
+ ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
+
+ aContent.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "DateModified" )) ) >>= pImp->m_aDateTime;
+ pImp->m_bGotDateTime = sal_True;
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ return pImp->m_aDateTime;
+}
+
+//------------------------------------------------------------------
+Reference < XContent > SfxMedium::GetContent() const
+{
+ if ( !pImp->aContent.get().is() )
+ {
+ Reference < ::com::sun::star::ucb::XContent > xContent;
+ Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
+
+ SFX_ITEMSET_ARG( pSet, pItem, SfxUnoAnyItem, SID_CONTENT, sal_False);
+ if ( pItem )
+ pItem->GetValue() >>= xContent;
+
+ if ( xContent.is() )
+ {
+ try
+ {
+ pImp->aContent = ::ucbhelper::Content( xContent, xEnv );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ else
+ {
+ // TODO: DBG_ERROR("SfxMedium::GetContent()\nCreate Content? This code exists as fallback only. Please clarify, why its used.");
+ String aURL;
+ if ( aName.Len() )
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL );
+ else if ( aLogicName.Len() )
+ aURL = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
+ if ( aURL.Len() )
+ ::ucbhelper::Content::create( aURL, xEnv, pImp->aContent );
+ }
+ }
+
+ return pImp->aContent.get();
+}
+
+//------------------------------------------------------------------
+::rtl::OUString SfxMedium::GetBaseURL( bool bForSaving )
+{
+ ::rtl::OUString aBaseURL;
+ const SfxStringItem* pBaseURLItem = static_cast<const SfxStringItem*>( GetItemSet()->GetItem(SID_DOC_BASEURL) );
+ if ( pBaseURLItem )
+ aBaseURL = pBaseURLItem->GetValue();
+ else if ( GetContent().is() )
+ {
+ try
+ {
+ Any aAny = pImp->aContent.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI" )) );
+ aAny >>= aBaseURL;
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ if ( !aBaseURL.getLength() )
+ aBaseURL = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ if ( bForSaving )
+ {
+ SvtSaveOptions aOpt;
+ sal_Bool bIsRemote = IsRemote();
+ if( (bIsRemote && !aOpt.IsSaveRelINet()) || (!bRemote && !aOpt.IsSaveRelFSys()) )
+ return ::rtl::OUString();
+ }
+
+ return aBaseURL;
+}
+
+//------------------------------------------------------------------
+SvStream* SfxMedium::GetInStream()
+{
+ if ( pInStream )
+ return pInStream;
+
+ if ( pImp->pTempFile )
+ {
+ pInStream = new SvFileStream( aName, nStorOpenMode );
+
+ eError = pInStream->GetError();
+
+ if( !eError && (nStorOpenMode & STREAM_WRITE)
+ && ! pInStream->IsWritable() )
+ {
+ eError = ERRCODE_IO_ACCESSDENIED;
+ delete pInStream;
+ pInStream = NULL;
+ }
+ else
+ return pInStream;
+ }
+
+ GetMedium_Impl();
+
+ if ( GetError() )
+ return NULL;
+
+ return pInStream;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::CloseInStream()
+{
+ CloseInStream_Impl();
+}
+
+void SfxMedium::CloseInStream_Impl()
+{
+ // if there is a storage based on the InStream, we have to
+ // close the storage, too, because otherwise the storage
+ // would use an invalid ( deleted ) stream.
+ if ( pInStream && pImp->xStorage.is() )
+ {
+ if ( pImp->bStorageBasedOnInStream )
+ CloseStorage();
+ }
+
+ if ( pInStream && !GetContent().is() )
+ {
+ CreateTempFile( sal_True );
+ return;
+ }
+
+ DELETEZ( pInStream );
+ if ( pSet )
+ pSet->ClearItem( SID_INPUTSTREAM );
+
+ CloseZipStorage_Impl();
+ pImp->xInputStream = uno::Reference< io::XInputStream >();
+
+ if ( !pOutStream )
+ {
+ // output part of the stream is not used so the whole stream can be closed
+ // TODO/LATER: is it correct?
+ pImp->xStream = uno::Reference< io::XStream >();
+ if ( pSet )
+ pSet->ClearItem( SID_STREAM );
+ }
+}
+
+//------------------------------------------------------------------
+SvStream* SfxMedium::GetOutStream()
+{
+ if ( !pOutStream )
+ {
+ // Create a temp. file if there is none because we always
+ // need one.
+ CreateTempFile( sal_False );
+
+ if ( pImp->pTempFile )
+ {
+ pOutStream = new SvFileStream( aName, STREAM_STD_READWRITE );
+ CloseStorage();
+ }
+ }
+
+ return pOutStream;
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::CloseOutStream()
+{
+ CloseOutStream_Impl();
+ return sal_True;
+}
+
+sal_Bool SfxMedium::CloseOutStream_Impl()
+{
+ if ( pOutStream )
+ {
+ // if there is a storage based on the OutStream, we have to
+ // close the storage, too, because otherwise the storage
+ // would use an invalid ( deleted ) stream.
+ //TODO/MBA: how to deal with this?!
+ //maybe we need a new flag when the storage was created from the outstream
+ if ( pImp->xStorage.is() )
+ {
+ //const SvStream *pStorage = aStorage->GetSvStream();
+ //if ( pStorage == pOutStream )
+ CloseStorage();
+ }
+
+ delete pOutStream;
+ pOutStream = NULL;
+ }
+
+ if ( !pInStream )
+ {
+ // input part of the stream is not used so the whole stream can be closed
+ // TODO/LATER: is it correct?
+ pImp->xStream = uno::Reference< io::XStream >();
+ if ( pSet )
+ pSet->ClearItem( SID_STREAM );
+ }
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------
+const String& SfxMedium::GetPhysicalName() const
+{
+ if ( !aName.Len() && aLogicName.Len() )
+ (( SfxMedium*)this)->CreateFileStream();
+
+ // return the name then
+ return aName;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::CreateFileStream()
+{
+ ForceSynchronStream_Impl( TRUE );
+ GetInStream();
+ if( pInStream )
+ {
+ CreateTempFile( sal_False );
+ pImp->bIsTemp = sal_True;
+ CloseInStream_Impl();
+ }
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::Commit()
+{
+ if( pImp->xStorage.is() )
+ StorageCommit_Impl();
+ else if( pOutStream )
+ pOutStream->Flush();
+ else if( pInStream )
+ pInStream->Flush();
+
+ if ( GetError() == SVSTREAM_OK )
+ {
+ // does something only in case there is a temporary file ( means aName points to different location than aLogicName )
+ Transfer_Impl();
+ }
+
+ sal_Bool bResult = ( GetError() == SVSTREAM_OK );
+
+ if ( bResult && DocNeedsFileDateCheck() )
+ GetInitFileDate( sal_True );
+
+ // remove truncation mode from the flags
+ nStorOpenMode &= (~STREAM_TRUNC);
+ return bResult;
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::IsStorage()
+{
+ if ( pImp->xStorage.is() )
+ return TRUE;
+
+ if ( bTriedStorage )
+ return pImp->bIsStorage;
+
+ if ( pImp->pTempFile )
+ {
+ String aURL;
+ if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL ) )
+ {
+ DBG_ERROR("Physical name not convertable!");
+ }
+ pImp->bIsStorage = SotStorage::IsStorageFile( aURL ) && !SotStorage::IsOLEStorage( aURL);
+ if ( !pImp->bIsStorage )
+ bTriedStorage = TRUE;
+ }
+ else if ( GetInStream() )
+ {
+ pImp->bIsStorage = SotStorage::IsStorageFile( pInStream ) && !SotStorage::IsOLEStorage( pInStream );
+ if ( !pInStream->GetError() && !pImp->bIsStorage )
+ bTriedStorage = TRUE;
+ }
+
+ return pImp->bIsStorage;
+}
+
+//------------------------------------------------------------------
+Link SfxMedium::GetDataAvailableLink() const
+{
+ return pImp->aAvailableLink.GetLink();
+}
+
+//------------------------------------------------------------------
+Link SfxMedium::GetDoneLink() const
+{
+ return pImp->aDoneLink.GetLink();
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::IsPreview_Impl()
+{
+ sal_Bool bPreview = sal_False;
+ SFX_ITEMSET_ARG( GetItemSet(), pPreview, SfxBoolItem, SID_PREVIEW, sal_False);
+ if ( pPreview )
+ bPreview = pPreview->GetValue();
+ else
+ {
+ SFX_ITEMSET_ARG( GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, sal_False);
+ if ( pFlags )
+ {
+ String aFileFlags = pFlags->GetValue();
+ aFileFlags.ToUpperAscii();
+ if ( STRING_NOTFOUND != aFileFlags.Search( 'B' ) )
+ bPreview = sal_True;
+ }
+ }
+
+ return bPreview;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::StorageBackup_Impl()
+{
+ ::ucbhelper::Content aOriginalContent;
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
+
+ sal_Bool bBasedOnOriginalFile = ( !pImp->pTempFile && !( aLogicName.Len() && pImp->m_bSalvageMode )
+ && GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).getLength()
+ && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
+ && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) );
+
+ if ( bBasedOnOriginalFile && !pImp->m_aBackupURL.getLength()
+ && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, aOriginalContent ) )
+ {
+ DoInternalBackup_Impl( aOriginalContent );
+ if( !pImp->m_aBackupURL.getLength() )
+ SetError( ERRCODE_SFX_CANTCREATEBACKUP, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+}
+
+//------------------------------------------------------------------
+::rtl::OUString SfxMedium::GetBackup_Impl()
+{
+ if ( !pImp->m_aBackupURL.getLength() )
+ StorageBackup_Impl();
+
+ return pImp->m_aBackupURL;
+}
+
+//------------------------------------------------------------------
+uno::Reference < embed::XStorage > SfxMedium::GetOutputStorage()
+{
+ if ( GetError() )
+ return uno::Reference< embed::XStorage >();
+
+ // if the medium was constructed with a Storage: use this one, not a temp. storage
+ // if a temporary storage already exists: use it
+ if ( pImp->xStorage.is() && ( !aLogicName.Len() || pImp->pTempFile ) )
+ return pImp->xStorage;
+
+ // if necessary close stream that was used for reading
+ if ( pInStream && !pInStream->IsWritable() )
+ CloseInStream();
+
+ DBG_ASSERT( !pOutStream, "OutStream in a readonly Medium?!" );
+
+ // TODO/LATER: The current solution is to store the document temporary and then copy it to the target location;
+ // in future it should be stored directly and then copied to the temporary location, since in this case no
+ // file attributes have to be preserved and system copying mechanics could be used instead of streaming.
+ CreateTempFileNoCopy();
+
+ return GetStorage();
+}
+
+//------------------------------------------------------------------
+void SfxMedium::SetPasswordToStorage_Impl()
+{
+ // in case media-descriptor contains password it should be used on opening
+ if ( pImp->xStorage.is() && pSet )
+ {
+ ::rtl::OUString aPasswd;
+ if ( GetPasswd_Impl( pSet, aPasswd ) )
+ {
+ try
+ {
+ ::comphelper::OStorageHelper::SetCommonStoragePassword( pImp->xStorage, aPasswd );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "It must be possible to set a common password for the storage" );
+ // TODO/LATER: set the error code in case of problem
+ // SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------
+sal_Int8 SfxMedium::ShowLockedDocumentDialog( const uno::Sequence< ::rtl::OUString >& aData, sal_Bool bIsLoading, sal_Bool bOwnLock )
+{
+ sal_Int8 nResult = LOCK_UI_NOLOCK;
+
+ // show the interaction regarding the document opening
+ uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
+
+ if ( ::svt::DocumentLockFile::IsInteractionAllowed() && xHandler.is() && ( bIsLoading || bOwnLock ) )
+ {
+ ::rtl::OUString aDocumentURL = GetURLObject().GetLastName();
+ ::rtl::OUString aInfo;
+ ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl;
+
+ if ( bOwnLock )
+ {
+ if ( aData.getLength() > LOCKFILE_EDITTIME_ID )
+ aInfo = aData[LOCKFILE_EDITTIME_ID];
+
+ xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
+ document::OwnLockOnDocumentRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo, !bIsLoading ) ) );
+ }
+ else
+ {
+ if ( aData.getLength() > LOCKFILE_EDITTIME_ID )
+ {
+ if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() )
+ aInfo = aData[LOCKFILE_OOOUSERNAME_ID];
+ else
+ aInfo = aData[LOCKFILE_SYSUSERNAME_ID];
+
+ if ( aInfo.getLength() && aData[LOCKFILE_EDITTIME_ID].getLength() )
+ {
+ aInfo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " ( " ) );
+ aInfo += aData[LOCKFILE_EDITTIME_ID];
+ aInfo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " )" ) );
+ }
+ }
+
+ if ( bIsLoading )
+ {
+ xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
+ document::LockedDocumentRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) );
+ }
+ else
+ {
+ xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
+ document::LockedOnSavingRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) );
+
+ }
+ }
+
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 );
+ aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() );
+ aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() );
+ aContinuations[2] = new ::ucbhelper::InteractionDisapprove( xInteractionRequestImpl.get() );
+ xInteractionRequestImpl->setContinuations( aContinuations );
+
+ xHandler->handle( xInteractionRequestImpl.get() );
+
+ ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection();
+ if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() )
+ {
+ SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ else if ( uno::Reference< task::XInteractionDisapprove >( xSelected.get(), uno::UNO_QUERY ).is() )
+ {
+ // own lock on loading, user has selected to ignore the lock
+ // own lock on saving, user has selected to ignore the lock
+ // alien lock on loading, user has selected to edit a copy of document
+ // TODO/LATER: alien lock on saving, user has selected to do SaveAs to different location
+ if ( bIsLoading && !bOwnLock )
+ {
+ // means that a copy of the document should be opened
+ GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) );
+ }
+ else if ( bOwnLock )
+ nResult = LOCK_UI_SUCCEEDED;
+ }
+ else // if ( XSelected == aContinuations[1] )
+ {
+ // own lock on loading, user has selected to open readonly
+ // own lock on saving, user has selected to open readonly
+ // alien lock on loading, user has selected to retry saving
+ // TODO/LATER: alien lock on saving, user has selected to retry saving
+
+ if ( bIsLoading )
+ GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
+ else
+ nResult = LOCK_UI_TRY;
+ }
+ }
+ else
+ {
+ if ( bIsLoading )
+ {
+ // if no interaction handler is provided the default answer is open readonly
+ // that usually happens in case the document is loaded per API
+ // so the document must be opened readonly for backward compatibility
+ GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
+ }
+ else
+ SetError( ERRCODE_IO_ACCESSDENIED, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ }
+
+ return nResult;
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI )
+{
+ // returns true if the document can be opened for editing ( even if it should be a copy )
+ // otherwise the document should be opened readonly
+ // if user cancel the loading the ERROR_ABORT is set
+
+ if ( pImp->m_bLocked && bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
+ {
+ // if the document is already locked the system locking might be temporarely off after storing
+ // check whether the system file locking should be taken again
+ GetLockingStream_Impl();
+ }
+
+ sal_Bool bResult = pImp->m_bLocked;
+
+ if ( !bResult )
+ {
+ // no read-write access is necessary on loading if the document is explicitly opened as copy
+ SFX_ITEMSET_ARG( GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
+ bResult = ( bLoading && pTemplateItem && pTemplateItem->GetValue() );
+ }
+
+ if ( !bResult && !IsReadOnly() )
+ {
+ sal_Bool bContentReadonly = sal_False;
+ if ( bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
+ {
+ // let the original document be opened to check the possibility to open it for editing
+ // and to let the writable stream stay open to hold the lock on the document
+ GetLockingStream_Impl();
+ }
+
+ // "IsReadOnly" property does not allow to detect whether the file is readonly always
+ // so we try always to open the file for editing
+ // the file is readonly only in case the read-write stream can not be opened
+ if ( bLoading && !pImp->m_xLockingStream.is() )
+ {
+ try
+ {
+ // MediaDescriptor does this check also, the duplication should be avoided in future
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
+ ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
+ aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bContentReadonly;
+ }
+ catch( uno::Exception )
+ {}
+
+ if ( !bContentReadonly )
+ {
+ // the file is not readonly, check the ACL
+
+ String aPhysPath;
+ if ( ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), aPhysPath ) )
+ bContentReadonly = IsReadonlyAccordingACL( aPhysPath.GetBuffer() );
+ }
+ }
+
+ // do further checks only if the file not readonly in fs
+ if ( !bContentReadonly )
+ {
+ // the special file locking should be used only for file URLs
+ if ( ::utl::LocalFileHelper::IsLocalFile( aLogicName ) )
+ {
+
+ // in case of storing the document should request the output before locking
+ if ( bLoading )
+ {
+ // let the stream be opened to check the system file locking
+ GetMedium_Impl();
+ }
+
+ sal_Int8 bUIStatus = LOCK_UI_NOLOCK;
+
+ // check whether system file locking has been used, the default value is false
+ sal_Bool bUseSystemLock = IsSystemFileLockingUsed();
+
+ // TODO/LATER: This implementation does not allow to detect the system lock on saving here, actually this is no big problem
+ // if system lock is used the writeable stream should be available
+ sal_Bool bHandleSysLocked = ( bLoading && bUseSystemLock && !pImp->xStream.is() && !pOutStream );
+
+ do
+ {
+ try
+ {
+ ::svt::DocumentLockFile aLockFile( aLogicName );
+ if ( !bHandleSysLocked )
+ {
+ try
+ {
+ bResult = aLockFile.CreateOwnLockFile();
+ }
+ catch ( ucb::InteractiveIOException& e )
+ {
+ // exception means that the lock file can not be successfuly accessed
+ // in this case it should be ignored if system file locking is anyway active
+ if ( bUseSystemLock || !IsOOoLockFileUsed() )
+ {
+ bResult = sal_True;
+ // take the ownership over the lock file
+ aLockFile.OverwriteOwnLockFile();
+ }
+ else if ( e.Code == IOErrorCode_INVALID_PARAMETER )
+ {
+ // system file locking is not active, ask user whether he wants to open the document without any locking
+ uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
+
+ if ( xHandler.is() )
+ {
+ ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl
+ = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) );
+
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 2 );
+ aContinuations[0] = new ::ucbhelper::InteractionAbort( xIgnoreRequestImpl.get() );
+ aContinuations[1] = new ::ucbhelper::InteractionApprove( xIgnoreRequestImpl.get() );
+ xIgnoreRequestImpl->setContinuations( aContinuations );
+
+ xHandler->handle( xIgnoreRequestImpl.get() );
+
+ ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xIgnoreRequestImpl->getSelection();
+ bResult = ( uno::Reference< task::XInteractionApprove >( xSelected.get(), uno::UNO_QUERY ).is() );
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ // exception means that the lock file can not be successfuly accessed
+ // in this case it should be ignored if system file locking is anyway active
+ if ( bUseSystemLock || !IsOOoLockFileUsed() )
+ {
+ bResult = sal_True;
+ // take the ownership over the lock file
+ aLockFile.OverwriteOwnLockFile();
+ }
+ }
+
+ // in case OOo locking is turned off the lock file is still written if possible
+ // but it is ignored while deciding whether the document should be opened for editing or not
+ if ( !bResult && !IsOOoLockFileUsed() )
+ {
+ bResult = sal_True;
+ // take the ownership over the lock file
+ aLockFile.OverwriteOwnLockFile();
+ }
+ }
+
+
+ if ( !bResult )
+ {
+ uno::Sequence< ::rtl::OUString > aData;
+ try
+ {
+ // impossibility to get data is no real problem
+ aData = aLockFile.GetLockData();
+ }
+ catch( uno::Exception ) {}
+
+ sal_Bool bOwnLock = sal_False;
+
+ if ( !bHandleSysLocked )
+ {
+ uno::Sequence< ::rtl::OUString > aOwnData = aLockFile.GenerateOwnEntry();
+ bOwnLock = ( aData.getLength() > LOCKFILE_USERURL_ID
+ && aOwnData.getLength() > LOCKFILE_USERURL_ID
+ && aOwnData[LOCKFILE_SYSUSERNAME_ID].equals( aData[LOCKFILE_SYSUSERNAME_ID] ) );
+
+ if ( bOwnLock
+ && aOwnData[LOCKFILE_LOCALHOST_ID].equals( aData[LOCKFILE_LOCALHOST_ID] )
+ && aOwnData[LOCKFILE_USERURL_ID].equals( aData[LOCKFILE_USERURL_ID] ) )
+ {
+ // this is own lock from the same installation, it could remain because of crash
+ bResult = sal_True;
+ }
+ }
+
+ if ( !bResult && !bNoUI )
+ {
+ bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock );
+ if ( bUIStatus == LOCK_UI_SUCCEEDED )
+ {
+ // take the ownership over the lock file
+ bResult = aLockFile.OverwriteOwnLockFile();
+ }
+ }
+
+ bHandleSysLocked = sal_False;
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ } while( !bResult && bUIStatus == LOCK_UI_TRY );
+
+ pImp->m_bLocked = bResult;
+ }
+ else
+ {
+ // this is no file URL, check whether the file is readonly
+ bResult = !bContentReadonly;
+ }
+ }
+ }
+
+ if ( !bResult && GetError() == ERRCODE_NONE )
+ {
+ // the error should be set in case it is storing process
+ // or the document has been opened for editing explicitly
+
+ SFX_ITEMSET_ARG( pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, FALSE );
+ if ( !bLoading || (pReadOnlyItem && !pReadOnlyItem->GetValue()) )
+ SetError( ERRCODE_IO_ACCESSDENIED, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ else
+ GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
+ }
+
+ // when the file is locked, get the current file date
+ if ( bResult && DocNeedsFileDateCheck() )
+ GetInitFileDate( sal_True );
+
+ return bResult;
+}
+
+//------------------------------------------------------------------
+uno::Reference < embed::XStorage > SfxMedium::GetStorage( sal_Bool bCreateTempIfNo )
+{
+ if ( pImp->xStorage.is() || bTriedStorage )
+ return pImp->xStorage;
+
+ uno::Sequence< uno::Any > aArgs( 2 );
+
+ // the medium should be retrieved before temporary file creation
+ // to let the MediaDescriptor be filled with the streams
+ GetMedium_Impl();
+
+ if ( bCreateTempIfNo )
+ CreateTempFile( sal_False );
+
+ GetMedium_Impl();
+
+ if ( GetError() )
+ return pImp->xStorage;
+
+ SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False);
+ if ( pRepairItem && pRepairItem->GetValue() )
+ {
+ // the storage should be created for repairing mode
+ CreateTempFile( sal_False );
+ GetMedium_Impl();
+
+ Reference< ::com::sun::star::ucb::XProgressHandler > xProgressHandler;
+ Reference< ::com::sun::star::task::XStatusIndicator > xStatusIndicator;
+
+ SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False );
+ if( pxProgressItem && ( pxProgressItem->GetValue() >>= xStatusIndicator ) )
+ xProgressHandler = Reference< ::com::sun::star::ucb::XProgressHandler >(
+ new utl::ProgressHandlerWrap( xStatusIndicator ) );
+
+ uno::Sequence< beans::PropertyValue > aAddProps( 2 );
+ aAddProps[0].Name = ::rtl::OUString::createFromAscii( "RepairPackage" );
+ aAddProps[0].Value <<= (sal_Bool)sal_True;
+ aAddProps[1].Name = ::rtl::OUString::createFromAscii( "StatusIndicator" );
+ aAddProps[1].Value <<= xProgressHandler;
+
+ // the first arguments will be filled later
+ aArgs.realloc( 3 );
+ aArgs[2] <<= aAddProps;
+ }
+
+ if ( pImp->xStream.is() )
+ {
+ // since the storage is based on temporary stream we open it always read-write
+ aArgs[0] <<= pImp->xStream;
+ aArgs[1] <<= embed::ElementModes::READWRITE;
+ pImp->bStorageBasedOnInStream = sal_True;
+ }
+ else if ( pImp->xInputStream.is() )
+ {
+ // since the storage is based on temporary stream we open it always read-write
+ aArgs[0] <<= pImp->xInputStream;
+ aArgs[1] <<= embed::ElementModes::READ;
+ pImp->bStorageBasedOnInStream = sal_True;
+ }
+ else
+ {
+ CloseStreams_Impl();
+ aArgs[0] <<= ::rtl::OUString( aName );
+ aArgs[1] <<= embed::ElementModes::READ;
+ pImp->bStorageBasedOnInStream = sal_False;
+ }
+
+ try
+ {
+ pImp->xStorage = uno::Reference< embed::XStorage >(
+ ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ),
+ uno::UNO_QUERY );
+ }
+ catch( uno::Exception& )
+ {
+ // impossibility to create the storage is no error
+ }
+
+ if( ( pImp->nLastStorageError = GetError() ) != SVSTREAM_OK )
+ {
+ pImp->xStorage = 0;
+ if ( pInStream )
+ pInStream->Seek(0);
+ return uno::Reference< embed::XStorage >();
+ }
+
+ bTriedStorage = sal_True;
+
+ // TODO/LATER: Get versionlist on demand
+ if ( pImp->xStorage.is() )
+ {
+ SetPasswordToStorage_Impl();
+ GetVersionList();
+ }
+
+ SFX_ITEMSET_ARG( pSet, pVersion, SfxInt16Item, SID_VERSION, sal_False);
+
+ BOOL bResetStorage = FALSE;
+ if ( pVersion && pVersion->GetValue() )
+ {
+ // Alle verf"ugbaren Versionen einlesen
+ if ( pImp->aVersions.getLength() )
+ {
+ // Die zum Kommentar passende Version suchen
+ // Die Versionen sind von 1 an durchnumeriert, mit negativen
+ // Versionsnummern werden die Versionen von der aktuellen aus
+ // r"uckw"arts gez"ahlt
+ short nVersion = pVersion ? pVersion->GetValue() : 0;
+ if ( nVersion<0 )
+ nVersion = ( (short) pImp->aVersions.getLength() ) + nVersion;
+ else if ( nVersion )
+ nVersion--;
+
+ util::RevisionTag& rTag = pImp->aVersions[nVersion];
+ {
+ // SubStorage f"ur alle Versionen "offnen
+ uno::Reference < embed::XStorage > xSub = pImp->xStorage->openStorageElement( DEFINE_CONST_UNICODE( "Versions" ),
+ embed::ElementModes::READ );
+
+ DBG_ASSERT( xSub.is(), "Versionsliste, aber keine Versionen!" );
+
+ // Dort ist die Version als gepackter Stream gespeichert
+ uno::Reference < io::XStream > xStr = xSub->openStreamElement( rTag.Identifier, embed::ElementModes::READ );
+ SvStream* pStream = utl::UcbStreamHelper::CreateStream( xStr );
+ if ( pStream && pStream->GetError() == SVSTREAM_OK )
+ {
+ // Stream ins TempDir auspacken
+ ::utl::TempFile aTempFile;
+ String aTmpName = aTempFile.GetURL();
+ SvFileStream aTmpStream( aTmpName, SFX_STREAM_READWRITE );
+
+ *pStream >> aTmpStream;
+ aTmpStream.Close();
+
+ // Datei als Storage "offnen
+ nStorOpenMode = SFX_STREAM_READONLY;
+ pImp->xStorage = comphelper::OStorageHelper::GetStorageFromURL( aTmpName, embed::ElementModes::READ );
+ pImp->bStorageBasedOnInStream = sal_False;
+ String aTemp;
+ ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTmpName, aTemp );
+ SetPhysicalName_Impl( aTemp );
+
+ pImp->bIsTemp = sal_True;
+ GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
+ // TODO/MBA
+ pImp->aVersions.realloc(0);
+ }
+ else
+ bResetStorage = TRUE;
+ }
+ }
+ else
+ bResetStorage = TRUE;
+ }
+
+ if ( bResetStorage )
+ {
+ pImp->xStorage = 0;
+ if ( pInStream )
+ pInStream->Seek( 0L );
+ }
+
+ pImp->bIsStorage = pImp->xStorage.is();
+ return pImp->xStorage;
+}
+
+//------------------------------------------------------------------
+uno::Reference< embed::XStorage > SfxMedium::GetZipStorageToSign_Impl( sal_Bool bReadOnly )
+{
+ if ( !GetError() && !pImp->m_xZipStorage.is() )
+ {
+ // very careful!!!
+ // if bReadOnly == sal_False and there is no temporary file the original file might be used
+ GetMedium_Impl();
+
+ try
+ {
+ // we can not sign document if there is no stream
+ // should it be possible at all?
+ if ( !bReadOnly && pImp->xStream.is() )
+ {
+ pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream, embed::ElementModes::READWRITE );
+ }
+ else if ( pImp->xInputStream.is() )
+ {
+ pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( ZIP_STORAGE_FORMAT_STRING, pImp->xInputStream );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "No possibility to get readonly version of storage from medium!\n" );
+ }
+
+ if ( GetError() ) // do not remove warnings
+ ResetError();
+ }
+
+ return pImp->m_xZipStorage;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::CloseZipStorage_Impl()
+{
+ if ( pImp->m_xZipStorage.is() )
+ {
+ try {
+ pImp->m_xZipStorage->dispose();
+ } catch( uno::Exception& )
+ {}
+
+ pImp->m_xZipStorage = uno::Reference< embed::XStorage >();
+ }
+}
+
+//------------------------------------------------------------------
+void SfxMedium::CloseStorage()
+{
+ if ( pImp->xStorage.is() )
+ {
+ uno::Reference < lang::XComponent > xComp( pImp->xStorage, uno::UNO_QUERY );
+ // in the salvage mode the medium does not own the storage
+ if ( pImp->bDisposeStorage && !pImp->m_bSalvageMode )
+ {
+ try {
+ xComp->dispose();
+ } catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Medium's storage is already disposed!\n" );
+ }
+ }
+
+ pImp->xStorage = 0;
+ pImp->bStorageBasedOnInStream = sal_False;
+ }
+
+ bTriedStorage = sal_False;
+ pImp->bIsStorage = sal_False;
+}
+
+void SfxMedium::CanDisposeStorage_Impl( sal_Bool bDisposeStorage )
+{
+ pImp->bDisposeStorage = bDisposeStorage;
+}
+
+sal_Bool SfxMedium::WillDisposeStorageOnClose_Impl()
+{
+ return pImp->bDisposeStorage;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::SetOpenMode( StreamMode nStorOpen,
+ sal_Bool bDirectP,
+ sal_Bool bDontClose )
+{
+ if ( nStorOpenMode != nStorOpen )
+ {
+ nStorOpenMode = nStorOpen;
+
+ if( !bDontClose )
+ {
+ if ( pImp->xStorage.is() )
+ CloseStorage();
+
+ CloseStreams_Impl();
+ }
+ }
+
+ bDirect = bDirectP;
+ bSetFilter = sal_False;
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::UseBackupToRestore_Impl( ::ucbhelper::Content& aOriginalContent,
+ const Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv )
+{
+ try
+ {
+ ::ucbhelper::Content aTransactCont( pImp->m_aBackupURL, xComEnv );
+
+ Reference< XInputStream > aOrigInput = aTransactCont.openStream();
+ aOriginalContent.writeStream( aOrigInput, sal_True );
+ return sal_True;
+ }
+ catch( Exception& )
+ {
+ // in case of failure here the backup file should not be removed
+ // TODO/LATER: a message should be used to let user know about the backup
+ pImp->m_bRemoveBackup = sal_False;
+ // TODO/LATER: needs a specific error code
+ eError = ERRCODE_IO_GENERAL;
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::StorageCommit_Impl()
+{
+ sal_Bool bResult = sal_False;
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
+ ::ucbhelper::Content aOriginalContent;
+
+ if ( pImp->xStorage.is() )
+ {
+ if ( !GetError() )
+ {
+ uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY );
+ if ( xTrans.is() )
+ {
+ try
+ {
+ xTrans->commit();
+ CloseZipStorage_Impl();
+ bResult = sal_True;
+ }
+ catch ( embed::UseBackupException& aBackupExc )
+ {
+ // since the temporary file is created always now, the scenario is close to be impossible
+ if ( !pImp->pTempFile )
+ {
+ OSL_ENSURE( pImp->m_aBackupURL.getLength(), "No backup on storage commit!\n" );
+ if ( pImp->m_aBackupURL.getLength()
+ && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ),
+ xDummyEnv,
+ aOriginalContent ) )
+ {
+ // use backup to restore the file
+ // the storage has already disconnected from original location
+ CloseAndReleaseStreams_Impl();
+ if ( !UseBackupToRestore_Impl( aOriginalContent, xDummyEnv ) )
+ {
+ // connect the medium to the temporary file of the storage
+ pImp->aContent = ::ucbhelper::Content();
+ aName = aBackupExc.TemporaryFileURL;
+ OSL_ENSURE( aName.Len(), "The exception _must_ contain the temporary URL!\n" );
+ }
+ }
+
+ if ( !GetError() )
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ //TODO/LATER: improve error handling
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource,
+ const INetURLObject& aDest,
+ const Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv )
+{
+ sal_Bool bResult = sal_False;
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
+ Reference< XOutputStream > aDestStream;
+ ::ucbhelper::Content aOriginalContent;
+
+ try
+ {
+ aOriginalContent = ::ucbhelper::Content( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
+ }
+ catch ( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ eError = ERRCODE_ABORT;
+ }
+ catch ( ::com::sun::star::ucb::CommandFailedException& )
+ {
+ eError = ERRCODE_ABORT;
+ }
+ catch (const ::com::sun::star::ucb::ContentCreationException& ex)
+ {
+ eError = ERRCODE_IO_GENERAL;
+ if (
+ (ex.eError == ::com::sun::star::ucb::ContentCreationError_NO_CONTENT_PROVIDER ) ||
+ (ex.eError == ::com::sun::star::ucb::ContentCreationError_CONTENT_CREATION_FAILED)
+ )
+ {
+ eError = ERRCODE_IO_NOTEXISTSPATH;
+ }
+ }
+ catch (const ::com::sun::star::uno::Exception&)
+ {
+ eError = ERRCODE_IO_GENERAL;
+ }
+
+ if( !eError || (eError & ERRCODE_WARNING_MASK) )
+ {
+ if ( pImp->xStorage.is() )
+ CloseStorage();
+
+ CloseStreams_Impl();
+
+ ::ucbhelper::Content aTempCont;
+ if( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, aTempCont ) )
+ {
+ sal_Bool bTransactStarted = sal_False;
+ SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False );
+ SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, sal_False );
+ sal_Bool bRename = pRename ? pRename->GetValue() : FALSE;
+ sal_Bool bOverWrite = pOverWrite ? pOverWrite->GetValue() : !bRename;
+
+ try
+ {
+ if( bOverWrite && ::utl::UCBContentHelper::IsDocument( aDest.GetMainURL( INetURLObject::NO_DECODE ) ) )
+ {
+ if( ! pImp->m_aBackupURL.getLength() )
+ DoInternalBackup_Impl( aOriginalContent );
+
+ if( pImp->m_aBackupURL.getLength() )
+ {
+ Reference< XInputStream > aTempInput = aTempCont.openStream();
+ bTransactStarted = sal_True;
+ aOriginalContent.setPropertyValue( ::rtl::OUString::createFromAscii( "Size" ),
+ uno::makeAny( (sal_Int64)0 ) );
+ aOriginalContent.writeStream( aTempInput, bOverWrite );
+ bResult = sal_True;
+ }
+ else
+ {
+ eError = ERRCODE_SFX_CANTCREATEBACKUP;
+ }
+ }
+ else
+ {
+ Reference< XInputStream > aTempInput = aTempCont.openStream();
+ aOriginalContent.writeStream( aTempInput, bOverWrite );
+ bResult = sal_True;
+ }
+ }
+ catch ( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ eError = ERRCODE_ABORT;
+ }
+ catch ( ::com::sun::star::ucb::CommandFailedException& )
+ {
+ eError = ERRCODE_ABORT;
+ }
+ catch ( ::com::sun::star::ucb::InteractiveIOException& r )
+ {
+ if ( r.Code == IOErrorCode_ACCESS_DENIED )
+ eError = ERRCODE_IO_ACCESSDENIED;
+ else if ( r.Code == IOErrorCode_NOT_EXISTING )
+ eError = ERRCODE_IO_NOTEXISTS;
+ else if ( r.Code == IOErrorCode_CANT_READ )
+ eError = ERRCODE_IO_CANTREAD;
+ else
+ eError = ERRCODE_IO_GENERAL;
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ eError = ERRCODE_IO_GENERAL;
+ }
+
+ if ( bResult )
+ {
+ if ( pImp->pTempFile )
+ {
+ pImp->pTempFile->EnableKillingFile( sal_True );
+ delete pImp->pTempFile;
+ pImp->pTempFile = NULL;
+ }
+ }
+ else if ( bTransactStarted )
+ {
+ UseBackupToRestore_Impl( aOriginalContent, xDummyEnv );
+ }
+ }
+ else
+ eError = ERRCODE_IO_CANTREAD;
+ }
+
+ return bResult;
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::TryDirectTransfer( const ::rtl::OUString& aURL, SfxItemSet& aTargetSet )
+{
+ if ( GetError() )
+ return sal_False;
+
+ // if the document had no password it should be stored without password
+ // if the document had password it should be stored with the same password
+ // otherwise the stream copying can not be done
+ SFX_ITEMSET_ARG( &aTargetSet, pNewPassItem, SfxStringItem, SID_PASSWORD, sal_False );
+ SFX_ITEMSET_ARG( GetItemSet(), pOldPassItem, SfxStringItem, SID_PASSWORD, sal_False );
+ if ( ( !pNewPassItem && !pOldPassItem )
+ || ( pNewPassItem && pOldPassItem && pNewPassItem->GetValue().Equals( pOldPassItem->GetValue() ) ) )
+ {
+ // the filter must be the same
+ SFX_ITEMSET_ARG( &aTargetSet, pNewFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ SFX_ITEMSET_ARG( GetItemSet(), pOldFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if ( pNewFilterItem && pOldFilterItem && pNewFilterItem->GetValue().Equals( pOldFilterItem->GetValue() ) )
+ {
+ // get the input stream and copy it
+ // in case of success return true
+ uno::Reference< io::XInputStream > xInStream = GetInputStream();
+
+ ResetError();
+ if ( xInStream.is() )
+ {
+ try
+ {
+ uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
+ sal_Int64 nPos = 0;
+ if ( xSeek.is() )
+ {
+ nPos = xSeek->getPosition();
+ xSeek->seek( 0 );
+ }
+
+ uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
+ ::ucbhelper::Content aTargetContent( aURL, xEnv );
+
+ InsertCommandArgument aInsertArg;
+ aInsertArg.Data = xInStream;
+ SFX_ITEMSET_ARG( &aTargetSet, pRename, SfxBoolItem, SID_RENAME, sal_False );
+ SFX_ITEMSET_ARG( &aTargetSet, pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False );
+ if ( (pOverWrite && !pOverWrite->GetValue()) // argument says: never overwrite
+ || (pRename && pRename->GetValue()) ) // argument says: rename file
+ aInsertArg.ReplaceExisting = sal_False;
+ else
+ aInsertArg.ReplaceExisting = sal_True; // default is overwrite existing files
+
+ Any aCmdArg;
+ aCmdArg <<= aInsertArg;
+ aTargetContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ aCmdArg );
+
+ if ( xSeek.is() )
+ xSeek->seek( nPos );
+
+ return sal_True;
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ }
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::Transfer_Impl()
+{
+ // The transfer is required only in two cases: either if there is a temporary file or if there is a salvage item
+ String aNameURL;
+ if ( pImp->pTempFile )
+ aNameURL = pImp->pTempFile->GetURL();
+ else if ( aLogicName.Len() && pImp->m_bSalvageMode )
+ {
+ // makes sence only in case logic name is set
+ if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aNameURL ) )
+ OSL_ENSURE( sal_False, "The medium name is not convertable!\n" );
+ }
+
+ if ( aNameURL.Len() && ( !eError || (eError & ERRCODE_WARNING_MASK) ) )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxMedium::Transfer_Impl, copying to target" );
+
+ Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
+ Reference< XOutputStream > rOutStream;
+
+ // in case an output stream is provided from outside and the URL is correct
+ // commit to the stream
+ if( aLogicName.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL )
+ {
+ // TODO/LATER: support storing to SID_STREAM
+ SFX_ITEMSET_ARG( pSet, pOutStreamItem, SfxUnoAnyItem, SID_OUTPUTSTREAM, sal_False);
+ if( pOutStreamItem && ( pOutStreamItem->GetValue() >>= rOutStream ) )
+ {
+ if ( pImp->xStorage.is() )
+ CloseStorage();
+
+ CloseStreams_Impl();
+
+ INetURLObject aSource( aNameURL );
+ ::ucbhelper::Content aTempCont;
+ if( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aTempCont ) )
+ {
+ try
+ {
+ sal_Int32 nRead;
+ sal_Int32 nBufferSize = 32767;
+ Sequence < sal_Int8 > aSequence ( nBufferSize );
+ Reference< XInputStream > aTempInput = aTempCont.openStream();
+
+ do
+ {
+ nRead = aTempInput->readBytes ( aSequence, nBufferSize );
+ if ( nRead < nBufferSize )
+ {
+ Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
+ rOutStream->writeBytes ( aTempBuf );
+ }
+ else
+ rOutStream->writeBytes ( aSequence );
+ }
+ while ( nRead == nBufferSize );
+
+ // remove temporary file
+ if ( pImp->pTempFile )
+ {
+ pImp->pTempFile->EnableKillingFile( sal_True );
+ delete pImp->pTempFile;
+ pImp->pTempFile = NULL;
+ }
+ }
+ catch( Exception& )
+ {}
+ }
+ }
+ else
+ {
+ DBG_ERROR( "Illegal Output stream parameter!\n" );
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ // free the reference
+ if ( pSet )
+ pSet->ClearItem( SID_OUTPUTSTREAM );
+
+ return;
+ }
+
+ GetContent();
+ if ( !pImp->aContent.get().is() )
+ {
+ eError = ERRCODE_IO_NOTEXISTS;
+ return;
+ }
+
+ SFX_ITEMSET_ARG( GetItemSet(), pSegmentSize, SfxInt32Item, SID_SEGMENTSIZE, sal_False);
+ if ( pSegmentSize )
+ {
+ // this file must be stored into a disk spanned package
+ try
+ {
+ uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetStorageFromURL( GetName(),
+ embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+
+ // set segment size property; package will automatically be divided in pieces fitting
+ // into this size
+ ::com::sun::star::uno::Any aAny;
+ aAny <<= pSegmentSize->GetValue();
+
+ uno::Reference < beans::XPropertySet > xSet( pImp->xStorage, uno::UNO_QUERY );
+ xSet->setPropertyValue( String::CreateFromAscii("SegmentSize"), aAny );
+
+ // copy the temporary storage into the disk spanned package
+ GetStorage()->copyToStorage( xStor );
+ uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY );
+ if ( xTrans.is() )
+ xTrans->commit();
+
+ }
+ catch ( uno::Exception& )
+ {
+ //TODO/MBA: error handling
+ }
+ return;
+ }
+
+ INetURLObject aDest( GetURLObject() );
+
+ // source is the temp file written so far
+ INetURLObject aSource( aNameURL );
+
+ // a special case, an interaction handler should be used for
+ // authentication in case it is available
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
+ Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler();
+ if (xInteractionHandler.is())
+ xComEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler,
+ Reference< ::com::sun::star::ucb::XProgressHandler >() );
+
+ if ( ::utl::LocalFileHelper::IsLocalFile( aDest.GetMainURL( INetURLObject::NO_DECODE ) ) || !aDest.removeSegment() )
+ {
+ TransactedTransferForFS_Impl( aSource, aDest, xComEnv );
+ }
+ else
+ {
+ // create content for the parent folder and call transfer on that content with the source content
+ // and the destination file name as parameters
+ ::ucbhelper::Content aSourceContent;
+ ::ucbhelper::Content aTransferContent;
+
+ String aFileName = GetLongName();
+ if ( !aFileName.Len() )
+ aFileName = GetURLObject().getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+
+ try
+ {
+ aTransferContent = ::ucbhelper::Content( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
+ }
+ catch (const ::com::sun::star::ucb::ContentCreationException& ex)
+ {
+ eError = ERRCODE_IO_GENERAL;
+ if (
+ (ex.eError == ::com::sun::star::ucb::ContentCreationError_NO_CONTENT_PROVIDER ) ||
+ (ex.eError == ::com::sun::star::ucb::ContentCreationError_CONTENT_CREATION_FAILED)
+ )
+ {
+ eError = ERRCODE_IO_NOTEXISTSPATH;
+ }
+ }
+ catch (const ::com::sun::star::uno::Exception&)
+ {
+ eError = ERRCODE_IO_GENERAL;
+ }
+
+ if ( !eError || (eError & ERRCODE_WARNING_MASK) )
+ {
+ // free resources, otherwise the transfer may fail
+ if ( pImp->xStorage.is() )
+ CloseStorage();
+
+ CloseStreams_Impl();
+
+ ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aSourceContent );
+
+ // check for external parameters that may customize the handling of NameClash situations
+ SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, sal_False );
+ SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False );
+ sal_Int32 nNameClash;
+ if ( pOverWrite && !pOverWrite->GetValue() )
+ // argument says: never overwrite
+ nNameClash = NameClash::ERROR;
+ else if ( pRename && pRename->GetValue() )
+ // argument says: rename file
+ nNameClash = NameClash::RENAME;
+ else
+ // default is overwrite existing files
+ nNameClash = NameClash::OVERWRITE;
+
+ try
+ {
+ if (!aTransferContent.transferContent( aSourceContent, ::ucbhelper::InsertOperation_COPY, aFileName, nNameClash ))
+ eError = ERRCODE_IO_GENERAL;
+ }
+ catch ( ::com::sun::star::ucb::CommandAbortedException& )
+ {
+ eError = ERRCODE_ABORT;
+ }
+ catch ( ::com::sun::star::ucb::CommandFailedException& )
+ {
+ eError = ERRCODE_ABORT;
+ }
+ catch ( ::com::sun::star::ucb::InteractiveIOException& r )
+ {
+ if ( r.Code == IOErrorCode_ACCESS_DENIED )
+ eError = ERRCODE_IO_ACCESSDENIED;
+ else if ( r.Code == IOErrorCode_NOT_EXISTING )
+ eError = ERRCODE_IO_NOTEXISTS;
+ else if ( r.Code == IOErrorCode_CANT_READ )
+ eError = ERRCODE_IO_CANTREAD;
+ else
+ eError = ERRCODE_IO_GENERAL;
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ eError = ERRCODE_IO_GENERAL;
+ }
+
+ // do not switch from temporary file in case of nonfile protocol
+ }
+ }
+
+ if ( ( !eError || (eError & ERRCODE_WARNING_MASK) ) && !pImp->pTempFile )
+ {
+ // without a TempFile the physical and logical name should be the same after successful transfer
+ ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ),
+ aName );
+ pImp->m_bSalvageMode = sal_False;
+ }
+ }
+}
+
+//------------------------------------------------------------------
+void SfxMedium::DoInternalBackup_Impl( const ::ucbhelper::Content& aOriginalContent,
+ const String& aPrefix,
+ const String& aExtension,
+ const String& aDestDir )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxMedium::DoInternalBackup_Impl( with destdir )" );
+
+ if ( pImp->m_aBackupURL.getLength() )
+ return; // the backup was done already
+
+ ::utl::TempFile aTransactTemp( aPrefix, &aExtension, &aDestDir );
+ aTransactTemp.EnableKillingFile( sal_False );
+
+ INetURLObject aBackObj( aTransactTemp.GetURL() );
+ ::rtl::OUString aBackupName = aBackObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+
+ Reference < ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
+ ::ucbhelper::Content aBackupCont;
+ if( ::ucbhelper::Content::create( aDestDir, xDummyEnv, aBackupCont ) )
+ {
+ try
+ {
+ if( aBackupCont.transferContent( aOriginalContent,
+ ::ucbhelper::InsertOperation_COPY,
+ aBackupName,
+ NameClash::OVERWRITE ) )
+ {
+ pImp->m_aBackupURL = aBackObj.GetMainURL( INetURLObject::NO_DECODE );
+ pImp->m_bRemoveBackup = sal_True;
+ }
+ }
+ catch( Exception& )
+ {}
+ }
+
+ if ( !pImp->m_aBackupURL.getLength() )
+ aTransactTemp.EnableKillingFile( sal_True );
+}
+
+//------------------------------------------------------------------
+void SfxMedium::DoInternalBackup_Impl( const ::ucbhelper::Content& aOriginalContent )
+{
+ if ( pImp->m_aBackupURL.getLength() )
+ return; // the backup was done already
+
+ ::rtl::OUString aFileName = GetURLObject().getName( INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::NO_DECODE );
+
+ sal_Int32 nPrefixLen = aFileName.lastIndexOf( '.' );
+ String aPrefix = ( nPrefixLen == -1 ) ? aFileName : aFileName.copy( 0, nPrefixLen );
+ String aExtension = ( nPrefixLen == -1 ) ? String() : String(aFileName.copy( nPrefixLen ));
+ String aBakDir = SvtPathOptions().GetBackupPath();
+
+ DoInternalBackup_Impl( aOriginalContent, aPrefix, aExtension, aBakDir );
+
+ if ( !pImp->m_aBackupURL.getLength() )
+ {
+ // the copiing to the backup catalog failed ( for example because
+ // of using an encrypted partition as target catalog )
+ // since the user did not specify to make backup explicitly
+ // office should try to make backup in another place,
+ // target catalog does not look bad for this case ( and looks
+ // to be the only way for encrypted partitions )
+
+ INetURLObject aDest = GetURLObject();
+ if ( aDest.removeSegment() )
+ DoInternalBackup_Impl( aOriginalContent, aPrefix, aExtension, aDest.GetMainURL( INetURLObject::NO_DECODE ) );
+ }
+}
+
+
+//------------------------------------------------------------------
+void SfxMedium::DoBackup_Impl()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxMedium::DoBackup_Impl" );
+
+ // source file name is the logical name of this medium
+ INetURLObject aSource( GetURLObject() );
+
+ // there is nothing to backup in case source file does not exist
+ if ( !::utl::UCBContentHelper::IsDocument( aSource.GetMainURL( INetURLObject::NO_DECODE ) ) )
+ return;
+
+ sal_Bool bSuccess = sal_False;
+
+ // get path for backups
+ String aBakDir = SvtPathOptions().GetBackupPath();
+ if( aBakDir.Len() )
+ {
+ // create content for the parent folder ( = backup folder )
+ ::ucbhelper::Content aContent;
+ Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
+ if( ::ucbhelper::Content::create( aBakDir, xEnv, aContent ) )
+ {
+ // save as ".bak" file
+ INetURLObject aDest( aBakDir );
+ aDest.insertName( aSource.getName() );
+ aDest.setExtension( DEFINE_CONST_UNICODE( "bak" ) );
+ String aFileName = aDest.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+
+ // create a content for the source file
+ ::ucbhelper::Content aSourceContent;
+ if ( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aSourceContent ) )
+ {
+ try
+ {
+ // do the transfer ( copy source file to backup dir )
+ bSuccess = aContent.transferContent( aSourceContent,
+ ::ucbhelper::InsertOperation_COPY,
+ aFileName,
+ NameClash::OVERWRITE );
+ if( bSuccess )
+ {
+ pImp->m_aBackupURL = aDest.GetMainURL( INetURLObject::NO_DECODE );
+ pImp->m_bRemoveBackup = sal_False;
+ }
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+
+ if ( !bSuccess )
+ {
+ eError = ERRCODE_SFX_CANTCREATEBACKUP;
+ }
+}
+
+//------------------------------------------------------------------
+void SfxMedium::ClearBackup_Impl()
+{
+ if( pImp->m_bRemoveBackup )
+ {
+ // currently a document is always stored in a new medium,
+ // thus if a backup can not be removed the backup URL should not be cleaned
+ if ( pImp->m_aBackupURL.getLength() )
+ {
+ if ( ::utl::UCBContentHelper::Kill( pImp->m_aBackupURL ) )
+ // || !::utl::UCBContentHelper::IsDocument( pImp->m_aBackupURL ) );
+ {
+ pImp->m_bRemoveBackup = sal_False;
+ pImp->m_aBackupURL = ::rtl::OUString();
+ }
+ else
+ {
+
+ DBG_ERROR("Couldn't remove backup file!");
+ }
+ }
+ }
+ else
+ pImp->m_aBackupURL = ::rtl::OUString();
+}
+
+//----------------------------------------------------------------
+void SfxMedium::GetLockingStream_Impl()
+{
+ if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
+ && !pImp->m_xLockingStream.is() )
+ {
+ SFX_ITEMSET_ARG( pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, sal_False);
+ if ( pWriteStreamItem )
+ pWriteStreamItem->GetValue() >>= pImp->m_xLockingStream;
+
+ if ( !pImp->m_xLockingStream.is() )
+ {
+ // open the original document
+ uno::Sequence< beans::PropertyValue > xProps;
+ TransformItems( SID_OPENDOC, *GetItemSet(), xProps );
+ comphelper::MediaDescriptor aMedium( xProps );
+
+ aMedium.addInputStreamOwnLock();
+
+ uno::Reference< io::XInputStream > xInputStream;
+ aMedium[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp->m_xLockingStream;
+ aMedium[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= xInputStream;
+
+ if ( !pImp->pTempFile && !aName.Len() )
+ {
+ // the medium is still based on the original file, it makes sence to initialize the streams
+ if ( pImp->m_xLockingStream.is() )
+ pImp->xStream = pImp->m_xLockingStream;
+
+ if ( xInputStream.is() )
+ pImp->xInputStream = xInputStream;
+
+ if ( !pImp->xInputStream.is() && pImp->xStream.is() )
+ pImp->xInputStream = pImp->xStream->getInputStream();
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------
+void SfxMedium::GetMedium_Impl()
+{
+ if ( !pInStream )
+ {
+ pImp->bDownloadDone = sal_False;
+ Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler();
+
+ //TODO/MBA: need support for SID_STREAM
+ SFX_ITEMSET_ARG( pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, sal_False);
+ SFX_ITEMSET_ARG( pSet, pInStreamItem, SfxUnoAnyItem, SID_INPUTSTREAM, sal_False);
+ if ( pWriteStreamItem )
+ {
+ pWriteStreamItem->GetValue() >>= pImp->xStream;
+
+ if ( pInStreamItem )
+ pInStreamItem->GetValue() >>= pImp->xInputStream;
+
+ if ( !pImp->xInputStream.is() && pImp->xStream.is() )
+ pImp->xInputStream = pImp->xStream->getInputStream();
+ }
+ else if ( pInStreamItem )
+ {
+ pInStreamItem->GetValue() >>= pImp->xInputStream;
+ }
+ else
+ {
+ uno::Sequence < beans::PropertyValue > xProps;
+ String aFileName;
+ if ( aName.Len() )
+ {
+ if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aFileName ) )
+ {
+ DBG_ERROR("Physical name not convertable!");
+ }
+ }
+ else
+ aFileName = GetName();
+
+ // in case the temporary file exists the streams should be initialized from it,
+ // but the original MediaDescriptor should not be changed
+ sal_Bool bFromTempFile = ( pImp->pTempFile != NULL );
+
+ if ( !bFromTempFile )
+ {
+ GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, aFileName ) );
+ if( !(nStorOpenMode & STREAM_WRITE ) )
+ GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, TRUE ) );
+ if (xInteractionHandler.is())
+ GetItemSet()->Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER, makeAny(xInteractionHandler) ) );
+ }
+
+ if ( m_xInputStreamToLoadFrom.is() )
+ {
+ pImp->xInputStream = m_xInputStreamToLoadFrom;
+ pImp->xInputStream->skipBytes(0);
+ if(m_bIsReadOnly)
+ GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
+
+ // m_xInputStreamToLoadFrom = 0;
+ }
+ else
+ {
+ TransformItems( SID_OPENDOC, *GetItemSet(), xProps );
+ comphelper::MediaDescriptor aMedium( xProps );
+
+ if ( pImp->m_xLockingStream.is() && !bFromTempFile )
+ {
+ // the medium is not based on the temporary file, so the original stream can be used
+ pImp->xStream = pImp->m_xLockingStream;
+ }
+ else
+ {
+ if ( bFromTempFile )
+ {
+ aMedium[comphelper::MediaDescriptor::PROP_URL()] <<= ::rtl::OUString( aFileName );
+ aMedium.erase( comphelper::MediaDescriptor::PROP_READONLY() );
+ aMedium.addInputStream();
+ }
+ else if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
+ {
+ // use the special locking approach only for file URLs
+ aMedium.addInputStreamOwnLock();
+ }
+ else
+ aMedium.addInputStream();
+
+ // the ReadOnly property set in aMedium is ignored
+ // the check is done in LockOrigFileOnDemand() for file and non-file URLs
+
+ //TODO/MBA: what happens if property is not there?!
+ aMedium[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp->xStream;
+ aMedium[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= pImp->xInputStream;
+ }
+
+ GetContent();
+ if ( !pImp->xInputStream.is() && pImp->xStream.is() )
+ pImp->xInputStream = pImp->xStream->getInputStream();
+ }
+
+ if ( !bFromTempFile )
+ {
+ //TODO/MBA: need support for SID_STREAM
+ if ( pImp->xStream.is() )
+ GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM, makeAny( pImp->xStream ) ) );
+
+ GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, makeAny( pImp->xInputStream ) ) );
+ }
+ }
+
+ //TODO/MBA: ErrorHandling - how to transport error from MediaDescriptor
+ if ( !GetError() && !pImp->xStream.is() && !pImp->xInputStream.is() )
+ SetError( ERRCODE_IO_ACCESSDENIED, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ if ( !GetError() )
+ {
+ if ( pImp->xStream.is() )
+ pInStream = utl::UcbStreamHelper::CreateStream( pImp->xStream );
+ else if ( pImp->xInputStream.is() )
+ pInStream = utl::UcbStreamHelper::CreateStream( pImp->xInputStream );
+ }
+
+ pImp->bDownloadDone = sal_True;
+ pImp->aDoneLink.ClearPendingCall();
+ pImp->aDoneLink.Call( (void*) GetError() );
+ }
+}
+
+//----------------------------------------------------------------
+sal_Bool SfxMedium::IsRemote()
+{
+ return bRemote;
+}
+
+//------------------------------------------------------------------
+
+void SfxMedium::SetUpdatePickList(sal_Bool bVal)
+{
+ if(!pImp)
+ pImp = new SfxMedium_Impl( this );
+ pImp->bUpdatePickList = bVal;
+}
+//------------------------------------------------------------------
+
+sal_Bool SfxMedium::IsUpdatePickList() const
+{
+ return pImp? pImp->bUpdatePickList: sal_True;
+}
+//----------------------------------------------------------------
+
+void SfxMedium::SetDoneLink( const Link& rLink )
+{
+ pImp->aDoneLink = rLink;
+}
+
+//----------------------------------------------------------------
+
+void SfxMedium::SetDataAvailableLink( const Link& rLink )
+{
+ pImp->aAvailableLink = rLink;
+}
+
+//----------------------------------------------------------------
+void SfxMedium::StartDownload()
+{
+ GetInStream();
+}
+
+void SfxMedium::DownLoad( const Link& aLink )
+{
+ SetDoneLink( aLink );
+ GetInStream();
+ if ( pInStream && !aLink.IsSet() )
+ {
+ while( !pImp->bDownloadDone )
+ Application::Yield();
+ }
+}
+
+//------------------------------------------------------------------
+void SfxMedium::Init_Impl()
+/* [Beschreibung]
+ Setzt in den Logischen Namen eine gueltige ::com::sun::star::util::URL (Falls zuvor ein Filename
+ drin war) und setzt den physikalschen Namen auf den Filenamen, falls
+ vorhanden.
+ */
+
+{
+ Reference< XOutputStream > rOutStream;
+
+ // TODO/LATER: handle lifetime of storages
+ pImp->bDisposeStorage = FALSE;
+
+ SFX_ITEMSET_ARG( pSet, pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
+ if ( pSalvageItem && !pSalvageItem->GetValue().Len() )
+ {
+ pSalvageItem = NULL;
+ pSet->ClearItem( SID_DOC_SALVAGE );
+ }
+
+ if( aLogicName.Len() )
+ {
+ INetURLObject aUrl( aLogicName );
+ INetProtocol eProt = aUrl.GetProtocol();
+ if ( eProt == INET_PROT_NOT_VALID )
+ {
+ DBG_ERROR ( "Unknown protocol!" );
+ }
+ else
+ {
+ if ( aUrl.HasMark() )
+ {
+ aLogicName = aUrl.GetURLNoMark( INetURLObject::NO_DECODE );
+ GetItemSet()->Put( SfxStringItem( SID_JUMPMARK, aUrl.GetMark() ) );
+ }
+
+ // try to convert the URL into a physical name - but never change a physical name
+ // physical name may be set if the logical name is changed after construction
+ if ( !aName.Len() )
+ ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), aName );
+ else {
+ DBG_ASSERT( pSalvageItem, "Suspicious change of logical name!" );
+ }
+ }
+ }
+
+ if ( pSalvageItem && pSalvageItem->GetValue().Len() )
+ {
+ aLogicName = pSalvageItem->GetValue();
+ DELETEZ( pURLObj );
+ pImp->m_bSalvageMode = sal_True;
+ }
+
+ // in case output stream is by mistake here
+ // clear the reference
+ SFX_ITEMSET_ARG( pSet, pOutStreamItem, SfxUnoAnyItem, SID_OUTPUTSTREAM, sal_False);
+ if( pOutStreamItem
+ && ( !( pOutStreamItem->GetValue() >>= rOutStream )
+ || !aLogicName.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL ) )
+ {
+ pSet->ClearItem( SID_OUTPUTSTREAM );
+ DBG_ERROR( "Unexpected Output stream parameter!\n" );
+ }
+
+ if ( aLogicName.Len() )
+ {
+ // if the logic name is set it should be set in MediaDescriptor as well
+ SFX_ITEMSET_ARG( pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE );
+ if ( !pFileNameItem )
+ {
+ // let the ItemSet be created if necessary
+ GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, INetURLObject( aLogicName ).GetMainURL( INetURLObject::NO_DECODE ) ) );
+ }
+ }
+
+ SetIsRemote_Impl();
+}
+
+//------------------------------------------------------------------
+SfxMedium::SfxMedium()
+: IMPL_CTOR( sal_False, 0 ), // bRoot, pURLObj
+
+ pFilter(0),
+ pSet(0),
+ pImp(new SfxMedium_Impl( this ))
+{
+ Init_Impl();
+}
+//------------------------------------------------------------------
+
+SfxMedium::SfxMedium( const SfxMedium& rMedium, sal_Bool bTemporary )
+: SvRefBase(),
+ IMPL_CTOR( sal_True, // bRoot, pURLObj
+ rMedium.pURLObj ? new INetURLObject(*rMedium.pURLObj) : 0 ),
+ pImp(new SfxMedium_Impl( this ))
+{
+ bDirect = rMedium.IsDirect();
+ nStorOpenMode = rMedium.GetOpenMode();
+ if ( !bTemporary )
+ aName = rMedium.aName;
+
+ pImp->bIsTemp = bTemporary;
+ DBG_ASSERT( ! rMedium.pImp->bIsTemp, "Temporaeres Medium darf nicht kopiert werden" );
+ aLogicName = rMedium.aLogicName;
+ pSet = rMedium.GetItemSet() ? new SfxItemSet(*rMedium.GetItemSet()) : 0;
+ pFilter = rMedium.pFilter;
+ Init_Impl();
+ if( bTemporary )
+ CreateTempFile( sal_True );
+}
+
+//------------------------------------------------------------------
+
+void SfxMedium::UseInteractionHandler( BOOL bUse )
+{
+ pImp->bAllowDefaultIntHdl = bUse;
+}
+
+//------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >
+SfxMedium::GetInteractionHandler()
+{
+ // if interaction isnt allowed explicitly ... return empty reference!
+ if ( !pImp->bUseInteractionHandler )
+ return ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >();
+
+ // search a possible existing handler inside cached item set
+ if ( pSet )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > xHandler;
+ SFX_ITEMSET_ARG( pSet, pHandler, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
+ if ( pHandler && (pHandler->GetValue() >>= xHandler) && xHandler.is() )
+ return xHandler;
+ }
+
+ // if default interaction isnt allowed explicitly ... return empty reference!
+ if ( !pImp->bAllowDefaultIntHdl )
+ return ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >();
+
+ // otherwhise return cached default handler ... if it exist.
+ if ( pImp->xInteraction.is() )
+ return pImp->xInteraction;
+
+ // create default handler and cache it!
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ if ( xFactory.is() )
+ {
+ pImp->xInteraction = ::com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler >( xFactory->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ), ::com::sun::star::uno::UNO_QUERY );
+ return pImp->xInteraction;
+ }
+
+ return ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >();
+}
+
+//----------------------------------------------------------------
+
+void SfxMedium::SetFilter( const SfxFilter* pFilterP, sal_Bool /*bResetOrig*/ )
+{
+ pFilter = pFilterP;
+ pImp->nFileVersion = 0;
+}
+
+//----------------------------------------------------------------
+
+const SfxFilter* SfxMedium::GetOrigFilter( sal_Bool bNotCurrent ) const
+{
+ return ( pImp->pOrigFilter || bNotCurrent ) ? pImp->pOrigFilter : pFilter;
+}
+
+//----------------------------------------------------------------
+
+void SfxMedium::SetOrigFilter_Impl( const SfxFilter* pOrigFilter )
+{
+ pImp->pOrigFilter = pOrigFilter;
+}
+
+//------------------------------------------------------------------
+
+sal_uInt32 SfxMedium::CreatePasswordToModifyHash( const ::rtl::OUString& aPasswd, sal_Bool bWriter )
+{
+ sal_uInt32 nHash = 0;
+
+ if ( aPasswd.getLength() )
+ {
+ if ( bWriter )
+ {
+ nHash = ::comphelper::DocPasswordHelper::GetWordHashAsUINT32( aPasswd );
+ }
+ else
+ {
+ rtl_TextEncoding nEncoding = RTL_TEXTENCODING_UTF8;
+
+ // if the MS-filter should be used
+ // use the inconsistent algorithm to find the encoding specified by MS
+ nEncoding = osl_getThreadTextEncoding();
+ switch( nEncoding )
+ {
+ case RTL_TEXTENCODING_ISO_8859_15:
+ case RTL_TEXTENCODING_MS_874:
+ case RTL_TEXTENCODING_MS_1250:
+ case RTL_TEXTENCODING_MS_1251:
+ case RTL_TEXTENCODING_MS_1252:
+ case RTL_TEXTENCODING_MS_1253:
+ case RTL_TEXTENCODING_MS_1254:
+ case RTL_TEXTENCODING_MS_1255:
+ case RTL_TEXTENCODING_MS_1256:
+ case RTL_TEXTENCODING_MS_1257:
+ case RTL_TEXTENCODING_MS_1258:
+ case RTL_TEXTENCODING_SHIFT_JIS:
+ case RTL_TEXTENCODING_GB_2312:
+ case RTL_TEXTENCODING_BIG5:
+ // in case the system uses an encoding from the list above, it should be used
+ break;
+
+ default:
+ // in case other encoding is used, use one of the encodings from the list
+ nEncoding = RTL_TEXTENCODING_MS_1250;
+ break;
+ }
+
+ nHash = ::comphelper::DocPasswordHelper::GetXLHashAsUINT16( aPasswd, nEncoding );
+ }
+ }
+
+ return nHash;
+}
+
+//------------------------------------------------------------------
+
+void SfxMedium::Close()
+{
+ if ( pImp->xStorage.is() )
+ {
+ // don't close the streams if they belong to the
+ // storage
+ //TODO/MBA: how to?! Do we need the flag?!
+ /*
+ const SvStream *pStream = aStorage->GetSvStream();
+ if ( pStream && pStream == pInStream )
+ {
+ CloseZipStorage_Impl();
+ pInStream = NULL;
+ pImp->xInputStream = Reference < XInputStream >();
+ pImp->xLockBytes.Clear();
+ if ( pSet )
+ pSet->ClearItem( SID_INPUTSTREAM );
+ aStorage->SetDeleteStream( TRUE );
+ }
+ else if ( pStream && pStream == pOutStream )
+ {
+ pOutStream = NULL;
+ aStorage->SetDeleteStream( TRUE );
+ } */
+
+ CloseStorage();
+ }
+
+ CloseStreams_Impl();
+
+ UnlockFile( sal_False );
+}
+
+void SfxMedium::CloseAndRelease()
+{
+ if ( pImp->xStorage.is() )
+ {
+ // don't close the streams if they belong to the
+ // storage
+ //TODO/MBA: how to?! Do we need the flag?!
+ /*
+ const SvStream *pStream = aStorage->GetSvStream();
+ if ( pStream && pStream == pInStream )
+ {
+ CloseZipStorage_Impl();
+ pInStream = NULL;
+ pImp->xInputStream = Reference < XInputStream >();
+ pImp->xLockBytes.Clear();
+ if ( pSet )
+ pSet->ClearItem( SID_INPUTSTREAM );
+ aStorage->SetDeleteStream( TRUE );
+ }
+ else if ( pStream && pStream == pOutStream )
+ {
+ pOutStream = NULL;
+ aStorage->SetDeleteStream( TRUE );
+ } */
+
+ CloseStorage();
+ }
+
+ CloseAndReleaseStreams_Impl();
+
+ UnlockFile( sal_True );
+}
+
+void SfxMedium::UnlockFile( sal_Bool bReleaseLockStream )
+{
+ if ( pImp->m_xLockingStream.is() )
+ {
+ if ( bReleaseLockStream )
+ {
+ try
+ {
+ uno::Reference< io::XInputStream > xInStream = pImp->m_xLockingStream->getInputStream();
+ uno::Reference< io::XOutputStream > xOutStream = pImp->m_xLockingStream->getOutputStream();
+ if ( xInStream.is() )
+ xInStream->closeInput();
+ if ( xOutStream.is() )
+ xOutStream->closeOutput();
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ pImp->m_xLockingStream = uno::Reference< io::XStream >();
+ }
+
+ if ( pImp->m_bLocked )
+ {
+ try
+ {
+ pImp->m_bLocked = sal_False;
+ ::svt::DocumentLockFile aLockFile( aLogicName );
+ // TODO/LATER: A warning could be shown in case the file is not the own one
+ aLockFile.RemoveFile();
+ }
+ catch( uno::Exception& )
+ {}
+ }
+}
+
+void SfxMedium::CloseAndReleaseStreams_Impl()
+{
+ CloseZipStorage_Impl();
+
+ uno::Reference< io::XInputStream > xInToClose = pImp->xInputStream;
+ uno::Reference< io::XOutputStream > xOutToClose;
+ if ( pImp->xStream.is() )
+ {
+ xOutToClose = pImp->xStream->getOutputStream();
+
+ // if the locking stream is closed here the related member should be cleaned
+ if ( pImp->xStream == pImp->m_xLockingStream )
+ pImp->m_xLockingStream = uno::Reference< io::XStream >();
+ }
+
+ // The probably exsisting SvStream wrappers should be closed first
+ CloseStreams_Impl();
+
+ // in case of salvage mode the storage is based on the streams
+ if ( !pImp->m_bSalvageMode )
+ {
+ try
+ {
+ if ( xInToClose.is() )
+ xInToClose->closeInput();
+ if ( xOutToClose.is() )
+ xOutToClose->closeOutput();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+}
+
+//------------------------------------------------------------------
+void SfxMedium::CloseStreams_Impl()
+{
+ CloseInStream_Impl();
+ CloseOutStream_Impl();
+
+ if ( pSet )
+ pSet->ClearItem( SID_CONTENT );
+
+ pImp->aContent = ::ucbhelper::Content();
+}
+
+//------------------------------------------------------------------
+
+void SfxMedium::RefreshName_Impl()
+{
+#if 0 //(dv)
+ if ( pImp->aContent.get().is() )
+ {
+ String aNameP = pImp->xAnchor->GetViewURL();
+ pImp->aOrigURL = aNameP;
+ aLogicName = aNameP;
+ DELETEZ( pURLObj );
+ if (aLogicName.Len())
+ aLogicName = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
+ SetIsRemote_Impl();
+ }
+#endif //(dv)
+}
+
+void SfxMedium::SetIsRemote_Impl()
+{
+ INetURLObject aObj( GetName() );
+ switch( aObj.GetProtocol() )
+ {
+ case INET_PROT_FTP:
+ case INET_PROT_HTTP:
+ case INET_PROT_HTTPS:
+ case INET_PROT_POP3:
+ case INET_PROT_NEWS:
+ case INET_PROT_IMAP:
+// case INET_PROT_OUT:
+ case INET_PROT_VIM:
+ bRemote = TRUE; break;
+ default:
+ bRemote = ( GetName().CompareToAscii( "private:msgid", 13 ) == COMPARE_EQUAL );
+ break;
+ }
+
+ // Da Dateien, die Remote geschrieben werden zur Uebertragung auch
+ // gelesen werden koennen muessen
+ if( bRemote )
+ nStorOpenMode |= STREAM_READ;
+}
+
+
+
+void SfxMedium::SetName( const String& aNameP, sal_Bool bSetOrigURL )
+{
+ if( !pImp->aOrigURL.Len() )
+ pImp->aOrigURL = aLogicName;
+ if( bSetOrigURL )
+ pImp->aOrigURL = aNameP;
+ aLogicName = aNameP;
+ DELETEZ( pURLObj );
+ pImp->aContent = ::ucbhelper::Content();
+ Init_Impl();
+}
+
+//----------------------------------------------------------------
+const String& SfxMedium::GetOrigURL() const
+{
+ return !pImp->aOrigURL.Len() ? (String &)aLogicName : pImp->aOrigURL;
+}
+
+//----------------------------------------------------------------
+
+void SfxMedium::SetPhysicalName_Impl( const String& rNameP )
+{
+ if ( rNameP != aName )
+ {
+ if( pImp->pTempFile )
+ {
+ delete pImp->pTempFile;
+ pImp->pTempFile = NULL;
+ }
+
+ if ( aName.Len() || rNameP.Len() )
+ pImp->aContent = ::ucbhelper::Content();
+
+ aName = rNameP;
+ bTriedStorage = sal_False;
+ pImp->bIsStorage = sal_False;
+ }
+}
+
+//------------------------------------------------------------------
+void SfxMedium::SetTemporary( sal_Bool bTemp )
+{
+ pImp->bIsTemp = bTemp;
+}
+
+//------------------------------------------------------------------
+sal_Bool SfxMedium::IsTemporary() const
+{
+ return pImp->bIsTemp;
+}
+
+//------------------------------------------------------------------
+
+sal_Bool SfxMedium::Exists( sal_Bool /*bForceSession*/ )
+{
+ DBG_ERROR( "Not implemented!" );
+ return sal_True;
+}
+
+//------------------------------------------------------------------
+
+void SfxMedium::ReOpen()
+{
+ BOOL bUseInteractionHandler = pImp->bUseInteractionHandler;
+ pImp->bUseInteractionHandler = FALSE;
+ GetMedium_Impl();
+ pImp->bUseInteractionHandler = bUseInteractionHandler;
+}
+
+//------------------------------------------------------------------
+
+void SfxMedium::CompleteReOpen()
+{
+ // do not use temporary file for reopen and in case of success throw the temporary file away
+ BOOL bUseInteractionHandler = pImp->bUseInteractionHandler;
+ pImp->bUseInteractionHandler = FALSE;
+
+ ::utl::TempFile* pTmpFile = NULL;
+ if ( pImp->pTempFile )
+ {
+ pTmpFile = pImp->pTempFile;
+ pImp->pTempFile = NULL;
+ aName = String();
+ }
+
+ GetMedium_Impl();
+
+ if ( GetError() )
+ {
+ if ( pImp->pTempFile )
+ {
+ pImp->pTempFile->EnableKillingFile( sal_True );
+ delete pImp->pTempFile;
+ }
+ pImp->pTempFile = pTmpFile;
+ if ( pImp->pTempFile )
+ aName = pImp->pTempFile->GetFileName();
+ }
+ else
+ {
+ pTmpFile->EnableKillingFile( sal_True );
+ delete pTmpFile;
+
+ }
+
+ pImp->bUseInteractionHandler = bUseInteractionHandler;
+}
+
+//------------------------------------------------------------------
+SfxMedium::SfxMedium
+(
+ const String &rName, StreamMode nOpenMode, sal_Bool bDirectP,
+ const SfxFilter *pFlt, SfxItemSet *pInSet
+)
+: IMPL_CTOR( sal_False, 0 ), // bRoot, pURLObj
+ pFilter(pFlt),
+ pSet( pInSet ),
+ pImp(new SfxMedium_Impl( this ))
+{
+ aLogicName = rName;
+ nStorOpenMode = nOpenMode;
+ bDirect = bDirectP;
+ Init_Impl();
+}
+
+
+SfxMedium::SfxMedium( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs )
+ : IMPL_CTOR( sal_False, 0 ), // bRoot, pURLObj
+ pFilter(0),
+ pSet(0),
+ pImp(new SfxMedium_Impl( this ))
+{
+ SfxAllItemSet *pParams = new SfxAllItemSet( SFX_APP()->GetPool() );
+ pSet = pParams;
+ TransformParameters( SID_OPENDOC, aArgs, *pParams );
+
+ String aFilterName;
+ SFX_ITEMSET_ARG( pSet, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if( pFilterNameItem )
+ aFilterName = pFilterNameItem->GetValue();
+ pFilter = SFX_APP()->GetFilterMatcher().GetFilter4FilterName( aFilterName );
+
+ sal_Bool bSalvage = sal_False;
+ SFX_ITEMSET_ARG( pSet, pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
+ if( pSalvageItem )
+ {
+ // QUESTION: there is some treatment of Salvage in Init_Impl; align!
+ bSalvage = sal_True;
+ if ( pSalvageItem->GetValue().Len() )
+ {
+ // if an URL is provided in SalvageItem that means that the FileName refers to a temporary file
+ // that must be copied here
+
+ SFX_ITEMSET_ARG( pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE );
+ if (!pFileNameItem) throw uno::RuntimeException();
+ ::rtl::OUString aNewTempFileURL = SfxMedium::CreateTempCopyWithExt( pFileNameItem->GetValue() );
+ if ( aNewTempFileURL.getLength() )
+ {
+ pSet->Put( SfxStringItem( SID_FILE_NAME, aNewTempFileURL ) );
+ pSet->ClearItem( SID_INPUTSTREAM );
+ pSet->ClearItem( SID_STREAM );
+ pSet->ClearItem( SID_CONTENT );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "Can not create a new temporary file for crash recovery!\n" );
+ }
+ }
+ }
+
+ BOOL bReadOnly = FALSE;
+ SFX_ITEMSET_ARG( pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, FALSE );
+ if ( pReadOnlyItem && pReadOnlyItem->GetValue() )
+ bReadOnly = TRUE;
+
+ SFX_ITEMSET_ARG( pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE );
+ if (!pFileNameItem) throw uno::RuntimeException();
+ aLogicName = pFileNameItem->GetValue();
+ nStorOpenMode = bReadOnly ? SFX_STREAM_READONLY : SFX_STREAM_READWRITE;
+ bDirect = FALSE;
+ Init_Impl();
+}
+
+
+//------------------------------------------------------------------
+
+SfxMedium::SfxMedium( const uno::Reference < embed::XStorage >& rStor, const String& rBaseURL, const SfxItemSet* p, sal_Bool bRootP )
+: IMPL_CTOR( bRootP, 0 ), // bRoot, pURLObj
+ pSet(0),
+ pImp( new SfxMedium_Impl( this ))
+{
+ String aType = SfxFilter::GetTypeFromStorage( rStor );
+ pFilter = SFX_APP()->GetFilterMatcher().GetFilter4EA( aType );
+ DBG_ASSERT( pFilter, "No Filter for storage found!" );
+
+ Init_Impl();
+ pImp->xStorage = rStor;
+ pImp->bDisposeStorage = FALSE;
+
+ // always take BaseURL first, could be overwritten by ItemSet
+ GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL, rBaseURL ) );
+ if ( p )
+ GetItemSet()->Put( *p );
+}
+
+//------------------------------------------------------------------
+
+SfxMedium::~SfxMedium()
+{
+ /* Attention
+ Don't enable CancelTransfers() till you know that the writer/web has changed his asynchronous load
+ behaviour. Otherwhise may StyleSheets inside a html file will be loaded at the right time.
+ => further the help will be empty then ... #100490#
+ */
+ //CancelTransfers();
+
+ // if there is a requirement to clean the backup this is the last possibility to do it
+ ClearBackup_Impl();
+
+ Close();
+
+ delete pSet;
+
+ if( pImp->bIsTemp && aName.Len() )
+ {
+ String aTemp;
+ if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aTemp ))
+ {
+ DBG_ERROR("Physical name not convertable!");
+ }
+
+ if ( !::utl::UCBContentHelper::Kill( aTemp ) )
+ {
+ DBG_ERROR("Couldn't remove temporary file!");
+ }
+ }
+
+ pFilter = 0;
+
+ delete pURLObj;
+ delete pImp;
+}
+
+//------------------------------------------------------------------
+void SfxMedium::SetItemSet(SfxItemSet *pNewSet)
+{
+ delete pSet;
+ pSet = pNewSet;
+}
+
+//----------------------------------------------------------------
+const INetURLObject& SfxMedium::GetURLObject() const
+{
+ if( !pURLObj )
+ {
+ SfxMedium* pThis = const_cast < SfxMedium* > (this);
+ pThis->pURLObj = new INetURLObject( aLogicName );
+ if ( pThis->pURLObj->HasMark() )
+ (*pThis->pURLObj) = INetURLObject( aLogicName ).GetURLNoMark();
+ }
+
+ return *pURLObj;
+}
+
+//----------------------------------------------------------------
+
+const String& SfxMedium::GetPreRedirectedURL() const
+{
+ return pImp->aPreRedirectionURL;
+}
+//----------------------------------------------------------------
+
+sal_uInt32 SfxMedium::GetMIMEAndRedirect( String& /*rName*/ )
+{
+/* dv !!!! not needed any longer ?
+ INetProtocol eProt = GetURLObject().GetProtocol();
+ if( eProt == INET_PROT_FTP && SvBinding::ShouldUseFtpProxy( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
+ {
+ Any aAny( UCB_Helper::GetProperty( GetContent(), WID_FLAG_IS_FOLDER ) );
+ sal_Bool bIsFolder = FALSE;
+ if ( ( aAny >>= bIsFolder ) && bIsFolder )
+ return ERRCODE_NONE;
+ }
+
+ GetMedium_Impl();
+ if( !eError && pImp->xBinding.Is() )
+ {
+ eError = pImp->xBinding->GetMimeType( rName );
+
+ // Wir koennen keine Parameter wie CharSets usw.
+ rName = rName.GetToken( 0, ';' );
+ if( !eError )
+ {
+ if( !pImp->aPreRedirectionURL.Len() )
+ pImp->aPreRedirectionURL = aLogicName;
+ SetName( pImp->xBinding->GetRedirectedURL() );
+ }
+ pImp->aExpireTime = pImp->xBinding->GetExpireDateTime();
+ }
+ return eError;
+*/
+ return 0;
+}
+
+//----------------------------------------------------------------
+
+void SfxMedium::SetReferer( const String& rRefer )
+{
+ pImp->aReferer = rRefer;
+}
+//----------------------------------------------------------------
+
+const String& SfxMedium::GetReferer( ) const
+{
+ return pImp->aReferer;
+}
+
+//----------------------------------------------------------------
+
+void SfxMedium::SetExpired_Impl( const DateTime& rDateTime )
+{
+ pImp->aExpireTime = rDateTime;
+}
+//----------------------------------------------------------------
+
+sal_Bool SfxMedium::IsExpired() const
+{
+ return pImp->aExpireTime.IsValid() && pImp->aExpireTime < DateTime();
+}
+//----------------------------------------------------------------
+
+void SfxMedium::ForceSynchronStream_Impl( sal_Bool bForce )
+{
+ if( pInStream )
+ {
+ SvLockBytes* pBytes = pInStream->GetLockBytes();
+ if( pBytes )
+ pBytes->SetSynchronMode( bForce );
+ }
+ pImp->bForceSynchron = bForce;
+}
+
+//----------------------------------------------------------------
+SfxFrame* SfxMedium::GetLoadTargetFrame() const
+{
+ return pImp->wLoadTargetFrame;
+}
+//----------------------------------------------------------------
+
+void SfxMedium::SetLoadTargetFrame(SfxFrame* pFrame )
+{
+ pImp->wLoadTargetFrame = pFrame;
+}
+//----------------------------------------------------------------
+
+void SfxMedium::SetStorage_Impl( const uno::Reference < embed::XStorage >& rStor )
+{
+ pImp->xStorage = rStor;
+}
+//----------------------------------------------------------------
+
+SfxItemSet* SfxMedium::GetItemSet() const
+{
+ // this method *must* return an ItemSet, returning NULL can cause crashes
+ if( !pSet )
+ ((SfxMedium*)this)->pSet = new SfxAllItemSet( SFX_APP()->GetPool() );
+ return pSet;
+}
+//----------------------------------------------------------------
+
+SvKeyValueIterator* SfxMedium::GetHeaderAttributes_Impl()
+{
+ if( !pImp->xAttributes.Is() )
+ {
+ pImp->xAttributes = SvKeyValueIteratorRef( new SvKeyValueIterator );
+
+ if ( GetContent().is() )
+ {
+ pImp->bIsCharsetInitialized = sal_True;
+
+ try
+ {
+ Any aAny = pImp->aContent.getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
+ ::rtl::OUString aContentType;
+ aAny >>= aContentType;
+
+ pImp->xAttributes->Append( SvKeyValue( ::rtl::OUString::createFromAscii( "content-type" ), aContentType ) );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+
+ return pImp->xAttributes;
+}
+//----------------------------------------------------------------
+
+SvCompatWeakHdl* SfxMedium::GetHdl()
+{
+ return pImp->GetHdl();
+}
+
+sal_Bool SfxMedium::IsDownloadDone_Impl()
+{
+ return pImp->bDownloadDone;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SfxMedium::GetInputStream()
+{
+ if ( !pImp->xInputStream.is() )
+ GetMedium_Impl();
+ return pImp->xInputStream;
+}
+
+const uno::Sequence < util::RevisionTag >& SfxMedium::GetVersionList( bool _bNoReload )
+{
+ // if the medium has no name, then this medium should represent a new document and can have no version info
+ if ( ( !_bNoReload || !pImp->m_bVersionsAlreadyLoaded ) && !pImp->aVersions.getLength() &&
+ ( aName.Len() || aLogicName.Len() ) && GetStorage().is() )
+ {
+ uno::Reference < document::XDocumentRevisionListPersistence > xReader( comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY );
+ if ( xReader.is() )
+ {
+ try
+ {
+ pImp->aVersions = xReader->load( GetStorage() );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ if ( !pImp->m_bVersionsAlreadyLoaded )
+ pImp->m_bVersionsAlreadyLoaded = sal_True;
+
+ return pImp->aVersions;
+}
+
+uno::Sequence < util::RevisionTag > SfxMedium::GetVersionList( const uno::Reference < embed::XStorage >& xStorage )
+{
+ uno::Reference < document::XDocumentRevisionListPersistence > xReader( comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY );
+ if ( xReader.is() )
+ {
+ try
+ {
+ return xReader->load( xStorage );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ return uno::Sequence < util::RevisionTag >();
+}
+
+sal_uInt16 SfxMedium::AddVersion_Impl( util::RevisionTag& rRevision )
+{
+ if ( GetStorage().is() )
+ {
+ // Einen eindeutigen Namen f"ur den Stream ermitteln
+ SvULongs aLongs;
+ sal_Int32 nLength = pImp->aVersions.getLength();
+ for ( sal_Int32 m=0; m<nLength; m++ )
+ {
+ sal_uInt32 nVer = (sal_uInt32) String( pImp->aVersions[m].Identifier ).Copy(7).ToInt32();
+ sal_uInt16 n;
+ for ( n=0; n<aLongs.Count(); n++ )
+ if ( nVer<aLongs[n] )
+ break;
+
+ aLongs.Insert( nVer, n );
+ }
+
+ sal_uInt16 nKey;
+ for ( nKey=0; nKey<aLongs.Count(); nKey++ )
+ if ( aLongs[nKey] > ( ULONG ) nKey+1 )
+ break;
+
+ String aRevName = DEFINE_CONST_UNICODE( "Version" );
+ aRevName += String::CreateFromInt32( nKey + 1 );
+ pImp->aVersions.realloc( nLength+1 );
+ rRevision.Identifier = aRevName;
+ pImp->aVersions[nLength] = rRevision;
+ return nKey;
+ }
+
+ return 0;
+}
+
+sal_Bool SfxMedium::RemoveVersion_Impl( const ::rtl::OUString& rName )
+{
+ if ( !pImp->aVersions.getLength() )
+ return sal_False;
+
+ sal_Int32 nLength = pImp->aVersions.getLength();
+ for ( sal_Int32 n=0; n<nLength; n++ )
+ {
+ if ( pImp->aVersions[n].Identifier == rName )
+ {
+ for ( sal_Int32 m=n; m<nLength-1; m++ )
+ pImp->aVersions[m] = pImp->aVersions[m+1];
+ pImp->aVersions.realloc(nLength-1);
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+sal_Bool SfxMedium::TransferVersionList_Impl( SfxMedium& rMedium )
+{
+ if ( rMedium.pImp->aVersions.getLength() )
+ {
+ pImp->aVersions = rMedium.pImp->aVersions;
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool SfxMedium::SaveVersionList_Impl( sal_Bool /*bUseXML*/ )
+{
+ if ( GetStorage().is() )
+ {
+ if ( !pImp->aVersions.getLength() )
+ return sal_True;
+
+ uno::Reference < document::XDocumentRevisionListPersistence > xWriter( comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence") ), uno::UNO_QUERY );
+ if ( xWriter.is() )
+ {
+ try
+ {
+ xWriter->store( GetStorage(), pImp->aVersions );
+ return sal_True;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ return sal_False;
+}
+
+//----------------------------------------------------------------
+sal_Bool SfxMedium::IsReadOnly()
+{
+ sal_Bool bReadOnly = sal_False;
+
+ // a) ReadOnly filter cant produce read/write contents!
+ bReadOnly = (
+ (pFilter ) &&
+ ((pFilter->GetFilterFlags() & SFX_FILTER_OPENREADONLY) == SFX_FILTER_OPENREADONLY)
+ );
+
+ // b) if filter allow read/write contents .. check open mode of the storage
+ if (!bReadOnly)
+ bReadOnly = !( GetOpenMode() & STREAM_WRITE );
+
+ // c) the API can force the readonly state!
+ if (!bReadOnly)
+ {
+ SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_DOC_READONLY, sal_False);
+ if (pItem)
+ bReadOnly = pItem->GetValue();
+ }
+
+ return bReadOnly;
+}
+
+//----------------------------------------------------------------
+sal_Bool SfxMedium::SetWritableForUserOnly( const ::rtl::OUString& aURL )
+{
+ // UCB does not allow to allow write access only for the user,
+ // use osl API
+ sal_Bool bResult = sal_False;
+
+ ::osl::DirectoryItem aDirItem;
+ if ( ::osl::DirectoryItem::get( aURL, aDirItem ) == ::osl::FileBase::E_None )
+ {
+ ::osl::FileStatus aFileStatus( FileStatusMask_Attributes );
+ if ( aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None
+ && aFileStatus.isValid( FileStatusMask_Attributes ) )
+ {
+ sal_uInt64 nAttributes = aFileStatus.getAttributes();
+
+ nAttributes &= ~(Attribute_OwnWrite |
+ Attribute_GrpWrite |
+ Attribute_OthWrite |
+ Attribute_ReadOnly);
+ nAttributes |= Attribute_OwnWrite;
+
+ bResult = ( osl::File::setAttributes( aURL, nAttributes ) == ::osl::FileBase::E_None );
+ }
+ }
+
+ return bResult;
+}
+
+//----------------------------------------------------------------
+void SfxMedium::CreateTempFile( sal_Bool bReplace )
+{
+ if ( pImp->pTempFile )
+ {
+ if ( !bReplace )
+ return;
+
+ DELETEZ( pImp->pTempFile );
+ aName = String();
+ }
+
+ pImp->pTempFile = new ::utl::TempFile();
+ pImp->pTempFile->EnableKillingFile( sal_True );
+ aName = pImp->pTempFile->GetFileName();
+ ::rtl::OUString aTmpURL = pImp->pTempFile->GetURL();
+ if ( !aName.Len() || !aTmpURL.getLength() )
+ {
+ SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return;
+ }
+
+ if ( !( nStorOpenMode & STREAM_TRUNC ) )
+ {
+ sal_Bool bTransferSuccess = sal_False;
+
+ if ( GetContent().is()
+ && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
+ && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
+ {
+ // if there is already such a document, we should copy it
+ // if it is a file system use OS copy process
+ try
+ {
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
+ INetURLObject aTmpURLObj( aTmpURL );
+ ::rtl::OUString aFileName = aTmpURLObj.getName( INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ if ( aFileName.getLength() && aTmpURLObj.removeSegment() )
+ {
+ ::ucbhelper::Content aTargetContent( aTmpURLObj.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
+ if ( aTargetContent.transferContent( pImp->aContent, ::ucbhelper::InsertOperation_COPY, aFileName, NameClash::OVERWRITE ) )
+ {
+ SetWritableForUserOnly( aTmpURL );
+ bTransferSuccess = sal_True;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+
+ if ( bTransferSuccess )
+ {
+ CloseOutStream();
+ CloseInStream();
+ }
+ }
+
+ if ( !bTransferSuccess && pInStream )
+ {
+ // the case when there is no URL-access available or this is a remote protocoll
+ // but there is an input stream
+ GetOutStream();
+ if ( pOutStream )
+ {
+ char *pBuf = new char [8192];
+ sal_uInt32 nErr = ERRCODE_NONE;
+
+ pInStream->Seek(0);
+ pOutStream->Seek(0);
+
+ while( !pInStream->IsEof() && nErr == ERRCODE_NONE )
+ {
+ sal_uInt32 nRead = pInStream->Read( pBuf, 8192 );
+ nErr = pInStream->GetError();
+ pOutStream->Write( pBuf, nRead );
+ }
+
+ bTransferSuccess = sal_True;
+ delete[] pBuf;
+ CloseInStream();
+ }
+ CloseOutStream_Impl();
+ }
+ else
+ {
+ // Quite strange design, but currently it is expected that in this case no transfer happens
+ // TODO/LATER: get rid of this inconsistent part of the call design
+ bTransferSuccess = sal_True;
+ CloseInStream();
+ }
+
+ if ( !bTransferSuccess )
+ {
+ SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return;
+ }
+ }
+
+ CloseStorage();
+}
+
+//----------------------------------------------------------------
+void SfxMedium::CreateTempFileNoCopy()
+{
+ // this call always replaces the existing temporary file
+ if ( pImp->pTempFile )
+ delete pImp->pTempFile;
+
+ pImp->pTempFile = new ::utl::TempFile();
+ pImp->pTempFile->EnableKillingFile( sal_True );
+ aName = pImp->pTempFile->GetFileName();
+ if ( !aName.Len() )
+ {
+ SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return;
+ }
+
+ CloseOutStream_Impl();
+ CloseStorage();
+}
+
+::rtl::OUString SfxMedium::GetCharset()
+{
+ if( !pImp->bIsCharsetInitialized )
+ {
+ // Set an error in case there is no content?
+ if ( GetContent().is() )
+ {
+ pImp->bIsCharsetInitialized = sal_True;
+
+ try
+ {
+ Any aAny = pImp->aContent.getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
+ ::rtl::OUString aField;
+ aAny >>= aField;
+
+ ::rtl::OString sContent = ::rtl::OUStringToOString( aField, RTL_TEXTENCODING_ASCII_US );
+ ByteString sType, sSubType;
+ INetContentTypeParameterList aParameters;
+
+ if( INetContentTypes::parse( sContent, sType, sSubType, &aParameters ) )
+ {
+ const INetContentTypeParameter * pCharset = aParameters.find("charset");
+ if (pCharset != 0)
+ pImp->aCharset = pCharset->m_sValue;
+ }
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+
+ return pImp->aCharset;
+}
+
+void SfxMedium::SetCharset( ::rtl::OUString aChs )
+{
+ pImp->bIsCharsetInitialized = sal_True;
+ pImp->aCharset = aChs;
+}
+
+sal_Bool SfxMedium::SignContents_Impl( sal_Bool bScriptingContent, const ::rtl::OUString& aODFVersion, sal_Bool bHasValidDocumentSignature )
+{
+ sal_Bool bChanges = FALSE;
+
+ // the medium should be closed to be able to sign, the caller is responsible to close it
+ if ( !IsOpen() && !GetError() )
+ {
+ // The component should know if there was a valid document signature, since
+ // it should show a warning in this case
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[0] <<= aODFVersion;
+ aArgs[1] <<= bHasValidDocumentSignature;
+ ::com::sun::star::uno::Reference< ::com::sun::star::security::XDocumentDigitalSignatures > xSigner(
+ comphelper::getProcessServiceFactory()->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ),
+ aArgs ),
+ ::com::sun::star::uno::UNO_QUERY );
+
+ if ( xSigner.is() )
+ {
+ uno::Reference< embed::XStorage > xWriteableZipStor;
+ if ( !IsReadOnly() )
+ {
+ // we can reuse the temporary file if there is one already
+ CreateTempFile( sal_False );
+ GetMedium_Impl();
+
+ try
+ {
+ if ( !pImp->xStream.is() )
+ throw uno::RuntimeException();
+
+ xWriteableZipStor = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream );
+ if ( !xWriteableZipStor.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< embed::XStorage > xMetaInf = xWriteableZipStor->openStorageElement(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ),
+ embed::ElementModes::READWRITE );
+ if ( !xMetaInf.is() )
+ throw uno::RuntimeException();
+
+ if ( bScriptingContent )
+ {
+ // If the signature has already the document signature it will be removed
+ // after the scripting signature is inserted.
+ uno::Reference< io::XStream > xStream(
+ xMetaInf->openStreamElement( xSigner->getScriptingContentSignatureDefaultStreamName(),
+ embed::ElementModes::READWRITE ),
+ uno::UNO_SET_THROW );
+
+ if ( xSigner->signScriptingContent( GetZipStorageToSign_Impl(), xStream ) )
+ {
+ // remove the document signature if any
+ ::rtl::OUString aDocSigName = xSigner->getDocumentContentSignatureDefaultStreamName();
+ if ( aDocSigName.getLength() && xMetaInf->hasByName( aDocSigName ) )
+ xMetaInf->removeElement( aDocSigName );
+
+ uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW );
+ xTransact->commit();
+ xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW );
+ xTransact->commit();
+
+ // the temporary file has been written, commit it to the original file
+ Commit();
+ bChanges = TRUE;
+ }
+ }
+ else
+ {
+ uno::Reference< io::XStream > xStream(
+ xMetaInf->openStreamElement( xSigner->getDocumentContentSignatureDefaultStreamName(),
+ embed::ElementModes::READWRITE ),
+ uno::UNO_SET_THROW );
+
+ if ( xSigner->signDocumentContent( GetZipStorageToSign_Impl(), xStream ) )
+ {
+ uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW );
+ xTransact->commit();
+ xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW );
+ xTransact->commit();
+
+ // the temporary file has been written, commit it to the original file
+ Commit();
+ bChanges = TRUE;
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" );
+ }
+
+ CloseAndRelease();
+ }
+ else
+ {
+ try
+ {
+ if ( bScriptingContent )
+ xSigner->showScriptingContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() );
+ else
+ xSigner->showDocumentContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" );
+ }
+ }
+ }
+
+ ResetError();
+ }
+
+ return bChanges;
+}
+
+//----------------------------------------------------------------
+sal_uInt16 SfxMedium::GetCachedSignatureState_Impl()
+{
+ return pImp->m_nSignatureState;
+}
+
+//----------------------------------------------------------------
+void SfxMedium::SetCachedSignatureState_Impl( sal_uInt16 nState )
+{
+ pImp->m_nSignatureState = nState;
+}
+
+//----------------------------------------------------------------
+sal_Bool SfxMedium::EqualURLs( const ::rtl::OUString& aFirstURL, const ::rtl::OUString& aSecondURL )
+{
+ sal_Bool bResult = sal_False;
+
+ if ( aFirstURL.getLength() && aSecondURL.getLength() )
+ {
+ INetURLObject aFirst( aFirstURL );
+ INetURLObject aSecond( aSecondURL );
+
+ if ( aFirst.GetProtocol() != INET_PROT_NOT_VALID && aSecond.GetProtocol() != INET_PROT_NOT_VALID )
+ {
+ try
+ {
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ if ( !pBroker )
+ throw uno::RuntimeException();
+
+ uno::Reference< ::com::sun::star::ucb::XContentIdentifierFactory > xIdFac
+ = pBroker->getContentIdentifierFactoryInterface();
+ if ( !xIdFac.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< ::com::sun::star::ucb::XContentIdentifier > xIdFirst
+ = xIdFac->createContentIdentifier( aFirst.GetMainURL( INetURLObject::NO_DECODE ) );
+ uno::Reference< ::com::sun::star::ucb::XContentIdentifier > xIdSecond
+ = xIdFac->createContentIdentifier( aSecond.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ if ( xIdFirst.is() && xIdSecond.is() )
+ {
+ uno::Reference< ::com::sun::star::ucb::XContentProvider > xProvider =
+ pBroker->getContentProviderInterface();
+ if ( !xProvider.is() )
+ throw uno::RuntimeException();
+ bResult = !xProvider->compareContentIds( xIdFirst, xIdSecond );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Can't compare URL's, treat as different!\n" );
+ }
+ }
+ }
+
+ return bResult;
+}
+
+BOOL SfxMedium::HasStorage_Impl() const
+{
+ return pImp->xStorage.is();
+}
+
+BOOL SfxMedium::IsOpen() const
+{
+ return pInStream || pOutStream || pImp->xStorage.is();
+}
+
+::rtl::OUString SfxMedium::CreateTempCopyWithExt( const ::rtl::OUString& aURL )
+{
+ ::rtl::OUString aResult;
+
+ if ( aURL.getLength() )
+ {
+ sal_Int32 nPrefixLen = aURL.lastIndexOf( '.' );
+ String aExt = ( nPrefixLen == -1 ) ? String() : String( aURL.copy( nPrefixLen ) );
+
+ ::rtl::OUString aNewTempFileURL = ::utl::TempFile( String(), &aExt ).GetURL();
+ if ( aNewTempFileURL.getLength() )
+ {
+ INetURLObject aSource( aURL );
+ INetURLObject aDest( aNewTempFileURL );
+ ::rtl::OUString aFileName = aDest.getName( INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ if ( aFileName.getLength() && aDest.removeSegment() )
+ {
+ try
+ {
+ uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
+ ::ucbhelper::Content aTargetContent( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
+ ::ucbhelper::Content aSourceContent( aSource.GetMainURL( INetURLObject::NO_DECODE ), xComEnv );
+ if ( aTargetContent.transferContent( aSourceContent,
+ ::ucbhelper::InsertOperation_COPY,
+ aFileName,
+ NameClash::OVERWRITE ) )
+ {
+ // Success
+ aResult = aNewTempFileURL;
+ }
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ }
+ }
+
+ return aResult;
+}
+
+sal_Bool SfxMedium::CallApproveHandler( const uno::Reference< task::XInteractionHandler >& xHandler, uno::Any aRequest, sal_Bool bAllowAbort )
+{
+ sal_Bool bResult = sal_False;
+
+ if ( xHandler.is() )
+ {
+ try
+ {
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( bAllowAbort ? 2 : 1 );
+
+ ::rtl::Reference< ::framework::ContinuationApprove > pApprove( new ::framework::ContinuationApprove() );
+ aContinuations[ 0 ] = pApprove.get();
+
+ if ( bAllowAbort )
+ {
+ ::rtl::Reference< ::framework::ContinuationAbort > pAbort( new ::framework::ContinuationAbort() );
+ aContinuations[ 1 ] = pAbort.get();
+ }
+
+ uno::Reference< task::XInteractionRequest > xRequest( new ::framework::InteractionRequest( aRequest, aContinuations ) );
+ xHandler->handle( xRequest );
+
+ bResult = pApprove->isSelected();
+ }
+ catch( const Exception& )
+ {
+ }
+ }
+
+ return bResult;
+}
+
+::rtl::OUString SfxMedium::SwitchDocumentToTempFile()
+{
+ // the method returns empty string in case of failure
+ ::rtl::OUString aResult;
+ ::rtl::OUString aOrigURL = aLogicName;
+
+ if ( aOrigURL.getLength() )
+ {
+ sal_Int32 nPrefixLen = aOrigURL.lastIndexOf( '.' );
+ String aExt = ( nPrefixLen == -1 ) ? String() : String( aOrigURL.copy( nPrefixLen ) );
+ ::rtl::OUString aNewURL = ::utl::TempFile( String(), &aExt ).GetURL();
+
+ // TODO/LATER: In future the aLogicName should be set to shared folder URL
+ // and a temporary file should be created. Transport_Impl should be impossible then.
+ if ( aNewURL.getLength() )
+ {
+ uno::Reference< embed::XStorage > xStorage = GetStorage();
+ uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY );
+
+ if ( xOptStorage.is() )
+ {
+ // TODO/LATER: reuse the pImp->pTempFile if it already exists
+ CanDisposeStorage_Impl( sal_False );
+ Close();
+ SetPhysicalName_Impl( String() );
+ SetName( aNewURL );
+
+ // remove the readonly state
+ sal_Bool bWasReadonly = sal_False;
+ nStorOpenMode = SFX_STREAM_READWRITE;
+ SFX_ITEMSET_ARG( pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, FALSE );
+ if ( pReadOnlyItem && pReadOnlyItem->GetValue() )
+ bWasReadonly = sal_True;
+ GetItemSet()->ClearItem( SID_DOC_READONLY );
+
+ GetMedium_Impl();
+ LockOrigFileOnDemand( sal_False, sal_False );
+ CreateTempFile( sal_True );
+ GetMedium_Impl();
+
+ if ( pImp->xStream.is() )
+ {
+ try
+ {
+ xOptStorage->writeAndAttachToStream( pImp->xStream );
+ pImp->xStorage = xStorage;
+ aResult = aNewURL;
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if ( !aResult.getLength() )
+ {
+ Close();
+ SetPhysicalName_Impl( String() );
+ SetName( aOrigURL );
+ if ( bWasReadonly )
+ {
+ // set the readonly state back
+ nStorOpenMode = SFX_STREAM_READONLY;
+ GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY, sal_True));
+ }
+ GetMedium_Impl();
+ pImp->xStorage = xStorage;
+ }
+ }
+ }
+ }
+
+ return aResult;
+}
+
+sal_Bool SfxMedium::SwitchDocumentToFile( ::rtl::OUString aURL )
+{
+ // the method is only for storage based documents
+ sal_Bool bResult = sal_False;
+ ::rtl::OUString aOrigURL = aLogicName;
+
+ if ( aURL.getLength() && aOrigURL.getLength() )
+ {
+ uno::Reference< embed::XStorage > xStorage = GetStorage();
+ uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY );
+
+ if ( xOptStorage.is() )
+ {
+ // TODO/LATER: reuse the pImp->pTempFile if it already exists
+ CanDisposeStorage_Impl( sal_False );
+ Close();
+ SetPhysicalName_Impl( String() );
+ SetName( aURL );
+
+ // open the temporary file based document
+ GetMedium_Impl();
+ LockOrigFileOnDemand( sal_False, sal_False );
+ CreateTempFile( sal_True );
+ GetMedium_Impl();
+
+ if ( pImp->xStream.is() )
+ {
+ try
+ {
+ uno::Reference< io::XTruncate > xTruncate( pImp->xStream, uno::UNO_QUERY_THROW );
+ if ( xTruncate.is() )
+ xTruncate->truncate();
+
+ xOptStorage->writeAndAttachToStream( pImp->xStream );
+ pImp->xStorage = xStorage;
+ bResult = sal_True;
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if ( !bResult )
+ {
+ Close();
+ SetPhysicalName_Impl( String() );
+ SetName( aOrigURL );
+ GetMedium_Impl();
+ pImp->xStorage = xStorage;
+ }
+ }
+ }
+
+ return bResult;
+}
+
diff --git a/sfx2/source/doc/docfilt.cxx b/sfx2/source/doc/docfilt.cxx
new file mode 100644
index 000000000000..1219d30d7b27
--- /dev/null
+++ b/sfx2/source/doc/docfilt.cxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#ifdef SOLARIS
+// HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
+#include <ctime>
+#endif
+
+#include <string> // HACK: prevent conflict between STLPORT and Workshop headers
+#include <sot/exchange.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <sfx2/docfac.hxx>
+#include <sfx2/docfilt.hxx>
+#include "fltfnc.hxx"
+#include <sfx2/sfxuno.hxx>
+#include <sfx2/objsh.hxx>
+
+using namespace ::com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+DBG_NAME(SfxFilter)
+
+SfxFilter::SfxFilter( const String &rName,
+ const String &rWildCard,
+ SfxFilterFlags nType,
+ sal_uInt32 lFmt,
+ const String &rTypNm,
+ sal_uInt16 nIcon,
+ const String &rMimeType,
+ const String &rUsrDat,
+ const String &rServiceName ):
+ aWildCard(rWildCard, ';'),
+ lFormat(lFmt),
+ aTypeName(rTypNm),
+ aUserData(rUsrDat),
+ nFormatType(nType),
+ nDocIcon(nIcon),
+ aServiceName( rServiceName ),
+ aMimeType( rMimeType ),
+ aFilterName( rName )
+{
+ String aExts = GetWildcard()();
+ String aShort, aLong;
+ String aRet;
+ sal_uInt16 nMaxLength = USHRT_MAX;
+ String aTest;
+ sal_uInt16 nPos = 0;
+ while( ( aRet = aExts.GetToken( nPos++, ';' ) ).Len() )
+ {
+ aTest = aRet;
+ aTest.SearchAndReplace( DEFINE_CONST_UNICODE( "*." ), String() );
+ if( aTest.Len() <= nMaxLength )
+ {
+ if( aShort.Len() ) aShort += ';';
+ aShort += aRet;
+ }
+ else
+ {
+ if( aLong.Len() ) aLong += ';';
+ aLong += aRet;
+ }
+ }
+ if( aShort.Len() && aLong.Len() )
+ {
+ aShort += ';';
+ aShort += aLong;
+ }
+ aWildCard = aShort;
+
+ nVersion = SOFFICE_FILEFORMAT_50;
+ aUIName = aFilterName;
+}
+
+SfxFilter::~SfxFilter()
+{
+}
+
+String SfxFilter::GetDefaultExtension() const
+{
+ return GetWildcard()().GetToken( 0, ';' );
+}
+
+String SfxFilter::GetSuffixes() const
+{
+ String aRet = GetWildcard()();
+ while( aRet.SearchAndReplaceAscii( "*.", String() ) != STRING_NOTFOUND ) ;
+ while( aRet.SearchAndReplace( ';', ',' ) != STRING_NOTFOUND ) ;
+ return aRet;
+}
+
+const SfxFilter* SfxFilter::GetDefaultFilter( const String& rName )
+{
+ return SfxFilterContainer::GetDefaultFilter_Impl( rName );
+}
+
+const SfxFilter* SfxFilter::GetDefaultFilterFromFactory( const String& rFact )
+{
+ return GetDefaultFilter( SfxObjectShell::GetServiceNameFromFactory( rFact ) );
+}
+
+const SfxFilter* SfxFilter::GetFilterByName( const String& rName )
+{
+ SfxFilterMatcher aMatch;
+ return aMatch.GetFilter4FilterName( rName, 0, 0 );
+}
+
+String SfxFilter::GetTypeFromStorage( const SotStorage& rStg )
+{
+ const char* pType=0;
+ if ( rStg.IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "WordDocument" ) ) ) )
+ {
+ if ( rStg.IsStream( String::CreateFromAscii("0Table" ) ) || rStg.IsStream( String::CreateFromAscii("1Table" ) ) )
+ pType = "writer_MS_Word_97";
+ else
+ pType = "writer_MS_Word_95";
+ }
+ else if ( rStg.IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Book" ) ) ) )
+ {
+ pType = "calc_MS_Excel_95";
+ }
+ else if ( rStg.IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Workbook" ) ) ) )
+ {
+ pType = "calc_MS_Excel_97";
+ }
+ else if ( rStg.IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PowerPoint Document" ) ) ) )
+ {
+ pType = "impress_MS_PowerPoint_97";
+ }
+ else if ( rStg.IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Equation Native" ) ) ) )
+ {
+ pType = "math_MathType_3x";
+ }
+ else
+ {
+ sal_Int32 nClipId = ((SotStorage&)rStg).GetFormat();
+ if ( nClipId )
+ {
+ const SfxFilter* pFilter = SfxFilterMatcher().GetFilter4ClipBoardId( nClipId );
+ if ( pFilter )
+ return pFilter->GetTypeName();
+ }
+ }
+
+ return pType ? String::CreateFromAscii(pType) : String();
+}
+
+String SfxFilter::GetTypeFromStorage( const com::sun::star::uno::Reference< com::sun::star::embed::XStorage >& xStorage, BOOL bTemplate,
+ String* pFilterName )
+ throw ( beans::UnknownPropertyException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ SfxFilterMatcher aMatcher;
+ const char* pType=0;
+ String aName;
+ if ( pFilterName )
+ {
+ aName = *pFilterName;
+ pFilterName->Erase();
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xProps( xStorage, com::sun::star::uno::UNO_QUERY );
+ if ( xProps.is() )
+ {
+ ::rtl::OUString aMediaType;
+ xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType;
+ if ( aMediaType.getLength() )
+ {
+ ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
+ aDataFlavor.MimeType = aMediaType;
+ sal_uInt32 nClipId = SotExchange::GetFormat( aDataFlavor );
+ if ( nClipId )
+ {
+ SfxFilterFlags nMust = SFX_FILTER_IMPORT, nDont = SFX_FILTER_NOTINSTALLED;
+ if ( bTemplate )
+ // template filter was preselected, try to verify
+ nMust |= SFX_FILTER_TEMPLATEPATH;
+ else
+ // template filters shouldn't be detected if not explicitly asked for
+ nDont |= SFX_FILTER_TEMPLATEPATH;
+
+ const SfxFilter* pFilter = 0;
+ if ( aName.Len() )
+ // get preselected Filter if it matches the desired filter flags
+ pFilter = aMatcher.GetFilter4FilterName( aName, nMust, nDont );
+
+ if ( !pFilter || pFilter->GetFormat() != nClipId )
+ {
+ // get filter from storage MediaType
+ pFilter = aMatcher.GetFilter4ClipBoardId( nClipId, nMust, nDont );
+ if ( !pFilter )
+ // template filter is asked for , but there isn't one; so at least the "normal" format should be detected
+ // or storage *is* a template, but bTemplate is not set
+ pFilter = aMatcher.GetFilter4ClipBoardId( nClipId );
+ }
+
+ if ( pFilter )
+ {
+ if ( pFilterName )
+ *pFilterName = pFilter->GetName();
+ return pFilter->GetTypeName();
+ }
+ }
+ }
+ }
+
+ //TODO: do it without SfxFilter
+ //TODO/LATER: don't yield FilterName, should be done in FWK!
+ String aRet;
+ if ( pType )
+ {
+ aRet = String::CreateFromAscii(pType);
+ if ( pFilterName )
+ *pFilterName = aMatcher.GetFilter4EA( aRet )->GetName();
+ }
+
+ return aRet;
+}
diff --git a/sfx2/source/doc/docinf.cxx b/sfx2/source/doc/docinf.cxx
new file mode 100644
index 000000000000..d0f6678d8641
--- /dev/null
+++ b/sfx2/source/doc/docinf.cxx
@@ -0,0 +1,309 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <sfx2/docinf.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+
+#include <rtl/ustring.hxx>
+#include <tools/debug.hxx>
+#include <comphelper/string.hxx>
+#include <sot/storage.hxx>
+#include <vcl/gdimtf.hxx>
+
+#include "oleprops.hxx"
+
+// ============================================================================
+
+// stream names
+#define STREAM_SUMMARYINFO "\005SummaryInformation"
+#define STREAM_DOCSUMMARYINFO "\005DocumentSummaryInformation"
+
+// usings
+using namespace ::com::sun::star;
+
+
+namespace sfx2 {
+
+sal_uInt32 SFX2_DLLPUBLIC LoadOlePropertySet(
+ uno::Reference< document::XDocumentProperties> i_xDocProps,
+ SotStorage* i_pStorage )
+{
+ // *** global properties from stream "005SummaryInformation" ***
+
+ // load the property set
+ SfxOlePropertySet aGlobSet;
+ ErrCode nGlobError = aGlobSet.LoadPropertySet(i_pStorage,
+ String( RTL_CONSTASCII_USTRINGPARAM( STREAM_SUMMARYINFO ) ) );
+
+ // global section
+ SfxOleSectionRef xGlobSect = aGlobSet.GetSection( SECTION_GLOBAL );
+ if( xGlobSect.get() )
+ {
+ // set supported properties
+ String aStrValue;
+ util::DateTime aDateTime;
+
+ if( xGlobSect->GetStringValue( aStrValue, PROPID_TITLE ) )
+ i_xDocProps->setTitle( aStrValue );
+ if( xGlobSect->GetStringValue( aStrValue, PROPID_SUBJECT ) )
+ i_xDocProps->setSubject( aStrValue );
+ if( xGlobSect->GetStringValue( aStrValue, PROPID_KEYWORDS ) ) {
+ i_xDocProps->setKeywords(
+ ::comphelper::string::convertCommaSeparated(aStrValue) );
+ }
+ if( xGlobSect->GetStringValue( aStrValue, PROPID_TEMPLATE ) )
+ i_xDocProps->setTemplateName( aStrValue );
+ if( xGlobSect->GetStringValue( aStrValue, PROPID_COMMENTS ) )
+ i_xDocProps->setDescription( aStrValue );
+
+ util::DateTime aInvalid;
+ if( xGlobSect->GetStringValue( aStrValue, PROPID_AUTHOR) )
+ i_xDocProps->setAuthor( aStrValue );
+ else
+ i_xDocProps->setAuthor( ::rtl::OUString() );
+ if( xGlobSect->GetFileTimeValue( aDateTime, PROPID_CREATED ) )
+ i_xDocProps->setCreationDate( aDateTime );
+ else
+ i_xDocProps->setCreationDate( aInvalid );
+
+ if( xGlobSect->GetStringValue( aStrValue, PROPID_LASTAUTHOR) )
+ i_xDocProps->setModifiedBy( aStrValue );
+ else
+ i_xDocProps->setModifiedBy( ::rtl::OUString() );
+ if( xGlobSect->GetFileTimeValue( aDateTime, PROPID_LASTSAVED ) )
+ i_xDocProps->setModificationDate( aDateTime );
+ else
+ i_xDocProps->setModificationDate( aInvalid );
+
+ i_xDocProps->setPrintedBy( ::rtl::OUString() );
+ if( xGlobSect->GetFileTimeValue( aDateTime, PROPID_LASTPRINTED ) )
+ i_xDocProps->setPrintDate( aDateTime );
+ else
+ i_xDocProps->setPrintDate( aInvalid );
+
+ if( xGlobSect->GetStringValue( aStrValue, PROPID_REVNUMBER ) )
+ {
+ sal_Int16 nRevision = static_cast< sal_Int16 >( aStrValue.ToInt32() );
+ if ( nRevision > 0 )
+ i_xDocProps->setEditingCycles( nRevision );
+ }
+
+ if( xGlobSect->GetFileTimeValue( aDateTime, PROPID_EDITTIME ) )
+ {
+ // subtract offset 1601-01-01
+ aDateTime.Year -= 1601;
+ aDateTime.Month -= 1;
+ aDateTime.Day -= 1;
+ try
+ {
+ i_xDocProps->setEditingDuration(
+ aDateTime.Day * 60*60*24 +
+ aDateTime.Hours * 60*60 +
+ aDateTime.Minutes * 60 +
+ aDateTime.Seconds );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ // ignore
+ }
+ }
+ }
+
+ // *** custom properties from stream "005DocumentSummaryInformation" ***
+
+ // load the property set
+ SfxOlePropertySet aDocSet;
+ ErrCode nDocError = aDocSet.LoadPropertySet(i_pStorage,
+ String( RTL_CONSTASCII_USTRINGPARAM( STREAM_DOCSUMMARYINFO ) ) );
+
+ // custom properties
+ SfxOleSectionRef xCustomSect = aDocSet.GetSection( SECTION_CUSTOM );
+ if( xCustomSect.get() )
+ {
+ uno::Reference < beans::XPropertyContainer > xUserDefined(
+ i_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ ::std::vector< sal_Int32 > aPropIds;
+ xCustomSect->GetPropertyIds( aPropIds );
+ for( ::std::vector< sal_Int32 >::const_iterator aIt = aPropIds.begin(),
+ aEnd = aPropIds.end(); aIt != aEnd; ++aIt )
+ {
+ ::rtl::OUString aPropName = xCustomSect->GetPropertyName( *aIt );
+ uno::Any aPropValue = xCustomSect->GetAnyValue( *aIt );
+ if( (aPropName.getLength() > 0) && aPropValue.hasValue() ) {
+ try {
+ xUserDefined->addProperty( aPropName,
+ beans::PropertyAttribute::REMOVEABLE, aPropValue );
+ } catch ( uno::Exception& ) {
+ //ignore
+ }
+ }
+ }
+ }
+
+ // return code
+ return (nGlobError != ERRCODE_NONE) ? nGlobError : nDocError;
+}
+
+bool SFX2_DLLPUBLIC SaveOlePropertySet(
+ uno::Reference< document::XDocumentProperties> i_xDocProps,
+ SotStorage* i_pStorage,
+ const uno::Sequence<sal_uInt8> * i_pThumb,
+ const uno::Sequence<sal_uInt8> * i_pGuid,
+ const uno::Sequence<sal_uInt8> * i_pHyperlinks)
+{
+ // *** global properties into stream "005SummaryInformation" ***
+
+ SfxOlePropertySet aGlobSet;
+
+ // set supported properties
+ SfxOleSection& rGlobSect = aGlobSet.AddSection( SECTION_GLOBAL );
+ rGlobSect.SetStringValue( PROPID_TITLE, i_xDocProps->getTitle() );
+ rGlobSect.SetStringValue( PROPID_SUBJECT, i_xDocProps->getSubject() );
+ String aStr = ::comphelper::string::convertCommaSeparated(
+ i_xDocProps->getKeywords() );
+ rGlobSect.SetStringValue( PROPID_KEYWORDS, aStr );
+ rGlobSect.SetStringValue( PROPID_TEMPLATE, i_xDocProps->getTemplateName() );
+ rGlobSect.SetStringValue( PROPID_COMMENTS, i_xDocProps->getDescription() );
+ rGlobSect.SetStringValue( PROPID_AUTHOR, i_xDocProps->getAuthor() );
+ rGlobSect.SetFileTimeValue(PROPID_CREATED, i_xDocProps->getCreationDate());
+ rGlobSect.SetStringValue( PROPID_LASTAUTHOR, i_xDocProps->getModifiedBy() );
+ rGlobSect.SetFileTimeValue(PROPID_LASTSAVED,
+ i_xDocProps->getModificationDate() );
+ // note: apparently PrintedBy is not supported in file format
+ rGlobSect.SetFileTimeValue(PROPID_LASTPRINTED, i_xDocProps->getPrintDate());
+
+ sal_Int32 dur = i_xDocProps->getEditingDuration();
+ util::DateTime aEditTime;
+ // add offset 1601-01-01
+ aEditTime.Year = 1601;
+ aEditTime.Month = 1;
+ aEditTime.Day = 1;
+ aEditTime.Hours = static_cast<sal_Int16>(dur / 3600);
+ aEditTime.Minutes = static_cast<sal_Int16>((dur % 3600) / 60);
+ aEditTime.Seconds = static_cast<sal_Int16>(dur % 60);
+ rGlobSect.SetFileTimeValue( PROPID_EDITTIME, aEditTime );
+
+ rGlobSect.SetStringValue( PROPID_REVNUMBER,
+ String::CreateFromInt32( i_xDocProps->getEditingCycles() ) );
+ if ( i_pThumb && i_pThumb->getLength() )
+ rGlobSect.SetThumbnailValue( PROPID_THUMBNAIL, *i_pThumb );
+
+ // save the property set
+ ErrCode nGlobError = aGlobSet.SavePropertySet(i_pStorage,
+ String( RTL_CONSTASCII_USTRINGPARAM( STREAM_SUMMARYINFO ) ) );
+
+ // *** custom properties into stream "005DocumentSummaryInformation" ***
+
+ SfxOlePropertySet aDocSet;
+
+ // set builtin properties
+ aDocSet.AddSection( SECTION_BUILTIN );
+
+ // set custom properties
+ SfxOleSection& rCustomSect = aDocSet.AddSection( SECTION_CUSTOM );
+
+ // write GUID
+ if (i_pGuid) {
+ const sal_Int32 nPropId = rCustomSect.GetFreePropertyId();
+ rCustomSect.SetBlobValue( nPropId, *i_pGuid );
+ rCustomSect.SetPropertyName( nPropId,
+ ::rtl::OUString::createFromAscii("_PID_GUID") );
+ }
+
+ // write hyperlinks
+ if (i_pHyperlinks) {
+ const sal_Int32 nPropId = rCustomSect.GetFreePropertyId();
+ rCustomSect.SetBlobValue( nPropId, *i_pHyperlinks );
+ rCustomSect.SetPropertyName( nPropId,
+ ::rtl::OUString::createFromAscii("_PID_HLINKS") );
+ }
+
+ uno::Reference<beans::XPropertySet> xUserDefinedProps(
+ i_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ DBG_ASSERT(xUserDefinedProps.is(), "UserDefinedProperties is null");
+ uno::Reference<beans::XPropertySetInfo> xPropInfo =
+ xUserDefinedProps->getPropertySetInfo();
+ DBG_ASSERT(xPropInfo.is(), "UserDefinedProperties Info is null");
+ uno::Sequence<beans::Property> props = xPropInfo->getProperties();
+ for (sal_Int32 i = 0; i < props.getLength(); ++i) {
+ try {
+ // skip transient properties
+ if (~props[i].Attributes & beans::PropertyAttribute::TRANSIENT)
+ {
+ const ::rtl::OUString name = props[i].Name;
+ const sal_Int32 nPropId = rCustomSect.GetFreePropertyId();
+ if (rCustomSect.SetAnyValue( nPropId,
+ xUserDefinedProps->getPropertyValue(name))) {
+ rCustomSect.SetPropertyName( nPropId, name );
+ }
+ }
+ } catch (uno::Exception &) {
+ // may happen with concurrent modification...
+ DBG_WARNING("SavePropertySet: exception");
+ }
+ }
+
+ // save the property set
+ ErrCode nDocError = aDocSet.SavePropertySet(i_pStorage,
+ String( RTL_CONSTASCII_USTRINGPARAM( STREAM_DOCSUMMARYINFO ) ) );
+
+ // return code
+ return (nGlobError == ERRCODE_NONE) && (nDocError == ERRCODE_NONE);
+}
+
+uno::Sequence<sal_uInt8> SFX2_DLLPUBLIC convertMetaFile(GDIMetaFile* i_pThumb)
+{
+ if (i_pThumb) {
+ BitmapEx aBitmap;
+ SvMemoryStream aStream;
+// magic value 160 taken from GraphicHelper::getThumbnailFormatFromGDI_Impl()
+ if( i_pThumb->CreateThumbnail( 160, aBitmap ) ) {
+ aBitmap.GetBitmap().Write( aStream, FALSE, FALSE );
+// uno::Sequence<sal_uInt8> aSeq(aStream.GetSize()); // WRONG
+ aStream.Seek(STREAM_SEEK_TO_END);
+ uno::Sequence<sal_uInt8> aSeq(aStream.Tell());
+ const sal_uInt8* pBlob(
+ static_cast<const sal_uInt8*>(aStream.GetData()));
+ for (sal_Int32 j = 0; j < aSeq.getLength(); ++j) {
+ aSeq[j] = pBlob[j];
+ }
+ return aSeq;
+ }
+ }
+ return uno::Sequence<sal_uInt8>();
+}
+
+} // namespace sfx2
+
diff --git a/sfx2/source/doc/docinsert.cxx b/sfx2/source/doc/docinsert.cxx
new file mode 100644
index 000000000000..2dcca2eadf56
--- /dev/null
+++ b/sfx2/source/doc/docinsert.cxx
@@ -0,0 +1,305 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <sfx2/app.hxx>
+#include "docinsert.hxx"
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include "openflag.hxx"
+#include <sfx2/passwd.hxx>
+
+#include <sfx2/sfxsids.hrc>
+#include <com/sun/star/ui/dialogs/ControlActions.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ListboxControlActions.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <tools/urlobj.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/itemset.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/stritem.hxx>
+
+#define _SVSTDARR_STRINGSDTOR
+#include <svl/svstdarr.hxx>
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+// implemented in 'sfx2/source/appl/appopen.cxx'
+extern sal_uInt32 CheckPasswd_Impl( SfxObjectShell* pDoc, SfxItemPool &rPool, SfxMedium* pFile );
+
+// =======================================================================
+
+namespace sfx2 {
+
+// =======================================================================
+
+// =======================================================================
+// DocumentInserter
+// =======================================================================
+
+DocumentInserter::DocumentInserter(
+ sal_Int64 _nFlags, const String& _rFactory, bool _bEnableMultiSelection ) :
+
+ m_sDocFactory ( _rFactory )
+ , m_bMultiSelectionEnabled ( _bEnableMultiSelection )
+ , m_nDlgFlags ( _nFlags | SFXWB_INSERT | WB_3DLOOK )
+ , m_nError ( ERRCODE_NONE )
+ , m_pFileDlg ( NULL )
+ , m_pItemSet ( NULL )
+ , m_pURLList ( NULL )
+
+{
+}
+
+DocumentInserter::~DocumentInserter()
+{
+ delete m_pFileDlg;
+}
+
+void DocumentInserter::StartExecuteModal( const Link& _rDialogClosedLink )
+{
+ m_aDialogClosedLink = _rDialogClosedLink;
+ m_nError = ERRCODE_NONE;
+ DELETEZ( m_pURLList );
+ if ( !m_pFileDlg )
+ {
+ sal_Int64 nFlags = m_bMultiSelectionEnabled ? ( m_nDlgFlags | SFXWB_MULTISELECTION )
+ : m_nDlgFlags;
+ m_pFileDlg = new FileDialogHelper( nFlags, m_sDocFactory );
+ }
+ m_pFileDlg->StartExecuteModal( LINK( this, DocumentInserter, DialogClosedHdl ) );
+}
+
+SfxMedium* DocumentInserter::CreateMedium()
+{
+ SfxMedium* pMedium = NULL;
+ if ( !m_nError && m_pItemSet && m_pURLList && m_pURLList->Count() > 0 )
+ {
+ DBG_ASSERT( m_pURLList->Count() == 1, "DocumentInserter::CreateMedium(): invalid URL list count" );
+ String sURL = *( m_pURLList->GetObject(0) );
+ pMedium = new SfxMedium(
+ sURL, SFX_STREAM_READONLY, FALSE,
+ SFX_APP()->GetFilterMatcher().GetFilter4FilterName( m_sFilter ), m_pItemSet );
+ pMedium->UseInteractionHandler( TRUE );
+ SfxFilterMatcher* pMatcher = NULL;
+ if ( m_sDocFactory.Len() )
+ pMatcher = new SfxFilterMatcher( m_sDocFactory );
+ else
+ pMatcher = new SfxFilterMatcher();
+
+ const SfxFilter* pFilter = NULL;
+ sal_uInt32 nError = pMatcher->DetectFilter( *pMedium, &pFilter, FALSE );
+ if ( nError == ERRCODE_NONE && pFilter )
+ pMedium->SetFilter( pFilter );
+ else
+ DELETEZ( pMedium );
+
+ if ( pMedium && CheckPasswd_Impl( 0, SFX_APP()->GetPool(), pMedium ) == ERRCODE_ABORT )
+ pMedium = NULL;
+
+ DELETEZ( pMatcher );
+ }
+
+ return pMedium;
+}
+
+SfxMediumList* DocumentInserter::CreateMediumList()
+{
+ SfxMediumList* pMediumList = new SfxMediumList;
+ if ( !m_nError && m_pItemSet && m_pURLList && m_pURLList->Count() > 0 )
+ {
+ sal_Int32 i = 0;
+ sal_Int32 nCount = m_pURLList->Count();
+ for ( ; i < nCount; ++i )
+ {
+ String sURL = *( m_pURLList->GetObject( static_cast< USHORT >(i) ) );
+ SfxMedium* pMedium = new SfxMedium(
+ sURL, SFX_STREAM_READONLY, FALSE,
+ SFX_APP()->GetFilterMatcher().GetFilter4FilterName( m_sFilter ), m_pItemSet );
+
+ pMedium->UseInteractionHandler( TRUE );
+
+ SfxFilterMatcher aMatcher( m_sDocFactory );
+ const SfxFilter* pFilter = NULL;
+ sal_uInt32 nError = aMatcher.DetectFilter( *pMedium, &pFilter, FALSE );
+ if ( nError == ERRCODE_NONE && pFilter )
+ pMedium->SetFilter( pFilter );
+ else
+ DELETEZ( pMedium );
+
+ if( pMedium && CheckPasswd_Impl( 0, SFX_APP()->GetPool(), pMedium ) != ERRCODE_ABORT )
+ pMediumList->Insert( pMedium );
+ else
+ delete pMedium;
+ }
+ }
+
+ return pMediumList;
+}
+
+void impl_FillURLList( sfx2::FileDialogHelper* _pFileDlg, SvStringsDtor*& _rpURLList )
+{
+ DBG_ASSERT( _pFileDlg, "DocumentInserter::fillURLList(): invalid file dialog" );
+ DBG_ASSERT( !_rpURLList, "DocumentInserter::fillURLList(): URLList already exists" );
+ Sequence < ::rtl::OUString > aPathSeq = _pFileDlg->GetSelectedFiles();
+
+ if ( aPathSeq.getLength() )
+ {
+ _rpURLList = new SvStringsDtor;
+
+ for ( USHORT i = 0; i < aPathSeq.getLength(); ++i )
+ {
+ INetURLObject aPathObj( aPathSeq[i] );
+ String* pURL = new String( aPathObj.GetMainURL( INetURLObject::NO_DECODE ) );
+ _rpURLList->Insert( pURL, _rpURLList->Count() );
+ }
+ }
+}
+
+IMPL_LINK( DocumentInserter, DialogClosedHdl, sfx2::FileDialogHelper*, EMPTYARG )
+{
+ DBG_ASSERT( m_pFileDlg, "DocumentInserter::DialogClosedHdl(): no file dialog" );
+
+ m_nError = m_pFileDlg->GetError();
+ if ( ERRCODE_NONE == m_nError )
+ impl_FillURLList( m_pFileDlg, m_pURLList );
+
+ Reference < XFilePicker > xFP = m_pFileDlg->GetFilePicker();
+ Reference < XFilePickerControlAccess > xCtrlAccess( xFP, UNO_QUERY );
+ if ( xCtrlAccess.is() )
+ {
+ // always create a new itemset
+ m_pItemSet = new SfxAllItemSet( SFX_APP()->GetPool() );
+
+ short nDlgType = m_pFileDlg->GetDialogType();
+ bool bHasPassword = (
+ TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD == nDlgType
+ || TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS == nDlgType );
+
+ // check, wether or not we have to display a password box
+ if ( bHasPassword && m_pFileDlg->IsPasswordEnabled() )
+ {
+ try
+ {
+ Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
+ sal_Bool bPassWord = sal_False;
+ if ( ( aValue >>= bPassWord ) && bPassWord )
+ {
+ // ask for the password
+ SfxPasswordDialog aPasswordDlg( NULL );
+ aPasswordDlg.ShowExtras( SHOWEXTRAS_CONFIRM );
+ short nRet = aPasswordDlg.Execute();
+ if ( RET_OK == nRet )
+ {
+ String aPasswd = aPasswordDlg.GetPassword();
+ m_pItemSet->Put( SfxStringItem( SID_PASSWORD, aPasswd ) );
+ }
+ else
+ {
+ DELETEZ( m_pItemSet );
+ return 0;
+ }
+ }
+ }
+ catch( IllegalArgumentException ){}
+ }
+
+ if ( SFXWB_EXPORT == ( m_nDlgFlags & SFXWB_EXPORT ) )
+ {
+ try
+ {
+ Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
+ sal_Bool bSelection = sal_False;
+ if ( aValue >>= bSelection )
+ m_pItemSet->Put( SfxBoolItem( SID_SELECTION, bSelection ) );
+ }
+ catch( IllegalArgumentException )
+ {
+ DBG_ERROR( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
+ }
+ }
+
+
+ // set the read-only flag. When inserting a file, this flag is always set
+ if ( SFXWB_INSERT == ( m_nDlgFlags & SFXWB_INSERT ) )
+ m_pItemSet->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
+ else
+ {
+ if ( ( TemplateDescription::FILEOPEN_READONLY_VERSION == nDlgType ) )
+ {
+ try
+ {
+ Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 );
+ sal_Bool bReadOnly = sal_False;
+ if ( ( aValue >>= bReadOnly ) && bReadOnly )
+ m_pItemSet->Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
+ }
+ catch( IllegalArgumentException )
+ {
+ DBG_ERROR( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
+ }
+ }
+ }
+
+ if ( TemplateDescription::FILEOPEN_READONLY_VERSION == nDlgType )
+ {
+ try
+ {
+ Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
+ ControlActions::GET_SELECTED_ITEM_INDEX );
+ sal_Int32 nVersion = 0;
+ if ( ( aValue >>= nVersion ) && nVersion > 0 )
+ // open a special version; 0 == current version
+ m_pItemSet->Put( SfxInt16Item( SID_VERSION, (short)nVersion ) );
+ }
+ catch( IllegalArgumentException ){}
+ }
+ }
+
+ m_sFilter = m_pFileDlg->GetRealFilter();
+
+ if ( m_aDialogClosedLink.IsSet() )
+ m_aDialogClosedLink.Call( m_pFileDlg );
+
+ return 0;
+}
+
+// =======================================================================
+
+} // namespace sfx2
+
+// =======================================================================
+
diff --git a/sfx2/source/doc/docmacromode.cxx b/sfx2/source/doc/docmacromode.cxx
new file mode 100644
index 000000000000..249ebbaf02ab
--- /dev/null
+++ b/sfx2/source/doc/docmacromode.cxx
@@ -0,0 +1,436 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "sfx2/docmacromode.hxx"
+#include "sfx2/signaturestate.hxx"
+#include "sfx2/docfile.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/task/ErrorCodeRequest.hpp>
+#include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
+#include <com/sun/star/task/InteractionClassification.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/processfactory.hxx>
+#include <framework/interaction.hxx>
+#include <osl/file.hxx>
+#include <rtl/ref.hxx>
+#include <unotools/securityoptions.hxx>
+#include <svtools/sfxecode.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/urlobj.hxx>
+
+//........................................................................
+namespace sfx2
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::task::XInteractionHandler;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::task::XInteractionHandler;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::task::XInteractionContinuation;
+ using ::com::sun::star::task::XInteractionRequest;
+ using ::com::sun::star::task::DocumentMacroConfirmationRequest;
+ using ::com::sun::star::task::ErrorCodeRequest;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::security::XDocumentDigitalSignatures;
+ using ::com::sun::star::security::DocumentSignatureInformation;
+ using ::com::sun::star::embed::XStorage;
+ using ::com::sun::star::task::InteractionClassification_QUERY;
+ using ::com::sun::star::document::XEmbeddedScripts;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::script::XLibraryContainer;
+ using ::com::sun::star::container::XNameAccess;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ /** === end UNO using === **/
+ namespace MacroExecMode = ::com::sun::star::document::MacroExecMode;
+
+ //====================================================================
+ //= DocumentMacroMode_Data
+ //====================================================================
+ struct DocumentMacroMode_Data
+ {
+ IMacroDocumentAccess& m_rDocumentAccess;
+ sal_Bool m_bMacroDisabledMessageShown;
+ sal_Bool m_bDocMacroDisabledMessageShown;
+
+ DocumentMacroMode_Data( IMacroDocumentAccess& rDocumentAccess )
+ :m_rDocumentAccess( rDocumentAccess )
+ ,m_bMacroDisabledMessageShown( sal_False )
+ ,m_bDocMacroDisabledMessageShown( sal_False )
+ {
+ }
+ };
+
+ //====================================================================
+ //= helper
+ //====================================================================
+ namespace
+ {
+ //................................................................
+ void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& rxHandler, const sal_Int32 nSfxErrorCode, sal_Bool& rbAlreadyShown )
+ {
+ if ( rbAlreadyShown )
+ return;
+
+ ErrorCodeRequest aErrorCodeRequest;
+ aErrorCodeRequest.ErrCode = nSfxErrorCode;
+
+ SfxMedium::CallApproveHandler( rxHandler, makeAny( aErrorCodeRequest ), sal_False );
+ rbAlreadyShown = sal_True;
+ }
+
+ //................................................................
+ void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown )
+ {
+ lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, rbAlreadyShown );
+ }
+
+ //................................................................
+ void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown )
+ {
+ lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, rbAlreadyShown );
+ }
+
+ //................................................................
+ sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& rxHandler,
+ const ::rtl::OUString& rDocumentLocation )
+ {
+ DocumentMacroConfirmationRequest aRequest;
+ aRequest.DocumentURL = rDocumentLocation;
+ return SfxMedium::CallApproveHandler( rxHandler, makeAny( aRequest ), sal_True );
+ }
+ }
+
+ //====================================================================
+ //= DocumentMacroMode
+ //====================================================================
+ //--------------------------------------------------------------------
+ DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& rDocumentAccess )
+ :m_pData( new DocumentMacroMode_Data( rDocumentAccess ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ DocumentMacroMode::~DocumentMacroMode()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool DocumentMacroMode::allowMacroExecution()
+ {
+ m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN );
+ return sal_True;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool DocumentMacroMode::disallowMacroExecution()
+ {
+ m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE );
+ return sal_False;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& rxInteraction )
+ {
+ sal_uInt16 nMacroExecutionMode = m_pData->m_rDocumentAccess.getCurrentMacroExecMode();
+
+ if ( SvtSecurityOptions().IsMacroDisabled() )
+ {
+ // no macro should be executed at all
+ lcl_showMacrosDisabledError( rxInteraction, m_pData->m_bMacroDisabledMessageShown );
+ return disallowMacroExecution();
+ }
+
+ // get setting from configuration if required
+ enum AutoConfirmation
+ {
+ eNoAutoConfirm,
+ eAutoConfirmApprove,
+ eAutoConfirmReject
+ };
+ AutoConfirmation eAutoConfirm( eNoAutoConfirm );
+
+ if ( ( nMacroExecutionMode == MacroExecMode::USE_CONFIG )
+ || ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
+ || ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
+ )
+ {
+ SvtSecurityOptions aOpt;
+ switch ( aOpt.GetMacroSecurityLevel() )
+ {
+ case 3:
+ nMacroExecutionMode = MacroExecMode::FROM_LIST_NO_WARN;
+ break;
+ case 2:
+ nMacroExecutionMode = MacroExecMode::FROM_LIST_AND_SIGNED_WARN;
+ break;
+ case 1:
+ nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE;
+ break;
+ case 0:
+ nMacroExecutionMode = MacroExecMode::ALWAYS_EXECUTE_NO_WARN;
+ break;
+ default:
+ OSL_ENSURE( sal_False, "DocumentMacroMode::adjustMacroMode: unexpected macro security level!" );
+ nMacroExecutionMode = MacroExecMode::NEVER_EXECUTE;
+ }
+
+ if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_REJECT_CONFIRMATION )
+ eAutoConfirm = eAutoConfirmReject;
+ else if ( nMacroExecutionMode == MacroExecMode::USE_CONFIG_APPROVE_CONFIRMATION )
+ eAutoConfirm = eAutoConfirmApprove;
+ }
+
+ if ( nMacroExecutionMode == MacroExecMode::NEVER_EXECUTE )
+ return sal_False;
+
+ if ( nMacroExecutionMode == MacroExecMode::ALWAYS_EXECUTE_NO_WARN )
+ return sal_True;
+
+ try
+ {
+ ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() );
+
+ // get document location from medium name and check whether it is a trusted one
+ // the service is created ohne document version, since it is not of interest here
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ Reference< XDocumentDigitalSignatures > xSignatures;
+ if ( aContext.createComponent( "com.sun.star.security.DocumentDigitalSignatures", xSignatures ) )
+ {
+ INetURLObject aURLReferer( sReferrer );
+
+ ::rtl::OUString aLocation;
+ if ( aURLReferer.removeSegment() )
+ aLocation = aURLReferer.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( aLocation.getLength() && xSignatures->isLocationTrusted( aLocation ) )
+ {
+ return allowMacroExecution();
+ }
+ }
+
+ // at this point it is clear that the document is not in the secure location
+ if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
+ {
+ lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown );
+ return disallowMacroExecution();
+ }
+
+ // check whether the document is signed with trusted certificate
+ if ( nMacroExecutionMode != MacroExecMode::FROM_LIST )
+ {
+ // the trusted macro check will also retrieve the signature state ( small optimization )
+ sal_Bool bHasTrustedMacroSignature = m_pData->m_rDocumentAccess.hasTrustedScriptingSignature( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN );
+
+ sal_uInt16 nSignatureState = m_pData->m_rDocumentAccess.getScriptingSignatureState();
+ if ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN )
+ {
+ // the signature is broken, no macro execution
+ if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
+ m_pData->m_rDocumentAccess.showBrokenSignatureWarning( rxInteraction );
+
+ return disallowMacroExecution();
+ }
+ else if ( bHasTrustedMacroSignature )
+ {
+ // there is trusted macro signature, allow macro execution
+ return allowMacroExecution();
+ }
+ else if ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK
+ || nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
+ {
+ // there is valid signature, but it is not from the trusted author
+ return disallowMacroExecution();
+ }
+ }
+
+ // at this point it is clear that the document is neither in secure location nor signed with trusted certificate
+ if ( ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
+ || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
+ )
+ {
+ if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
+ lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown );
+
+ return disallowMacroExecution();
+ }
+ }
+ catch ( Exception& )
+ {
+ if ( ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN )
+ || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN )
+ || ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN )
+ )
+ {
+ return disallowMacroExecution();
+ }
+ }
+
+ // conformation is required
+ sal_Bool bSecure = sal_False;
+
+ if ( eAutoConfirm == eNoAutoConfirm )
+ {
+ ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() );
+
+ ::rtl::OUString aSystemFileURL;
+ if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None )
+ sReferrer = aSystemFileURL;
+
+ bSecure = lcl_showMacroWarning( rxInteraction, sReferrer );
+ }
+ else
+ bSecure = ( eAutoConfirm == eAutoConfirmApprove );
+
+ return ( bSecure ? allowMacroExecution() : disallowMacroExecution() );
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool DocumentMacroMode::isMacroExecutionDisallowed() const
+ {
+ return m_pData->m_rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool DocumentMacroMode::hasMacroLibrary() const
+ {
+ sal_Bool bHasMacroLib = sal_False;
+ try
+ {
+ Reference< XEmbeddedScripts > xScripts( m_pData->m_rDocumentAccess.getEmbeddedDocumentScripts() );
+ Reference< XLibraryContainer > xContainer;
+ if ( xScripts.is() )
+ xContainer.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW );
+
+ if ( xContainer.is() )
+ {
+ // a library container exists; check if it's empty
+
+ // if there are libraries except the "Standard" library
+ // we assume that they are not empty (because they have been created by the user)
+ if ( !xContainer->hasElements() )
+ bHasMacroLib = sal_False;
+ else
+ {
+ ::rtl::OUString aStdLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ Sequence< ::rtl::OUString > aElements = xContainer->getElementNames();
+ if ( aElements.getLength() )
+ {
+ if ( aElements.getLength() > 1 || !aElements[0].equals( aStdLibName ) )
+ bHasMacroLib = sal_True;
+ else
+ {
+ // usually a "Standard" library is always present (design)
+ // for this reason we must check if it's empty
+ //
+ // Note: Since #i73229#, this is not true anymore. There's no default
+ // "Standard" lib anymore. Wouldn't it be time to get completely
+ // rid of the "Standard" thingie - this shouldn't be necessary
+ // anymore, should it?
+ // 2007-01-25 / frank.schoenheit@sun.com
+ Reference < XNameAccess > xLib;
+ Any aAny = xContainer->getByName( aStdLibName );
+ aAny >>= xLib;
+ if ( xLib.is() )
+ bHasMacroLib = xLib->hasElements();
+ }
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ return bHasMacroLib;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& rxStorage )
+ {
+ sal_Bool bHasMacros = sal_False;
+ if ( rxStorage.is() )
+ {
+ try
+ {
+ static const ::rtl::OUString s_sBasicStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ) );
+ static const ::rtl::OUString s_sScriptsStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) ) );
+
+ bHasMacros =( ( rxStorage->hasByName( s_sBasicStorageName )
+ && rxStorage->isStorageElement( s_sBasicStorageName )
+ )
+ || ( rxStorage->hasByName( s_sScriptsStorageName )
+ && rxStorage->isStorageElement( s_sScriptsStorageName )
+ )
+ );
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ return bHasMacros;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& rxInteraction )
+ {
+ sal_Bool bAllow = sal_False;
+ if ( SvtSecurityOptions().IsMacroDisabled() )
+ {
+ // no macro should be executed at all
+ bAllow = disallowMacroExecution();
+ }
+ else
+ {
+ if ( m_pData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() )
+ {
+ bAllow = adjustMacroMode( rxInteraction );
+ }
+ else if ( !isMacroExecutionDisallowed() )
+ {
+ // if macros will be added by the user later, the security check is obsolete
+ bAllow = allowMacroExecution();
+ }
+ }
+ return bAllow;
+ }
+
+//........................................................................
+} // namespace sfx2
+//........................................................................
diff --git a/sfx2/source/doc/docstoragemodifylistener.cxx b/sfx2/source/doc/docstoragemodifylistener.cxx
new file mode 100644
index 000000000000..625aff0031fc
--- /dev/null
+++ b/sfx2/source/doc/docstoragemodifylistener.cxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "sfx2/docstoragemodifylistener.hxx"
+#include <vos/mutex.hxx>
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+//........................................................................
+namespace sfx2
+{
+//........................................................................
+
+ /** === 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::lang::EventObject;
+ /** === end UNO using === **/
+
+ //====================================================================
+ //=
+ //====================================================================
+ //--------------------------------------------------------------------
+ DocumentStorageModifyListener::DocumentStorageModifyListener( IModifiableDocument& _rDocument, ::vos::IMutex& _rMutex )
+ :m_pDocument( &_rDocument )
+ ,m_rMutex( _rMutex )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ DocumentStorageModifyListener::~DocumentStorageModifyListener()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentStorageModifyListener::dispose()
+ {
+ ::vos::OGuard aGuard( m_rMutex );
+ m_pDocument = NULL;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentStorageModifyListener::modified( const EventObject& /*aEvent*/ ) throw (RuntimeException)
+ {
+ ::vos::OGuard aGuard( m_rMutex );
+ // storageIsModified must not contain any locking!
+ if ( m_pDocument )
+ m_pDocument->storageIsModified();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentStorageModifyListener::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
+ {
+ // not interested in. In particular, we do *not* dispose ourself when a storage we're
+ // listening at is disposed. The reason here is that this listener instance is *reused*
+ // in case the document is re-based to another storage.
+ }
+
+//........................................................................
+} // namespace sfx2
+//........................................................................
diff --git a/sfx2/source/doc/doctdlg.cxx b/sfx2/source/doc/doctdlg.cxx
new file mode 100644
index 000000000000..7a5fea18004f
--- /dev/null
+++ b/sfx2/source/doc/doctdlg.cxx
@@ -0,0 +1,238 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#include <svl/stritem.hxx>
+#ifndef GCC
+#endif
+
+#include <sfx2/doctdlg.hxx>
+#include "docvor.hxx"
+#include "sfxresid.hxx"
+#include "sfxtypes.hxx"
+#include <sfx2/dispatch.hxx>
+#include <sfx2/app.hxx>
+
+#include <sfx2/sfx.hrc>
+#include "doc.hrc"
+#include "doctdlg.hrc"
+#include <sfx2/basedlgs.hxx>
+
+//=========================================================================
+
+SfxDocumentTemplateDlg::SfxDocumentTemplateDlg( Window * pParent, SfxDocumentTemplates* pTempl ) :
+
+ ModalDialog( pParent, SfxResId( DLG_DOC_TEMPLATE ) ),
+
+ aEditFL ( this, SfxResId( FL_EDIT ) ),
+ aNameEd ( this, SfxResId( ED_NAME ) ),
+ aTemplateFL ( this, SfxResId( FL_STYLESHEETS ) ),
+ aRegionFt ( this, SfxResId( FT_SECTION ) ),
+ aRegionLb ( this, SfxResId( LB_SECTION ) ),
+ aTemplateFt ( this, SfxResId( FT_STYLESHEETS ) ),
+ aTemplateLb ( this, SfxResId( LB_STYLESHEETS ) ),
+
+ aOkBt ( this, SfxResId( BT_OK ) ),
+ aCancelBt ( this, SfxResId( BT_CANCEL ) ),
+ aHelpBt ( this, SfxResId( BT_HELP ) ),
+ aEditBt ( this, SfxResId( BT_EDIT ) ),
+ aOrganizeBt ( this, SfxResId( BT_ORGANIZE ) ),
+
+ pTemplates ( pTempl ),
+ pHelper ( NULL )
+
+{
+ FreeResource();
+
+ pHelper = new SfxModalDefParentHelper( this );
+ aOrganizeBt.SetClickHdl(LINK(this, SfxDocumentTemplateDlg, OrganizeHdl));
+ aNameEd.SetModifyHdl(LINK(this, SfxDocumentTemplateDlg, NameModify));
+ aOkBt.SetClickHdl(LINK(this, SfxDocumentTemplateDlg, OkHdl));
+ aEditBt.SetClickHdl(LINK(this, SfxDocumentTemplateDlg, EditHdl));
+ Init();
+}
+
+//-------------------------------------------------------------------------
+
+SfxDocumentTemplateDlg::~SfxDocumentTemplateDlg()
+{
+ delete pHelper;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxDocumentTemplateDlg, EditHdl, Button *, pBut )
+{
+ (void)pBut; //unused
+ if ( !aRegionLb.GetSelectEntryCount() ||
+ !aTemplateLb.GetSelectEntryCount())
+ return 0;
+
+ const SfxStringItem aRegion( SID_TEMPLATE_REGIONNAME, aRegionLb.GetSelectEntry() );
+ const SfxStringItem aName( SID_TEMPLATE_NAME, aTemplateLb.GetSelectEntry() );
+ SFX_APP()->GetAppDispatcher_Impl()->Execute( SID_OPENTEMPLATE, SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD, &aRegion, &aName, 0L );
+ EndDialog(RET_EDIT_STYLE);
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxDocumentTemplateDlg::Init()
+{
+ if(!pTemplates->IsConstructed())
+ pTemplates->Construct();
+
+ const USHORT nCount = pTemplates->GetRegionCount();
+ for(USHORT i = 0; i < nCount; ++i)
+ aRegionLb.InsertEntry(pTemplates->GetFullRegionName(i));
+ if(!nCount)
+ aRegionLb.InsertEntry(String(SfxResId(STR_STANDARD)));
+ aRegionLb.SelectEntryPos(0);
+ if(nCount)
+ {
+ aRegionLb.SetSelectHdl(LINK(this, SfxDocumentTemplateDlg, RegionSelect));
+ RegionSelect(&aRegionLb);
+ aTemplateLb.SetSelectHdl(LINK(this, SfxDocumentTemplateDlg, TemplateSelect));
+ aTemplateLb.SetDoubleClickHdl(LINK(this, SfxDocumentTemplateDlg, EditHdl));
+ }
+ else {
+ Link aLink;
+ aTemplateLb.SetSelectHdl(aLink);
+ aTemplateLb.SetDoubleClickHdl(aLink);
+ }
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxDocumentTemplateDlg, OrganizeHdl, Button *, pButton )
+{
+ (void)pButton; //unused
+ SfxTemplateOrganizeDlg *pDlg =
+ new SfxTemplateOrganizeDlg(this, pTemplates);
+ const short nRet = pDlg->Execute();
+ delete pDlg;
+ if(RET_OK == nRet)
+ {
+ // View aktualisieren
+ aRegionLb.SetUpdateMode( FALSE );
+ aRegionLb.Clear();
+ Init();
+ aRegionLb.SetUpdateMode( TRUE );
+ aRegionLb.Invalidate();
+ aRegionLb.Update();
+ aCancelBt.SetText(String(SfxResId(STR_CLOSE)));
+ }
+ else if(RET_EDIT_STYLE == nRet)
+ EndDialog(RET_CANCEL);
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxDocumentTemplateDlg, OkHdl, Control *, pControl )
+{
+ (void)pControl; //unused
+ // pruefen, ob eine Vorlage diesen Namens existiert
+ if(LISTBOX_ENTRY_NOTFOUND != aTemplateLb.GetEntryPos(
+ GetTemplateName())) {
+ QueryBox aQuery(this, SfxResId(MSG_CONFIRM_OVERWRITE_TEMPLATE));
+ if(RET_NO == aQuery.Execute())
+ return 0;
+ }
+ EndDialog(RET_OK);
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxDocumentTemplateDlg, RegionSelect, ListBox *, pBox )
+{
+ const USHORT nRegion = pBox->GetSelectEntryPos();
+ const USHORT nCount = pTemplates->GetCount(nRegion);
+ aTemplateLb.SetUpdateMode(FALSE);
+ aTemplateLb.Clear();
+ for(USHORT i = 0; i < nCount; ++i)
+ aTemplateLb.InsertEntry(pTemplates->GetName(nRegion, i));
+ aTemplateLb.SelectEntryPos(0);
+ aTemplateLb.SetUpdateMode(TRUE);
+ aTemplateLb.Invalidate();
+ aTemplateLb.Update();
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( SfxDocumentTemplateDlg, TemplateSelect, ListBox *, pBox )
+{
+ aNameEd.SetText(pBox->GetSelectEntry());
+ NameModify(&aNameEd);
+ return 0;
+}
+IMPL_LINK_INLINE_END( SfxDocumentTemplateDlg, TemplateSelect, ListBox *, pBox )
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxDocumentTemplateDlg, NameModify, Edit *, pBox )
+{
+ const String &rText=pBox->GetText();
+ if(!rText.Len())
+ aEditBt.Enable();
+ else
+ {
+ aTemplateLb.SelectEntry(rText);
+ aEditBt.Enable( aTemplateLb.GetSelectEntry() == rText );
+ }
+
+ aOkBt.Enable( rText.Len() > 0 );
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+String SfxDocumentTemplateDlg::GetTemplatePath()
+{
+ const String& rPath=GetTemplateName();
+ if(pTemplates->GetRegionCount())
+ return pTemplates->GetTemplatePath(
+ aRegionLb.GetSelectEntryPos(), rPath);
+ return pTemplates->GetDefaultTemplatePath(rPath);
+}
+
+//-------------------------------------------------------------------------
+
+void SfxDocumentTemplateDlg::NewTemplate(const String &rPath)
+{
+ pTemplates->NewTemplate(
+ aRegionLb.GetSelectEntryPos(), GetTemplateName(), rPath);
+}
+
diff --git a/sfx2/source/doc/doctdlg.hrc b/sfx2/source/doc/doctdlg.hrc
new file mode 100644
index 000000000000..8deed4699f3b
--- /dev/null
+++ b/sfx2/source/doc/doctdlg.hrc
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#define FT_SECTION 1
+#define LB_SECTION 2
+#define FT_STYLESHEETS 3
+#define LB_STYLESHEETS 4
+#define BT_ORGANIZE 20
+#define BT_HELP 21
+#define FL_EDIT 5
+#define FT_NAME 6
+#define ED_NAME 7
+#define BT_OK 10
+#define BT_SECTION 11
+#define BT_EDIT 12
+#define BT_NEW 13
+#define BT_DELETE 15
+#define BT_CANCEL 16
+#define FL_STYLESHEETS 17
diff --git a/sfx2/source/doc/doctdlg.src b/sfx2/source/doc/doctdlg.src
new file mode 100644
index 000000000000..91d966fbd2d5
--- /dev/null
+++ b/sfx2/source/doc/doctdlg.src
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <sfx2/sfx.hrc>
+#include "doc.hrc"
+#include "doctdlg.hrc"
+
+ModalDialog DLG_DOC_TEMPLATE
+{
+ HelpId = SID_DOCTEMPLATE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 280 , 128 ) ;
+ Text [ en-US ] = "Templates" ;
+ Moveable = TRUE ;
+ FixedLine FL_EDIT
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 212 , 8 ) ;
+ Text [ en-US ] = "New template" ;
+ };
+ Edit ED_NAME
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 200 , 12 ) ;
+ };
+ FixedLine FL_STYLESHEETS
+ {
+ Pos = MAP_APPFONT ( 6 , 32 ) ;
+ Size = MAP_APPFONT ( 212 , 8 ) ;
+ Text [ en-US ] = "Templates" ;
+ };
+ FixedText FT_SECTION
+ {
+ Pos = MAP_APPFONT ( 12 , 43 ) ;
+ Size = MAP_APPFONT ( 97 , 10 ) ;
+ Text [ en-US ] = "~Categories" ;
+ };
+ ListBox LB_SECTION
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 56 ) ;
+ Size = MAP_APPFONT ( 97 , 66 ) ;
+ };
+ FixedText FT_STYLESHEETS
+ {
+ Pos = MAP_APPFONT ( 115 , 43 ) ;
+ Size = MAP_APPFONT ( 97 , 10 ) ;
+ Text [ en-US ] = "~Templates" ;
+ };
+ ListBox LB_STYLESHEETS
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 115 , 56 ) ;
+ Size = MAP_APPFONT ( 97 , 66 ) ;
+ };
+ OKButton BT_OK
+ {
+ Pos = MAP_APPFONT ( 224 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ Disable = TRUE ;
+ };
+ CancelButton BT_CANCEL
+ {
+ Pos = MAP_APPFONT ( 224 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BT_HELP
+ {
+ Pos = MAP_APPFONT ( 224 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ PushButton BT_EDIT
+ {
+ Pos = MAP_APPFONT ( 224 , 62 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Edit" ;
+ };
+ PushButton BT_ORGANIZE
+ {
+ Pos = MAP_APPFONT ( 224 , 79 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Organizer..." ;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sfx2/source/doc/doctempl.cxx b/sfx2/source/doc/doctempl.cxx
new file mode 100644
index 000000000000..db6f2a2d133f
--- /dev/null
+++ b/sfx2/source/doc/doctempl.cxx
@@ -0,0 +1,2735 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <limits.h>
+#include <com/sun/star/uno/Any.h>
+#include <vos/mutex.hxx>
+#include <vos/thread.hxx>
+
+#ifndef _SV_RESARY_HXX
+#include <tools/resary.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <svtools/ehdl.hxx>
+#include <svtools/sfxecode.hxx>
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XDocumentTemplates.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XPersist.hpp>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/ContentInfo.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/XCommandProcessor.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/ucb/XAnyCompare.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+
+#include "sfxurlrelocator.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::document;
+using namespace ::rtl;
+using namespace ::ucbhelper;
+
+
+#include <sfx2/doctempl.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include "sfxtypes.hxx"
+#include <sfx2/app.hxx>
+#include "sfxresid.hxx"
+#include "doc.hrc"
+#include <sfx2/fcontnr.hxx>
+#include <svtools/templatefoldercache.hxx>
+
+#include <comphelper/storagehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+
+//========================================================================
+
+// #define DONT_USE_HIERARCHY
+
+#define TITLE "Title"
+#define IS_FOLDER "IsFolder"
+#define PROPERTY_TYPE "TypeDescription"
+#define TARGET_URL "TargetURL"
+#define TYPE_FOLDER "application/vnd.sun.star.hier-folder"
+#define TYPE_LINK "application/vnd.sun.star.hier-link"
+#define TYPE_FSYS_FOLDER "application/vnd.sun.staroffice.fsys-folder"
+
+#define TARGET_DIR_URL "TargetDirURL"
+#define COMMAND_DELETE "delete"
+#define COMMAND_TRANSFER "transfer"
+
+#define STANDARD_FOLDER "standard"
+
+#define SERVICENAME_TYPEDETECTION "com.sun.star.document.TypeDetection"
+#define TYPEDETECTION_PARAMETER "FileName"
+//#define SERVICENAME_OLD_TYPEDETECTION "com.sun.star.frame.FrameLoaderFactory"
+//#define PARAMETER_OLD_TYPEDETECTION "DeepDetection"
+#define SERVICENAME_DOCINFO "com.sun.star.document.DocumentProperties"
+#define SERVICENAME_DOCTEMPLATES "com.sun.star.frame.DocumentTemplates"
+#define SERVICENAME_DESKTOP "com.sun.star.frame.Desktop"
+
+//========================================================================
+
+class RegionData_Impl;
+
+namespace DocTempl {
+
+class DocTempl_EntryData_Impl
+{
+ RegionData_Impl* mpParent;
+ SfxObjectShellLock mxObjShell;
+ OUString maTitle;
+ OUString maOwnURL;
+ OUString maTargetURL;
+ sal_Bool mbIsOwner : 1;
+ sal_Bool mbDidConvert: 1;
+
+private:
+ RegionData_Impl* GetParent() const { return mpParent; }
+
+public:
+ DocTempl_EntryData_Impl( RegionData_Impl* pParent,
+ const OUString& rTitle );
+
+ const OUString& GetTitle() const { return maTitle; }
+ const OUString& GetTargetURL();
+ const OUString& GetHierarchyURL();
+
+ void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
+ void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
+ void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
+
+ int Compare( const OUString& rTitle ) const;
+
+ SfxObjectShellRef CreateObjectShell();
+ sal_Bool DeleteObjectShell();
+};
+
+}
+
+using namespace ::DocTempl;
+
+// ------------------------------------------------------------------------
+
+class RegionData_Impl
+{
+ DECLARE_LIST( EntryList_Impl, DocTempl_EntryData_Impl* )
+ const SfxDocTemplate_Impl* mpParent;
+ EntryList_Impl maEntries;
+ OUString maTitle;
+ OUString maOwnURL;
+ OUString maTargetURL;
+
+private:
+ long GetEntryPos( const OUString& rTitle,
+ sal_Bool& rFound ) const;
+ const SfxDocTemplate_Impl* GetParent() const { return mpParent; }
+
+public:
+ RegionData_Impl( const SfxDocTemplate_Impl* pParent,
+ const OUString& rTitle );
+ ~RegionData_Impl();
+
+ void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
+ void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
+
+ DocTempl_EntryData_Impl* GetEntry( ULONG nIndex ) const;
+ DocTempl_EntryData_Impl* GetEntry( const OUString& rName ) const;
+ DocTempl_EntryData_Impl* GetByTargetURL( const OUString& rName ) const;
+
+ const OUString& GetTitle() const { return maTitle; }
+ const OUString& GetTargetURL();
+ const OUString& GetHierarchyURL();
+
+ ULONG GetCount() const;
+
+ void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
+
+ void AddEntry( const OUString& rTitle,
+ const OUString& rTargetURL,
+ USHORT *pPos = NULL );
+ void DeleteEntry( ULONG nIndex );
+
+ int Compare( const OUString& rTitle ) const
+ { return maTitle.compareTo( rTitle ); }
+ int Compare( RegionData_Impl* pCompareWith ) const;
+};
+
+DECLARE_LIST( RegionList_Impl, RegionData_Impl* )
+
+// ------------------------------------------------------------------------
+
+class SfxDocTemplate_Impl : public SvRefBase
+{
+ uno::Reference< XPersist > mxInfo;
+ uno::Reference< XDocumentTemplates > mxTemplates;
+
+ ::osl::Mutex maMutex;
+ OUString maRootURL;
+ OUString maStandardGroup;
+ RegionList_Impl maRegions;
+ sal_Bool mbConstructed;
+
+ uno::Reference< XAnyCompareFactory > m_rCompareFactory;
+
+ // the following member is intended to prevent clearing of the global data when it is in use
+ // TODO/LATER: it still does not make the implementation complete thread-safe
+ sal_Int32 mnLockCounter;
+
+private:
+ void Clear();
+
+public:
+ SfxDocTemplate_Impl();
+ ~SfxDocTemplate_Impl();
+
+ void IncrementLock();
+ void DecrementLock();
+
+ sal_Bool Construct( );
+ void CreateFromHierarchy( Content &rTemplRoot );
+ void ReInitFromComponent();
+ void AddRegion( const OUString& rTitle,
+ Content& rContent );
+
+ void Rescan();
+
+ void DeleteRegion( ULONG nIndex );
+
+ ULONG GetRegionCount() const
+ { return maRegions.Count(); }
+ RegionData_Impl* GetRegion( const OUString& rName ) const;
+ RegionData_Impl* GetRegion( ULONG nIndex ) const;
+ void GetTemplates( Content& rTargetFolder,
+ Content& rParentFolder,
+ RegionData_Impl* pRegion );
+
+ long GetRegionPos( const OUString& rTitle,
+ sal_Bool& rFound ) const;
+
+ sal_Bool GetTitleFromURL( const OUString& rURL, OUString& aTitle );
+ sal_Bool InsertRegion( RegionData_Impl *pData, ULONG nPos = LIST_APPEND );
+ OUString GetRootURL() const { return maRootURL; }
+
+ uno::Reference< XDocumentTemplates > getDocTemplates() { return mxTemplates; }
+};
+
+// ------------------------------------------------------------------------
+
+class DocTemplLocker_Impl
+{
+ SfxDocTemplate_Impl& m_aDocTempl;
+public:
+ DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl )
+ : m_aDocTempl( aDocTempl )
+ {
+ m_aDocTempl.IncrementLock();
+ }
+
+ ~DocTemplLocker_Impl()
+ {
+ m_aDocTempl.DecrementLock();
+ }
+};
+
+// ------------------------------------------------------------------------
+
+#ifndef SFX_DECL_DOCTEMPLATES_DEFINED
+#define SFX_DECL_DOCTEMPLATES_DEFINED
+SV_DECL_REF(SfxDocTemplate_Impl)
+#endif
+
+SV_IMPL_REF(SfxDocTemplate_Impl)
+
+// ------------------------------------------------------------------------
+
+SfxDocTemplate_Impl *gpTemplateData = 0;
+
+// -----------------------------------------------------------------------
+
+static sal_Bool getTextProperty_Impl( Content& rContent,
+ const OUString& rPropName,
+ OUString& rPropValue );
+
+//========================================================================
+//========================================================================
+//========================================================================
+
+String SfxDocumentTemplates::GetFullRegionName
+(
+ USHORT nIdx // Index des Bereiches
+) const
+
+/* [Beschreibung]
+
+ Liefert den logischen Namen eines Bereiches Plus seinem Pfad
+
+
+ [R"uckgabewert] Referenz auf diesen Namen
+
+*/
+
+{
+ // First: find the RegionData for the index
+ String aName;
+
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( pImp->Construct() )
+ {
+ RegionData_Impl *pData1 = pImp->GetRegion( nIdx );
+
+ if ( pData1 )
+ aName = pData1->GetTitle();
+
+ // --**-- here was some code which appended the path to the
+ // group if there was more than one with the same name.
+ // this should not happen anymore
+ }
+
+ return aName;
+}
+
+//------------------------------------------------------------------------
+
+const String& SfxDocumentTemplates::GetRegionName
+(
+ USHORT nIdx // Index des Bereiches
+) const
+
+/* [Beschreibung]
+
+ Liefert den logischen Namen eines Bereiches
+
+
+ [R"uckgabewert]
+
+ const String& Referenz auf diesen Namen
+
+*/
+{
+ static String maTmpString;
+
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( pImp->Construct() )
+ {
+ RegionData_Impl *pData = pImp->GetRegion( nIdx );
+
+ if ( pData )
+ maTmpString = pData->GetTitle();
+ else
+ maTmpString.Erase();
+ }
+ else
+ maTmpString.Erase();
+
+ return maTmpString;
+}
+
+
+//------------------------------------------------------------------------
+
+USHORT SfxDocumentTemplates::GetRegionNo
+(
+ const String &rRegion // Name der Region
+) const
+
+/* [Beschreibung]
+
+ Liefert den Index f"ur einen logischen Namen eines Bereiches.
+
+
+ [R"uckgabewert]
+
+ USHORT Index von 'rRegion' oder USHRT_MAX falls unbekannt
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return USHRT_MAX;
+
+ sal_Bool bFound;
+ ULONG nIndex = pImp->GetRegionPos( rRegion, bFound );
+
+ if ( bFound )
+ return (USHORT) nIndex;
+ else
+ return USHRT_MAX;
+}
+
+
+//------------------------------------------------------------------------
+
+USHORT SfxDocumentTemplates::GetRegionCount() const
+
+/* [Beschreibung]
+
+ Liefert die Anzahl der Bereiche
+
+
+ [R"uckgabewert]
+
+ USHORT Anzahl der Bereiche
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ ULONG nCount = pImp->GetRegionCount();
+
+ return (USHORT) nCount;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::IsRegionLoaded( USHORT nIdx ) const
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pData = pImp->GetRegion( nIdx );
+
+ if ( pData )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+USHORT SfxDocumentTemplates::GetCount
+(
+ const String& rName /* Name des Bereiches, dessen Eintrags-
+ anzahl ermittelt werden soll */
+
+) const
+
+/* [Beschreibung]
+
+ Liefert die Anzahl der Eintr"age eines Bereiches
+
+
+ [R"uckgabewert]
+
+ USHORT Anzahl der Eintr"age
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ RegionData_Impl *pData = pImp->GetRegion( rName );
+ ULONG nCount = 0;
+
+ if ( pData )
+ nCount = pData->GetCount();
+
+ return (USHORT) nCount;
+}
+
+//------------------------------------------------------------------------
+
+USHORT SfxDocumentTemplates::GetCount
+(
+ USHORT nRegion /* Index des Bereiches, dessen Eintrags-
+ anzahl ermittelt werden soll */
+
+) const
+
+/* [Beschreibung]
+
+ Liefert die Anzahl der Eintr"age eines Bereiches
+
+
+ [R"uckgabewert] Anzahl der Eintr"age
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ RegionData_Impl *pData = pImp->GetRegion( nRegion );
+ ULONG nCount = 0;
+
+ if ( pData )
+ nCount = pData->GetCount();
+
+ return (USHORT) nCount;
+}
+
+//------------------------------------------------------------------------
+
+const String& SfxDocumentTemplates::GetName
+(
+ USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
+ USHORT nIdx // Index des Eintrags
+) const
+
+/* [Beschreibung]
+
+ Liefert den logischen Namen eines Eintrags eines Bereiches
+
+
+ [R"uckgabewert]
+
+ const String& Name des Eintrags
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ static String maTmpString;
+
+ if ( pImp->Construct() )
+ {
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ maTmpString = pEntry->GetTitle();
+ else
+ maTmpString.Erase();
+ }
+ else
+ maTmpString.Erase();
+
+ return maTmpString;
+}
+
+//------------------------------------------------------------------------
+
+String SfxDocumentTemplates::GetFileName
+(
+ USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
+ USHORT nIdx // Index des Eintrags
+) const
+
+/* [Beschreibung]
+
+ Liefert den Dateinamen eines Eintrags eines Bereiches
+
+ [R"uckgabewert] Dateiname des Eintrags
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return String();
+
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ {
+ INetURLObject aURLObj( pEntry->GetTargetURL() );
+ return aURLObj.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ }
+ else
+ return String();
+}
+
+//------------------------------------------------------------------------
+
+String SfxDocumentTemplates::GetPath
+(
+ USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
+ USHORT nIdx // Index des Eintrags
+) const
+
+/* [Beschreibung]
+
+ Liefert den Dateinamen mit vollst"andigem Pfad zu der einem
+ Eintrag zugeordneten Datei
+
+
+ [R"uckgabewert]
+
+ String Dateiname mit vollst"andigem Pfad
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return String();
+
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ return pEntry->GetTargetURL();
+ else
+ return String();
+}
+
+//------------------------------------------------------------------------
+
+String SfxDocumentTemplates::GetTemplatePath
+(
+ USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
+ const String& rLongName // logischer Name des Eintrags
+) const
+
+/* [Beschreibung]
+
+ Liefert den Dateinamen mit vollst"andigem Pfad zu der einem
+ Eintrag zugeordneten Datei
+
+
+ [R"uckgabewert]
+
+ String Dateiname mit vollst"andigem Pfad
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return String();
+
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( rLongName );
+
+ if ( pEntry )
+ return pEntry->GetTargetURL();
+ else if ( pRegion )
+ {
+ // a new template is going to be inserted, generate a new URL
+ // TODO/LATER: if the title is localized, use minimized URL in future
+
+ // --**-- extension handling will become more complicated, because
+ // every new document type will have it's own extension
+ // e.g.: .stw or .stc instead of .vor
+ INetURLObject aURLObj( pRegion->GetTargetURL() );
+ aURLObj.insertName( rLongName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ OUString aExtension = aURLObj.getExtension();
+
+ if ( ! aExtension.getLength() )
+ aURLObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM( "vor" ) ) );
+
+ return aURLObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ return String();
+}
+
+//------------------------------------------------------------------------
+
+String SfxDocumentTemplates::GetDefaultTemplatePath
+(
+ const String& rLongName
+)
+
+/* [Beschreibung]
+
+ Liefert den Standardpfad zu Dokumentvorlagen
+
+
+ [R"uckgabewert]
+
+ String Standardpfad zu Dokumentvorlagen
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return String();
+
+ // the first region in the list should always be the standard
+ // group
+ // --**-- perhaps we have to create it ???
+ RegionData_Impl *pRegion = pImp->GetRegion( 0L );
+ DocTempl_EntryData_Impl *pEntry = NULL;
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( rLongName );
+
+ if ( pEntry )
+ return pEntry->GetTargetURL();
+ else if ( pRegion )
+ {
+ // a new template is going to be inserted, generate a new URL
+ // TODO/LATER: if the title is localized, use minimized URL in future
+
+ INetURLObject aURLObj( pRegion->GetTargetURL() );
+ aURLObj.insertName( rLongName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ OUString aExtension = aURLObj.getExtension();
+
+ if ( ! aExtension.getLength() )
+ aURLObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM( "vor" ) ) );
+
+ return aURLObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ return String();
+
+/* dv! missing: create the directory, if it doesn't exists
+
+
+ DBG_ASSERT(aDirs.GetTokenCount(cDelim), "Keine Bereiche");
+ DirEntry aPath(aDirs.GetToken(0, cDelim));
+
+ // Verzeichnis anlegen
+ if(!aPath.MakeDir())
+ return String();
+
+ MakeFileName_Impl(aPath, rLongName, sal_True);
+ SfxTemplateDir *pEntry = new SfxTemplateDir;
+ SfxTemplateDirEntryPtr pDirEntry =
+ new SfxTemplateDirEntry( String( '.' ), aPath.GetPath() );
+ pDirEntry->SetContent(new SfxTemplateDir(aPath.GetPath()));
+ pEntry->Insert(pDirEntry, pEntry->Count());
+ pDirs->Insert(pEntry, pDirs->Count());
+ return aPath.GetFull();
+*/
+}
+
+//------------------------------------------------------------------------
+
+::rtl::OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( const ::rtl::OUString& aGroupName,
+ const ::rtl::OUString& aTitle )
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ INetURLObject aTemplateObj( pImp->GetRootURL() );
+
+ aTemplateObj.insertName( aGroupName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ aTemplateObj.insertName( aTitle, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+
+ ::rtl::OUString aResult;
+ Content aTemplate;
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, aTemplate ) )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+ getTextProperty_Impl( aTemplate, aPropName, aResult );
+ aResult = SvtPathOptions().SubstituteVariable( aResult );
+ }
+
+ return aResult;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::SaveDir
+(
+// SfxTemplateDir& rDir // das zu speichernde Directory
+)
+
+/* [Beschreibung]
+
+ Speichert das Directory rDir
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_False,
+ Schreibfehler
+
+ sal_True
+ gespeichert
+
+*/
+
+{
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+void SfxDocumentTemplates::NewTemplate
+(
+ USHORT nRegion, /* Index des Bereiches, in dem die Vorlage
+ angelegt werden soll */
+
+ const String& rLongName, // logischer Name der neuen Vorlage
+ const String& rFileName // Dateiname der neuen Vorlage
+)
+
+/* [Beschreibung]
+
+ Eintragen einer neuen Dokumentvorlage in die Verwaltungsstrukturen
+ Das "Uberschreiben einer Vorlage gleichen Namens wird
+ verhindert (!! Fehlermeldung)
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return;
+
+ DocTempl_EntryData_Impl *pEntry;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ // do nothing if there is no region with that index
+ if ( !pRegion )
+ return;
+
+ pEntry = pRegion->GetEntry( rLongName );
+
+ // do nothing if there is already an entry with that name
+ if ( pEntry )
+ return;
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+
+ if ( xTemplates->addTemplate( pRegion->GetTitle(), rLongName, rFileName ) )
+ pRegion->AddEntry( rLongName, rFileName );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::CopyOrMove
+(
+ USHORT nTargetRegion, // Index des Zielbereiches
+ USHORT nTargetIdx, // Index Zielposition
+ USHORT nSourceRegion, // Index des Quellbereiches
+ USHORT nSourceIdx, /* Index der zu kopierenden / zu verschiebenden
+ Dokumentvorlage */
+ sal_Bool bMove // kopieren / verschieben
+)
+
+/* [Beschreibung]
+
+ Kopieren oder Verschieben einer Dokumentvorlage
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef2uhrt werden
+ [Querverweise]
+
+ <SfxDocumentTemplates::Move(USHORT,USHORT,USHORT,USHORT)>
+ <SfxDocumentTemplates::Copy(USHORT,USHORT,USHORT,USHORT)>
+*/
+
+{
+ /* to perform a copy or move, we need to send a transfer command to
+ the destination folder with the URL of the source as parameter.
+ ( If the destination content doesn't support the transfer command,
+ we could try a copy ( and delete ) instead. )
+ We need two transfers ( one for the real template and one for its
+ representation in the hierarchy )
+ ...
+ */
+
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return sal_False;
+
+ // Don't copy or move any folders
+ if( nSourceIdx == USHRT_MAX )
+ return sal_False ;
+
+ if ( nSourceRegion == nTargetRegion )
+ {
+ DBG_ERRORFILE( "Don't know, what to do!" );
+ return sal_False;
+#if 0
+ // Verschieben einer Vorlage innerhalb eines Bereiches
+ // --> nur Verwaltungsdaten aktualisieren
+ if ( bMove && nTargetRegion == nSourceRegion )
+ {
+ if(nTargetIdx == USHRT_MAX)
+ nTargetIdx = 0;
+ const SfxTemplateDirEntryPtr pEntry = rTargetDir[nSourceIdx];
+ rTargetDir.Insert(pEntry, nTargetIdx);
+ if(nTargetIdx < nSourceIdx)
+ ++nSourceIdx;
+ rTargetDir.Remove(nSourceIdx);
+ return SaveDir(rTargetDir);
+ }
+#endif
+ }
+
+ RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion );
+ if ( !pSourceRgn )
+ return sal_False;
+
+ DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx );
+ if ( !pSource )
+ return sal_False;
+
+ RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion );
+ if ( !pTargetRgn )
+ return sal_False;
+
+ OUString aTitle = pSource->GetTitle();
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+
+ if ( xTemplates->addTemplate( pTargetRgn->GetTitle(),
+ aTitle,
+ pSource->GetTargetURL() ) )
+ {
+
+ INetURLObject aSourceObj( pSource->GetTargetURL() );
+
+ ::rtl::OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle );
+ if ( !aNewTargetURL.getLength() )
+ return sal_False;
+
+ if ( bMove )
+ {
+ // --**-- delete the original file
+ sal_Bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(),
+ pSource->GetTitle() );
+ if ( bDeleted )
+ pSourceRgn->DeleteEntry( nSourceIdx );
+ else
+ {
+ if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) )
+ return sal_False; // will trigger tetry with copy instead of move
+
+ // if it is not possible to remove just created template ( must be possible! )
+ // it is better to report success here, since at least the copy has succeeded
+ // TODO/LATER: solve it more gracefully in future
+ }
+ }
+
+ pTargetRgn->AddEntry( aTitle, aNewTargetURL, &nTargetIdx );
+
+ return sal_True;
+ }
+
+ // --**-- wenn aktuell das File geoeffnet ist,
+ // muss es hinterher wieder geoeffnet werden
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Move
+(
+ USHORT nTargetRegion, // Index des Zielbereiches
+ USHORT nTargetIdx, // Index Zielposition
+ USHORT nSourceRegion, // Index des Quellbereiches
+ USHORT nSourceIdx /* Index der zu kopierenden / zu verschiebenden
+ Dokumentvorlage */
+)
+
+/* [Beschreibung]
+
+ Verschieben einer Dokumentvorlage
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef2uhrt werden
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::CopyOrMove(USHORT,USHORT,USHORT,USHORT,sal_Bool)>
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ return CopyOrMove( nTargetRegion, nTargetIdx,
+ nSourceRegion, nSourceIdx, sal_True );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Copy
+(
+ USHORT nTargetRegion, // Index des Zielbereiches
+ USHORT nTargetIdx, // Index Zielposition
+ USHORT nSourceRegion, // Index des Quellbereiches
+ USHORT nSourceIdx /* Index der zu kopierenden / zu verschiebenden
+ Dokumentvorlage */
+)
+
+/* [Beschreibung]
+
+ Kopieren einer Dokumentvorlage
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::CopyOrMove(USHORT,USHORT,USHORT,USHORT,sal_Bool)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ return CopyOrMove( nTargetRegion, nTargetIdx,
+ nSourceRegion, nSourceIdx, sal_False );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::CopyTo
+(
+ USHORT nRegion, /* Bereich der Vorlage, die exportiert werden
+ soll */
+ USHORT nIdx, /* Index der Vorlage, die exportiert werden
+ soll */
+ const String& rName /* Dateiname, unter dem die Vorlage angelegt
+ werden soll */
+) const
+
+/* [Beschreibung]
+
+ Exportieren einer Dokumentvorlage in das Dateisystem
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::CopyFrom(USHORT,USHORT,String&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion );
+ if ( !pSourceRgn )
+ return sal_False;
+
+ DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx );
+ if ( !pSource )
+ return sal_False;
+
+ INetURLObject aTargetURL( rName );
+
+ OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET ) );
+ aTargetURL.removeSegment();
+
+ OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::NO_DECODE );
+
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ Content aTarget;
+
+ try
+ {
+ aTarget = Content( aParentURL, aCmdEnv );
+
+ TransferInfo aTransferInfo;
+ aTransferInfo.MoveData = sal_False;
+ aTransferInfo.SourceURL = pSource->GetTargetURL();
+ aTransferInfo.NewTitle = aTitle;
+ aTransferInfo.NameClash = NameClash::OVERWRITE;
+
+ Any aArg = makeAny( aTransferInfo );
+ OUString aCmd( RTL_CONSTASCII_USTRINGPARAM( COMMAND_TRANSFER ) );
+
+ aTarget.executeCommand( aCmd, aArg );
+ }
+ catch ( ContentCreationException& )
+ { return sal_False; }
+ catch ( Exception& )
+ { return sal_False; }
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::CopyFrom
+(
+ USHORT nRegion, /* Bereich, in den die Vorlage importiert
+ werden soll */
+ USHORT nIdx, // Index der neuen Vorlage in diesem Bereich
+ String& rName /* Dateiname der Vorlage, die importiert
+ werden soll, als out-Parameter der (auto-
+ matisch aus dem Dateinamen generierte)
+ logische Name der Vorlage */
+)
+
+/* [Beschreibung]
+
+ Importieren einer Dokumentvorlage aus dem Dateisystem
+
+
+ [R"uckgabewert] Erfolg (sal_True) oder Mi"serfpTargetDirectory->GetContent());
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::CopyTo(USHORT,USHORT,const String&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion );
+
+ if ( !pTargetRgn )
+ return sal_False;
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+ if ( !xTemplates.is() )
+ return sal_False;
+
+ OUString aTitle;
+ sal_Bool bTemplateAdded = sal_False;
+
+ if( pImp->GetTitleFromURL( rName, aTitle ) )
+ {
+ bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName );
+ }
+ else
+ {
+ OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DESKTOP ) );
+ uno::Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( aService ),
+ UNO_QUERY );
+
+ Sequence< PropertyValue > aArgs( 1 );
+ aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden");
+ aArgs[0].Value <<= sal_True;
+
+ INetURLObject aTemplURL( rName );
+ uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier;
+ uno::Reference< XStorable > xStorable;
+ try
+ {
+ xStorable = uno::Reference< XStorable >(
+ xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::NO_DECODE),
+ OUString::createFromAscii( "_blank" ),
+ 0,
+ aArgs ),
+ UNO_QUERY );
+
+ xDocPropsSupplier = uno::Reference< XDocumentPropertiesSupplier >(
+ xStorable, UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( xStorable.is() )
+ {
+ // get Title from XDocumentPropertiesSupplier
+ if( xDocPropsSupplier.is() )
+ {
+ uno::Reference< XDocumentProperties > xDocProps
+ = xDocPropsSupplier->getDocumentProperties();
+ if (xDocProps.is() ) {
+ aTitle = xDocProps->getTitle();
+ }
+ }
+
+ if( ! aTitle.getLength() )
+ {
+ INetURLObject aURL( aTemplURL );
+ aURL.CutExtension();
+ aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ }
+
+ // write a template using XStorable interface
+ bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable );
+ }
+ }
+
+
+ if( bTemplateAdded )
+ {
+ INetURLObject aTemplObj( pTargetRgn->GetHierarchyURL() );
+ aTemplObj.insertName( aTitle, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ Content aTemplCont;
+
+ if( Content::create( aTemplURL, aCmdEnv, aTemplCont ) )
+ {
+ OUString aTemplName;
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+
+ if( getTextProperty_Impl( aTemplCont, aPropName, aTemplName ) )
+ {
+ if ( nIdx == USHRT_MAX )
+ nIdx = 0;
+ else
+ nIdx += 1;
+
+ pTargetRgn->AddEntry( aTitle, aTemplName, &nIdx );
+ rName = aTitle;
+ return sal_True;
+ }
+ else
+ {
+ DBG_ASSERT( sal_False, "CopyFrom(): The content should contain target URL!" );
+ }
+ }
+ else
+ {
+ DBG_ASSERT( sal_False, "CopyFrom(): The content just was created!" );
+ }
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Delete
+(
+ USHORT nRegion, // Index des Bereiches
+ USHORT nIdx /* Index des Eintrags oder USHRT_MAX,
+ wenn ein Verzeichnis gemeint ist. */
+)
+
+/* [Beschreibung]
+
+ "oschen eines Eintrags oder eines Verzeichnisses
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::InsertDir(const String&,USHORT)>
+ <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
+ <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ /* delete the template or folder in the hierarchy and in the
+ template folder by sending a delete command to the content.
+ Then remove the data from the lists
+ */
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( !pRegion )
+ return sal_False;
+
+ sal_Bool bRet;
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+
+ if ( nIdx == USHRT_MAX )
+ {
+ bRet = xTemplates->removeGroup( pRegion->GetTitle() );
+ if ( bRet )
+ pImp->DeleteRegion( nRegion );
+ }
+ else
+ {
+ DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
+
+ if ( !pEntry )
+ return sal_False;
+
+ bRet = xTemplates->removeTemplate( pRegion->GetTitle(),
+ pEntry->GetTitle() );
+ if( bRet )
+ pRegion->DeleteEntry( nIdx );
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::InsertDir
+(
+ const String& rText, // der logische Name des neuen Bereiches
+ USHORT nRegion // Index des Bereiches
+)
+
+/* [Beschreibung]
+
+ Einf"ugen eines Verzeichnisses
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
+ <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)>
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( rText );
+
+ if ( pRegion )
+ return sal_False;
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+
+ if ( xTemplates->addGroup( rText ) )
+ {
+ RegionData_Impl* pNewRegion = new RegionData_Impl( pImp, rText );
+
+ if ( ! pImp->InsertRegion( pNewRegion, nRegion ) )
+ {
+ delete pNewRegion;
+ return sal_False;
+ }
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::SetName
+(
+ const String& rName, // Der zu setzende Name
+ USHORT nRegion, // Index des Bereiches
+ USHORT nIdx /* Index des Eintrags oder USHRT_MAX,
+ wenn ein Verzeichnis gemeint ist. */
+)
+
+/* [Beschreibung]
+
+ "Andern des Namens eines Eintrags oder eines Verzeichnisses
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+ DocTempl_EntryData_Impl *pEntry = NULL;
+
+ if ( !pRegion )
+ return sal_False;
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+ OUString aEmpty;
+
+ if ( nIdx == USHRT_MAX )
+ {
+ if ( pRegion->GetTitle() == OUString( rName ) )
+ return sal_True;
+
+ // we have to rename a region
+ if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) )
+ {
+ pRegion->SetTitle( rName );
+ pRegion->SetTargetURL( aEmpty );
+ pRegion->SetHierarchyURL( aEmpty );
+ return sal_True;
+ }
+ }
+ else
+ {
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( !pEntry )
+ return sal_False;
+
+ if ( pEntry->GetTitle() == OUString( rName ) )
+ return sal_True;
+
+ if ( xTemplates->renameTemplate( pRegion->GetTitle(),
+ pEntry->GetTitle(),
+ rName ) )
+ {
+ pEntry->SetTitle( rName );
+ pEntry->SetTargetURL( aEmpty );
+ pEntry->SetHierarchyURL( aEmpty );
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Rescan()
+
+/* [Beschreibung]
+
+ Abgleich des Verwaltungsdaten mit dem aktuellen Zustand auf der Platte.
+ Die logischen Namen, zu denen keine Datei mit existiert, werden aus
+ der Verwaltungsstruktur entfernt; Dateien, zu denen kein Eintrag
+ existiert, werden aufgenommen.
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxTemplateDir::Scan(sal_Bool bDirectory, sal_Bool bSave)>
+ <SfxTemplateDir::Freshen(const SfxTemplateDir &rNew)>
+*/
+{
+ if ( !pImp->Construct() )
+ return sal_False;
+
+ pImp->Rescan();
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+SfxObjectShellRef SfxDocumentTemplates::CreateObjectShell
+(
+ USHORT nRegion, // Index des Bereiches
+ USHORT nIdx // Index des Eintrags
+)
+
+/* [Beschreibung]
+
+ Zugriff auf die DokumentShell eines Eintrags
+
+
+ [R"uckgabewert]
+
+ SfxObjectShellRef Referenz auf die ObjectShell
+
+
+ [Querverweise]
+
+ <SfxTemplateDirEntry::CreateObjectShell()>
+ <SfxDocumentTemplates::DeleteObjectShell(USHORT, USHORT)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return NULL;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+ DocTempl_EntryData_Impl *pEntry = NULL;
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ return pEntry->CreateObjectShell();
+ else
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::DeleteObjectShell
+(
+ USHORT nRegion, // Index des Bereiches
+ USHORT nIdx // Index des Eintrags
+)
+
+/* [Beschreibung]
+
+ Freigeben der ObjectShell eines Eintrags
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+ [Querverweise]
+
+ <SfxTemplateDirEntry::DeleteObjectShell()>
+ <SfxDocumentTemplates::CreateObjectShell(USHORT, USHORT)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_True;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+ DocTempl_EntryData_Impl *pEntry = NULL;
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ return pEntry->DeleteObjectShell();
+ else
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::GetFull
+(
+ const String &rRegion, // Der Name des Bereiches
+ const String &rName, // Der Name der Vorlage
+ String &rPath // Out: Pfad + Dateiname
+)
+
+/* [Beschreibung]
+
+ Liefert Pfad + Dateiname zu der durch rRegion und rName bezeichneten
+ Vorlage
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ // We don't search for empty names!
+ if ( ! rName.Len() )
+ return sal_False;
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ DocTempl_EntryData_Impl* pEntry = NULL;
+ const USHORT nCount = GetRegionCount();
+
+ for ( USHORT i = 0; i < nCount; ++i )
+ {
+ RegionData_Impl *pRegion = pImp->GetRegion( i );
+
+ if( pRegion &&
+ ( !rRegion.Len() || ( rRegion == String( pRegion->GetTitle() ) ) ) )
+ {
+ pEntry = pRegion->GetEntry( rName );
+
+ if ( pEntry )
+ {
+ rPath = pEntry->GetTargetURL();
+ break;
+ }
+ }
+ }
+
+ return ( pEntry != NULL );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::GetLogicNames
+(
+ const String &rPath, // vollst"andiger Pfad zu der Vorlage
+ String &rRegion, // Out: der Bereichsname
+ String &rName // Out: der Vorlagenname
+) const
+
+/* [Beschreibung]
+
+ Liefert Pfad und logischen Namen zu der durch rPath bezeichneten
+ Vorlage
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ INetURLObject aFullPath;
+
+ aFullPath.SetSmartProtocol( INET_PROT_FILE );
+ aFullPath.SetURL( rPath );
+ OUString aPath( aFullPath.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ RegionData_Impl *pData = NULL;
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ sal_Bool bFound = sal_False;
+
+ ULONG nCount = GetRegionCount();
+
+ for ( ULONG i=0; !bFound && (i<nCount); i++ )
+ {
+ pData = pImp->GetRegion( i );
+ if ( pData )
+ {
+ ULONG nChildCount = pData->GetCount();
+
+ for ( ULONG j=0; !bFound && (j<nChildCount); j++ )
+ {
+ pEntry = pData->GetEntry( j );
+ if ( pEntry->GetTargetURL() == aPath )
+ {
+ bFound = sal_True;
+ }
+ }
+ }
+ }
+
+ if ( bFound )
+ {
+ rRegion = pData->GetTitle();
+ rName = pEntry->GetTitle();
+ }
+
+ return bFound;
+}
+
+//------------------------------------------------------------------------
+
+SfxDocumentTemplates::SfxDocumentTemplates()
+
+/* [Beschreibung]
+
+ Konstruktor
+*/
+{
+ if ( !gpTemplateData )
+ gpTemplateData = new SfxDocTemplate_Impl;
+
+ pImp = gpTemplateData;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxDocumentTemplates::Construct()
+
+// verz"ogerter Aufbau der Verwaltungsdaten
+
+{
+// pImp->Construct();
+}
+
+//------------------------------------------------------------------------
+
+SfxDocumentTemplates::~SfxDocumentTemplates()
+
+/* [Beschreibung]
+
+ Destruktor
+ Freigeben der Verwaltungsdaten
+*/
+
+{
+ pImp = NULL;
+}
+
+void SfxDocumentTemplates::Update( sal_Bool _bSmart )
+{
+ if ( !_bSmart // don't be smart
+ || ::svt::TemplateFolderCache( sal_True ).needsUpdate() // update is really necessary
+ )
+ {
+ if ( pImp->Construct() )
+ pImp->Rescan();
+ }
+}
+
+void SfxDocumentTemplates::ReInitFromComponent()
+{
+ pImp->ReInitFromComponent();
+}
+
+
+sal_Bool SfxDocumentTemplates::HasUserContents( sal_uInt16 nRegion, sal_uInt16 nIdx ) const
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ sal_Bool bResult = sal_False;
+
+ RegionData_Impl* pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ {
+ ::rtl::OUString aRegionTargetURL = pRegion->GetTargetURL();
+ if ( aRegionTargetURL.getLength() )
+ {
+ sal_uInt16 nLen = 0;
+ sal_uInt16 nStartInd = 0;
+
+ if( nIdx == USHRT_MAX )
+ {
+ // this is a folder
+ // check whether there is at least one editable template
+ nLen = ( sal_uInt16 )pRegion->GetCount();
+ nStartInd = 0;
+ if ( nLen == 0 )
+ bResult = sal_True; // the writing part of empty folder with writing URL can be removed
+ }
+ else
+ {
+ // this is a template
+ // check whether the template is inserted by user
+ nLen = 1;
+ nStartInd = nIdx;
+ }
+
+ for ( sal_uInt16 nInd = nStartInd; nInd < nStartInd + nLen; nInd++ )
+ {
+ DocTempl_EntryData_Impl* pEntryData = pRegion->GetEntry( nInd );
+ if ( pEntryData )
+ {
+ ::rtl::OUString aEntryTargetURL = pEntryData->GetTargetURL();
+ if ( aEntryTargetURL.getLength()
+ && ::utl::UCBContentHelper::IsSubPath( aRegionTargetURL, aEntryTargetURL ) )
+ {
+ bResult = sal_True;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl* pParent,
+ const OUString& rTitle )
+{
+ mpParent = pParent;
+ maTitle = rTitle;
+ mbIsOwner = sal_False;
+ mbDidConvert= sal_False;
+}
+
+// -----------------------------------------------------------------------
+int DocTempl_EntryData_Impl::Compare( const OUString& rTitle ) const
+{
+ return maTitle.compareTo( rTitle );
+}
+
+//------------------------------------------------------------------------
+SfxObjectShellRef DocTempl_EntryData_Impl::CreateObjectShell()
+{
+ if( ! mxObjShell.Is() )
+ {
+ mbIsOwner = sal_False;
+ sal_Bool bDum = sal_False;
+ SfxApplication *pSfxApp = SFX_APP();
+ String aTargetURL = GetTargetURL();
+
+ mxObjShell = pSfxApp->DocAlreadyLoaded( aTargetURL, sal_True, bDum );
+
+ if( ! mxObjShell.Is() )
+ {
+ mbIsOwner = sal_True;
+ SfxMedium *pMed=new SfxMedium(
+ aTargetURL,(STREAM_STD_READWRITE | STREAM_SHARE_DENYALL), sal_False, 0 );
+ const SfxFilter* pFilter = NULL;
+ pMed->UseInteractionHandler(TRUE);
+ if( pSfxApp->GetFilterMatcher().GuessFilter(
+ *pMed, &pFilter, SFX_FILTER_TEMPLATE, 0 ) ||
+ (pFilter && !pFilter->IsOwnFormat()) ||
+ (pFilter && !pFilter->UsesStorage()) )
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_LOADTEMPLATE,
+ aTargetURL );
+ delete pMed;
+ mbDidConvert=sal_True;
+ ULONG lErr;
+ if ( mxObjShell.Is() ) {
+ lErr = pSfxApp->LoadTemplate( mxObjShell,aTargetURL);
+ if( lErr != ERRCODE_NONE )
+ ErrorHandler::HandleError(lErr);
+ }
+
+ }
+ else if (pFilter)
+ {
+ mbDidConvert=sal_False;
+ mxObjShell = SfxObjectShell::CreateObject( pFilter->GetServiceName(), SFX_CREATE_MODE_ORGANIZER );
+ if ( mxObjShell.Is() )
+ {
+ mxObjShell->DoInitNew(0);
+ // TODO/LATER: make sure that we don't use binary templates!
+ if( mxObjShell->LoadFrom( *pMed ) )
+ {
+ mxObjShell->DoSaveCompleted( pMed );
+ }
+ else
+ mxObjShell.Clear();
+ }
+ }
+ }
+ }
+
+ return (SfxObjectShellRef)(SfxObjectShell*) mxObjShell;
+}
+
+//------------------------------------------------------------------------
+BOOL DocTempl_EntryData_Impl::DeleteObjectShell()
+{
+ sal_Bool bRet = sal_True;
+
+ if ( mxObjShell.Is() )
+ {
+ if( mxObjShell->IsModified() )
+ {
+ //Hier speichern wir auch, falls die Vorlage in Bearbeitung ist...
+ bRet = sal_False;
+
+ if ( mbIsOwner )
+ {
+ if( mbDidConvert )
+ {
+ bRet=mxObjShell->PreDoSaveAs_Impl(
+ GetTargetURL(),
+ mxObjShell->GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_EXPORT | SFX_FILTER_IMPORT, SFX_FILTER_INTERNAL )->GetFilterName(), 0 );
+ }
+ else
+ {
+ if( mxObjShell->Save() )
+ {
+ uno::Reference< embed::XTransactedObject > xTransacted( mxObjShell->GetStorage(), uno::UNO_QUERY );
+ DBG_ASSERT( xTransacted.is(), "Storage must implement XTransactedObject!\n" );
+ if ( xTransacted.is() )
+ {
+ try
+ {
+ xTransacted->commit();
+ bRet = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if( bRet )
+ {
+ mxObjShell.Clear();
+ }
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+const OUString& DocTempl_EntryData_Impl::GetHierarchyURL()
+{
+ if ( !maOwnURL.getLength() )
+ {
+ INetURLObject aTemplateObj( GetParent()->GetHierarchyURL() );
+
+ aTemplateObj.insertName( GetTitle(), false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ maOwnURL = aTemplateObj.GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" );
+ }
+
+ return maOwnURL;
+}
+
+// -----------------------------------------------------------------------
+const OUString& DocTempl_EntryData_Impl::GetTargetURL()
+{
+ if ( !maTargetURL.getLength() )
+ {
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ Content aRegion;
+
+ if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+
+ getTextProperty_Impl( aRegion, aPropName, maTargetURL );
+ }
+ else
+ {
+ DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" );
+ }
+ }
+
+ return maTargetURL;
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
+ const OUString& rTitle )
+{
+ maTitle = rTitle;
+ mpParent = pParent;
+}
+
+// -----------------------------------------------------------------------
+RegionData_Impl::~RegionData_Impl()
+{
+ DocTempl_EntryData_Impl *pData = maEntries.First();
+
+ while ( pData )
+ {
+ delete pData;
+ pData = maEntries.Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+long RegionData_Impl::GetEntryPos( const OUString& rTitle,
+ sal_Bool& rFound ) const
+{
+#if 1 // Don't use binary search today
+ ULONG i;
+ ULONG nCount = maEntries.Count();
+
+ for ( i=0; i<nCount; i++ )
+ {
+ DocTempl_EntryData_Impl *pData = maEntries.GetObject( i );
+
+ if ( pData->Compare( rTitle ) == 0 )
+ {
+ rFound = sal_True;
+ return i;
+ }
+ }
+
+ rFound = sal_False;
+ return i;
+
+#else
+ // use binary search to find the correct position
+ // in the maEntries list
+
+ int nCompVal = 1;
+ long nStart = 0;
+ long nEnd = maEntries.Count() - 1;
+ long nMid;
+
+ DocTempl_EntryData_Impl* pMid;
+
+ rFound = sal_False;
+
+ while ( nCompVal && ( nStart <= nEnd ) )
+ {
+ nMid = ( nEnd - nStart ) / 2 + nStart;
+ pMid = maEntries.GetObject( nMid );
+
+ nCompVal = pMid->Compare( rTitle );
+
+ if ( nCompVal < 0 ) // pMid < pData
+ nStart = nMid + 1;
+ else
+ nEnd = nMid - 1;
+ }
+
+ if ( nCompVal == 0 )
+ {
+ rFound = sal_True;
+ }
+ else
+ {
+ if ( nCompVal < 0 ) // pMid < pData
+ nMid++;
+ }
+
+ return nMid;
+#endif
+}
+
+// -----------------------------------------------------------------------
+void RegionData_Impl::AddEntry( const OUString& rTitle,
+ const OUString& rTargetURL,
+ USHORT *pPos )
+{
+ INetURLObject aLinkObj( GetHierarchyURL() );
+ aLinkObj.insertName( rTitle, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ DocTempl_EntryData_Impl *pEntry;
+ sal_Bool bFound = sal_False;
+ long nPos = GetEntryPos( rTitle, bFound );
+
+ if ( bFound )
+ {
+ pEntry = maEntries.GetObject( nPos );
+ }
+ else
+ {
+ if ( pPos )
+ nPos = *pPos;
+
+ pEntry = new DocTempl_EntryData_Impl( this, rTitle );
+ pEntry->SetTargetURL( rTargetURL );
+ pEntry->SetHierarchyURL( aLinkURL );
+ maEntries.Insert( pEntry, nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+ULONG RegionData_Impl::GetCount() const
+{
+ return maEntries.Count();
+}
+
+// -----------------------------------------------------------------------
+const OUString& RegionData_Impl::GetHierarchyURL()
+{
+ if ( !maOwnURL.getLength() )
+ {
+ INetURLObject aRegionObj( GetParent()->GetRootURL() );
+
+ aRegionObj.insertName( GetTitle(), false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ maOwnURL = aRegionObj.GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" );
+ }
+
+ return maOwnURL;
+}
+
+// -----------------------------------------------------------------------
+const OUString& RegionData_Impl::GetTargetURL()
+{
+ if ( !maTargetURL.getLength() )
+ {
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ Content aRegion;
+
+ if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+
+ getTextProperty_Impl( aRegion, aPropName, maTargetURL );
+ // --> PB 2004-10-27 #i32656# - the targeturl must be substituted: $(baseinsturl)
+ maTargetURL = SvtPathOptions().SubstituteVariable( maTargetURL );
+ // <--
+ }
+ else
+ {
+ DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" );
+ }
+ }
+
+ return maTargetURL;
+}
+
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( const OUString& rName ) const
+{
+ sal_Bool bFound = sal_False;
+ long nPos = GetEntryPos( rName, bFound );
+
+ if ( bFound )
+ return maEntries.GetObject( nPos );
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl* RegionData_Impl::GetByTargetURL( const OUString& rName ) const
+{
+ DocTempl_EntryData_Impl *pEntry;
+
+ ULONG nCount = maEntries.Count();
+
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ pEntry = maEntries.GetObject( i );
+ if ( pEntry && ( pEntry->GetTargetURL() == rName ) )
+ return pEntry;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( ULONG nIndex ) const
+{
+ return maEntries.GetObject( nIndex );
+}
+
+// -----------------------------------------------------------------------
+void RegionData_Impl::DeleteEntry( ULONG nIndex )
+{
+ DocTempl_EntryData_Impl *pEntry = maEntries.GetObject( nIndex );
+
+ if ( pEntry )
+ {
+ delete pEntry;
+ maEntries.Remove( (ULONG) nIndex );
+ }
+}
+
+// -----------------------------------------------------------------------
+int RegionData_Impl::Compare( RegionData_Impl* pCompare ) const
+{
+ int nCompare = maTitle.compareTo( pCompare->maTitle );
+
+ return nCompare;
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+
+SfxDocTemplate_Impl::SfxDocTemplate_Impl()
+: mbConstructed( sal_False )
+, mnLockCounter( 0 )
+{
+}
+
+// -----------------------------------------------------------------------
+SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
+{
+ Clear();
+
+ gpTemplateData = NULL;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::IncrementLock()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ mnLockCounter++;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::DecrementLock()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mnLockCounter )
+ mnLockCounter--;
+}
+
+// -----------------------------------------------------------------------
+RegionData_Impl* SfxDocTemplate_Impl::GetRegion( ULONG nIndex ) const
+{
+ return maRegions.GetObject( nIndex );
+}
+
+// -----------------------------------------------------------------------
+RegionData_Impl* SfxDocTemplate_Impl::GetRegion( const OUString& rName )
+ const
+{
+ ULONG nCount = maRegions.Count();
+ RegionData_Impl *pData;
+
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ pData = maRegions.GetObject( i );
+
+ if ( pData->GetTitle() == rName )
+ return pData;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::DeleteRegion( ULONG nIndex )
+{
+ RegionData_Impl* pRegion = maRegions.GetObject( nIndex );
+
+ if ( pRegion )
+ {
+ delete pRegion;
+ maRegions.Remove( (ULONG) nIndex );
+ }
+}
+
+// -----------------------------------------------------------------------
+/* AddRegion adds a Region to the RegionList
+*/
+void SfxDocTemplate_Impl::AddRegion( const OUString& rTitle,
+ Content& rContent )
+{
+ RegionData_Impl* pRegion;
+ pRegion = new RegionData_Impl( this, rTitle );
+
+ if ( ! InsertRegion( pRegion ) )
+ {
+ delete pRegion;
+ return;
+ }
+
+ // now get the content of the region
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(2);
+ aProps[0] = OUString::createFromAscii( TITLE );
+ aProps[1] = OUString::createFromAscii( TARGET_URL );
+
+ try
+ {
+ ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
+ Sequence< NumberedSortingInfo > aSortingInfo(1);
+ aSortingInfo.getArray()->ColumnIndex = 1;
+ aSortingInfo.getArray()->Ascending = sal_True;
+ xResultSet = rContent.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ OUString aTitle( xRow->getString( 1 ) );
+ OUString aTargetDir( xRow->getString( 2 ) );
+
+ pRegion->AddEntry( aTitle, aTargetDir );
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::CreateFromHierarchy( Content &rTemplRoot )
+{
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(1);
+ aProps[0] = OUString::createFromAscii( TITLE );
+
+ try
+ {
+ ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
+ Sequence< NumberedSortingInfo > aSortingInfo(1);
+ aSortingInfo.getArray()->ColumnIndex = 1;
+ aSortingInfo.getArray()->Ascending = sal_True;
+ xResultSet = rTemplRoot.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ OUString aTitle( xRow->getString( 1 ) );
+
+ OUString aId = xContentAccess->queryContentIdentifierString();
+ Content aContent = Content( aId, aCmdEnv );
+
+ AddRegion( aTitle, aContent );
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+// ------------------------------------------------------------------------
+sal_Bool SfxDocTemplate_Impl::Construct( )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( mbConstructed )
+ return sal_True;
+
+ uno::Reference< XMultiServiceFactory > xFactory;
+ xFactory = ::comphelper::getProcessServiceFactory();
+
+ OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO ) );
+ uno::Reference< XPersist > xInfo( xFactory->createInstance( aService ), UNO_QUERY );
+ mxInfo = xInfo;
+
+ aService = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCTEMPLATES ) );
+ uno::Reference< XDocumentTemplates > xTemplates( xFactory->createInstance( aService ), UNO_QUERY );
+
+ if ( xTemplates.is() )
+ mxTemplates = xTemplates;
+ else
+ return sal_False;
+
+ uno::Reference< XLocalizable > xLocalizable( xTemplates, UNO_QUERY );
+
+ Sequence< Any > aCompareArg(1);
+ *(aCompareArg.getArray()) <<= xLocalizable->getLocale();;
+ m_rCompareFactory = uno::Reference< XAnyCompareFactory >(
+ xFactory->createInstanceWithArguments( OUString::createFromAscii( "com.sun.star.ucb.AnyCompareFactory" ),
+ aCompareArg ),
+ UNO_QUERY );
+
+ uno::Reference < XContent > aRootContent = xTemplates->getContent();
+ uno::Reference < XCommandEnvironment > aCmdEnv;
+
+ if ( ! aRootContent.is() )
+ return sal_False;
+
+ mbConstructed = sal_True;
+ maRootURL = aRootContent->getIdentifier()->getContentIdentifier();
+
+ ResStringArray aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
+
+ if ( aLongNames.Count() )
+ maStandardGroup = aLongNames.GetString( 0 );
+
+ Content aTemplRoot( aRootContent, aCmdEnv );
+ CreateFromHierarchy( aTemplRoot );
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::ReInitFromComponent()
+{
+ uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
+ if ( xTemplates.is() )
+ {
+ uno::Reference < XContent > aRootContent = xTemplates->getContent();
+ uno::Reference < XCommandEnvironment > aCmdEnv;
+ Content aTemplRoot( aRootContent, aCmdEnv );
+ Clear();
+ CreateFromHierarchy( aTemplRoot );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::GetTemplates( Content& rTargetFolder,
+ Content& /*rParentFolder*/,
+ RegionData_Impl* pRegion )
+{
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(1);
+
+ aProps[0] = OUString::createFromAscii( TITLE );
+
+ try
+ {
+ ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
+ Sequence< NumberedSortingInfo > aSortingInfo(1);
+ aSortingInfo.getArray()->ColumnIndex = 1;
+ aSortingInfo.getArray()->Ascending = sal_True;
+ xResultSet = rTargetFolder.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ OUString aTitle( xRow->getString(1) );
+
+ if ( aTitle.compareToAscii( "sfx.tlx" ) == 0 )
+ continue;
+
+ OUString aId = xContentAccess->queryContentIdentifierString();
+
+ DocTempl_EntryData_Impl* pEntry = pRegion->GetByTargetURL( aId );
+
+ if ( ! pEntry )
+ {
+ OUString aFullTitle;
+ if( !GetTitleFromURL( aId, aFullTitle ) )
+ {
+ DBG_ERRORFILE( "GetTemplates(): template of alien format" );
+ continue;
+ }
+
+ if ( aFullTitle.getLength() )
+ aTitle = aFullTitle;
+
+ pRegion->AddEntry( aTitle, aId );
+ }
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+
+// -----------------------------------------------------------------------
+long SfxDocTemplate_Impl::GetRegionPos( const OUString& rTitle,
+ sal_Bool& rFound ) const
+{
+ int nCompVal = 1;
+ long nStart = 0;
+ long nEnd = maRegions.Count() - 1;
+ long nMid = 0;
+
+ RegionData_Impl* pMid;
+
+ while ( nCompVal && ( nStart <= nEnd ) )
+ {
+ nMid = ( nEnd - nStart ) / 2 + nStart;
+ pMid = maRegions.GetObject( nMid );
+
+ nCompVal = pMid->Compare( rTitle );
+
+ if ( nCompVal < 0 ) // pMid < pData
+ nStart = nMid + 1;
+ else
+ nEnd = nMid - 1;
+ }
+
+ if ( nCompVal == 0 )
+ rFound = sal_True;
+ else
+ {
+ if ( nCompVal < 0 ) // pMid < pData
+ nMid++;
+
+ rFound = sal_False;
+ }
+
+ return nMid;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTemplate_Impl::InsertRegion( RegionData_Impl *pNew,
+ ULONG nPos )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ RegionData_Impl *pData = maRegions.First();
+
+ while ( pData && ( pData->Compare( pNew ) != 0 ) )
+ pData = maRegions.Next();
+
+ if ( ! pData )
+ {
+ // compare with the name of the standard group here to insert it
+ // first
+
+ if ( pNew->GetTitle() == maStandardGroup )
+ maRegions.Insert( pNew, (ULONG) 0 );
+ else
+ maRegions.Insert( pNew, nPos );
+ }
+
+ return ( pData == NULL );
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::Rescan()
+{
+ Clear();
+
+ try
+ {
+ uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
+ DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
+ if ( xTemplates.is() )
+ {
+ xTemplates->update();
+
+ uno::Reference < XContent > aRootContent = xTemplates->getContent();
+ uno::Reference < XCommandEnvironment > aCmdEnv;
+
+ Content aTemplRoot( aRootContent, aCmdEnv );
+ CreateFromHierarchy( aTemplRoot );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_ERRORFILE( "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update!" );
+ }
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL,
+ OUString& aTitle )
+{
+ if ( mxInfo.is() )
+ {
+ try
+ {
+ mxInfo->read( rURL );
+ }
+ catch ( Exception& )
+ {
+ // the document is not a StarOffice document
+ return sal_False;
+ }
+
+
+ try
+ {
+ uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
+ if ( aPropSet.is() )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ Any aValue = aPropSet->getPropertyValue( aPropName );
+ aValue >>= aTitle;
+ }
+ }
+ catch ( IOException& ) {}
+ catch ( UnknownPropertyException& ) {}
+ catch ( Exception& ) {}
+ }
+
+ if ( ! aTitle.getLength() )
+ {
+ INetURLObject aURL( rURL );
+ aURL.CutExtension();
+ aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ }
+
+ return sal_True;
+}
+
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::Clear()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mnLockCounter )
+ return;
+
+ RegionData_Impl *pRegData = maRegions.First();
+
+ while ( pRegData )
+ {
+ delete pRegData;
+ pRegData = maRegions.Next();
+ }
+
+ maRegions.Clear();
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+sal_Bool getTextProperty_Impl( Content& rContent,
+ const OUString& rPropName,
+ OUString& rPropValue )
+{
+ sal_Bool bGotProperty = sal_False;
+
+ // Get the property
+ try
+ {
+ uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
+
+ // check, wether or not the property exists
+ if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
+ {
+ return sal_False;
+ }
+
+ // now get the property
+ Any aAnyValue;
+
+ aAnyValue = rContent.getPropertyValue( rPropName );
+ aAnyValue >>= rPropValue;
+
+ if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
+ {
+ SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessServiceFactory() );
+ aRelocImpl.makeAbsoluteURL( rPropValue );
+ }
+
+ bGotProperty = sal_True;
+ }
+ catch ( RuntimeException& ) {}
+ catch ( Exception& ) {}
+
+ return bGotProperty;
+}
+
diff --git a/sfx2/source/doc/doctempl.src b/sfx2/source/doc/doctempl.src
new file mode 100644
index 000000000000..2c91358f845e
--- /dev/null
+++ b/sfx2/source/doc/doctempl.src
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <sfx2/sfx.hrc>
+
+#include "doc.hrc"
+
+StringArray TEMPLATE_SHORT_NAMES_ARY
+{
+ ItemList =
+ {
+ < "standard" ; > ;
+ < "officorr" ; > ;
+ < "offimisc" ; > ;
+ < "personal" ; > ;
+ < "forms" ; > ;
+ < "finance" ; > ;
+ < "educate" ; > ;
+ < "layout" ; > ;
+ < "presnt" ; > ;
+ < "misc" ; > ;
+ };
+};
+
+StringArray TEMPLATE_LONG_NAMES_ARY
+{
+ ItemList [ en-US ] =
+ {
+ < "My Templates" ; > ;
+ < "Business Correspondence" ; > ;
+ < "Other Business Documents" ; > ;
+ < "Personal Correspondence and Documents" ; > ;
+ < "Forms and Contracts" ; > ;
+ < "Finances" ; > ;
+ < "Education" ; > ;
+ < "Presentation Backgrounds" ; > ;
+ < "Presentations" ; > ;
+ < "Miscellaneous" ; > ;
+ };
+
+ };
+
+String RID_CNT_STR_WAITING
+{
+ Text [ en-US ] = "The templates are being initialized for first-time usage." ;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sfx2/source/doc/doctemplates.cxx b/sfx2/source/doc/doctemplates.cxx
new file mode 100644
index 000000000000..b921f2d97f1f
--- /dev/null
+++ b/sfx2/source/doc/doctemplates.cxx
@@ -0,0 +1,2898 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "doctemplates.hxx"
+#include <vos/mutex.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#ifndef _SV_RESARY_HXX
+#include <tools/resary.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <unotools/pathoptions.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+#include <com/sun/star/container/XContainerQuery.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/document/XStandaloneDocumentInfo.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
+
+#include <svtools/templatefoldercache.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/ucbhelper.hxx>
+
+#include "sfxresid.hxx"
+#include "sfxurlrelocator.hxx"
+#include "doctemplateslocal.hxx"
+#include <sfx2/docfac.hxx>
+#include <sfx2/docfile.hxx>
+#include "doc.hrc"
+
+//-----------------------------------------------------------------------------
+
+//=============================================================================
+
+#define TEMPLATE_SERVICE_NAME "com.sun.star.frame.DocumentTemplates"
+#define TEMPLATE_IMPLEMENTATION_NAME "com.sun.star.comp.sfx2.DocumentTemplates"
+
+#define SERVICENAME_TYPEDETECTION "com.sun.star.document.TypeDetection"
+#define SERVICENAME_DOCINFO "com.sun.star.document.StandaloneDocumentInfo"
+
+#define TEMPLATE_ROOT_URL "vnd.sun.star.hier:/templates"
+#define TITLE "Title"
+#define IS_FOLDER "IsFolder"
+#define IS_DOCUMENT "IsDocument"
+#define TARGET_URL "TargetURL"
+#define TEMPLATE_VERSION "TemplateComponentVersion"
+#define TEMPLATE_VERSION_VALUE "2"
+#define TYPE_FOLDER "application/vnd.sun.star.hier-folder"
+#define TYPE_LINK "application/vnd.sun.star.hier-link"
+#define TYPE_FSYS_FOLDER "application/vnd.sun.staroffice.fsys-folder"
+#define TYPE_FSYS_FILE "application/vnd.sun.staroffice.fsys-file"
+
+#define PROPERTY_DIRLIST "DirectoryList"
+#define PROPERTY_NEEDSUPDATE "NeedsUpdate"
+#define PROPERTY_TYPE "TypeDescription"
+
+#define TARGET_DIR_URL "TargetDirURL"
+#define COMMAND_DELETE "delete"
+#define COMMAND_TRANSFER "transfer"
+
+#define STANDARD_FOLDER "standard"
+
+#define C_DELIM ';'
+
+//=============================================================================
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+
+using namespace ::rtl;
+using namespace ::ucbhelper;
+using namespace ::comphelper;
+
+//=============================================================================
+
+class WaitWindow_Impl : public WorkWindow
+{
+ Rectangle _aRect;
+ USHORT _nTextStyle;
+ String _aText;
+
+ public:
+ WaitWindow_Impl();
+ ~WaitWindow_Impl();
+ virtual void Paint( const Rectangle& rRect );
+};
+
+#define X_OFFSET 15
+#define Y_OFFSET 15
+
+//=============================================================================
+
+struct NamePair_Impl
+{
+ OUString maShortName;
+ OUString maLongName;
+};
+
+DECLARE_LIST( NameList_Impl, NamePair_Impl* )
+
+class Updater_Impl;
+class GroupList_Impl;
+class DocTemplates_EntryData_Impl;
+class GroupData_Impl;
+
+//=============================================================================
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+
+class TplTaskEnvironment : public ::cppu::WeakImplHelper1< ucb::XCommandEnvironment >
+{
+ uno::Reference< task::XInteractionHandler > m_xInteractionHandler;
+ uno::Reference< ucb::XProgressHandler > m_xProgressHandler;
+
+public:
+ TplTaskEnvironment( const uno::Reference< task::XInteractionHandler>& rxInteractionHandler )
+ : m_xInteractionHandler( rxInteractionHandler )
+ {}
+
+ virtual uno::Reference<task::XInteractionHandler> SAL_CALL getInteractionHandler() throw (uno::RuntimeException)
+ { return m_xInteractionHandler; }
+
+ virtual uno::Reference<ucb::XProgressHandler> SAL_CALL getProgressHandler() throw (uno::RuntimeException)
+ { return m_xProgressHandler; }
+};
+
+class SfxDocTplService_Impl
+{
+ uno::Reference< XMultiServiceFactory > mxFactory;
+ uno::Reference< XCommandEnvironment > maCmdEnv;
+ uno::Reference< XStandaloneDocumentInfo > mxInfo;
+ uno::Reference< XTypeDetection > mxType;
+
+ ::osl::Mutex maMutex;
+ Sequence< OUString > maTemplateDirs;
+ OUString maRootURL;
+ NameList_Impl maNames;
+ Locale maLocale;
+ Content maRootContent;
+ Updater_Impl* mpUpdater;
+ sal_Bool mbIsInitialized : 1;
+ sal_Bool mbLocaleSet : 1;
+
+ SfxURLRelocator_Impl maRelocator;
+
+ void init_Impl();
+ void getDefaultLocale();
+ void getDirList();
+ void readFolderList();
+ sal_Bool needsUpdate();
+ OUString getLongName( const OUString& rShortName );
+ sal_Bool setTitleForURL( const OUString& rURL, const OUString& aTitle );
+ sal_Bool getTitleFromURL( const OUString& rURL, OUString& aTitle, OUString& aType, sal_Bool& bDocHasTitle );
+
+ sal_Bool addEntry( Content& rParentFolder,
+ const OUString& rTitle,
+ const OUString& rTargetURL,
+ const OUString& rType );
+
+ sal_Bool createFolder( const OUString& rNewFolderURL,
+ sal_Bool bCreateParent,
+ sal_Bool bFsysFolder,
+ Content &rNewFolder );
+
+ sal_Bool CreateNewUniqueFolderWithPrefix( const ::rtl::OUString& aPath,
+ const ::rtl::OUString& aPrefix,
+ ::rtl::OUString& aNewFolderName,
+ ::rtl::OUString& aNewFolderURL,
+ Content& aNewFolder );
+ ::rtl::OUString CreateNewUniqueFileWithPrefix( const ::rtl::OUString& aPath,
+ const ::rtl::OUString& aPrefix,
+ const ::rtl::OUString& aExt );
+
+ uno::Sequence< beans::StringPair > ReadUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath );
+ sal_Bool UpdateUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
+ const ::rtl::OUString& aGroupName,
+ const ::rtl::OUString& aNewFolderName );
+ sal_Bool ReplaceUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
+ const ::rtl::OUString& aFsysGroupName,
+ const ::rtl::OUString& aOldGroupName,
+ const ::rtl::OUString& aNewGroupName );
+ sal_Bool RemoveUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
+ const ::rtl::OUString& aGroupName );
+ sal_Bool WriteUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
+ const uno::Sequence< beans::StringPair >& aUINames );
+
+ ::rtl::OUString CreateNewGroupFsys( const ::rtl::OUString& rGroupName, Content& aGroup );
+
+ sal_Bool removeContent( Content& rContent );
+ sal_Bool removeContent( const OUString& rContentURL );
+
+ sal_Bool setProperty( Content& rContent,
+ const OUString& rPropName,
+ const Any& rPropValue );
+ sal_Bool getProperty( Content& rContent,
+ const OUString& rPropName,
+ Any& rPropValue );
+
+ void createFromContent( GroupList_Impl& rList,
+ Content &rContent,
+ sal_Bool bHierarchy,
+ sal_Bool bWriteableContent = sal_False );
+ void addHierGroup( GroupList_Impl& rList,
+ const OUString& rTitle,
+ const OUString& rOwnURL );
+ void addFsysGroup( GroupList_Impl& rList,
+ const OUString& rTitle,
+ const OUString& rUITitle,
+ const OUString& rOwnURL,
+ sal_Bool bWriteableGroup = sal_False );
+ void removeFromHierarchy( DocTemplates_EntryData_Impl *pData );
+ void addToHierarchy( GroupData_Impl *pGroup,
+ DocTemplates_EntryData_Impl *pData );
+
+ void removeFromHierarchy( GroupData_Impl *pGroup );
+ void addGroupToHierarchy( GroupData_Impl *pGroup );
+
+ void updateData( DocTemplates_EntryData_Impl *pData );
+
+public:
+ SfxDocTplService_Impl( uno::Reference< XMultiServiceFactory > xFactory );
+ ~SfxDocTplService_Impl();
+
+ sal_Bool init() { if ( !mbIsInitialized ) init_Impl(); return mbIsInitialized; }
+ Content getContent() { return maRootContent; }
+
+ void setLocale( const Locale & rLocale );
+ Locale getLocale();
+
+ sal_Bool storeTemplate( const OUString& rGroupName,
+ const OUString& rTemplateName,
+ const uno::Reference< XSTORABLE >& rStorable );
+
+ sal_Bool addTemplate( const OUString& rGroupName,
+ const OUString& rTemplateName,
+ const OUString& rSourceURL );
+ sal_Bool removeTemplate( const OUString& rGroupName,
+ const OUString& rTemplateName );
+ sal_Bool renameTemplate( const OUString& rGroupName,
+ const OUString& rOldName,
+ const OUString& rNewName );
+
+ sal_Bool addGroup( const OUString& rGroupName );
+ sal_Bool removeGroup( const OUString& rGroupName );
+ sal_Bool renameGroup( const OUString& rOldName,
+ const OUString& rNewName );
+
+ void update( sal_Bool bUpdateNow );
+ void doUpdate();
+ void finished() { mpUpdater = NULL; }
+};
+
+//=============================================================================
+
+class Updater_Impl : public ::vos::OThread
+{
+private:
+ SfxDocTplService_Impl *mpDocTemplates;
+
+public:
+ Updater_Impl( SfxDocTplService_Impl* pTemplates );
+ ~Updater_Impl();
+
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL onTerminated();
+};
+
+//=============================================================================
+
+class DocTemplates_EntryData_Impl
+{
+ OUString maTitle;
+ OUString maType;
+ OUString maTargetURL;
+ OUString maHierarchyURL;
+
+ sal_Bool mbInHierarchy : 1;
+ sal_Bool mbInUse : 1;
+ sal_Bool mbUpdateType : 1;
+ sal_Bool mbUpdateLink : 1;
+
+public:
+ DocTemplates_EntryData_Impl( const OUString& rTitle );
+
+ void setInUse() { mbInUse = sal_True; }
+ void setHierarchy( sal_Bool bInHierarchy ) { mbInHierarchy = bInHierarchy; }
+ void setUpdateLink( sal_Bool bUpdateLink ) { mbUpdateLink = bUpdateLink; }
+ void setUpdateType( sal_Bool bUpdateType ) { mbUpdateType = bUpdateType; }
+
+ sal_Bool getInUse() const { return mbInUse; }
+ sal_Bool getInHierarchy() const { return mbInHierarchy; }
+ sal_Bool getUpdateLink() const { return mbUpdateLink; }
+ sal_Bool getUpdateType() const { return mbUpdateType; }
+
+ const OUString& getHierarchyURL() const { return maHierarchyURL; }
+ const OUString& getTargetURL() const { return maTargetURL; }
+ const OUString& getTitle() const { return maTitle; }
+ const OUString& getType() const { return maType; }
+
+ void setHierarchyURL( const OUString& rURL ) { maHierarchyURL = rURL; }
+ void setTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
+ void setType( const OUString& rType ) { maType = rType; }
+};
+
+//=============================================================================
+
+class GroupData_Impl
+{
+ DECLARE_LIST( EntryList_Impl, DocTemplates_EntryData_Impl* )
+ EntryList_Impl maEntries;
+ OUString maTitle;
+ OUString maHierarchyURL;
+ OUString maTargetURL;
+ sal_Bool mbInUse : 1;
+ sal_Bool mbInHierarchy : 1;
+
+public:
+ GroupData_Impl( const OUString& rTitle );
+ ~GroupData_Impl();
+
+ void setInUse() { mbInUse = sal_True; }
+ void setHierarchy( sal_Bool bInHierarchy ) { mbInHierarchy = bInHierarchy; }
+ void setHierarchyURL( const OUString& rURL ) { maHierarchyURL = rURL; }
+ void setTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
+
+ sal_Bool getInUse() { return mbInUse; }
+ sal_Bool getInHierarchy() { return mbInHierarchy; }
+ const OUString& getHierarchyURL() const { return maHierarchyURL; }
+ const OUString& getTargetURL() const { return maTargetURL; }
+ const OUString& getTitle() const { return maTitle; }
+
+ DocTemplates_EntryData_Impl* addEntry( const OUString& rTitle,
+ const OUString& rTargetURL,
+ const OUString& rType,
+ const OUString& rHierURL );
+ ULONG count() { return maEntries.Count(); }
+ DocTemplates_EntryData_Impl* getEntry( ULONG nPos ) { return maEntries.GetObject( nPos ); }
+};
+
+DECLARE_LIST( GroupList_Impl, GroupData_Impl* )
+
+//=============================================================================
+//=============================================================================
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// private SfxDocTplService_Impl
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::init_Impl()
+{
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ if ( xFactory.is() )
+ {
+ uno::Reference < task::XInteractionHandler > xInteractionHandler( xFactory->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ), uno::UNO_QUERY );
+ maCmdEnv = new TplTaskEnvironment( xInteractionHandler );
+ }
+
+ ::osl::ClearableMutexGuard aGuard( maMutex );
+ sal_Bool bIsInitialized = sal_False;
+ sal_Bool bNeedsUpdate = sal_False;
+
+ if ( !mbLocaleSet )
+ getDefaultLocale();
+
+ // convert locale to string
+ OUString aLang = maLocale.Language;
+ aLang += String( '-' );
+ aLang += maLocale.Country;
+
+ // set maRootContent to the root of the templates hierarchy. Create the
+ // entry if necessary
+
+ maRootURL = OUString( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_ROOT_URL ) );
+ maRootURL += String( '/' );
+ maRootURL += aLang;
+
+ ::rtl::OUString aTemplVersPropName( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_VERSION ) );
+ ::rtl::OUString aTemplVers( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_VERSION_VALUE ) );
+ if ( Content::create( maRootURL, maCmdEnv, maRootContent ) )
+ {
+ uno::Any aValue;
+ ::rtl::OUString aPropValue;
+ if ( getProperty( maRootContent, aTemplVersPropName, aValue )
+ && ( aValue >>= aPropValue )
+ && aPropValue.equals( aTemplVers ) )
+ {
+ bIsInitialized = sal_True;
+ }
+ else
+ removeContent( maRootContent );
+ }
+
+ if ( !bIsInitialized )
+ {
+ if ( createFolder( maRootURL, sal_True, sal_False, maRootContent )
+ && setProperty( maRootContent, aTemplVersPropName, uno::makeAny( aTemplVers ) ) )
+ bIsInitialized = sal_True;
+
+ bNeedsUpdate = sal_True;
+ }
+
+ if ( bIsInitialized )
+ {
+ OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO ) );
+ try {
+ mxInfo = uno::Reference< XStandaloneDocumentInfo > (
+ mxFactory->createInstance( aService ), UNO_QUERY );
+ } catch (uno::RuntimeException &) {
+ OSL_ENSURE(false, "SfxDocTplService_Impl::init_Impl: "
+ "cannot create DocumentProperties service");
+ }
+
+ aService = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_TYPEDETECTION ) );
+ mxType = uno::Reference< XTypeDetection > ( mxFactory->createInstance( aService ), UNO_QUERY );
+
+ getDirList();
+ readFolderList();
+
+ if ( bNeedsUpdate )
+ {
+ aGuard.clear();
+ ::vos::OClearableGuard aSolarGuard( Application::GetSolarMutex() );
+
+ WaitWindow_Impl* pWin = new WaitWindow_Impl();
+
+ aSolarGuard.clear();
+ ::osl::ClearableMutexGuard anotherGuard( maMutex );
+
+ update( sal_True );
+
+ anotherGuard.clear();
+ ::vos::OGuard aSecondSolarGuard( Application::GetSolarMutex() );
+
+ delete pWin;
+ }
+ else if ( needsUpdate() )
+ // the UI should be shown only on the first update
+ update( sal_True );
+ }
+ else
+ {
+ DBG_ERRORFILE( "init_Impl(): Could not create root" );
+ }
+
+ mbIsInitialized = bIsInitialized;
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::getDefaultLocale()
+{
+ if ( !mbLocaleSet )
+ {
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( !mbLocaleSet )
+ {
+ rtl::OUString aLocale;
+ utl::ConfigManager::GetDirectConfigProperty( utl::ConfigManager::LOCALE )
+ >>= aLocale;
+
+ if ( aLocale.getLength() > 0 )
+ {
+ sal_Int32 nPos = aLocale.indexOf( sal_Unicode( '-' ) );
+ if ( nPos != -1 )
+ {
+ maLocale.Language = aLocale.copy( 0, nPos );
+ nPos = aLocale.indexOf( sal_Unicode( '_' ), nPos + 1 );
+ if ( nPos != -1 )
+ {
+ maLocale.Country
+ = aLocale.copy( maLocale.Language.getLength() + 1,
+ nPos - maLocale.Language.getLength() - 1 );
+ maLocale.Variant
+ = aLocale.copy( nPos + 1 );
+ }
+ else
+ {
+ maLocale.Country
+ = aLocale.copy( maLocale.Language.getLength() + 1 );
+ }
+ }
+
+ }
+
+ mbLocaleSet = sal_True;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTplService_Impl::readFolderList()
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ ResStringArray aShortNames( SfxResId( TEMPLATE_SHORT_NAMES_ARY ) );
+ ResStringArray aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
+
+ NamePair_Impl* pPair;
+
+ USHORT nCount = (USHORT)( Min( aShortNames.Count(), aLongNames.Count() ) );
+
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ pPair = new NamePair_Impl;
+ pPair->maShortName = aShortNames.GetString( i );
+ pPair->maLongName = aLongNames.GetString( i );
+
+ maNames.Insert( pPair, LIST_APPEND );
+ }
+}
+
+// -----------------------------------------------------------------------
+OUString SfxDocTplService_Impl::getLongName( const OUString& rShortName )
+{
+ OUString aRet;
+ NamePair_Impl *pPair = maNames.First();
+
+ while ( pPair )
+ {
+ if ( pPair->maShortName == rShortName )
+ {
+ aRet = pPair->maLongName;
+ break;
+ }
+ else
+ pPair = maNames.Next();
+ }
+
+ if ( !aRet.getLength() )
+ aRet = rShortName;
+
+ return aRet;
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::getDirList()
+{
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_DIRLIST ) );
+ Any aValue;
+
+ // Get the template dir list
+ // TODO/LATER: let use service, register listener
+ INetURLObject aURL;
+ String aDirs = SvtPathOptions().GetTemplatePath();
+ USHORT nCount = aDirs.GetTokenCount( C_DELIM );
+
+ maTemplateDirs = Sequence< OUString >( nCount );
+
+ for ( USHORT i=0; i<nCount; i++ )
+ {
+ aURL.SetSmartProtocol( INET_PROT_FILE );
+ aURL.SetURL( aDirs.GetToken( i, C_DELIM ) );
+ maTemplateDirs[i] = aURL.GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ aValue <<= maTemplateDirs;
+
+ // Store the template dir list
+ setProperty( maRootContent, aPropName, aValue );
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::needsUpdate()
+{
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_NEEDSUPDATE ) );
+ sal_Bool bHasProperty = sal_False;
+ sal_Bool bNeedsUpdate = sal_True;
+ Any aValue;
+
+ // Get the template dir list
+ bHasProperty = getProperty( maRootContent, aPropName, aValue );
+
+ if ( bHasProperty )
+ aValue >>= bNeedsUpdate;
+
+ // the old template component also checks this state, but it is initialized from this component
+ // so if this componend was already updated the old component does not need such an update
+ ::svt::TemplateFolderCache aTempCache;
+ if ( !bNeedsUpdate )
+ bNeedsUpdate = aTempCache.needsUpdate();
+
+ if ( bNeedsUpdate )
+ aTempCache.storeState();
+
+ return bNeedsUpdate;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::setTitleForURL( const OUString& rURL, const OUString& aTitle )
+{
+ sal_Bool bResult = sal_False;
+ if ( mxInfo.is() )
+ {
+ try
+ {
+ mxInfo->loadFromURL( rURL );
+ uno::Reference< XPropertySet > xPropSet( mxInfo, UNO_QUERY_THROW );
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ xPropSet->setPropertyValue( aPropName, uno::makeAny( aTitle ) );
+ mxInfo->storeIntoURL( rURL );
+ bResult = sal_True;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ return bResult;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::getTitleFromURL( const OUString& rURL, OUString& aTitle, OUString& aType, sal_Bool& bDocHasTitle )
+{
+ bDocHasTitle = sal_False;
+
+ if ( mxInfo.is() )
+ {
+ try
+ {
+ mxInfo->loadFromURL( rURL );
+ }
+ catch ( Exception& )
+ {
+ // the document is not a StarOffice document
+ return sal_False;
+ }
+
+ try
+ {
+ uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
+ if ( aPropSet.is() )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ Any aValue = aPropSet->getPropertyValue( aPropName );
+ aValue >>= aTitle;
+
+ aPropName = OUString( RTL_CONSTASCII_USTRINGPARAM( "MIMEType" ) );
+ aValue = aPropSet->getPropertyValue( aPropName );
+ aValue >>= aType;
+ }
+ }
+ catch ( UnknownPropertyException& ) {}
+ catch ( Exception& ) {}
+ }
+
+ if ( ! aType.getLength() && mxType.is() )
+ {
+ ::rtl::OUString aDocType = mxType->queryTypeByURL( rURL );
+ if ( aDocType.getLength() )
+ try
+ {
+ uno::Reference< container::XNameAccess > xTypeDetection( mxType, uno::UNO_QUERY_THROW );
+ SequenceAsHashMap aTypeProps( xTypeDetection->getByName( aDocType ) );
+ aType = aTypeProps.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "MediaType" ),
+ ::rtl::OUString() );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if ( ! aTitle.getLength() )
+ {
+ INetURLObject aURL( rURL );
+ aURL.CutExtension();
+ aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ }
+ else
+ bDocHasTitle = sal_True;
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::addEntry( Content& rParentFolder,
+ const OUString& rTitle,
+ const OUString& rTargetURL,
+ const OUString& rType )
+{
+ sal_Bool bAddedEntry = sal_False;
+
+ INetURLObject aLinkObj( rParentFolder.getURL() );
+ aLinkObj.insertName( rTitle, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ Content aLink;
+
+ if ( ! Content::create( aLinkURL, maCmdEnv, aLink ) )
+ {
+ Sequence< OUString > aNames(3);
+ aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ aNames[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER ) );
+ aNames[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+
+ Sequence< Any > aValues(3);
+ aValues[0] = makeAny( rTitle );
+ aValues[1] = makeAny( sal_Bool( sal_False ) );
+ aValues[2] = makeAny( rTargetURL );
+
+ OUString aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_LINK ) );
+ OUString aAdditionalProp( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_TYPE ) );
+
+ try
+ {
+ rParentFolder.insertNewContent( aType, aNames, aValues, aLink );
+ setProperty( aLink, aAdditionalProp, makeAny( rType ) );
+ bAddedEntry = sal_True;
+ }
+ catch( Exception& )
+ {}
+ }
+ return bAddedEntry;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::createFolder( const OUString& rNewFolderURL,
+ sal_Bool bCreateParent,
+ sal_Bool bFsysFolder,
+ Content &rNewFolder )
+{
+ Content aParent;
+ sal_Bool bCreatedFolder = sal_False;
+ INetURLObject aParentURL( rNewFolderURL );
+ OUString aFolderName = aParentURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+
+ // compute the parent folder url from the new folder url
+ // and remove the final slash, because Content::create doesn't
+ // like it
+ aParentURL.removeSegment();
+ if ( aParentURL.getSegmentCount() >= 1 )
+ aParentURL.removeFinalSlash();
+
+ // if the parent exists, we can continue with the creation of the
+ // new folder, we have to create the parent otherwise ( as long as
+ // bCreateParent is set to true )
+ if ( Content::create( aParentURL.GetMainURL( INetURLObject::NO_DECODE ), maCmdEnv, aParent ) )
+ {
+ try
+ {
+ Sequence< OUString > aNames(2);
+ aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ aNames[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER ) );
+
+ Sequence< Any > aValues(2);
+ aValues[0] = makeAny( aFolderName );
+ aValues[1] = makeAny( sal_Bool( sal_True ) );
+
+ OUString aType;
+
+ if ( bFsysFolder )
+ aType = OUString( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FOLDER ) );
+ else
+ aType = OUString( RTL_CONSTASCII_USTRINGPARAM( TYPE_FOLDER ) );
+
+ aParent.insertNewContent( aType, aNames, aValues, rNewFolder );
+ bCreatedFolder = sal_True;
+ }
+ catch( RuntimeException& )
+ {
+ DBG_ERRORFILE( "createFolder(): got runtime exception" );
+ }
+ catch( Exception& )
+ {
+ DBG_ERRORFILE( "createFolder(): Could not create new folder" );
+ }
+ }
+ else if ( bCreateParent )
+ {
+ // if the parent doesn't exists and bCreateParent is set to true,
+ // we try to create the parent and if this was successful, we
+ // try to create the new folder again ( but this time, we set
+ // bCreateParent to false to avoid endless recusions )
+ if ( ( aParentURL.getSegmentCount() >= 1 ) &&
+ createFolder( aParentURL.GetMainURL( INetURLObject::NO_DECODE ), bCreateParent, bFsysFolder, aParent ) )
+ {
+ bCreatedFolder = createFolder( rNewFolderURL, sal_False, bFsysFolder, rNewFolder );
+ }
+ }
+
+ return bCreatedFolder;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::CreateNewUniqueFolderWithPrefix( const ::rtl::OUString& aPath,
+ const ::rtl::OUString& aPrefix,
+ ::rtl::OUString& aNewFolderName,
+ ::rtl::OUString& aNewFolderURL,
+ Content& aNewFolder )
+{
+ sal_Bool bCreated = sal_False;
+ INetURLObject aDirPath( aPath );
+
+ Content aParent;
+ if ( Content::create( aDirPath.GetMainURL( INetURLObject::NO_DECODE ), maCmdEnv, aParent ) )
+ {
+ for ( sal_Int32 nInd = 0; nInd < 32000; nInd++ )
+ {
+ ::rtl::OUString aTryName = aPrefix;
+ if ( nInd )
+ aTryName += ::rtl::OUString::valueOf( nInd );
+
+ try
+ {
+ Sequence< OUString > aNames(2);
+ aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ aNames[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER ) );
+
+ Sequence< Any > aValues(2);
+ aValues[0] = makeAny( aTryName );
+ aValues[1] = makeAny( sal_Bool( sal_True ) );
+
+ OUString aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FOLDER ) );
+
+ bCreated = aParent.insertNewContent( aType, aNames, aValues, aNewFolder );
+ }
+ catch( ucb::NameClashException& )
+ {
+ // if there is already an element, retry
+ }
+ catch( Exception& )
+ {
+ INetURLObject aObjPath( aDirPath );
+ aObjPath.insertName( aTryName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ // if there is already an element, retry
+ // if there was another error, do not try any more
+ if ( !::utl::UCBContentHelper::Exists( aObjPath.GetMainURL( INetURLObject::NO_DECODE ) ) )
+ break;
+ }
+
+ if ( bCreated )
+ {
+ aNewFolderName = aTryName;
+ aNewFolderURL = aNewFolder.get()->getIdentifier()->getContentIdentifier();
+ break;
+ }
+ }
+ }
+
+ return bCreated;
+}
+
+// -----------------------------------------------------------------------
+::rtl::OUString SfxDocTplService_Impl::CreateNewUniqueFileWithPrefix( const ::rtl::OUString& aPath,
+ const ::rtl::OUString& aPrefix,
+ const ::rtl::OUString& aExt )
+{
+ ::rtl::OUString aNewFileURL;
+ INetURLObject aDirPath( aPath );
+
+ Content aParent;
+
+ uno::Reference< XCommandEnvironment > aQuietEnv;
+ if ( Content::create( aDirPath.GetMainURL( INetURLObject::NO_DECODE ), aQuietEnv, aParent ) )
+ {
+ for ( sal_Int32 nInd = 0; nInd < 32000; nInd++ )
+ {
+ Content aNewFile;
+ sal_Bool bCreated = sal_False;
+ ::rtl::OUString aTryName = aPrefix;
+ if ( nInd )
+ aTryName += ::rtl::OUString::valueOf( nInd );
+ if ( aExt.toChar() != '.' )
+ aTryName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
+ aTryName += aExt;
+
+ try
+ {
+ Sequence< OUString > aNames(2);
+ aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ aNames[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_DOCUMENT ) );
+
+ Sequence< Any > aValues(2);
+ aValues[0] = makeAny( aTryName );
+ aValues[1] = makeAny( sal_Bool( sal_True ) );
+
+ OUString aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FILE ) );
+
+ bCreated = aParent.insertNewContent( aType, aNames, aValues, aNewFile );
+ }
+ catch( ucb::NameClashException& )
+ {
+ // if there is already an element, retry
+ }
+ catch( Exception& )
+ {
+ INetURLObject aObjPath( aPath );
+ aObjPath.insertName( aTryName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ // if there is already an element, retry
+ // if there was another error, do not try any more
+ if ( !::utl::UCBContentHelper::Exists( aObjPath.GetMainURL( INetURLObject::NO_DECODE ) ) )
+ break;
+ }
+
+ if ( bCreated )
+ {
+ aNewFileURL = aNewFile.get()->getIdentifier()->getContentIdentifier();
+ break;
+ }
+ }
+ }
+
+ return aNewFileURL;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::removeContent( Content& rContent )
+{
+ sal_Bool bRemoved = sal_False;
+ try
+ {
+ OUString aCmd( RTL_CONSTASCII_USTRINGPARAM( COMMAND_DELETE ) );
+ Any aArg = makeAny( sal_Bool( sal_True ) );
+
+ rContent.executeCommand( aCmd, aArg );
+ bRemoved = sal_True;
+ }
+ catch ( RuntimeException& ) {}
+ catch ( Exception& ) {}
+
+ return bRemoved;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::removeContent( const OUString& rContentURL )
+{
+ Content aContent;
+
+ if ( Content::create( rContentURL, maCmdEnv, aContent ) )
+ return removeContent( aContent );
+ else
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::setProperty( Content& rContent,
+ const OUString& rPropName,
+ const Any& rPropValue )
+{
+ sal_Bool bPropertySet = sal_False;
+
+ // Store the property
+ try
+ {
+ Any aPropValue( rPropValue );
+ uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
+
+ // check, wether or not the property exists, create it, when not
+ if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
+ {
+ uno::Reference< XPropertyContainer > xProperties( rContent.get(), UNO_QUERY );
+ if ( xProperties.is() )
+ {
+ try
+ {
+ xProperties->addProperty( rPropName, PropertyAttribute::MAYBEVOID, rPropValue );
+ }
+ catch( PropertyExistException& ) {}
+ catch( IllegalTypeException& ) { DBG_ERRORFILE( "IllegalTypeException" ); }
+ catch( IllegalArgumentException& ) { DBG_ERRORFILE( "IllegalArgumentException" ); }
+ }
+ }
+
+ // To ensure a reloctable office installation, the path to the
+ // office installtion directory must never be stored directly.
+ if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
+ {
+ OUString aValue;
+ if ( rPropValue >>= aValue )
+ {
+ maRelocator.makeRelocatableURL( aValue );
+ aPropValue = makeAny( aValue );
+ }
+ else
+ {
+ Sequence< OUString > aValues;
+ if ( rPropValue >>= aValues )
+ {
+ for ( sal_Int32 n = 0; n < aValues.getLength(); n++ )
+ {
+ maRelocator.makeRelocatableURL( aValues[ n ] );
+ }
+ aPropValue = makeAny( aValues );
+ }
+ else
+ {
+ OSL_ENSURE( false, "Unsupported property value type" );
+ }
+ }
+ }
+
+ // now set the property
+
+ rContent.setPropertyValue( rPropName, aPropValue );
+ bPropertySet = sal_True;
+ }
+ catch ( RuntimeException& ) {}
+ catch ( Exception& ) {}
+
+ return bPropertySet;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::getProperty( Content& rContent,
+ const OUString& rPropName,
+ Any& rPropValue )
+{
+ sal_Bool bGotProperty = sal_False;
+
+ // Get the property
+ try
+ {
+ uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
+
+ // check, wether or not the property exists
+ if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
+ {
+ return sal_False;
+ }
+
+ // now get the property
+
+ rPropValue = rContent.getPropertyValue( rPropName );
+
+ // To ensure a reloctable office installation, the path to the
+ // office installtion directory must never be stored directly.
+ if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
+ {
+ OUString aValue;
+ if ( rPropValue >>= aValue )
+ {
+ maRelocator.makeAbsoluteURL( aValue );
+ rPropValue = makeAny( aValue );
+ }
+ else
+ {
+ Sequence< OUString > aValues;
+ if ( rPropValue >>= aValues )
+ {
+ for ( sal_Int32 n = 0; n < aValues.getLength(); n++ )
+ {
+ maRelocator.makeAbsoluteURL( aValues[ n ] );
+ }
+ rPropValue = makeAny( aValues );
+ }
+ else
+ {
+ OSL_ENSURE( false, "Unsupported property value type" );
+ }
+ }
+ }
+
+ bGotProperty = sal_True;
+ }
+ catch ( RuntimeException& ) {}
+ catch ( Exception& ) {}
+
+ return bGotProperty;
+}
+
+// -----------------------------------------------------------------------
+// static
+bool SfxURLRelocator_Impl::propertyCanContainOfficeDir(
+ const rtl::OUString & rPropName )
+{
+ // Note: TargetURL is handled by UCB itself (because it is a property
+ // with a predefined semantic). Additional Core properties introduced
+ // be a client app must be handled by the client app itself, because
+ // the UCB does not know the semantics of those properties.
+ return ( rPropName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TARGET_DIR_URL ) ) ||
+ rPropName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( PROPERTY_DIRLIST ) ) );
+}
+
+//-----------------------------------------------------------------------------
+// public SfxDocTplService_Impl
+//-----------------------------------------------------------------------------
+
+SfxDocTplService_Impl::SfxDocTplService_Impl( uno::Reference< XMultiServiceFactory > xFactory )
+: maRelocator( xFactory )
+{
+ mxFactory = xFactory;
+ mpUpdater = NULL;
+ mbIsInitialized = sal_False;
+ mbLocaleSet = sal_False;
+}
+
+//-----------------------------------------------------------------------------
+SfxDocTplService_Impl::~SfxDocTplService_Impl()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( mpUpdater )
+ {
+ mpUpdater->kill();
+ delete mpUpdater;
+ }
+}
+
+//-----------------------------------------------------------------------------
+Locale SfxDocTplService_Impl::getLocale()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( !mbLocaleSet )
+ getDefaultLocale();
+
+ return maLocale;
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::setLocale( const Locale &rLocale )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( mbLocaleSet &&
+ ( maLocale.Language != rLocale.Language ) &&
+ ( maLocale.Country != rLocale.Country ) )
+ mbIsInitialized = sal_False;
+
+ maLocale = rLocale;
+ mbLocaleSet = sal_True;
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::update( sal_Bool bUpdateNow )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( bUpdateNow )
+ doUpdate();
+ else
+ {
+ mpUpdater = new Updater_Impl( this );
+ mpUpdater->create();
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::doUpdate()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_NEEDSUPDATE ) );
+ Any aValue;
+
+ aValue <<= sal_True;
+ setProperty( maRootContent, aPropName, aValue );
+
+ GroupList_Impl aGroupList;
+
+ // get the entries from the hierarchy
+ createFromContent( aGroupList, maRootContent, sal_True );
+
+ // get the entries from the template directories
+ sal_Int32 nCountDir = maTemplateDirs.getLength();
+ OUString* pDirs = maTemplateDirs.getArray();
+ Content aDirContent;
+
+ // the last directory in the list must be writable
+ sal_Bool bWriteableDirectory = sal_True;
+
+ // the target folder might not exist, for this reason no interaction handler should be used
+ uno::Reference< XCommandEnvironment > aQuietEnv;
+
+ while ( nCountDir )
+ {
+ nCountDir--;
+ if ( Content::create( pDirs[ nCountDir ], aQuietEnv, aDirContent ) )
+ {
+ createFromContent( aGroupList, aDirContent, sal_False, bWriteableDirectory );
+ }
+
+ bWriteableDirectory = sal_False;
+ }
+
+ // now check the list
+ GroupData_Impl *pGroup = aGroupList.First();
+ while ( pGroup )
+ {
+ if ( pGroup->getInUse() )
+ {
+ if ( pGroup->getInHierarchy() )
+ {
+ Content aGroup;
+ if ( Content::create( pGroup->getHierarchyURL(), maCmdEnv, aGroup ) )
+ setProperty( aGroup,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) ),
+ makeAny( pGroup->getTargetURL() ) );
+
+ ULONG nCount = pGroup->count();
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ DocTemplates_EntryData_Impl *pData = pGroup->getEntry( i );
+ if ( ! pData->getInUse() )
+ {
+ if ( pData->getInHierarchy() )
+ removeFromHierarchy( pData ); // delete entry in hierarchy
+ else
+ addToHierarchy( pGroup, pData ); // add entry to hierarchy
+ }
+ else if ( pData->getUpdateType() ||
+ pData->getUpdateLink() )
+ {
+ updateData( pData );
+ }
+ }
+ }
+ else
+ {
+ addGroupToHierarchy( pGroup ); // add group to hierarchy
+ }
+ }
+ else
+ removeFromHierarchy( pGroup ); // delete group from hierarchy
+
+ delete pGroup;
+ pGroup = aGroupList.Next();
+ }
+
+ aValue <<= sal_False;
+ setProperty( maRootContent, aPropName, aValue );
+}
+
+//-----------------------------------------------------------------------------
+uno::Sequence< beans::StringPair > SfxDocTplService_Impl::ReadUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath )
+{
+ INetURLObject aLocObj( aUserPath );
+ aLocObj.insertName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) ), false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ Content aLocContent;
+
+ // TODO/LATER: Use hashmap in future
+ uno::Sequence< beans::StringPair > aUINames;
+ if ( Content::create( aLocObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference < ucb::XCommandEnvironment >(), aLocContent ) )
+ {
+ try
+ {
+ uno::Reference< io::XInputStream > xLocStream = aLocContent.openStream();
+ if ( xLocStream.is() )
+ aUINames = DocTemplLocaleHelper::ReadGroupLocalizationSequence( xLocStream, mxFactory );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ return aUINames;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::UpdateUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
+ const ::rtl::OUString& aGroupName,
+ const ::rtl::OUString& aNewFolderName )
+{
+ uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
+ sal_Int32 nLen = aUINames.getLength();
+
+ // it is possible that the name is used already, but it should be checked before
+ for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
+ if ( aUINames[nInd].First.equals( aNewFolderName ) )
+ return sal_False;
+
+ aUINames.realloc( ++nLen );
+ aUINames[nLen-1].First = aNewFolderName;
+ aUINames[nLen-1].Second = aGroupName;
+
+ return WriteUINamesForTemplateDir_Impl( aUserPath, aUINames );
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::ReplaceUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
+ const ::rtl::OUString& aDefaultFsysGroupName,
+ const ::rtl::OUString& aOldGroupName,
+ const ::rtl::OUString& aNewGroupName )
+{
+ uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
+ sal_Int32 nLen = aUINames.getLength();
+
+ sal_Bool bChanged = sal_False;
+ for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
+ if ( aUINames[nInd].Second.equals( aOldGroupName ) )
+ {
+ aUINames[nInd].Second = aNewGroupName;
+ bChanged = sal_True;
+ }
+
+ if ( !bChanged )
+ {
+ aUINames.realloc( ++nLen );
+ aUINames[nLen-1].First = aDefaultFsysGroupName;
+ aUINames[nLen-1].Second = aNewGroupName;
+ }
+ return WriteUINamesForTemplateDir_Impl( aUserPath, aUINames );
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::RemoveUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
+ const ::rtl::OUString& aGroupName )
+{
+ uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
+ sal_Int32 nLen = aUINames.getLength();
+ uno::Sequence< beans::StringPair > aNewUINames( nLen );
+ sal_Int32 nNewLen = 0;
+
+ sal_Bool bChanged = sal_False;
+ for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
+ if ( aUINames[nInd].Second.equals( aGroupName ) )
+ bChanged = sal_True;
+ else
+ {
+ nNewLen++;
+ aNewUINames[nNewLen-1].First = aUINames[nInd].First;
+ aNewUINames[nNewLen-1].Second = aUINames[nInd].Second;
+ }
+
+ aNewUINames.realloc( nNewLen );
+
+ return bChanged ? WriteUINamesForTemplateDir_Impl( aUserPath, aNewUINames ) : sal_True;
+}
+
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::WriteUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
+ const uno::Sequence< beans::StringPair >& aUINames )
+{
+ sal_Bool bResult = sal_False;
+ try {
+ uno::Reference< beans::XPropertySet > xTempFile(
+ mxFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ uno::UNO_QUERY_THROW );
+
+ ::rtl::OUString aTempURL;
+ uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
+ aUrl >>= aTempURL;
+
+ uno::Reference< io::XStream > xStream( xTempFile, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XOutputStream > xOutStream = xStream->getOutputStream();
+ if ( !xOutStream.is() )
+ throw uno::RuntimeException();
+
+ DocTemplLocaleHelper::WriteGroupLocalizationSequence( xOutStream, aUINames, mxFactory );
+ try {
+ // the SAX writer might close the stream
+ xOutStream->closeOutput();
+ } catch( uno::Exception& )
+ {}
+
+ Content aTargetContent( aUserPath, maCmdEnv );
+ Content aSourceContent( aTempURL, maCmdEnv );
+ aTargetContent.transferContent( aSourceContent,
+ InsertOperation_COPY,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) ),
+ ucb::NameClash::OVERWRITE );
+ bResult = sal_True;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ return bResult;
+}
+
+//-----------------------------------------------------------------------------
+::rtl::OUString SfxDocTplService_Impl::CreateNewGroupFsys( const ::rtl::OUString& rGroupName, Content& aGroup )
+{
+ ::rtl::OUString aResultURL;
+
+ if ( maTemplateDirs.getLength() )
+ {
+ ::rtl::OUString aTargetPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
+
+ // create a new folder with the given name
+ Content aNewFolder;
+ ::rtl::OUString aNewFolderName;
+
+ // the Fsys name instead of GroupName should be used, the groupuinames must be added also
+ if ( !CreateNewUniqueFolderWithPrefix( aTargetPath,
+ rGroupName,
+ aNewFolderName,
+ aResultURL,
+ aNewFolder )
+ && !CreateNewUniqueFolderWithPrefix( aTargetPath,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserGroup" ) ),
+ aNewFolderName,
+ aResultURL,
+ aNewFolder ) )
+
+ return ::rtl::OUString();
+
+ if ( !UpdateUINamesForTemplateDir_Impl( aTargetPath, rGroupName, aNewFolderName ) )
+ {
+ // we could not create the groupuinames for the folder, so we delete the group in the
+ // the folder and return
+ removeContent( aNewFolder );
+ return ::rtl::OUString();
+ }
+
+ // Now set the target url for this group and we are done
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+ Any aValue = makeAny( aResultURL );
+
+ if ( ! setProperty( aGroup, aPropName, aValue ) )
+ {
+ removeContent( aNewFolder );
+ return ::rtl::OUString();
+ }
+ }
+
+ return aResultURL;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::addGroup( const OUString& rGroupName )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // Check, wether or not there is a group with this name
+ Content aNewGroup;
+ OUString aNewGroupURL;
+ INetURLObject aNewGroupObj( maRootURL );
+
+ aNewGroupObj.insertName( rGroupName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ aNewGroupURL = aNewGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( Content::create( aNewGroupURL, maCmdEnv, aNewGroup ) ||
+ ! createFolder( aNewGroupURL, sal_False, sal_False, aNewGroup ) )
+ {
+ // if there already was a group with this name or the new group
+ // could not be created, we return here
+ return sal_False;
+ }
+
+ // Get the user template path entry ( new group will always
+ // be added in the user template path )
+ sal_Int32 nIndex;
+ OUString aUserPath;
+
+ nIndex = maTemplateDirs.getLength();
+ if ( nIndex )
+ nIndex--;
+ else
+ return sal_False; // We don't know where to add the group
+
+ aUserPath = maTemplateDirs[ nIndex ];
+
+ // create a new folder with the given name
+ Content aNewFolder;
+ OUString aNewFolderName;
+ OUString aNewFolderURL;
+
+ // the Fsys name instead of GroupName should be used, the groupuinames must be added also
+ if ( !CreateNewUniqueFolderWithPrefix( aUserPath,
+ rGroupName,
+ aNewFolderName,
+ aNewFolderURL,
+ aNewFolder )
+ && !CreateNewUniqueFolderWithPrefix( aUserPath,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserGroup" ) ),
+ aNewFolderName,
+ aNewFolderURL,
+ aNewFolder ) )
+ {
+ // we could not create the folder, so we delete the group in the
+ // hierarchy and return
+ removeContent( aNewGroup );
+ return sal_False;
+ }
+
+ if ( !UpdateUINamesForTemplateDir_Impl( aUserPath, rGroupName, aNewFolderName ) )
+ {
+ // we could not create the groupuinames for the folder, so we delete the group in the
+ // hierarchy, the folder and return
+ removeContent( aNewGroup );
+ removeContent( aNewFolder );
+ return sal_False;
+ }
+
+ // Now set the target url for this group and we are done
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+ Any aValue = makeAny( aNewFolderURL );
+
+ if ( ! setProperty( aNewGroup, aPropName, aValue ) )
+ {
+ removeContent( aNewGroup );
+ removeContent( aNewFolder );
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::removeGroup( const OUString& rGroupName )
+{
+ // remove all the elements that have the prefix aTargetURL
+ // if the group does not have other elements remove it
+
+ ::osl::MutexGuard aGuard( maMutex );
+
+ sal_Bool bResult = sal_False;
+
+ // create the group url
+ INetURLObject aGroupObj( maRootURL );
+ aGroupObj.insertName( rGroupName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ // Get the target url
+ Content aGroup;
+ OUString aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( Content::create( aGroupURL, maCmdEnv, aGroup ) )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+ Any aValue;
+
+ OUString aGroupTargetURL;
+ if ( getProperty( aGroup, aPropName, aValue ) )
+ aValue >>= aGroupTargetURL;
+
+ if ( !aGroupTargetURL.getLength() )
+ return sal_False; // nothing is allowed to be removed
+
+ if ( !maTemplateDirs.getLength() )
+ return sal_False;
+ ::rtl::OUString aGeneralTempPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
+
+ // check that the fs location is in writeble folder and this is not a "My templates" folder
+ INetURLObject aGroupParentFolder( aGroupTargetURL );
+ if ( !aGroupParentFolder.removeSegment()
+ || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath,
+ aGroupParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) )
+ return sal_False;
+
+ // now get the content of the Group
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps( 1 );
+
+ aProps[0] = OUString::createFromAscii( TARGET_URL );
+
+ try
+ {
+ sal_Bool bHasNonRemovable = sal_False;
+ sal_Bool bHasShared = sal_False;
+
+ ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
+ xResultSet = aGroup.createCursor( aProps, eInclude );
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
+
+ while ( xResultSet->next() )
+ {
+ OUString aTemplTargetURL( xRow->getString( 1 ) );
+ OUString aHierURL = xContentAccess->queryContentIdentifierString();
+
+ if ( ::utl::UCBContentHelper::IsSubPath( aGroupTargetURL, aTemplTargetURL ) )
+ {
+ // this is a user template, and it can be removed
+ if ( removeContent( aTemplTargetURL ) )
+ removeContent( aHierURL );
+ else
+ bHasNonRemovable = sal_True;
+ }
+ else
+ bHasShared = sal_True;
+ }
+
+ if ( !bHasNonRemovable && !bHasShared )
+ {
+ if ( removeContent( aGroupTargetURL )
+ || !::utl::UCBContentHelper::Exists( aGroupTargetURL ) )
+ {
+ removeContent( aGroupURL );
+ RemoveUINamesForTemplateDir_Impl( aGeneralTempPath, rGroupName );
+ bResult = sal_True; // the operation is successful only if the whole group is removed
+ }
+ }
+ else if ( !bHasNonRemovable )
+ {
+ if ( removeContent( aGroupTargetURL )
+ || !::utl::UCBContentHelper::Exists( aGroupTargetURL ) )
+ {
+ RemoveUINamesForTemplateDir_Impl( aGeneralTempPath, rGroupName );
+ setProperty( aGroup, aPropName, uno::makeAny( ::rtl::OUString() ) );
+ }
+ }
+ }
+ }
+ catch ( Exception& ) {}
+ }
+
+ return bResult;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::renameGroup( const OUString& rOldName,
+ const OUString& rNewName )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // create the group url
+ Content aGroup;
+ INetURLObject aGroupObj( maRootURL );
+ aGroupObj.insertName( rNewName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ OUString aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ // Check, if there is a group with the new name, return false
+ // if there is one.
+ if ( Content::create( aGroupURL, maCmdEnv, aGroup ) )
+ return sal_False;
+
+ aGroupObj.removeSegment();
+ aGroupObj.insertName( rOldName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ // When there is no group with the old name, we can't rename it
+ if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
+ return sal_False;
+
+ OUString aGroupTargetURL;
+ // there is no need to check whether target dir url is in target path, since if the target path is changed
+ // the target dir url should be already generated new
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+ Any aValue;
+ if ( getProperty( aGroup, aPropName, aValue ) )
+ aValue >>= aGroupTargetURL;
+
+ if ( !aGroupTargetURL.getLength() )
+ return sal_False;
+
+ if ( !maTemplateDirs.getLength() )
+ return sal_False;
+ ::rtl::OUString aGeneralTempPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
+
+ // check that the fs location is in writeble folder and this is not a "My templates" folder
+ INetURLObject aGroupParentFolder( aGroupTargetURL );
+ if ( !aGroupParentFolder.removeSegment()
+ || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath,
+ aGroupParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) )
+ return sal_False;
+
+ // check that the group can be renamed ( all the contents must be in target location )
+ sal_Bool bCanBeRenamed = sal_False;
+ try
+ {
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps( 1 );
+
+ aProps[0] = OUString::createFromAscii( TARGET_URL );
+ ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
+ xResultSet = aGroup.createCursor( aProps, eInclude );
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
+
+ while ( xResultSet->next() )
+ {
+ OUString aTemplTargetURL( xRow->getString( 1 ) );
+
+ if ( !::utl::UCBContentHelper::IsSubPath( aGroupTargetURL, aTemplTargetURL ) )
+ throw uno::Exception();
+ }
+
+ bCanBeRenamed = sal_True;
+ }
+ }
+ catch ( Exception& ) {}
+
+ if ( bCanBeRenamed )
+ {
+ INetURLObject aGroupTargetObj( aGroupTargetURL );
+ ::rtl::OUString aFsysName = aGroupTargetObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+
+ if ( aGroupTargetObj.removeSegment()
+ && ReplaceUINamesForTemplateDir_Impl( aGroupTargetObj.GetMainURL( INetURLObject::NO_DECODE ),
+ aFsysName,
+ rOldName,
+ rNewName ) )
+ {
+ // rename the group in the hierarchy
+ OUString aTitleProp( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ Any aTitleValue;
+ aTitleValue <<= rNewName;
+
+ return setProperty( aGroup, aTitleProp, aTitleValue );
+ }
+ }
+
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::storeTemplate( const OUString& rGroupName,
+ const OUString& rTemplateName,
+ const uno::Reference< XSTORABLE >& rStorable )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // Check, wether or not there is a group with this name
+ // Return false, if there is no group with the given name
+ Content aGroup, aTemplate, aTargetGroup, aTemplateToRemove;
+ OUString aGroupURL, aTemplateURL, aTemplateToRemoveTargetURL;
+ INetURLObject aGroupObj( maRootURL );
+ sal_Bool bRemoveOldTemplateContent = sal_False;
+ ::rtl::OUString sDocServiceName;
+
+ aGroupObj.insertName( rGroupName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
+ return sal_False;
+
+ ::rtl::OUString aGroupTargetURL;
+ ::rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+ Any aValue;
+ if ( getProperty( aGroup, aPropName, aValue ) )
+ aValue >>= aGroupTargetURL;
+
+
+ // Check, if there's a template with the given name in this group
+ // the target template should be overwritten if it is imported by user
+ // in case the template is installed by office installation of by an add-in
+ // it can not be replaced
+ aGroupObj.insertName( rTemplateName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( Content::create( aTemplateURL, maCmdEnv, aTemplateToRemove ) )
+ {
+ OUString aTargetTemplPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+
+ bRemoveOldTemplateContent = sal_True;
+ if ( getProperty( aTemplateToRemove, aTargetTemplPropName, aValue ) )
+ aValue >>= aTemplateToRemoveTargetURL;
+
+ if ( !aGroupTargetURL.getLength() || !maTemplateDirs.getLength()
+ || (aTemplateToRemoveTargetURL.getLength() && !::utl::UCBContentHelper::IsSubPath( maTemplateDirs[ maTemplateDirs.getLength() - 1 ], aTemplateToRemoveTargetURL )) )
+ return sal_False; // it is not allowed to remove the template
+ }
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ if ( !xFactory.is() )
+ throw uno::RuntimeException();
+
+ // get document service name
+ uno::Reference< frame::XModuleManager > xModuleManager(
+ xFactory->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.frame.ModuleManager" ) ),
+ uno::UNO_QUERY_THROW );
+ sDocServiceName = xModuleManager->identify( uno::Reference< uno::XInterface >( rStorable, uno::UNO_QUERY ) );
+ if ( !sDocServiceName.getLength() )
+ throw uno::RuntimeException();
+
+ // get the actual filter name
+ ::rtl::OUString aFilterName;
+
+ uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
+ xFactory->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ) ),
+ uno::UNO_QUERY_THROW );
+
+ uno::Sequence< uno::Any > aArgs( 1 );
+ beans::PropertyValue aPathProp;
+ aPathProp.Name = ::rtl::OUString::createFromAscii( "nodepath" );
+ aPathProp.Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/" ) );
+ aArgs[0] <<= aPathProp;
+
+ uno::Reference< container::XNameAccess > xSOFConfig(
+ xConfigProvider->createInstanceWithArguments(
+ ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ),
+ aArgs ),
+ uno::UNO_QUERY_THROW );
+
+ uno::Reference< container::XNameAccess > xApplConfig;
+ xSOFConfig->getByName( sDocServiceName ) >>= xApplConfig;
+ if ( !xApplConfig.is() )
+ throw uno::RuntimeException();
+
+ xApplConfig->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualTemplateFilter" ) ) ) >>= aFilterName;
+ if ( !aFilterName.getLength() )
+ throw uno::RuntimeException();
+
+ // find the related type name
+ ::rtl::OUString aTypeName;
+ uno::Reference< container::XNameAccess > xFilterFactory(
+ xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
+ uno::UNO_QUERY_THROW );
+
+ uno::Sequence< beans::PropertyValue > aFilterData;
+ xFilterFactory->getByName( aFilterName ) >>= aFilterData;
+ for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
+ if ( aFilterData[nInd].Name.equalsAscii( "Type" ) )
+ aFilterData[nInd].Value >>= aTypeName;
+
+ if ( !aTypeName.getLength() )
+ throw uno::RuntimeException();
+
+ // find the mediatype and extension
+ uno::Reference< container::XNameAccess > xTypeDetection =
+ mxType.is() ?
+ uno::Reference< container::XNameAccess >( mxType, uno::UNO_QUERY_THROW ) :
+ uno::Reference< container::XNameAccess >(
+ xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
+ uno::UNO_QUERY_THROW );
+
+ SequenceAsHashMap aTypeProps( xTypeDetection->getByName( aTypeName ) );
+ uno::Sequence< ::rtl::OUString > aAllExt =
+ aTypeProps.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Extensions" ), Sequence< ::rtl::OUString >() );
+ if ( !aAllExt.getLength() )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aMediaType = aTypeProps.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "MediaType" ), ::rtl::OUString() );
+ ::rtl::OUString aExt = aAllExt[0];
+
+ if ( !aMediaType.getLength() || !aExt.getLength() )
+ throw uno::RuntimeException();
+
+ // construct destination url
+ if ( !aGroupTargetURL.getLength() )
+ {
+ aGroupTargetURL = CreateNewGroupFsys( rGroupName, aGroup );
+
+ if ( !aGroupTargetURL.getLength() )
+ throw uno::RuntimeException();
+ }
+
+ ::rtl::OUString aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aGroupTargetURL, rTemplateName, aExt );
+ if ( !aNewTemplateTargetURL.getLength() )
+ {
+ aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aGroupTargetURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserTemplate" ) ), aExt );
+
+ if ( !aNewTemplateTargetURL.getLength() )
+ throw uno::RuntimeException();
+ }
+
+ // store template
+ uno::Sequence< PropertyValue > aStoreArgs( 2 );
+ aStoreArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
+ aStoreArgs[0].Value <<= aFilterName;
+ aStoreArgs[1].Name = ::rtl::OUString::createFromAscii( "DocumentTitle" );
+ aStoreArgs[1].Value <<= rTemplateName;
+
+ ::rtl::OUString aCurrentDocumentURL = rStorable->getLocation();
+ if( !SfxMedium::EqualURLs( aNewTemplateTargetURL, rStorable->getLocation() ))
+ rStorable->storeToURL( aNewTemplateTargetURL, aStoreArgs );
+ else
+ rStorable->store();
+
+ // the storing was successful, now the old template with the same name can be removed if it existed
+ if ( aTemplateToRemoveTargetURL.getLength() )
+ {
+ removeContent( aTemplateToRemoveTargetURL );
+
+ /*
+ * pb: #i79496#
+ * if the old template was the standard template
+ * it is necessary to change the standard template with the new file name
+ */
+ String sStdTmplFile = SfxObjectFactory::GetStandardTemplate( sDocServiceName );
+ if ( INetURLObject( sStdTmplFile ) == INetURLObject( aTemplateToRemoveTargetURL ) )
+ {
+ SfxObjectFactory::SetStandardTemplate( sDocServiceName, aNewTemplateTargetURL );
+ }
+ }
+
+ if ( bRemoveOldTemplateContent )
+ removeContent( aTemplateToRemove );
+
+ // add the template to hierarchy
+ return addEntry( aGroup, rTemplateName, aNewTemplateTargetURL, aMediaType );
+ }
+ catch( Exception& )
+ {
+ // the template was not stored
+ return sal_False;
+ }
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::addTemplate( const OUString& rGroupName,
+ const OUString& rTemplateName,
+ const OUString& rSourceURL )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // Check, wether or not there is a group with this name
+ // Return false, if there is no group with the given name
+ Content aGroup, aTemplate, aTargetGroup;
+ OUString aGroupURL, aTemplateURL;
+ INetURLObject aGroupObj( maRootURL );
+
+ aGroupObj.insertName( rGroupName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
+ return sal_False;
+
+ // Check, if there's a template with the given name in this group
+ // Return false, if there already is a template
+ aGroupObj.insertName( rTemplateName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
+ return sal_False;
+
+ // get the target url of the group
+ OUString aTargetURL;
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+ Any aValue;
+
+ if ( getProperty( aGroup, aPropName, aValue ) )
+ aValue >>= aTargetURL;
+
+ if ( !aTargetURL.getLength() )
+ {
+ aTargetURL = CreateNewGroupFsys( rGroupName, aGroup );
+
+ if ( !aTargetURL.getLength() )
+ return sal_False;
+ }
+
+ // Get the content type
+ OUString aTitle, aType, aTargetURL2, aFullName;
+
+ // only StarOffice documents are acceptable
+ sal_Bool bDocHasTitle = sal_False;
+ if( !getTitleFromURL( rSourceURL, aTitle, aType, bDocHasTitle ) )
+ return sal_False;
+
+ INetURLObject aSourceObj( rSourceURL );
+ if ( rTemplateName.equals( aTitle ) )
+ {
+ /////////////////////////////////////////////////////
+ // addTemplate will sometimes be called just to add an entry in the
+ // hierarchy; the target URL and the source URL will be the same in
+ // this scenario
+ // TODO/LATER: get rid of this old hack
+
+ INetURLObject aTargetObj( aTargetURL );
+
+ aTargetObj.insertName( rTemplateName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aTargetObj.setExtension( aSourceObj.getExtension() );
+
+ aTargetURL2 = aTargetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( aTargetURL2 == rSourceURL )
+ return addEntry( aGroup, rTemplateName, aTargetURL2, aType );
+ }
+
+ /////////////////////////////////////////////////////
+ // copy the template into the new group (targeturl)
+
+ INetURLObject aTmpURL( aSourceObj );
+ aTmpURL.CutExtension();
+ ::rtl::OUString aPattern = aTmpURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+
+ ::rtl::OUString aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aTargetURL, aPattern, aSourceObj.getExtension() );
+ INetURLObject aNewTemplateTargetObj( aNewTemplateTargetURL );
+ ::rtl::OUString aNewTemplateTargetName = aNewTemplateTargetObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ if ( !aNewTemplateTargetURL.getLength() || !aNewTemplateTargetName.getLength() )
+ return sal_False;
+
+ // get access to source file
+ Content aSourceContent;
+ uno::Reference < ucb::XCommandEnvironment > xEnv;
+ INetURLObject aSourceURL( rSourceURL );
+ if( ! Content::create( aSourceURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aSourceContent ) )
+ return sal_False;
+
+ if( ! Content::create( aTargetURL, xEnv, aTargetGroup ) )
+ return sal_False;
+
+ // transfer source file
+ try
+ {
+ if( ! aTargetGroup.transferContent( aSourceContent,
+ InsertOperation_COPY,
+ aNewTemplateTargetName,
+ NameClash::OVERWRITE ) )
+ return sal_False;
+
+ // allow to edit the added template
+ Content aResultContent;
+ if ( Content::create( aNewTemplateTargetURL, xEnv, aResultContent ) )
+ {
+ ::rtl::OUString aPropertyName( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) );
+ uno::Any aProperty;
+ sal_Bool bReadOnly = sal_False;
+ if ( getProperty( aResultContent, aPropertyName, aProperty ) && ( aProperty >>= bReadOnly ) && bReadOnly )
+ setProperty( aResultContent, aPropertyName, uno::makeAny( (sal_Bool)sal_False ) );
+ }
+ }
+ catch ( ContentCreationException& )
+ { return sal_False; }
+ catch ( Exception& )
+ { return sal_False; }
+
+
+ // either the document has title and it is the same as requested, or we have to set it
+ sal_Bool bCorrectTitle = ( bDocHasTitle && aTitle.equals( rTemplateName ) );
+ if ( !bCorrectTitle )
+ {
+ if ( !bDocHasTitle )
+ {
+ INetURLObject aNewTmpObj( aNewTemplateTargetObj );
+ aNewTmpObj.CutExtension();
+ bCorrectTitle = ( aNewTmpObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).equals( rTemplateName ) );
+ }
+
+ if ( !bCorrectTitle )
+ bCorrectTitle = setTitleForURL( aNewTemplateTargetURL, rTemplateName );
+ }
+
+ if ( bCorrectTitle )
+ {
+ // create a new entry in the hierarchy
+ return addEntry( aGroup, rTemplateName, aNewTemplateTargetURL, aType );
+ }
+
+ // TODO/LATER: The user could be notified here that the renaming has failed
+ // create a new entry in the hierarchy
+ addEntry( aGroup, aTitle, aNewTemplateTargetURL, aType );
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::removeTemplate( const OUString& rGroupName,
+ const OUString& rTemplateName )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // Check, wether or not there is a group with this name
+ // Return false, if there is no group with the given name
+ Content aGroup, aTemplate;
+ OUString aGroupURL, aTemplateURL;
+ INetURLObject aGroupObj( maRootURL );
+
+ aGroupObj.insertName( rGroupName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
+ return sal_False;
+
+ // Check, if there's a template with the given name in this group
+ // Return false, if there is no template
+ aGroupObj.insertName( rTemplateName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( !Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
+ return sal_False;
+
+ // get the target URL from the template
+ OUString aTargetURL;
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+ Any aValue;
+
+ if ( getProperty( aTemplate, aPropName, aValue ) )
+ aValue >>= aTargetURL;
+
+ // delete the target template
+ if ( aTargetURL.getLength() )
+ {
+ if ( !maTemplateDirs.getLength()
+ || !::utl::UCBContentHelper::IsSubPath( maTemplateDirs[ maTemplateDirs.getLength() - 1 ], aTargetURL ) )
+ return sal_False;
+
+ removeContent( aTargetURL );
+ }
+
+ // delete the template entry
+ return removeContent( aTemplate );
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SfxDocTplService_Impl::renameTemplate( const OUString& rGroupName,
+ const OUString& rOldName,
+ const OUString& rNewName )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // Check, wether or not there is a group with this name
+ // Return false, if there is no group with the given name
+ Content aGroup, aTemplate;
+ OUString aGroupURL, aTemplateURL;
+ INetURLObject aGroupObj( maRootURL );
+
+ aGroupObj.insertName( rGroupName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
+ return sal_False;
+
+ // Check, if there's a template with the new name in this group
+ // Return false, if there is one
+ aGroupObj.insertName( rNewName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
+ return sal_False;
+
+ // Check, if there's a template with the old name in this group
+ // Return false, if there is no template
+ aGroupObj.removeSegment();
+ aGroupObj.insertName( rOldName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( !Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
+ return sal_False;
+
+ OUString aTemplateTargetURL;
+ OUString aTargetProp( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+ Any aTargetValue;
+
+ if ( getProperty( aTemplate, aTargetProp, aTargetValue ) )
+ aTargetValue >>= aTemplateTargetURL;
+
+ if ( !setTitleForURL( aTemplateTargetURL, rNewName ) )
+ return sal_False;
+
+ // rename the template entry in the cache
+ OUString aTitleProp( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ Any aTitleValue;
+ aTitleValue <<= rNewName;
+
+ return setProperty( aTemplate, aTitleProp, aTitleValue );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+SFX_IMPL_XSERVICEINFO( SfxDocTplService, TEMPLATE_SERVICE_NAME, TEMPLATE_IMPLEMENTATION_NAME )
+SFX_IMPL_SINGLEFACTORY( SfxDocTplService )
+
+//-----------------------------------------------------------------------------
+SfxDocTplService::SfxDocTplService( const uno::Reference< XMultiServiceFactory >& xFactory )
+{
+ pImp = new SfxDocTplService_Impl( xFactory );
+}
+
+//-----------------------------------------------------------------------------
+
+SfxDocTplService::~SfxDocTplService()
+{
+ delete pImp;
+}
+
+//-----------------------------------------------------------------------------
+//--- XLocalizable ---
+//-----------------------------------------------------------------------------
+
+Locale SAL_CALL SfxDocTplService::getLocale()
+ throw( RUNTIMEEXCEPTION )
+{
+ return pImp->getLocale();
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocTplService::setLocale( const Locale & rLocale )
+ throw( RUNTIMEEXCEPTION )
+{
+ pImp->setLocale( rLocale );
+}
+
+//-----------------------------------------------------------------------------
+//--- XDocumentTemplates ---
+//-----------------------------------------------------------------------------
+uno::Reference< XCONTENT > SAL_CALL SfxDocTplService::getContent()
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( pImp->init() )
+ return pImp->getContent().get();
+ else
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxDocTplService::storeTemplate( const OUString& GroupName,
+ const OUString& TemplateName,
+ const uno::Reference< XSTORABLE >& Storable )
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( pImp->init() )
+ return pImp->storeTemplate( GroupName, TemplateName, Storable );
+ else
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxDocTplService::addTemplate( const OUString& rGroupName,
+ const OUString& rTemplateName,
+ const OUString& rSourceURL )
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( pImp->init() )
+ return pImp->addTemplate( rGroupName, rTemplateName, rSourceURL );
+ else
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxDocTplService::removeTemplate( const OUString& rGroupName,
+ const OUString& rTemplateName )
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( pImp->init() )
+ return pImp->removeTemplate( rGroupName, rTemplateName );
+ else
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxDocTplService::renameTemplate( const OUString& rGroupName,
+ const OUString& rOldName,
+ const OUString& rNewName )
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( rOldName == rNewName )
+ return sal_True;
+
+ if ( pImp->init() )
+ return pImp->renameTemplate( rGroupName, rOldName, rNewName );
+ else
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxDocTplService::addGroup( const OUString& rGroupName )
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( pImp->init() )
+ return pImp->addGroup( rGroupName );
+ else
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxDocTplService::removeGroup( const OUString& rGroupName )
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( pImp->init() )
+ return pImp->removeGroup( rGroupName );
+ else
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxDocTplService::renameGroup( const OUString& rOldName,
+ const OUString& rNewName )
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( rOldName == rNewName )
+ return sal_True;
+
+ if ( pImp->init() )
+ return pImp->renameGroup( rOldName, rNewName );
+ else
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxDocTplService::update()
+ throw( RUNTIMEEXCEPTION )
+{
+ if ( pImp->init() )
+ pImp->update( sal_True );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//------------------------------------------------------------------------
+
+Updater_Impl::Updater_Impl( SfxDocTplService_Impl* pTemplates )
+{
+ mpDocTemplates = pTemplates;
+}
+
+//------------------------------------------------------------------------
+Updater_Impl::~Updater_Impl()
+{
+}
+
+//------------------------------------------------------------------------
+void SAL_CALL Updater_Impl::run()
+{
+ mpDocTemplates->doUpdate();
+}
+
+//------------------------------------------------------------------------
+void SAL_CALL Updater_Impl::onTerminated()
+{
+ mpDocTemplates->finished();
+ delete this;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+WaitWindow_Impl::WaitWindow_Impl()
+ : WorkWindow( NULL, WB_BORDER | WB_3DLOOK )
+{
+ Rectangle aRect = Rectangle( 0, 0, 300, 30000 );
+ _nTextStyle = TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE;
+ _aText = String( SfxResId( RID_CNT_STR_WAITING ) );
+ _aRect = GetTextRect( aRect, _aText, _nTextStyle );
+ aRect = _aRect;
+ aRect.Right() += 2*X_OFFSET;
+ aRect.Bottom() += 2*Y_OFFSET;
+ _aRect.SetPos( Point( X_OFFSET, Y_OFFSET ) );
+ SetOutputSizePixel( aRect.GetSize() );
+ Show();
+ Update();
+ Flush();
+}
+
+//-----------------------------------------------------------------------------
+WaitWindow_Impl::~WaitWindow_Impl()
+{
+ Hide();
+}
+
+//-----------------------------------------------------------------------------
+void WaitWindow_Impl::Paint( const Rectangle& /*rRect*/ )
+{
+ DrawText( _aRect, _aText, _nTextStyle );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::addHierGroup( GroupList_Impl& rList,
+ const OUString& rTitle,
+ const OUString& rOwnURL )
+{
+ // now get the content of the Group
+ Content aContent;
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(3);
+
+ aProps[0] = OUString::createFromAscii( TITLE );
+ aProps[1] = OUString::createFromAscii( TARGET_URL );
+ aProps[2] = OUString::createFromAscii( PROPERTY_TYPE );
+
+ try
+ {
+ aContent = Content( rOwnURL, maCmdEnv );
+ ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
+ xResultSet = aContent.createCursor( aProps, eInclude );
+ }
+ catch ( ContentCreationException& )
+ {
+ DBG_ERRORFILE( "addHierGroup: ContentCreationException" );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ GroupData_Impl *pGroup = new GroupData_Impl( rTitle );
+ pGroup->setHierarchy( sal_True );
+ pGroup->setHierarchyURL( rOwnURL );
+ rList.Insert( pGroup );
+
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ BOOL bUpdateType = sal_False;
+ DocTemplates_EntryData_Impl *pData;
+
+ OUString aTitle( xRow->getString( 1 ) );
+ OUString aTargetDir( xRow->getString( 2 ) );
+ OUString aType( xRow->getString( 3 ) );
+ OUString aHierURL = xContentAccess->queryContentIdentifierString();
+
+ if ( !aType.getLength() )
+ {
+ OUString aTmpTitle;
+
+ sal_Bool bDocHasTitle = sal_False;
+ if( !getTitleFromURL( aTargetDir, aTmpTitle, aType, bDocHasTitle ) )
+ {
+ DBG_ERRORFILE( "addHierGroup(): template of alien format" );
+ continue;
+ }
+
+ if ( aType.getLength() )
+ bUpdateType = sal_True;
+ }
+
+ pData = pGroup->addEntry( aTitle, aTargetDir, aType, aHierURL );
+ pData->setUpdateType( bUpdateType );
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::addFsysGroup( GroupList_Impl& rList,
+ const OUString& rTitle,
+ const OUString& rUITitle,
+ const OUString& rOwnURL,
+ sal_Bool bWriteableGroup )
+{
+ ::rtl::OUString aTitle;
+
+ if ( !rUITitle.getLength() )
+ {
+ // reserved FS names that should not be used
+ if ( rTitle.compareToAscii( "wizard" ) == 0 )
+ return;
+ else if ( rTitle.compareToAscii( "internal" ) == 0 )
+ return;
+
+ aTitle = getLongName( rTitle );
+ }
+ else
+ aTitle = rUITitle;
+
+ if ( !aTitle.getLength() )
+ return;
+
+ GroupData_Impl *pGroup = rList.First();
+
+ while ( pGroup && pGroup->getTitle() != aTitle )
+ pGroup = rList.Next();
+
+ if ( !pGroup )
+ {
+ pGroup = new GroupData_Impl( aTitle );
+ rList.Insert( pGroup );
+ }
+
+ if ( bWriteableGroup )
+ pGroup->setTargetURL( rOwnURL );
+
+ pGroup->setInUse();
+
+ // now get the content of the Group
+ Content aContent;
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(1);
+ aProps[0] = OUString::createFromAscii( TITLE );
+
+ try
+ {
+ // this method is only used during checking of the available template-folders
+ // that should happen quietly
+ uno::Reference< XCommandEnvironment > aQuietEnv;
+ aContent = Content( rOwnURL, aQuietEnv );
+ ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
+ xResultSet = aContent.createCursor( aProps, eInclude );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ OUString aChildTitle( xRow->getString( 1 ) );
+ OUString aTargetURL = xContentAccess->queryContentIdentifierString();
+ OUString aType;
+ OUString aHierURL;
+
+ if ( aChildTitle.compareToAscii( "sfx.tlx" ) == 0
+ || aChildTitle.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "groupuinames.xml" ) ) )
+ continue;
+
+ // only StarOffice templates are accepted
+ sal_Bool bDocHasTitle = sal_False;
+ if( !getTitleFromURL( aTargetURL, aChildTitle, aType, bDocHasTitle ) )
+ continue;
+
+ pGroup->addEntry( aChildTitle, aTargetURL, aType, aHierURL );
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTplService_Impl::createFromContent( GroupList_Impl& rList,
+ Content &rContent,
+ sal_Bool bHierarchy,
+ sal_Bool bWriteableContent )
+{
+ OUString aTargetURL = rContent.get()->getIdentifier()->getContentIdentifier();
+
+ // when scanning the file system, we have to add the 'standard' group, too
+ if ( ! bHierarchy )
+ {
+ OUString aUIStdTitle = getLongName( OUString( RTL_CONSTASCII_USTRINGPARAM( STANDARD_FOLDER ) ) );
+ addFsysGroup( rList, ::rtl::OUString(), aUIStdTitle, aTargetURL, bWriteableContent );
+ }
+
+ // search for predefined UI names
+ INetURLObject aLayerObj( aTargetURL );
+
+ // TODO/LATER: Use hashmap in future
+ uno::Sequence< beans::StringPair > aUINames;
+ if ( !bHierarchy )
+ aUINames = ReadUINamesForTemplateDir_Impl( aLayerObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(1);
+ aProps[0] = OUString::createFromAscii( TITLE );
+
+ try
+ {
+ ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
+ xResultSet = rContent.createCursor( aProps, eInclude );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ // TODO/LATER: clarify the encoding of the Title
+ OUString aTitle( xRow->getString( 1 ) );
+ OUString aTargetSubfolderURL( xContentAccess->queryContentIdentifierString() );
+
+ if ( bHierarchy )
+ addHierGroup( rList, aTitle, aTargetSubfolderURL );
+ else
+ {
+ ::rtl::OUString aUITitle;
+ for ( sal_Int32 nInd = 0; nInd < aUINames.getLength(); nInd++ )
+ if ( aUINames[nInd].First.equals( aTitle ) )
+ {
+ aUITitle = aUINames[nInd].Second;
+ break;
+ }
+
+ addFsysGroup( rList, aTitle, aUITitle, aTargetSubfolderURL, bWriteableContent );
+ }
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::removeFromHierarchy( DocTemplates_EntryData_Impl *pData )
+{
+ Content aTemplate;
+
+ if ( Content::create( pData->getHierarchyURL(), maCmdEnv, aTemplate ) )
+ {
+ removeContent( aTemplate );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::addToHierarchy( GroupData_Impl *pGroup,
+ DocTemplates_EntryData_Impl *pData )
+{
+ Content aGroup, aTemplate;
+
+ if ( ! Content::create( pGroup->getHierarchyURL(), maCmdEnv, aGroup ) )
+ return;
+
+ // Check, if there's a template with the given name in this group
+ // Return if there is already a template
+ INetURLObject aGroupObj( pGroup->getHierarchyURL() );
+
+ aGroupObj.insertName( pData->getTitle(), false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ OUString aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
+ return;
+
+ addEntry( aGroup, pData->getTitle(),
+ pData->getTargetURL(),
+ pData->getType() );
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::updateData( DocTemplates_EntryData_Impl *pData )
+{
+ Content aTemplate;
+
+ if ( ! Content::create( pData->getHierarchyURL(), maCmdEnv, aTemplate ) )
+ return;
+
+ OUString aPropName;
+
+ if ( pData->getUpdateType() )
+ {
+ aPropName = OUString( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_TYPE ) );
+ setProperty( aTemplate, aPropName, makeAny( pData->getType() ) );
+ }
+
+ if ( pData->getUpdateLink() )
+ {
+ aPropName = OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+ setProperty( aTemplate, aPropName, makeAny( pData->getTargetURL() ) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::addGroupToHierarchy( GroupData_Impl *pGroup )
+{
+ OUString aAdditionalProp( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+ Content aGroup;
+
+ INetURLObject aNewGroupObj( maRootURL );
+ aNewGroupObj.insertName( pGroup->getTitle(), false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ OUString aNewGroupURL = aNewGroupObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( createFolder( aNewGroupURL, sal_False, sal_False, aGroup ) )
+ {
+ setProperty( aGroup, aAdditionalProp, makeAny( pGroup->getTargetURL() ) );
+ pGroup->setHierarchyURL( aNewGroupURL );
+
+ ULONG nCount = pGroup->count();
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ DocTemplates_EntryData_Impl *pData = pGroup->getEntry( i );
+ addToHierarchy( pGroup, pData ); // add entry to hierarchy
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SfxDocTplService_Impl::removeFromHierarchy( GroupData_Impl *pGroup )
+{
+ Content aGroup;
+
+ if ( Content::create( pGroup->getHierarchyURL(), maCmdEnv, aGroup ) )
+ {
+ removeContent( aGroup );
+ }
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+GroupData_Impl::GroupData_Impl( const OUString& rTitle )
+{
+ maTitle = rTitle;
+ mbInUse = sal_False;
+ mbInHierarchy = sal_False;
+}
+
+// -----------------------------------------------------------------------
+GroupData_Impl::~GroupData_Impl()
+{
+ DocTemplates_EntryData_Impl *pData = maEntries.First();
+ while ( pData )
+ {
+ delete pData;
+ pData = maEntries.Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+DocTemplates_EntryData_Impl* GroupData_Impl::addEntry( const OUString& rTitle,
+ const OUString& rTargetURL,
+ const OUString& rType,
+ const OUString& rHierURL )
+{
+ DocTemplates_EntryData_Impl *pData = maEntries.First();
+
+ while ( pData && pData->getTitle() != rTitle )
+ pData = maEntries.Next();
+
+ if ( !pData )
+ {
+ pData = new DocTemplates_EntryData_Impl( rTitle );
+ pData->setTargetURL( rTargetURL );
+ pData->setType( rType );
+ if ( rHierURL.getLength() )
+ {
+ pData->setHierarchyURL( rHierURL );
+ pData->setHierarchy( sal_True );
+ }
+ maEntries.Insert( pData );
+ }
+ else
+ {
+ if ( rHierURL.getLength() )
+ {
+ pData->setHierarchyURL( rHierURL );
+ pData->setHierarchy( sal_True );
+ }
+
+ if ( pData->getInHierarchy() )
+ pData->setInUse();
+
+ if ( rTargetURL != pData->getTargetURL() )
+ {
+ pData->setTargetURL( rTargetURL );
+ pData->setUpdateLink( sal_True );
+ }
+ }
+
+ return pData;
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+DocTemplates_EntryData_Impl::DocTemplates_EntryData_Impl( const OUString& rTitle )
+{
+ maTitle = rTitle;
+ mbInUse = sal_False;
+ mbInHierarchy = sal_False;
+ mbUpdateType = sal_False;
+ mbUpdateLink = sal_False;
+}
+
+// -----------------------------------------------------------------------
+SfxURLRelocator_Impl::SfxURLRelocator_Impl( uno::Reference< XMultiServiceFactory > xFactory )
+: mxFactory( xFactory )
+{
+}
+
+// -----------------------------------------------------------------------
+SfxURLRelocator_Impl::~SfxURLRelocator_Impl()
+{
+}
+
+// -----------------------------------------------------------------------
+void SfxURLRelocator_Impl::initOfficeInstDirs()
+{
+ if ( !mxOfficeInstDirs.is() )
+ {
+ osl::MutexGuard aGuard( maMutex );
+ if ( !mxOfficeInstDirs.is() )
+ {
+ OSL_ENSURE( mxFactory.is(), "No service manager!" );
+
+ uno::Reference< XComponentContext > xCtx;
+ uno::Reference< XPropertySet > xPropSet( mxFactory, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
+ >>= xCtx;
+ }
+
+ OSL_ENSURE( xCtx.is(),
+ "Unable to obtain component context from "
+ "service manager!" );
+
+ if ( xCtx.is() )
+ {
+ xCtx->getValueByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/"
+ "com.sun.star.util.theOfficeInstallationDirectories" ) ) )
+ >>= mxOfficeInstDirs;
+ }
+
+ OSL_ENSURE( mxOfficeInstDirs.is(),
+ "Unable to obtain office installation directory "
+ "singleton!" );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxURLRelocator_Impl::makeRelocatableURL( rtl::OUString & rURL )
+{
+ if ( rURL.getLength() > 0 )
+ {
+ initOfficeInstDirs();
+ rURL = mxOfficeInstDirs->makeRelocatableURL( rURL );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxURLRelocator_Impl::makeAbsoluteURL( rtl::OUString & rURL )
+{
+ if ( rURL.getLength() > 0 )
+ {
+ initOfficeInstDirs();
+ rURL = mxOfficeInstDirs->makeAbsoluteURL( rURL );
+ }
+}
+
+
diff --git a/sfx2/source/doc/doctemplateslocal.cxx b/sfx2/source/doc/doctemplateslocal.cxx
new file mode 100644
index 000000000000..277199d30051
--- /dev/null
+++ b/sfx2/source/doc/doctemplateslocal.cxx
@@ -0,0 +1,263 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
+#include <com/sun/star/beans/StringPair.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP
+#include <com/sun/star/xml/sax/XParser.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#endif
+
+#include <comphelper/attributelist.hxx>
+
+#include "doctemplateslocal.hxx"
+
+using namespace ::com::sun::star;
+
+// -----------------------------------
+uno::Sequence< beans::StringPair > DocTemplLocaleHelper::ReadGroupLocalizationSequence( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory > xFactory )
+ throw( uno::Exception )
+{
+ ::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) );
+ return ReadLocalizationSequence_Impl( xInStream, aStringID, xFactory );
+}
+
+// -----------------------------------
+void SAL_CALL DocTemplLocaleHelper::WriteGroupLocalizationSequence( const uno::Reference< io::XOutputStream >& xOutStream, const 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 aGroupListElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group-list" ) );
+ ::rtl::OUString aGroupElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group" ) );
+ ::rtl::OUString aNameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:name" ) );
+ ::rtl::OUString aUINameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:default-ui-name" ) );
+ ::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) );
+ ::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) );
+
+ // write the namespace
+ ::comphelper::AttributeList* pRootAttrList = new ::comphelper::AttributeList;
+ uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList );
+ pRootAttrList->AddAttribute(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ),
+ aCDATAString,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://openoffice.org/2006/groupuinames" ) ) );
+
+ xWriterHandler->startDocument();
+ xWriterHandler->startElement( aGroupListElement, xRootAttrList );
+
+ for ( sal_Int32 nInd = 0; nInd < aSequence.getLength(); nInd++ )
+ {
+ ::comphelper::AttributeList *pAttrList = new ::comphelper::AttributeList;
+ uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList );
+ pAttrList->AddAttribute( aNameAttr, aCDATAString, aSequence[nInd].First );
+ pAttrList->AddAttribute( aUINameAttr, aCDATAString, aSequence[nInd].Second );
+
+ xWriterHandler->startElement( aGroupElement, xAttrList );
+ xWriterHandler->ignorableWhitespace( aWhiteSpace );
+ xWriterHandler->endElement( aGroupElement );
+ }
+
+ xWriterHandler->ignorableWhitespace( aWhiteSpace );
+ xWriterHandler->endElement( aGroupListElement );
+ xWriterHandler->endDocument();
+}
+
+// ==================================================================================
+
+// -----------------------------------
+uno::Sequence< beans::StringPair > SAL_CALL DocTemplLocaleHelper::ReadLocalizationSequence_Impl( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString& aStringID, const uno::Reference< lang::XMultiServiceFactory > xFactory )
+ throw( uno::Exception )
+{
+ if ( !xFactory.is() || !xInStream.is() )
+ throw uno::RuntimeException();
+
+ 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 );
+
+ DocTemplLocaleHelper* pHelper = new DocTemplLocaleHelper();
+ 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();
+}
+
+// -----------------------------------
+DocTemplLocaleHelper::DocTemplLocaleHelper()
+: m_aGroupListElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group-list" ) )
+, m_aGroupElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group" ) )
+, m_aNameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:name" ) )
+, m_aUINameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:default-ui-name" ) )
+{
+}
+
+// -----------------------------------
+DocTemplLocaleHelper::~DocTemplLocaleHelper()
+{
+}
+
+// -----------------------------------
+uno::Sequence< beans::StringPair > DocTemplLocaleHelper::GetParsingResult()
+{
+ if ( m_aElementsSeq.getLength() )
+ throw uno::RuntimeException(); // the parsing has still not finished!
+
+ return m_aResultSeq;
+}
+
+// -----------------------------------
+void SAL_CALL DocTemplLocaleHelper::startDocument()
+ throw(xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+// -----------------------------------
+void SAL_CALL DocTemplLocaleHelper::endDocument()
+ throw(xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+// -----------------------------------
+void SAL_CALL DocTemplLocaleHelper::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+ if ( aName == m_aGroupListElement )
+ {
+ 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_aGroupElement )
+ {
+ 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 );
+
+ ::rtl::OUString aNameValue = xAttribs->getValueByName( m_aNameAttr );
+ if ( !aNameValue.getLength() )
+ throw xml::sax::SAXException(); // TODO: the ID value must present
+
+ ::rtl::OUString aUINameValue = xAttribs->getValueByName( m_aUINameAttr );
+ if ( !aUINameValue.getLength() )
+ throw xml::sax::SAXException(); // TODO: the ID value must present
+
+ m_aResultSeq[nNewEntryNum-1].First = aNameValue;
+ m_aResultSeq[nNewEntryNum-1].Second = aUINameValue;
+ }
+ else
+ {
+ // accept future extensions
+ sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;
+
+ if ( !nNewLength )
+ throw xml::sax::SAXException(); // TODO: the extension element must not be the first level element
+
+ m_aElementsSeq.realloc( nNewLength );
+ m_aElementsSeq[nNewLength-1] = aName;
+ }
+}
+
+// -----------------------------------
+void SAL_CALL DocTemplLocaleHelper::endElement( const ::rtl::OUString& aName )
+ throw( xml::sax::SAXException, uno::RuntimeException )
+{
+ 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 DocTemplLocaleHelper::characters( const ::rtl::OUString& /*aChars*/ )
+ throw(xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+// -----------------------------------
+void SAL_CALL DocTemplLocaleHelper::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ )
+ throw(xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+// -----------------------------------
+void SAL_CALL DocTemplLocaleHelper::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
+ throw(xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
+// -----------------------------------
+void SAL_CALL DocTemplLocaleHelper::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
+ throw(xml::sax::SAXException, uno::RuntimeException)
+{
+}
+
diff --git a/sfx2/source/doc/doctemplateslocal.hxx b/sfx2/source/doc/doctemplateslocal.hxx
new file mode 100644
index 000000000000..84b1a9cc9611
--- /dev/null
+++ b/sfx2/source/doc/doctemplateslocal.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SFX_DOCTEMPLATESLOCAL_HXX
+#define _SFX_DOCTEMPLATESLOCAL_HXX
+
+#ifndef _COM_SUN_STAR_XML_SAX_XDUCUMENTHANDLER_HPP_
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#endif
+#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>
+
+
+class DocTemplLocaleHelper : public cppu::WeakImplHelper1 < com::sun::star::xml::sax::XDocumentHandler >
+{
+ // Relations info related strings
+ ::rtl::OUString m_aGroupListElement;
+ ::rtl::OUString m_aGroupElement;
+ ::rtl::OUString m_aNameAttr;
+ ::rtl::OUString m_aUINameAttr;
+
+ ::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
+
+ DocTemplLocaleHelper(); // must not be created directly
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > GetParsingResult();
+
+ static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > SAL_CALL ReadLocalizationSequence_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInStream, const ::rtl::OUString& aStringID, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory )
+ throw( ::com::sun::star::uno::Exception );
+
+public:
+ ~DocTemplLocaleHelper();
+
+ // returns sequence of pairs ( GroupName, GroupUIName )
+ static
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >
+ ReadGroupLocalizationSequence(
+ 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 ( GroupName, GroupUIName )
+ static
+ void SAL_CALL WriteGroupLocalizationSequence(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutStream,
+ const ::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 );
+
+ // 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);
+};
+
+#endif
+
diff --git a/sfx2/source/doc/docvor.cxx b/sfx2/source/doc/docvor.cxx
new file mode 100644
index 000000000000..719dc5b8d223
--- /dev/null
+++ b/sfx2/source/doc/docvor.cxx
@@ -0,0 +1,2466 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
+
+#include <stdio.h>
+
+#ifndef _SV_PRNSETUP_HXX //autogen
+#include <svtools/prnsetup.hxx>
+#endif
+#include <vcl/cmdevt.hxx>
+#include <vcl/menubtn.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/print.hxx>
+#include <svl/style.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <svtools/imagemgr.hxx>
+#include <vcl/waitobj.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/color.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <sot/exchange.hxx>
+#include <comphelper/storagehelper.hxx>
+
+#include "helpid.hrc"
+#include "docvor.hxx"
+#include <sfx2/docfac.hxx>
+#include "orgmgr.hxx"
+#include <sfx2/doctempl.hxx>
+#include <sfx2/templdlg.hxx>
+#include "sfxtypes.hxx"
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include "sfxresid.hxx"
+#include "doc.hrc"
+#include <sfx2/sfx.hrc>
+#include "docvor.hrc"
+#include <sfx2/docfilt.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <svtools/localresaccess.hxx>
+#ifndef _SVT_DOC_ADDRESSTEMPLATE_HXX_
+#include <svtools/addresstemplate.hxx>
+#endif
+#include <comphelper/processfactory.hxx>
+#define _SVSTDARR_STRINGSDTOR
+#include <svl/svstdarr.hxx>
+
+static const char cDelim = ':';
+BOOL SfxOrganizeListBox_Impl::bDropMoveOk = TRUE;
+
+using namespace ::com::sun::star;
+
+//=========================================================================
+
+class SuspendAccel
+{
+public:
+ Accelerator* pAccel;
+
+ SuspendAccel( Accelerator* pA )
+ {
+ pAccel=pA;
+ GetpApp()->RemoveAccel( pAccel );
+ }
+ ~SuspendAccel()
+ {
+ GetpApp()->InsertAccel( pAccel );
+ }
+};
+
+//=========================================================================
+
+
+inline void SfxOrganizeListBox_Impl::SetBitmaps(
+ const Image &rOFolder, const Image &rCFolder, const Image &rODoc, const Image &rCDoc,
+ const Image &rOFolderHC, const Image &rCFolderHC, const Image &rODocHC, const Image &rCDocHC )
+{
+ aOpenedFolderBmp = rOFolder;
+ aClosedFolderBmp = rCFolder;
+ aOpenedDocBmp = rODoc;
+ aClosedDocBmp = rCDoc;
+
+ aOpenedFolderBmpHC = rOFolderHC;
+ aClosedFolderBmpHC = rCFolderHC;
+ aOpenedDocBmpHC = rODocHC;
+ aClosedDocBmpHC = rCDocHC;
+
+}
+
+//=========================================================================
+
+#define NO_DROP_ACTION ((sal_Int8)-1)
+
+class SfxOrganizeDlg_Impl
+{
+friend class SfxTemplateOrganizeDlg;
+friend class SfxOrganizeListBox_Impl;
+
+ SuspendAccel* pSuspend;
+ SfxTemplateOrganizeDlg* pDialog;
+
+ SfxOrganizeListBox_Impl* pFocusBox;
+ Printer* pPrt;
+
+ // save pointer for asynchronous D&D
+ SvLBox* pSourceView;
+ SvLBoxEntry* pTargetEntry;
+ SfxOrganizeListBox_Impl* pFinishedBox;
+ sal_Int8 nDropAction;
+ bool bExecDropFinished;
+
+ // save some variables for the asynchronous file dialog
+ USHORT m_nRegion;
+ USHORT m_nIndex;
+ String m_sExtension4Save;
+
+ SfxOrganizeListBox_Impl aLeftLb;
+ ListBox aLeftTypLb;
+
+ SfxOrganizeListBox_Impl aRightLb;
+ ListBox aRightTypLb;
+
+ OKButton aOkBtn;
+ MenuButton aEditBtn;
+ HelpButton aHelpBtn;
+ PushButton aAddressTemplateBtn;
+ PushButton aFilesBtn;
+
+ Accelerator aEditAcc;
+
+ String aLastDir;
+ SfxOrganizeMgr aMgr;
+ sfx2::FileDialogHelper* pFileDlg;
+
+ SvStringsDtor* GetAllFactoryURLs_Impl() const;
+ sal_Bool GetServiceName_Impl( String& rFactoryURL, String& rFileURL ) const;
+ long Dispatch_Impl( USHORT nId, Menu* _pMenu );
+ String GetPath_Impl( BOOL bOpen, const String& rFileName );
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >
+ GetPaths_Impl( const String& rFileName );
+ void InitBitmaps( void );
+
+ DECL_LINK( GetFocus_Impl, SfxOrganizeListBox_Impl * );
+ DECL_LINK( LeftListBoxSelect_Impl, ListBox * );
+ DECL_LINK( RightListBoxSelect_Impl, ListBox * );
+ DECL_LINK( AccelSelect_Impl, Accelerator * );
+ DECL_LINK( MenuSelect_Impl, Menu * );
+ DECL_LINK( MenuActivate_Impl, Menu * );
+ DECL_LINK( AddFiles_Impl, Button * );
+ DECL_LINK( OnAddressTemplateClicked, Button * );
+
+ DECL_LINK( ImportHdl, sfx2::FileDialogHelper* );
+ DECL_LINK( ExportHdl, sfx2::FileDialogHelper* );
+ DECL_LINK( AddFilesHdl, sfx2::FileDialogHelper* );
+
+ BOOL DontDelete_Impl( SvLBoxEntry* pEntry );
+ void OkHdl( Button* );
+
+public:
+ SfxOrganizeDlg_Impl( SfxTemplateOrganizeDlg* pParent, SfxDocumentTemplates* pTempl );
+ ~SfxOrganizeDlg_Impl();
+};
+
+//-------------------------------------------------------------------------
+
+SfxOrganizeDlg_Impl::SfxOrganizeDlg_Impl( SfxTemplateOrganizeDlg* pParent,
+ SfxDocumentTemplates* pTempl ) :
+
+ pSuspend ( NULL ),
+ pDialog ( pParent ),
+ pFocusBox ( NULL ),
+ pPrt ( NULL ),
+ pSourceView ( NULL ),
+ pTargetEntry ( NULL ),
+ pFinishedBox ( NULL ),
+ nDropAction ( NO_DROP_ACTION ),
+ bExecDropFinished ( true ),
+
+ aLeftLb ( this, pParent, WB_BORDER | WB_TABSTOP | WB_HSCROLL, SfxOrganizeListBox_Impl::VIEW_TEMPLATES ),
+ aLeftTypLb ( pParent, SfxResId( LB_LEFT_TYP ) ),
+
+ aRightLb ( this, pParent, WB_BORDER | WB_TABSTOP | WB_HSCROLL, SfxOrganizeListBox_Impl::VIEW_FILES ),
+ aRightTypLb ( pParent, SfxResId( LB_RIGHT_TYP ) ),
+
+ aOkBtn ( pParent, SfxResId( BTN_OK ) ),
+ aEditBtn ( pParent, SfxResId( BTN_EDIT ) ),
+ aHelpBtn ( pParent, SfxResId( BTN_HELP ) ),
+ aAddressTemplateBtn ( pParent, SfxResId( BTN_ADDRESSTEMPLATE ) ),
+ aFilesBtn ( pParent, SfxResId( BTN_FILES ) ),
+
+ aEditAcc ( SfxResId( ACC_EDIT ) ),
+ aMgr ( &aLeftLb, &aRightLb, pTempl ),
+ pFileDlg ( NULL )
+
+{
+ // update the SfxDocumentTemplates the manager works with
+ if ( aMgr.GetTemplates() ) // should never fail, but who knows ....
+ {
+ // for this, show a wait cursor (it may take a while)
+ Window* pWaitObjectRange = pDialog ? pDialog->GetParent() : NULL;
+ if ( !pWaitObjectRange )
+ pWaitObjectRange = pDialog;
+
+ WaitObject aWaitCursor( pWaitObjectRange );
+ const_cast< SfxDocumentTemplates* >( aMgr.GetTemplates() )->Update( sal_True /* be smart */ );
+ // this const_cast is a hack - but the alternative would be to
+ // * have a method which returns the templates non-const
+ // * use a new SfxDocumentTemplates instance for the update (knowing that they all share the same
+ // implementation class)
+ // * always work with an own instance, even if we get only NULL in this ctor
+ }
+
+ aLeftLb.SetHelpId( HID_CTL_ORGANIZER_LEFT );
+ aRightLb.SetHelpId( HID_CTL_ORGANIZER_RIGHT );
+
+ String aWorkPath = SvtPathOptions().GetWorkPath();
+ if ( aWorkPath.Len() )
+ {
+ INetURLObject aObj( aWorkPath );
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL !" );
+ aObj.setFinalSlash();
+ aLastDir = aObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ }
+ else
+ {
+ // fallback
+ String aProgURL = SvtPathOptions().SubstituteVariable( String::CreateFromAscii("$(PROGURL)") );
+ INetURLObject aObj( aProgURL );
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL !" );
+ aLastDir = aObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ }
+
+ InitBitmaps();
+
+ aEditBtn.GetPopupMenu()->SetSelectHdl( LINK( this, SfxOrganizeDlg_Impl, MenuSelect_Impl ) );
+ aEditBtn.GetPopupMenu()->SetActivateHdl( LINK( this, SfxOrganizeDlg_Impl, MenuActivate_Impl ) );
+ aEditAcc.SetSelectHdl( LINK( this, SfxOrganizeDlg_Impl, AccelSelect_Impl ) );
+ GetpApp()->InsertAccel( &aEditAcc );
+
+ aFilesBtn.SetClickHdl(
+ LINK(this,SfxOrganizeDlg_Impl, AddFiles_Impl));
+ aAddressTemplateBtn.SetClickHdl(
+ LINK(this,SfxOrganizeDlg_Impl, OnAddressTemplateClicked));
+ aLeftTypLb.SetSelectHdl(
+ LINK(this, SfxOrganizeDlg_Impl, LeftListBoxSelect_Impl));
+ aRightTypLb.SetSelectHdl(
+ LINK(this, SfxOrganizeDlg_Impl, RightListBoxSelect_Impl));
+ aLeftLb.SetGetFocusHdl(
+ LINK(this, SfxOrganizeDlg_Impl, GetFocus_Impl));
+ aRightLb.SetGetFocusHdl(
+ LINK(this, SfxOrganizeDlg_Impl, GetFocus_Impl));
+ aLeftLb.SetPosSizePixel(pParent->LogicToPixel(Point(3, 6), MAP_APPFONT),
+ pParent->LogicToPixel(Size(94, 132), MAP_APPFONT));
+ aRightLb.SetPosSizePixel(pParent->LogicToPixel(Point(103, 6), MAP_APPFONT),
+ pParent->LogicToPixel(Size(94, 132), MAP_APPFONT));
+
+ if ( !SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SDATABASE) )
+ aAddressTemplateBtn.Hide();
+ Font aFont(aLeftLb.GetFont());
+ aFont.SetWeight(WEIGHT_NORMAL);
+ aLeftLb.SetFont(aFont);
+ aRightLb.SetFont(aFont);
+ const long nIndent = aLeftLb.GetIndent() / 2;
+ aLeftLb.SetIndent( (short)nIndent );
+ aRightLb.SetIndent( (short)nIndent );
+
+ aLeftLb.SetMgr(&aMgr);
+ aRightLb.SetMgr(&aMgr);
+ aLeftLb.Reset();
+ aRightLb.Reset();//SetModel(aLeftLb.GetModel());
+
+ aLeftLb.Show();
+ aRightLb.Show();
+
+ aLeftLb.SelectAll( FALSE );
+ aRightLb.SelectAll( FALSE );
+ aRightLb.GrabFocus();
+}
+
+//-------------------------------------------------------------------------
+
+SfxOrganizeDlg_Impl::~SfxOrganizeDlg_Impl()
+{
+ delete pFileDlg;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxOrganizeDlg_Impl::InitBitmaps( void )
+{
+ Image aOpenedFolderBmp( SfxResId( IMG_OPENED_FOLDER ) );
+ Image aClosedFolderBmp( SfxResId( IMG_CLOSED_FOLDER ) );
+ Image aOpenedDocBmp( SfxResId( IMG_OPENED_DOC ) );
+ Image aClosedDocBmp( SfxResId( IMG_CLOSED_DOC ) );
+
+ Image aOpenedFolderBmpHC( SfxResId( IMG_OPENED_FOLDER_HC ) );
+ Image aClosedFolderBmpHC( SfxResId( IMG_CLOSED_FOLDER_HC ) );
+ Image aOpenedDocBmpHC( SfxResId( IMG_OPENED_DOC_HC ) );
+ Image aClosedDocBmpHC( SfxResId( IMG_CLOSED_DOC_HC ) );
+
+ aLeftLb.SetBitmaps( aOpenedFolderBmp, aClosedFolderBmp, aOpenedDocBmp, aClosedDocBmp,
+ aOpenedFolderBmpHC, aClosedFolderBmpHC, aOpenedDocBmpHC, aClosedDocBmpHC );
+ aRightLb.SetBitmaps( aOpenedFolderBmp, aClosedFolderBmp, aOpenedDocBmp, aClosedDocBmp,
+ aOpenedFolderBmpHC, aClosedFolderBmpHC, aOpenedDocBmpHC, aClosedDocBmpHC );
+}
+
+//=========================================================================
+
+BOOL QueryDelete_Impl(Window *pParent, // Parent der QueryBox
+ USHORT nId, // Resource Id
+ const String &rTemplateName) // Name der zu l"oschenden Vorlage
+/* [Beschreibung]
+
+ "oschabfrage
+
+*/
+{
+ SfxResId aResId( nId );
+ String aEntryText( aResId );
+ aEntryText.SearchAndReplaceAscii( "$1", rTemplateName );
+ QueryBox aBox( pParent, WB_YES_NO | WB_DEF_NO, aEntryText );
+ return RET_NO != aBox.Execute();
+}
+
+//-------------------------------------------------------------------------
+
+void ErrorDelete_Impl(Window *pParent, const String &rName, sal_Bool bFolder = sal_False )
+
+/* [Beschreibung]
+
+ Benutzerinformation, da"s die Vorlage rName nicht gel"oscht werden konnte
+
+*/
+{
+ if ( bFolder )
+ {
+ String aText( SfxResId( STR_ERROR_DELETE_TEMPLATE_DIR ) );
+ ErrorBox( pParent, WB_OK, aText ).Execute();
+ }
+ else
+ {
+ String aText( SfxResId( STR_ERROR_DELETE_TEMPLATE ) );
+ aText.SearchAndReplaceAscii( "$1", rName );
+ ErrorBox( pParent, WB_OK, aText ).Execute();
+ }
+}
+
+
+//=========================================================================
+
+/* [Beschreibung]
+
+ Implementierungsklasse; Referenzklasse f"ur USHORT-Array
+
+*/
+
+struct ImpPath_Impl
+{
+ SvUShorts aUS;
+ USHORT nRef;
+
+ ImpPath_Impl();
+ ImpPath_Impl( const ImpPath_Impl& rCopy );
+};
+
+//-------------------------------------------------------------------------
+
+ImpPath_Impl::ImpPath_Impl() : aUS(5), nRef(1)
+{
+}
+
+//-------------------------------------------------------------------------
+
+ImpPath_Impl::ImpPath_Impl( const ImpPath_Impl& rCopy ) :
+
+ aUS ( (BYTE)rCopy.aUS.Count() ),
+ nRef( 1 )
+
+{
+ const USHORT nCount = rCopy.aUS.Count();
+
+ for ( USHORT i = 0; i < nCount; ++i )
+ aUS.Insert( rCopy.aUS[i], i );
+}
+
+//==========================================================================
+
+/* [Beschreibung]
+
+ Implementierungsklasse; Darstellung einer Position in der Outline-
+ Listbox als USHORT-Array; dieses beschreibt die Position jeweil
+ als relative Postion zum "ubergeordneten Eintrag
+
+*/
+class Path
+{
+ ImpPath_Impl *pData;
+ void NewImp();
+public:
+ Path(SvLBox *pBox, SvLBoxEntry *pEntry);
+ Path(const Path &rPath):
+ pData(rPath.pData)
+ {
+ ++pData->nRef;
+ }
+ const Path &operator=(const Path &rPath)
+ {
+ if(&rPath != this)
+ {
+ if(!--pData->nRef)
+ delete pData;
+ pData = rPath.pData;
+ pData->nRef++;
+ }
+ return *this;
+ }
+ ~Path()
+ {
+ if(!--pData->nRef)
+ delete pData;
+ }
+ USHORT Count() const { return pData->aUS.Count(); }
+ USHORT operator[]( USHORT i ) const
+ {
+ return i < Count()? pData->aUS[i]: INDEX_IGNORE;
+ }
+};
+
+//-------------------------------------------------------------------------
+
+Path::Path(SvLBox *pBox, SvLBoxEntry *pEntry) :
+ pData(new ImpPath_Impl)
+{
+ DBG_ASSERT(pEntry != 0, "EntryPtr ist NULL");
+ if(!pEntry)
+ return;
+ SvLBoxEntry *pParent = pBox->GetParent(pEntry);
+ do {
+ pData->aUS.Insert((USHORT)pBox->GetModel()->GetRelPos(pEntry), 0);
+ if(0 == pParent)
+ break;
+ pEntry = pParent;
+ pParent = pBox->GetParent(pEntry);
+ } while(1);
+}
+
+//-------------------------------------------------------------------------
+
+void Path::NewImp()
+{
+ if(pData->nRef != 1)
+ {
+ pData->nRef--;
+ pData = new ImpPath_Impl(*pData);
+ }
+}
+
+//-------------------------------------------------------------------------
+
+SvLBoxEntry *GetIndices_Impl(SvLBox *pBox,
+ SvLBoxEntry *pEntry,
+ USHORT &rRegion,
+ USHORT &rOffset)
+/* [Beschreibung]
+
+ Bereich und Position innerhalb eines Bereiches f"ur eine
+ Dokumentvorlage wird ermittelt.
+
+ [Parameter]
+
+ SvLBox *pBox Listbox, an der das Ereignis auftrat
+ SvLBoxEntry *pEntry Eintrag, dessen Position ermittelt werden soll
+ USHORT &rRegion der Bereich innerhalb der Bereiche der
+ Dokumentvorlagen (Out-Parameter)
+ USHORT &rOffset die Position innerhalb des Bereiches
+ Dokumentvorlagen (Out-Parameter)
+
+ [Querverweise]
+
+ <class Path> (unter Umst"anden kann auf diese Funktion zugunsten
+ von Path verzichtet werden.)
+
+*/
+
+{
+ if(!pEntry)
+ {
+ rRegion = rOffset = 0;
+ return pEntry;
+ }
+ if(0 == pBox->GetModel()->GetDepth(pEntry))
+ {
+ rRegion = (USHORT)pBox->GetModel()->GetRelPos(pEntry);
+ rOffset = USHRT_MAX;
+ return pEntry;
+ }
+ SvLBoxEntry *pParent = pBox->GetParent(pEntry);
+ rRegion = (USHORT)pBox->GetModel()->GetRelPos(pParent);
+ rOffset = (USHORT)pBox->GetModel()->GetRelPos(pEntry);
+ return pEntry;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::Select( SvLBoxEntry* pEntry, BOOL bSelect )
+{
+ if(!bSelect)
+ return SvTreeListBox::Select(pEntry,bSelect);
+ USHORT nLevel = GetDocLevel();
+ if(GetModel()->GetDepth(pEntry)+nLevel<3)
+ return SvTreeListBox::Select(pEntry,bSelect);
+
+ Path aPath(this, pEntry);
+ GetObjectShell(aPath)->TriggerHelpPI(
+ aPath[nLevel+1], aPath[nLevel+2], aPath[nLevel+3]);
+ return SvTreeListBox::Select(pEntry,bSelect);
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::MoveOrCopyTemplates(SvLBox *pSourceBox,
+ SvLBoxEntry *pSource,
+ SvLBoxEntry* pTarget,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx,
+ BOOL bCopy)
+/* [Beschreibung]
+
+ Verschieben oder Kopieren von Dokumentvorlagen
+
+ [Parameter]
+
+ SvLBox *pSourceBox Quell-Listbox, an der das Ereignis auftrat
+ SvLBoxEntry *pSource Quell-Eintrag, der kopiert / verschoben werden soll
+ SvLBoxEntry* pTarget Ziel-Eintrag, auf den verschoben werden soll
+ SvLBoxEntry *&pNewParent der Parent der an der Zielposition erzeugten
+ Eintrags (Out-Parameter)
+ ULONG &rIdx Index des Zieleintrags
+ BOOL bCopy Flag f"ur Kopieren / Verschieben
+
+
+ [Returnwert] BOOL: Erfolg oder Mi"serfolg
+
+ [Querverweise]
+
+ <SfxOrganizeListBox_Impl::MoveOrCopyContents(SvLBox *pSourceBox,
+ SvLBoxEntry *pSource,
+ SvLBoxEntry* pTarget,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx,
+ BOOL bCopy)>
+ <BOOL SfxOrganizeListBox_Impl::NotifyMoving(SvLBoxEntry *pTarget,
+ SvLBoxEntry* pSource,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx)>
+ <BOOL SfxOrganizeListBox_Impl::NotifyCopying(SvLBoxEntry *pTarget,
+ SvLBoxEntry* pSource,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx)>
+*/
+
+{
+ BOOL bOk = FALSE;
+
+ if(pSource)
+ {
+ USHORT nTargetRegion = 0, nTargetIndex = 0;
+ GetIndices_Impl(this, pTarget, nTargetRegion, nTargetIndex);
+
+ USHORT nSourceRegion = 0, nSourceIndex = 0;
+ GetIndices_Impl(pSourceBox, pSource, nSourceRegion, nSourceIndex);
+
+ bOk = bCopy ?
+ pMgr->Copy(nTargetRegion, nTargetIndex+1,
+ nSourceRegion, nSourceIndex):
+ pMgr->Move(nTargetRegion, nTargetIndex+1,
+ nSourceRegion, nSourceIndex);
+
+ if(bOk)
+ {
+ if(pSourceBox->GetModel()->GetDepth(pSource) == GetModel()->GetDepth(pTarget))
+ {
+ pNewParent = GetParent(pTarget);
+ rIdx = GetModel()->GetRelPos(pTarget)+1;
+ }
+ else
+ {
+ if(nTargetIndex == USHRT_MAX)
+ {
+ pNewParent = pTarget;
+ rIdx = 0;
+ }
+ else
+ SvLBox::NotifyCopying(
+ pTarget, pSource, pNewParent, rIdx);
+ }
+ }
+ else if ( bCopy )
+ {
+ // the template organizer always tries copy after the move, so no error is required for move case
+ String aText( SfxResId( bCopy ? STR_ERROR_COPY_TEMPLATE : STR_ERROR_MOVE_TEMPLATE ) );
+ aText.SearchAndReplaceAscii( "$1",
+ ( (SvTreeListBox *)pSourceBox )->GetEntryText( pSource ) );
+ ErrorBox( this, WB_OK, aText ).Execute();
+ }
+ }
+ return bOk;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::MoveOrCopyContents(SvLBox *pSourceBox,
+ SvLBoxEntry *pSource,
+ SvLBoxEntry* pTarget,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx,
+ BOOL bCopy)
+/* [Beschreibung]
+
+ Verschieben oder Kopieren von Dokumentinhalten
+
+ [Parameter]
+
+ SvLBox *pSourceBox Quell-Listbox, an der das Ereignis auftrat
+ SvLBoxEntry *pSource Quell-Eintrag, der kopiert / verschoben werden soll
+ SvLBoxEntry* pTarget Ziel-Eintrag, auf den verschoben werden soll
+ SvLBoxEntry *&pNewParent der Parent der an der Zielposition erzeugten
+ Eintrags (Out-Parameter)
+ ULONG &rIdx Index des Zieleintrags
+ BOOL bCopy Flag f"ur Kopieren / Verschieben
+
+
+ [Returnwert] BOOL: Erfolg oder Mi"serfolg
+
+ [Querverweise]
+
+ <SfxOrganizeListBox_Impl::MoveOrCopyTemplates(SvLBox *pSourceBox,
+ SvLBoxEntry *pSource,
+ SvLBoxEntry* pTarget,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx,
+ BOOL bCopy)>
+ <BOOL SfxOrganizeListBox_Impl::NotifyMoving(SvLBoxEntry *pTarget,
+ SvLBoxEntry* pSource,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx)>
+ <BOOL SfxOrganizeListBox_Impl::NotifyCopying(SvLBoxEntry *pTarget,
+ SvLBoxEntry* pSource,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx)>
+*/
+
+{
+ SfxErrorContext aEc( ERRCTX_SFX_MOVEORCOPYCONTENTS, this);
+ BOOL bOk = FALSE, bKeepExpansion = FALSE;
+ BOOL bRemovedFromSource = FALSE;
+ Path aSource(pSourceBox, pSource);
+ Path aTarget(this, pTarget);
+ SfxObjectShellRef aSourceDoc =
+ ((SfxOrganizeListBox_Impl *)pSourceBox)->GetObjectShell(aSource);
+
+ SfxObjectShellRef aTargetDoc = GetObjectShell(aTarget);
+ const USHORT nSLevel =
+ ((SfxOrganizeListBox_Impl *)pSourceBox)->GetDocLevel();
+ const USHORT nTLevel = GetDocLevel();
+
+ if(aSourceDoc.Is() && aTargetDoc.Is())
+ {
+ if (aSourceDoc->GetStyleSheetPool())
+ aSourceDoc->GetStyleSheetPool()->SetSearchMask(
+ SFX_STYLE_FAMILY_ALL, SFXSTYLEBIT_USERDEF | SFXSTYLEBIT_USED);
+
+ if (aTargetDoc->GetStyleSheetPool())
+ aTargetDoc->GetStyleSheetPool()->SetSearchMask(
+ SFX_STYLE_FAMILY_ALL, SFXSTYLEBIT_USERDEF | SFXSTYLEBIT_USED);
+ USHORT p[3];
+ USHORT nIdxDeleted = INDEX_IGNORE;
+ p[0]=aTarget[nTLevel+1];
+ p[1]=aTarget[nTLevel+2];
+ if(p[1]!=INDEX_IGNORE)p[1]++;
+ p[2]=aTarget[nTLevel+3];
+
+ bOk = aTargetDoc->Insert(
+ *aSourceDoc, aSource[nSLevel+1],
+ aSource[nSLevel+2], aSource[nSLevel+3],
+ p[0], p[1], p[2], nIdxDeleted);
+ // Positionskorrektur auswerten
+ // a = Dokumentinhalt
+ // b = Position Sub-Inhalt 1
+ // c = Position Sub-Inhalt 2
+ // doppelte Eintraege loeschen
+ if(bOk)
+ {
+ SvLBoxEntry *pParentIter = pTarget;
+ // bis auf die DokumentEbene nach oben als
+ // allgemeiner Bezugspunkt
+ while(GetModel()->GetDepth(pParentIter) != nTLevel)
+ pParentIter = GetParent(pParentIter);
+ if(pParentIter->HasChildsOnDemand() &&
+ !GetModel()->HasChilds(pParentIter))
+ RequestingChilds(pParentIter);
+ SvLBoxEntry *pChildIter = 0;
+
+ USHORT i = 0;
+ while(i < 2 && p[i+1] != INDEX_IGNORE)
+ {
+ pChildIter = FirstChild(pParentIter);
+ // bis zum Index der aktuellen Ebene
+ for(USHORT j = 0; j < p[i]; ++j)
+ pChildIter = NextSibling(pChildIter);
+ // gfs Fuellen bei Items onDemand
+ ++i;
+ if(p[i+1] != INDEX_IGNORE &&
+ pChildIter->HasChildsOnDemand() &&
+ !GetModel()->HasChilds(pChildIter))
+ RequestingChilds(pChildIter);
+ pParentIter = pChildIter;
+ }
+ rIdx = p[i];
+ pNewParent = pParentIter;
+ if(!IsExpanded(pNewParent) &&
+ pNewParent->HasChildsOnDemand() &&
+ !GetModel()->HasChilds(pNewParent))
+ {
+ bOk = FALSE;
+ if(!bCopy)
+ pSourceBox->GetModel()->Remove(pSource);
+ }
+ // Geloeschte Eintraege entfernen
+ // (kann durch Ueberschreiben geschehen)
+ if(nIdxDeleted != INDEX_IGNORE)
+ {
+ pChildIter = FirstChild(pParentIter);
+ for(USHORT j = 0; j < nIdxDeleted; ++j)
+ pChildIter = NextSibling(pChildIter);
+ if( pChildIter && pChildIter != pSource )
+ {
+ bKeepExpansion = IsExpanded(pParentIter);
+ GetModel()->Remove(pChildIter);
+ }
+ else
+ bOk = FALSE;
+ }
+ if(!bCopy && &aSourceDoc != &aTargetDoc)
+ {
+ //#109566# pool styles that are moved produce
+ //an rIdx == INDEX_IGNORE
+ //the method has to return true to keep the box content consistent
+ bRemovedFromSource = aSourceDoc->Remove(aSource[nSLevel+1],
+ aSource[nSLevel+2],
+ aSource[nSLevel+3]);
+ }
+ }
+ }
+// rIdx++;
+ return (((rIdx != INDEX_IGNORE)|| bRemovedFromSource) && bOk )
+ ? bKeepExpansion? (BOOL)2: TRUE: FALSE;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::NotifyMoving(SvLBoxEntry *pTarget,
+ SvLBoxEntry* pSource,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx)
+
+/* [Beschreibung]
+
+ Benachrichtigung, da"s ein Eintrag verschoben werden soll
+ (SV-Handler)
+
+ [Parameter]
+
+ SvLBoxEntry* pTarget Ziel-Eintrag, auf den verschoben werden soll
+ SvLBoxEntry *pSource Quell-Eintrag, der verschoben werden soll
+ SvLBoxEntry *&pNewParent der Parent der an der Zielposition erzeugten
+ Eintrags (Out-Parameter)
+ ULONG &rIdx Index des Zieleintrags
+
+
+ [Returnwert] BOOL: Erfolg oder Mi"serfolg
+
+ [Querverweise]
+
+ <SfxOrganizeListBox_Impl::MoveOrCopyTemplates(SvLBox *pSourceBox,
+ SvLBoxEntry *pSource,
+ SvLBoxEntry* pTarget,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx,
+ BOOL bCopy)>
+ <SfxOrganizeListBox_Impl::MoveOrCopyContents(SvLBox *pSourceBox,
+ SvLBoxEntry *pSource,
+ SvLBoxEntry* pTarget,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx,
+ BOOL bCopy)>
+ <BOOL SfxOrganizeListBox_Impl::NotifyCopying(SvLBoxEntry *pTarget,
+ SvLBoxEntry* pSource,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx)>
+*/
+
+{
+ BOOL bOk = FALSE;
+ SvLBox* pSourceBox = GetSourceView();
+ if ( !pSourceBox )
+ pSourceBox = pDlg->pSourceView;
+ DBG_ASSERT( pSourceBox, "no source view" );
+ if ( !pTarget )
+ pTarget = pDlg->pTargetEntry;
+
+ if ( pSourceBox->GetModel()->GetDepth( pSource ) <= GetDocLevel() &&
+ GetModel()->GetDepth( pTarget ) <= GetDocLevel() )
+ bOk = MoveOrCopyTemplates( pSourceBox, pSource, pTarget, pNewParent, rIdx, FALSE );
+ else
+ bOk = MoveOrCopyContents(pSourceBox, pSource, pTarget, pNewParent, rIdx, FALSE );
+
+ return bOk;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::NotifyCopying(SvLBoxEntry *pTarget,
+ SvLBoxEntry* pSource,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx)
+/* [Beschreibung]
+
+ Benachrichtigung, da"s ein Eintrag kopiert werden soll
+ (SV-Handler)
+
+ [Parameter]
+
+ SvLBoxEntry* pTarget Ziel-Eintrag, auf den kopiert werden soll
+ SvLBoxEntry *pSource Quell-Eintrag, der kopiert werden soll
+ SvLBoxEntry *&pNewParent der Parent der an der Zielposition erzeugten
+ Eintrags (Out-Parameter)
+ ULONG &rIdx Index des Zieleintrags
+
+
+ [Returnwert] BOOL: Erfolg oder Mi"serfolg
+
+ [Querverweise]
+
+ <SfxOrganizeListBox_Impl::MoveOrCopyTemplates(SvLBox *pSourceBox,
+ SvLBoxEntry *pSource,
+ SvLBoxEntry* pTarget,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx,
+ BOOL bCopy)>
+ <SfxOrganizeListBox_Impl::MoveOrCopyContents(SvLBox *pSourceBox,
+ SvLBoxEntry *pSource,
+ SvLBoxEntry* pTarget,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx,
+ BOOL bCopy)>
+ <BOOL SfxOrganizeListBox_Impl::NotifyMoving(SvLBoxEntry *pTarget,
+ SvLBoxEntry* pSource,
+ SvLBoxEntry *&pNewParent,
+ ULONG &rIdx)>
+*/
+{
+ BOOL bOk = FALSE;
+ SvLBox* pSourceBox = GetSourceView();
+ if ( !pSourceBox )
+ pSourceBox = pDlg->pSourceView;
+ DBG_ASSERT( pSourceBox, "no source view" );
+ if ( !pTarget )
+ pTarget = pDlg->pTargetEntry;
+ if ( pSourceBox->GetModel()->GetDepth( pSource ) <= GetDocLevel() &&
+ GetModel()->GetDepth( pTarget ) <= GetDocLevel() )
+ bOk = MoveOrCopyTemplates( pSourceBox, pSource, pTarget, pNewParent, rIdx, TRUE );
+ else
+ bOk = MoveOrCopyContents( pSourceBox, pSource, pTarget, pNewParent, rIdx, TRUE );
+
+ return bOk;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::EditingEntry( SvLBoxEntry* pEntry, Selection& )
+
+/* [Beschreibung]
+
+ Nachfrage, ob ein Eintrag editierbar ist
+ (SV-Handler)
+
+ [Querverweise]
+ <SfxOrganizeListBox_Impl::EditedEntry(SvLBoxEntry* pEntry, const String& rText)>
+*/
+
+{
+ if( VIEW_TEMPLATES == eViewType &&
+ GetModel()->GetDepth(pEntry) < 2 )
+ {
+ pDlg->pSuspend = new SuspendAccel( &pDlg->aEditAcc );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::EditedEntry(SvLBoxEntry* pEntry, const String& rText)
+
+/* [Beschreibung]
+
+ Der Name eines Eintrags wurde bearbeitet; ist der eingegebene Name
+ ein g"ultiger Name ("ange > 0), wird das Model aktualisiert.
+ (SV-Handler)
+
+ [Returnwert]
+
+ BOOL TRUE: der Name soll in der Anzeige ge"andert werden
+ FALSE:der Name soll nicht ge"andert werden
+
+ [Querverweise]
+ <SfxOrganizeListBox_Impl::EditingEntry(SvLBoxEntry* pEntry, const String& rText)>
+*/
+
+{
+ DBG_ASSERT(pEntry, "kein Entry selektiert");
+ delete pDlg->pSuspend;
+ pDlg->pSuspend = NULL;
+ SvLBoxEntry* pParent = GetParent(pEntry);
+ if( !rText.Len() )
+ {
+ ErrorBox aBox( this, SfxResId( MSG_ERROR_EMPTY_NAME ) );
+ aBox.GrabFocus();
+ aBox.Execute();
+ return FALSE;
+ }
+ if ( !IsUniqName_Impl( rText, pParent, pEntry ) )
+ {
+ ErrorBox aBox( this, SfxResId( MSG_ERROR_UNIQ_NAME ) );
+ aBox.GrabFocus();
+ aBox.Execute();
+ return FALSE;
+ }
+ USHORT nRegion = 0, nIndex = 0;
+ GetIndices_Impl( this, pEntry, nRegion, nIndex );
+ String aOldName;
+ if ( USHRT_MAX != nIndex )
+ aOldName = pMgr->GetTemplates()->GetName( nRegion, nIndex );
+ else
+ aOldName = pMgr->GetTemplates()->GetRegionName( nRegion );
+
+ if ( !pMgr->SetName( rText, nRegion, nIndex ) )
+ {
+ SfxResId aResId( USHRT_MAX != nIndex ? MSG_ERROR_RENAME_TEMPLATE
+ : MSG_ERROR_RENAME_TEMPLATE_REGION );
+ ErrorBox( this, aResId ).Execute();
+ return FALSE;
+ }
+/*
+ else
+ {
+ SfxTemplateOrganizeDlg* pDlg = (SfxTemplateOrganizeDlg*)Window::GetParent();
+ }
+*/
+ return TRUE;
+}
+
+//-------------------------------------------------------------------------
+
+DragDropMode SfxOrganizeListBox_Impl::NotifyStartDrag( TransferDataContainer&, SvLBoxEntry* pEntry )
+{
+ USHORT nSourceLevel = GetModel()->GetDepth( pEntry );
+ if ( VIEW_FILES == GetViewType() )
+ ++nSourceLevel;
+ if ( nSourceLevel >= 2 )
+ bDropMoveOk = FALSE;
+ else
+ bDropMoveOk = TRUE;
+
+ return GetDragDropMode();
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::NotifyAcceptDrop( SvLBoxEntry* pEntry )
+{
+ if(!pEntry)
+ return FALSE;
+ SvLBox *pSource = GetSourceView();
+ SvLBoxEntry *pSourceEntry = pSource->FirstSelected();
+ if(pEntry == pSourceEntry)
+ return FALSE;
+ USHORT nSourceLevel = pSource->GetModel()->GetDepth(pSourceEntry);
+ if(VIEW_FILES == ((SfxOrganizeListBox_Impl *)pSource)->GetViewType())
+ ++nSourceLevel;
+ USHORT nTargetLevel = GetModel()->GetDepth(pEntry);
+ if(VIEW_FILES == GetViewType())
+ ++nTargetLevel;
+ Path aSource(pSource, pSourceEntry);
+ Path aTarget(this, pEntry);
+ const USHORT SL = ((SfxOrganizeListBox_Impl *)pSource)->GetDocLevel();
+ const USHORT TL = GetDocLevel();
+
+ return( (nSourceLevel == 1 && nTargetLevel == 0 &&
+ VIEW_TEMPLATES ==
+ ((SfxOrganizeListBox_Impl *)pSource)->GetViewType()) ||
+ (nSourceLevel == 1 && nTargetLevel == 1 &&
+ VIEW_TEMPLATES ==
+ ((SfxOrganizeListBox_Impl *)pSource)->GetViewType() &&
+ VIEW_TEMPLATES == GetViewType()) ||
+ (nSourceLevel == 3 && nTargetLevel == 1) ||
+ (nSourceLevel == 3 && nTargetLevel == 2 &&
+ aSource[1+SL] == aTarget[1+TL]) ||
+ (nSourceLevel == 3 && nTargetLevel == 3 &&
+ aSource[1+SL] == aTarget[1+TL]) ||
+ (nSourceLevel == 4 && nTargetLevel == 3 &&
+ aSource[1+SL] == aTarget[1+TL] &&
+ aSource[2+SL] == aTarget[2+TL]) ||
+ (nSourceLevel == 4 && nTargetLevel == 4 &&
+ aSource[1+SL] == aTarget[1+TL] &&
+ aSource[2+SL] == aTarget[2+TL]));
+}
+
+//-------------------------------------------------------------------------
+
+sal_Int8 SfxOrganizeListBox_Impl::AcceptDrop( const AcceptDropEvent& rEvt )
+{
+ sal_Bool bAccept = ( eViewType == VIEW_FILES && IsDropFormatSupported( SOT_FORMAT_FILE ) );
+ if ( bAccept )
+ return rEvt.mnAction;
+ else
+ return SvTreeListBox::AcceptDrop( rEvt );
+}
+
+//-------------------------------------------------------------------------
+
+sal_Int8 SfxOrganizeListBox_Impl::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ TransferableDataHelper aHelper( rEvt.maDropEvent.Transferable );
+ sal_uInt32 nFormatCount = aHelper.GetFormatCount();
+ BOOL bSuccess = FALSE;
+ for ( sal_uInt32 i = 0; i < nFormatCount; ++i )
+ {
+ String aFileName;
+ SotFormatStringId nId = aHelper.GetFormat(i);
+
+ if ( SOT_FORMAT_FILE == nId && aHelper.GetString( nId, aFileName ) )
+ {
+ INetURLObject aObj( aFileName, INET_PROT_FILE );
+ bSuccess |= pMgr->InsertFile( this, aObj.GetMainURL(INetURLObject::DECODE_TO_IURI) );
+ }
+ }
+ bDropMoveOk = TRUE;
+ sal_Int8 nRet = rEvt.mnAction;
+ if ( !bSuccess )
+ {
+ // asynchronous, because of MessBoxes
+ pDlg->pSourceView = GetSourceView();
+ pDlg->pTargetEntry = pTargetEntry;
+ pDlg->pFinishedBox = NULL;
+ pDlg->nDropAction = NO_DROP_ACTION;
+ PostUserEvent( LINK( this, SfxOrganizeListBox_Impl, OnAsyncExecuteDrop ),
+ new ExecuteDropEvent( rEvt ) );
+ }
+
+ return nRet;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxOrganizeListBox_Impl::DragFinished( sal_Int8 nDropAction )
+{
+ if ( pDlg->bExecDropFinished )
+ {
+ if ( pDlg->nDropAction != NO_DROP_ACTION )
+ nDropAction = pDlg->nDropAction;
+ SvTreeListBox::DragFinished( nDropAction );
+ pDlg->nDropAction = NO_DROP_ACTION;
+ }
+ else
+ pDlg->pFinishedBox = this;
+}
+
+//-------------------------------------------------------------------------
+
+inline USHORT SfxOrganizeListBox_Impl::GetDocLevel() const
+
+/* [Beschreibung]
+
+ Ermittelt, auf welche Ebene sich Dokumente befinden (unterschiedlich
+ in der Dokumentvorlagensicht und der Dokumentensicht)
+
+ [Returnwert]
+
+ USHORT Die Ebene der Dokumente
+
+*/
+
+{
+ return eViewType == VIEW_FILES? 0: 1;
+}
+
+//-------------------------------------------------------------------------
+
+SfxObjectShellRef SfxOrganizeListBox_Impl::GetObjectShell(const Path &rPath)
+
+/* [Beschreibung]
+
+ Zugriff auf die ObjectShell, die dem aktuellen Eintrag zugeordnet
+ ist.
+
+ [Parameter]
+
+ const Path &rPath Beschreibung des aktuellen Eintrags
+
+ [Returnwert]
+
+ SfxObjectShellRef Referenz auf die ObjectShell
+
+ [Querverweise]
+
+ <class Path>
+
+*/
+
+{
+ SfxObjectShellRef aDoc;
+ if(eViewType == VIEW_FILES)
+ aDoc = pMgr->CreateObjectShell(rPath[0]);
+ else
+ aDoc = pMgr->CreateObjectShell(rPath[0], rPath[1]);
+ return aDoc;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxOrganizeListBox_Impl::RequestingChilds( SvLBoxEntry* pEntry )
+
+/* [Beschreibung]
+
+ Aufforderung, der Childs eines Eintrags einzuf"ugen
+ ist.
+ (SV-Handler)
+
+ [Parameter]
+
+ SvLBoxEntry* pEntry der Eintrag, dessen Childs erfragt werden
+
+
+*/
+
+{
+ // wenn keine Childs vorhanden sind, gfs. Childs
+ // einfuegen
+ BmpColorMode eColorMode = BMP_COLOR_NORMAL;
+
+ if ( GetSettings().GetStyleSettings().GetHighContrastMode() )
+ eColorMode = BMP_COLOR_HIGHCONTRAST;
+
+
+ if ( !GetModel()->HasChilds( pEntry ) )
+ {
+ WaitObject aWaitCursor( this );
+
+ // Choose the correct mask color dependent from eColorMode. This must be adopted if
+ // we change the mask color for normal images, too!
+ Color aMaskColor( COL_LIGHTMAGENTA );
+
+ // hier sind alle initial eingefuegt
+ SfxErrorContext aEc(ERRCTX_SFX_CREATEOBJSH, pDlg->pDialog);
+ if(VIEW_TEMPLATES == GetViewType() && 0 == GetModel()->GetDepth(pEntry))
+ {
+ USHORT i = (USHORT)GetModel()->GetRelPos(pEntry);
+ const USHORT nEntryCount = pMgr->GetTemplates()->GetCount(i);
+ for(USHORT j = 0; j < nEntryCount; ++j)
+ InsertEntryByBmpType( pMgr->GetTemplates()->GetName( i, j ), BMPTYPE_DOC, pEntry, TRUE );
+ }
+ else
+ {
+ const USHORT nDocLevel = GetDocLevel();
+ Path aPath(this, pEntry);
+ SfxObjectShellRef aRef = GetObjectShell(aPath);
+ if(aRef.Is())
+ {
+ const USHORT nCount = aRef->GetContentCount(
+ aPath[nDocLevel+1], aPath[nDocLevel+2]);
+ String aText;
+ Bitmap aClosedBmp, aOpenedBmp;
+ const BOOL bCanHaveChilds =
+ aRef->CanHaveChilds(aPath[nDocLevel+1],
+ aPath[nDocLevel+2]);
+ for(USHORT i = 0; i < nCount; ++i)
+ {
+ BOOL bDeletable;
+ aRef->GetContent(
+ aText, aClosedBmp, aOpenedBmp, eColorMode, bDeletable,
+ i, aPath[nDocLevel+1], aPath[nDocLevel+2]);
+
+ // Create image with the correct mask color
+ Image aClosedImage( aClosedBmp, aMaskColor );
+ Image aOpenedImage( aOpenedBmp, aMaskColor );
+
+ SvLBoxEntry *pNew = SvTreeListBox::InsertEntry(
+ aText, aOpenedImage, aClosedImage,
+ pEntry, bCanHaveChilds);
+ pNew->SetUserData(bDeletable ? &bDeletable : 0);
+ }
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+
+long SfxOrganizeListBox_Impl::ExpandingHdl()
+
+/* [Beschreibung]
+
+ SV-Handler, der nach dem und vor dem Aufklappen eines Eintrags
+ gerufen wird.
+ Wird verwendet, um gfs. die ObjectShell wieder zu schlie"sen;
+ die Eintr"age mit den Inhalten dieser Shell werden ebenfalls
+ entfernt.
+
+*/
+
+{
+ if ( !(nImpFlags & SVLBOX_IS_EXPANDING) )
+ {
+ SvLBoxEntry* pEntry = GetHdlEntry();
+ const USHORT nLevel = GetModel()->GetDepth(pEntry);
+ if((eViewType == VIEW_FILES && nLevel == 0) ||
+ (eViewType == VIEW_TEMPLATES && nLevel == 1))
+ {
+ Path aPath(this, pEntry);
+ // Beim Schliessen des Files die ObjectShell freigeben
+ if(eViewType == VIEW_FILES && nLevel == 0)
+ pMgr->DeleteObjectShell(aPath[0]);
+ else
+ pMgr->DeleteObjectShell(aPath[0], aPath[1]);
+ // alle SubEntries loeschen
+ SvLBoxEntry *pToDel = SvLBox::GetEntry(pEntry, 0);
+ while(pToDel)
+ {
+ GetModel()->Remove(pToDel);
+ pToDel = SvLBox::GetEntry(pEntry, 0);
+ }
+ }
+ }
+ return TRUE;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeListBox_Impl::IsUniqName_Impl(const String &rText,
+ SvLBoxEntry* pParent, SvLBoxEntry *pEntry) const
+
+/* [Beschreibung]
+
+ Pr"uft, ob eine Name auf seiner Ebene eindeutig ist.
+
+ [Parameter]
+
+ const String & Name des zu suchenden Eintrags
+ SvLBoxEntry* pSibling Geschwister (bezeichnet die Ebene)
+
+ [Returnwert]
+
+ BOOL TRUE, wenn der Name eindeutig ist, sonst FALSE
+*/
+
+{
+ SvLBoxEntry* pChild = FirstChild(pParent);
+ while(pChild) {
+ const String aEntryText(GetEntryText(pChild));
+ if(COMPARE_EQUAL == aEntryText.CompareIgnoreCaseToAscii(rText)&&(!pEntry || pEntry!=pChild))
+ return FALSE;
+ pChild = NextSibling(pChild);
+ }
+ return TRUE;
+}
+
+//-------------------------------------------------------------------------
+
+USHORT SfxOrganizeListBox_Impl::GetLevelCount_Impl(SvLBoxEntry* pParent) const
+{
+ SvLBoxEntry* pChild = FirstChild(pParent);
+ USHORT nCount = 0;
+ while(pChild) {
+ pChild = NextSibling(pChild);
+ ++nCount;
+ }
+ return nCount;
+}
+
+//-------------------------------------------------------------------------
+
+SvLBoxEntry* SfxOrganizeListBox_Impl::InsertEntryByBmpType( const XubString& rText, BMPTYPE eBmpType,
+ SvLBoxEntry* pParent, BOOL bChildsOnDemand, ULONG nPos, void* pUserData )
+{
+ SvLBoxEntry* pEntry = NULL;
+ const Image* pExp = NULL;
+ const Image* pCol = NULL;
+ const Image* pExpHC = NULL;
+ const Image* pColHC = NULL;
+
+ switch( eBmpType )
+ {
+ case BMPTYPE_FOLDER:
+ pExp = &aOpenedFolderBmp;
+ pCol = &aClosedFolderBmp;
+ pExpHC = &aOpenedFolderBmpHC;
+ pColHC = &aClosedFolderBmpHC;
+ break;
+ default:
+ DBG_ERROR( "SfxOrganizeListBox_Impl::InsertEntryByBmpType(): something forgotten?!" );
+
+ case BMPTYPE_DOC:
+ pExp = &aOpenedDocBmp;
+ pCol = &aClosedDocBmp;
+ pExpHC = &aOpenedDocBmpHC;
+ pColHC = &aClosedDocBmpHC;
+ break;
+ }
+
+ pEntry = SvTreeListBox::InsertEntry( rText, *pExp, *pCol, pParent, bChildsOnDemand, nPos, pUserData );
+
+ SetExpandedEntryBmp( pEntry, *pExpHC, BMP_COLOR_HIGHCONTRAST );
+ SetCollapsedEntryBmp( pEntry, *pColHC, BMP_COLOR_HIGHCONTRAST );
+
+ return pEntry;
+}
+
+//-------------------------------------------------------------------------
+
+SfxOrganizeListBox_Impl::SfxOrganizeListBox_Impl
+(
+ SfxOrganizeDlg_Impl* pArgDlg,
+ Window* pParent,
+ WinBits nBits,
+ DataEnum eType
+) :
+
+ SvTreeListBox( pParent, nBits ),
+
+ pMgr ( NULL ),
+ pDlg ( pArgDlg ),
+ eViewType ( eType )
+
+/* [Beschreibung]
+
+ Konstruktor SfxOrganizeListBox
+
+*/
+
+{
+ SetDragDropMode(
+ SV_DRAGDROP_CTRL_MOVE | SV_DRAGDROP_CTRL_COPY |
+ SV_DRAGDROP_APP_MOVE | SV_DRAGDROP_APP_COPY | SV_DRAGDROP_APP_DROP );
+ SetEntryHeight( 16 );
+ SetSelectionMode( SINGLE_SELECTION );
+ GetModel()->SetSortMode( SortNone );
+
+ EnableContextMenuHandling();
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeListBox_Impl, OnAsyncExecuteDrop, ExecuteDropEvent*, pEvent )
+{
+ DBG_ASSERT( pEvent, "invalid DropEvent" );
+ if ( pEvent )
+ {
+ SvLBox* pSourceView = GetSourceView();
+ if ( !pSourceView )
+ pSourceView = pDlg->pSourceView;
+ pDlg->bExecDropFinished = false;
+ // if a template can not be moved it should be copied
+ if ( pEvent->mnAction == DND_ACTION_MOVE )
+ pEvent->mnAction = DND_ACTION_COPYMOVE;
+ pDlg->nDropAction = SvTreeListBox::ExecuteDrop( *pEvent, pSourceView );
+ delete pEvent;
+ pDlg->pSourceView = NULL;
+ pDlg->pTargetEntry = NULL;
+ pDlg->bExecDropFinished = true;
+ if ( pDlg->pFinishedBox )
+ {
+ pDlg->pFinishedBox->DragFinished( pDlg->nDropAction );
+ pDlg->pFinishedBox = NULL;
+ }
+ }
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxOrganizeListBox_Impl::Reset()
+
+/* [Beschreibung]
+
+ Einf"ugen der Elemente in die ListBox
+
+*/
+
+{
+ DBG_ASSERT( pMgr != 0, "kein Manager" );
+ // Inhalte l"oschen
+ SetUpdateMode(FALSE);
+ Clear();
+ if ( VIEW_TEMPLATES == eViewType )
+ {
+ const USHORT nCount = pMgr->GetTemplates()->GetRegionCount();
+ for ( USHORT i = 0; i < nCount; ++i )
+ InsertEntryByBmpType( pMgr->GetTemplates()->GetFullRegionName(i), BMPTYPE_FOLDER, 0, TRUE );
+ }
+ else
+ {
+ const SfxObjectList& rList = pMgr->GetObjectList();
+ const USHORT nCount = rList.Count();
+ for ( USHORT i = 0; i < nCount; ++i )
+ InsertEntryByBmpType( rList.GetBaseName(i), BMPTYPE_DOC, 0, TRUE );
+
+ }
+ SetUpdateMode(TRUE);
+ Invalidate();
+ Update();
+}
+
+//-------------------------------------------------------------------------
+
+const Image &SfxOrganizeListBox_Impl::GetClosedBmp(USHORT nLevel) const
+
+/* [Beschreibung]
+
+ Zugriff auf die Bitmap f"ur einen geschlossenen Eintrag
+ der jeweiligen Ebene
+
+ [Parameter]
+
+ USHORT nLevel Angabe der Ebene, 2 Ebenen sind erlaubt
+
+ [Returnwert]
+
+ const Image & das Image auf der Ebenen nLevel
+
+*/
+
+{
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+ const Image* pRet = NULL;
+
+ switch( nLevel )
+ {
+ default: DBG_ERROR( "Bitmaps ueberindiziert" );
+
+ case 0: pRet = bHC? &aClosedFolderBmpHC : &aClosedFolderBmp; break;
+ case 1: pRet = bHC? &aClosedDocBmpHC : &aClosedDocBmp; break;
+ }
+
+ return *pRet;
+}
+
+//-------------------------------------------------------------------------
+
+const Image &SfxOrganizeListBox_Impl::GetOpenedBmp(USHORT nLevel) const
+
+/* [Beschreibung]
+
+ Zugriff auf die Bitmap f"ur einen ge"offneten Eintrag
+ der jeweiligen Ebene
+
+ [Parameter]
+
+ USHORT nLevel Angabe der Ebene, 2 Ebenen sind erlaubt
+
+ [Returnwert]
+
+ const Image & das Image auf der Ebenen nLevel
+
+*/
+
+{
+ BOOL bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+ const Image* pRet = NULL;
+
+ switch( nLevel )
+ {
+ case 0:
+ pRet = bHC ? &aOpenedFolderBmpHC : &aOpenedFolderBmp; break;
+ case 1:
+ pRet = bHC ? &aOpenedDocBmpHC : &aOpenedDocBmp; break;
+ default:
+ pRet = bHC ? &aClosedFolderBmpHC : &aClosedFolderBmp; break;
+ }
+
+ return *pRet;
+}
+
+//-------------------------------------------------------------------------
+
+PopupMenu* SfxOrganizeListBox_Impl::CreateContextMenu()
+{
+ return new PopupMenu( *( pDlg->aEditBtn.GetPopupMenu() ) );
+}
+
+//-------------------------------------------------------------------------
+
+String SfxOrganizeDlg_Impl::GetPath_Impl( BOOL bOpen, const String& rFileName )
+
+/* [Beschreibung]
+
+ Pfad per FileDialog erfragen, f"ur Import / Export von
+ Dokumentvorlagen
+
+ [Parameter]
+
+ BOOL bOpen Flag: "Offnen / Speichern
+ const String& rFileName aktueller Dateiname als Vorschlag
+
+ [R"uckgabewert] Dateiname mit Pfad oder Leerstring, wenn
+ der Benutzer 'Abbrechen' gedr"uckt hat
+*/
+
+{
+ String aPath;
+ m_sExtension4Save = DEFINE_CONST_UNICODE( "vor" );
+ sal_Int16 nDialogType = bOpen
+ ? com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
+ : com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE;
+ if ( pFileDlg )
+ delete pFileDlg;
+ pFileDlg = new sfx2::FileDialogHelper( nDialogType, 0L );
+
+ // add "All" filter
+ pFileDlg->AddFilter( String( SfxResId( STR_SFX_FILTERNAME_ALL ) ),
+ DEFINE_CONST_UNICODE( FILEDIALOG_FILTER_ALL ) );
+ // add template filter
+ String sFilterName( SfxResId( STR_TEMPLATE_FILTER ) );
+ String sFilterExt;
+ // add filters of modules which are installed
+ SvtModuleOptions aModuleOpt;
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ sFilterExt += DEFINE_CONST_UNICODE( "*.ott;*.stw;*.oth" );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ {
+ if ( sFilterExt.Len() > 0 )
+ sFilterExt += ';';
+ sFilterExt += DEFINE_CONST_UNICODE( "*.ots;*.stc" );
+ }
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ {
+ if ( sFilterExt.Len() > 0 )
+ sFilterExt += ';';
+ sFilterExt += DEFINE_CONST_UNICODE( "*.otp;*.sti" );
+ }
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ {
+ if ( sFilterExt.Len() > 0 )
+ sFilterExt += ';';
+ sFilterExt += DEFINE_CONST_UNICODE( "*.otg;*.std" );
+ }
+ if ( sFilterExt.Len() > 0 )
+ sFilterExt += ';';
+ sFilterExt += DEFINE_CONST_UNICODE( "*.vor" );
+
+ sFilterName += DEFINE_CONST_UNICODE( " (" );
+ sFilterName += sFilterExt;
+ sFilterName += ')';
+ pFileDlg->AddFilter( sFilterName, sFilterExt );
+ pFileDlg->SetCurrentFilter( sFilterName );
+
+ if ( aLastDir.Len() || rFileName.Len() )
+ {
+ INetURLObject aObj;
+ if ( aLastDir.Len() )
+ {
+ aObj.SetURL( aLastDir );
+ if ( rFileName.Len() )
+ aObj.insertName( rFileName );
+ }
+ else
+ aObj.SetURL( rFileName );
+
+ if ( aObj.hasExtension() )
+ {
+ m_sExtension4Save = aObj.getExtension(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ aObj.removeExtension();
+ }
+
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ pFileDlg->SetDisplayDirectory( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
+ }
+
+ pFileDlg->StartExecuteModal( LINK( this, SfxOrganizeDlg_Impl, ImportHdl ) );
+
+ return aPath;
+}
+
+//-------------------------------------------------------------------------
+
+::com::sun::star::uno::Sequence< ::rtl::OUString >
+ SfxOrganizeDlg_Impl::GetPaths_Impl( const String& rFileName )
+
+/* [Description]
+
+ Query plural paths by FileDialog, for Import / Export from document
+ templates
+
+ [Parameter]
+
+ const String& rFileName The default file name when dialog executes
+
+ [Return value] Empty sequence when users have clicked
+ 'Cancel', a sequence just containing one
+ file name with path when they have
+ choosed one file or a sequence containing
+ path and file names without path
+*/
+
+{
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > aPaths;
+ m_sExtension4Save = DEFINE_CONST_UNICODE( "vor" );
+ if ( pFileDlg )
+ delete pFileDlg;
+ pFileDlg = new sfx2::FileDialogHelper(
+ com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, SFXWB_MULTISELECTION );
+
+ // add "All" filter
+ pFileDlg->AddFilter( String( SfxResId( STR_SFX_FILTERNAME_ALL ) ),
+ DEFINE_CONST_UNICODE( FILEDIALOG_FILTER_ALL ) );
+
+ // add template filter
+ String sFilterName( SfxResId( STR_TEMPLATE_FILTER ) );
+ String sFilterExt;
+ // add filters of modules which are installed
+ SvtModuleOptions aModuleOpt;
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ sFilterExt += DEFINE_CONST_UNICODE( "*.ott;*.stw;*.oth" );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ {
+ if ( sFilterExt.Len() > 0 )
+ sFilterExt += ';';
+ sFilterExt += DEFINE_CONST_UNICODE( "*.ots;*.stc" );
+ }
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ {
+ if ( sFilterExt.Len() > 0 )
+ sFilterExt += ';';
+ sFilterExt += DEFINE_CONST_UNICODE( "*.otp;*.sti" );
+ }
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ {
+ if ( sFilterExt.Len() > 0 )
+ sFilterExt += ';';
+ sFilterExt += DEFINE_CONST_UNICODE( "*.otg;*.std" );
+ }
+ if ( sFilterExt.Len() > 0 )
+ sFilterExt += ';';
+ sFilterExt += DEFINE_CONST_UNICODE( "*.vor" );
+
+ sFilterName += DEFINE_CONST_UNICODE( " (" );
+ sFilterName += sFilterExt;
+ sFilterName += ')';
+ pFileDlg->AddFilter( sFilterName, sFilterExt );
+ pFileDlg->SetCurrentFilter( sFilterName );
+
+ if ( aLastDir.Len() || rFileName.Len() )
+ {
+ INetURLObject aObj;
+ if ( aLastDir.Len() )
+ {
+ aObj.SetURL( aLastDir );
+ if ( rFileName.Len() )
+ aObj.insertName( rFileName );
+ }
+ else
+ aObj.SetURL( rFileName );
+
+ if ( aObj.hasExtension() )
+ {
+ m_sExtension4Save = aObj.getExtension(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ aObj.removeExtension();
+ }
+
+ DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
+ pFileDlg->SetDisplayDirectory( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
+ }
+
+ pFileDlg->StartExecuteModal( LINK( this, SfxOrganizeDlg_Impl, ExportHdl ) );
+
+ return aPaths;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxOrganizeDlg_Impl::DontDelete_Impl( SvLBoxEntry* pEntry )
+{
+ USHORT nDepth = pFocusBox->GetModel()->GetDepth(pEntry);
+ if(SfxOrganizeListBox_Impl::VIEW_FILES ==
+ pFocusBox->GetViewType())
+ nDepth++;
+ if( (nDepth > 2 && !pEntry->GetUserData()) ||
+ //Delete ueber GetContent verboten
+ nDepth==2 || //Vorlage / Konfigurtionsrubrik nicht loeshcen
+ (nDepth==1 && SfxOrganizeListBox_Impl::VIEW_FILES ==
+ pFocusBox->GetViewType()) || //Files nicht loeschen
+ (0 == nDepth && pFocusBox->GetLevelCount_Impl(0) < 2))
+ //Mindestens eine Vorlage behalten
+ {
+ return TRUE;
+ }
+
+ USHORT nRegion = 0, nIndex = 0;
+ GetIndices_Impl( pFocusBox, pEntry, nRegion, nIndex );
+ const SfxDocumentTemplates* pTemplates = aMgr.GetTemplates();
+ if ( !pTemplates || !pTemplates->HasUserContents( nRegion, nIndex ) )
+ return TRUE;
+
+ return FALSE;
+}
+
+SvStringsDtor* SfxOrganizeDlg_Impl::GetAllFactoryURLs_Impl( ) const
+{
+ SvtModuleOptions aModOpt;
+ const ::com::sun::star::uno::Sequence < ::rtl::OUString >& aServiceNames = aModOpt.GetAllServiceNames() ;
+ SvStringsDtor* pList = new SvStringsDtor;
+ sal_Int32 nCount = aServiceNames.getLength();
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ if ( SfxObjectFactory::GetStandardTemplate( aServiceNames[i] ).Len() > 0 )
+ {
+ SvtModuleOptions::EFactory eFac = SvtModuleOptions::E_WRITER;
+ SvtModuleOptions::ClassifyFactoryByName( aServiceNames[i], eFac );
+ String* pURL = new String( aModOpt.GetFactoryEmptyDocumentURL( eFac ) );
+ pList->Insert( pURL, pList->Count() );
+ }
+ }
+
+ return pList;
+}
+
+sal_Bool SfxOrganizeDlg_Impl::GetServiceName_Impl( String& rName, String& rFileURL ) const
+{
+ sal_Bool bRet = sal_False;
+ const SfxDocumentTemplates* pTemplates = aMgr.GetTemplates();
+ SvLBoxEntry* pEntry = pFocusBox ? pFocusBox->FirstSelected() : NULL;
+ USHORT nRegion = 0, nIndex = 0;
+ GetIndices_Impl( pFocusBox, pEntry, nRegion, nIndex );
+ rFileURL = pTemplates->GetPath( nRegion, nIndex );
+ if ( rFileURL.Len() > 0 )
+ {
+ try
+ {
+ uno::Reference< embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
+ rFileURL,
+ embed::ElementModes::READ );
+ ULONG nFormat = SotStorage::GetFormatID( xStorage );
+ const SfxFilter* pFilter =
+ SFX_APP()->GetFilterMatcher().GetFilter4ClipBoardId( nFormat );
+ if ( pFilter )
+ {
+ rName = pFilter->GetServiceName();
+ bRet = TRUE;
+ }
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ return bRet;
+}
+
+long SfxOrganizeDlg_Impl::Dispatch_Impl( USHORT nId, Menu* _pMenu )
+
+/* [Beschreibung]
+
+ Verarbeiten der Events aus MenuButton oder Accelerator
+
+ [Parameter]
+
+ USHORT nId ID des Events
+
+ [R"uckgabewert] 1: Event wurde verarbeitet,
+ 0: Event wurde nicht verarbeitet (SV-Menu)
+
+*/
+
+{
+ SuspendAccel aTmp(&aEditAcc);
+ SvLBoxEntry *pEntry = pFocusBox? pFocusBox->FirstSelected(): 0;
+ sal_Bool bHandled = sal_True;
+ switch(nId)
+ {
+ case ID_NEW:
+ {
+ if(!pEntry)
+ return 1;
+ if(pFocusBox->GetViewType() == SfxOrganizeListBox_Impl::VIEW_TEMPLATES)
+ {
+ if(0 == pFocusBox->GetModel()->GetDepth(pEntry))
+ {
+ const String aNoName( SfxResId(STR_NONAME) );
+ SvLBoxEntry* pParent = pFocusBox->GetParent(pEntry);
+ String aName(aNoName);
+ USHORT n = 1;
+ while(!pFocusBox->IsUniqName_Impl(aName, pParent))
+ {
+ aName = aNoName;
+ aName += String::CreateFromInt32( n++ );
+ }
+ aMgr.InsertDir( pFocusBox, aName,
+ (USHORT)pFocusBox->GetModel()->GetRelPos(pEntry)+1);
+ }
+ }
+ break;
+ }
+
+ case ID_DELETE:
+ {
+ if(!pEntry || DontDelete_Impl(pEntry))
+ return 1;
+ const USHORT nDepth = pFocusBox->GetModel()->GetDepth(pEntry);
+ if(nDepth < 2)
+ {
+ if(0 == nDepth && pFocusBox->GetLevelCount_Impl(0) < 2) return 1;
+ if(SfxOrganizeListBox_Impl::VIEW_TEMPLATES == pFocusBox->GetViewType())
+ {
+ USHORT nResId = nDepth? STR_DELETE_TEMPLATE :
+ STR_DELETE_REGION;
+ if( !QueryDelete_Impl(
+ pDialog, nResId, pFocusBox->GetEntryText(pEntry)))
+ return 1;
+ if ( STR_DELETE_REGION == nResId &&
+ pFocusBox->GetChildCount(pEntry))
+ {
+ QueryBox aQBox(pDialog, SfxResId(MSG_REGION_NOTEMPTY));
+ if(RET_NO == aQBox.Execute())
+ return 1;
+ }
+ USHORT nRegion = 0, nIndex = 0;
+ GetIndices_Impl(pFocusBox, pEntry, nRegion, nIndex);
+
+ USHORT nDeleteInd = ( STR_DELETE_REGION == nResId? USHRT_MAX: nIndex );
+ if ( !aMgr.Delete( pFocusBox, nRegion, nDeleteInd ) )
+ ErrorDelete_Impl(
+ pDialog,
+ pFocusBox->GetEntryText(pEntry),
+ ( nDeleteInd == USHRT_MAX && pFocusBox->GetChildCount(pEntry) ) );
+ }
+ }
+ // Inhaltsformen
+ else if(nDepth + pFocusBox->GetDocLevel() >= 2)
+ {
+ if(!QueryDelete_Impl(pDialog, STR_DELETE_TEMPLATE, pFocusBox->GetEntryText(pEntry)))
+ return 1;
+ Path aPath(pFocusBox, pEntry);
+ SfxObjectShellRef aRef = pFocusBox->GetObjectShell(aPath);
+ if(aRef.Is() &&
+ aRef->Remove(aPath[1+pFocusBox->GetDocLevel()],
+ aPath[2+pFocusBox->GetDocLevel()],
+ aPath[3+pFocusBox->GetDocLevel()]))
+ pFocusBox->GetModel()->Remove(pEntry);
+ else
+ ErrorDelete_Impl(pDialog, pFocusBox->GetEntryText(pEntry), sal_False );
+ }
+ break;
+ }
+
+ case ID_EDIT:
+ {
+ if(!pEntry)
+ return 1;
+ USHORT nRegion = 0, nIndex = 0;
+ GetIndices_Impl( pFocusBox, pEntry, nRegion, nIndex );
+ const SfxStringItem aName( SID_FILE_NAME, aMgr.GetTemplates()->GetPath( nRegion, nIndex ) );
+ const SfxStringItem aLongName( SID_FILE_LONGNAME, pFocusBox->GetEntryText( pEntry ) );
+ const SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE( "private:user" ) );
+ const SfxStringItem aTargetName( SID_TARGETNAME, DEFINE_CONST_UNICODE( "_default" ) );
+ const SfxBoolItem aTemplateIndicator( SID_TEMPLATE, sal_False );
+
+ SFX_APP()->GetAppDispatcher_Impl()->Execute( SID_OPENTEMPLATE, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
+ &aName, &aLongName, &aReferer, &aTargetName, &aTemplateIndicator, 0L );
+ pDialog->EndDialog( RET_EDIT_STYLE );
+ break;
+ }
+
+ case ID_COPY_FROM:
+ {
+ if ( !pEntry )
+ return 1;
+ m_nRegion = 0;
+ m_nIndex = 0;
+ GetIndices_Impl( pFocusBox, pEntry, m_nRegion, m_nIndex );
+ GetPaths_Impl( String() );
+ break;
+ }
+
+ case ID_COPY_TO:
+ {
+ if ( !pEntry )
+ return 1;
+ m_nRegion = 0;
+ m_nIndex = 0;
+ GetIndices_Impl( pFocusBox, pEntry, m_nRegion, m_nIndex );
+ GetPath_Impl( FALSE, aMgr.GetTemplates()->GetFileName( m_nRegion, m_nIndex ) );
+ break;
+ }
+
+ case ID_RESCAN:
+ if ( !aMgr.Rescan() )
+ ErrorBox( pDialog, SfxResId( MSG_ERROR_RESCAN ) ).Execute();
+ if ( SfxOrganizeListBox_Impl::VIEW_TEMPLATES == aLeftLb.GetViewType() )
+ aLeftLb.Reset();
+ if ( SfxOrganizeListBox_Impl::VIEW_TEMPLATES == aRightLb.GetViewType() )
+ aRightLb.Reset();
+ break;
+
+ case ID_PRINT:
+ {
+ if ( !pEntry )
+ return 1;
+ Path aPath( pFocusBox, pEntry );
+ SfxObjectShellRef aRef = pFocusBox->GetObjectShell( aPath );
+ if ( aRef.Is() )
+ {
+ const USHORT nDocLevel = pFocusBox->GetDocLevel();
+ if ( !pPrt )
+ pPrt = new Printer;
+ SvLBoxEntry *pDocEntry = pEntry;
+ while ( pFocusBox->GetModel()->GetDepth( pDocEntry ) > nDocLevel )
+ pDocEntry = pFocusBox->GetParent( pDocEntry );
+ const String aName(pFocusBox->GetEntryText(pDocEntry));
+ if ( !aRef->Print( *pPrt, aPath[1+nDocLevel],
+ aPath[2+nDocLevel], aPath[3+nDocLevel], &aName ) )
+ ErrorBox( pDialog, SfxResId( MSG_PRINT_ERROR ) ).Execute();
+ }
+ break;
+ }
+
+ case ID_PRINTER_SETUP:
+ {
+ PrinterSetupDialog* pDlg = new PrinterSetupDialog( pDialog );
+ if ( !pPrt )
+ pPrt = new Printer;
+ pDlg->SetPrinter( pPrt );
+ pDlg->Execute();
+ delete pDlg;
+ break;
+ }
+
+ case ID_DEFAULT_TEMPLATE:
+ {
+ String aServiceName, aFileURL;
+ if ( GetServiceName_Impl( aServiceName, aFileURL ) )
+ SfxObjectFactory::SetStandardTemplate( aServiceName, aFileURL );
+ break;
+ }
+
+ default:
+ bHandled = sal_False;
+ }
+
+ if ( !bHandled && ( nId > ID_RESET_DEFAULT_TEMPLATE || nId <= ID_RESET_DEFAULT_TEMPLATE_END ) )
+ {
+ Menu* pSubMenu = _pMenu ? _pMenu : aEditBtn.GetPopupMenu()->GetPopupMenu( ID_RESET_DEFAULT_TEMPLATE );
+ if ( pSubMenu )
+ {
+ String aServiceName = SfxObjectShell::GetServiceNameFromFactory( pSubMenu->GetItemCommand( nId ) );
+ SfxObjectFactory::SetStandardTemplate( aServiceName, String() );
+ bHandled = sal_True;
+ }
+ }
+
+ return bHandled ? 1 : 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( SfxOrganizeDlg_Impl, MenuSelect_Impl, Menu *, pMenu )
+
+/* [Beschreibung]
+
+ SelectHandler des Men"us des Men"ubuttons (SV)
+
+ [Parameter]
+
+ MenuButton *pBtn der das Event ausl"osende Button
+
+ [R"uckgabewert] 1: Event wurde verarbeitet,
+ 0: Event wurde nicht verarbeitet (SV-Menu)
+
+*/
+{
+ return Dispatch_Impl( pMenu->GetCurItemId(), pMenu );
+}
+IMPL_LINK_INLINE_END( SfxOrganizeDlg_Impl, MenuSelect_Impl, Menu *, pMenu )
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, AccelSelect_Impl, Accelerator *, pAccel )
+
+/* [Beschreibung]
+
+ SelectHandler des Accelerators (SV)
+
+ [Parameter]
+
+ Accelerator *pAccel der das Event ausl"osende Accelerator
+
+ [R"uckgabewert] 1: Event wurde verarbeitet,
+ 0: Event wurde nicht verarbeitet (SV)
+
+*/
+
+{
+ SvLBoxEntry* pEntry = pFocusBox && pFocusBox->GetSelectionCount() ?
+ pFocusBox->FirstSelected() : NULL ;
+ return pEntry && ( pAccel->GetCurItemId() == ID_NEW || !DontDelete_Impl( pEntry ) ) ?
+ Dispatch_Impl( pAccel->GetCurItemId(), NULL ) : 0;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxOrganizeDlg_Impl::OkHdl(Button *pButton)
+{
+ if(pFocusBox && pFocusBox->IsEditingActive())
+ pFocusBox->EndEditing(FALSE);
+ pButton->Click();
+}
+
+
+
+IMPL_LINK( SfxOrganizeDlg_Impl, MenuActivate_Impl, Menu *, pMenu )
+
+/* [Beschreibung]
+
+ ActivateHandler des Men"us des Men"ubuttons (SV)
+
+ [Parameter]
+
+ Menu *pMenu das das Event ausl"osende Men"u
+
+ [R"uckgabewert] 1: Event wurde verarbeitet,
+ 0: Event wurde nicht verarbeitet (SV-Menu)
+
+*/
+{
+ if ( pFocusBox && pFocusBox->IsEditingActive() )
+ pFocusBox->EndEditing( FALSE );
+ BOOL bEnable = ( pFocusBox && pFocusBox->GetSelectionCount() );
+ SvLBoxEntry* pEntry = bEnable ? pFocusBox->FirstSelected() : NULL;
+ const USHORT nDepth =
+ ( bEnable && pFocusBox->GetSelectionCount() ) ? pFocusBox->GetModel()->GetDepth( pEntry ) : 0;
+ const USHORT nDocLevel = bEnable ? pFocusBox->GetDocLevel() : 0;
+ int eVT = pFocusBox ? pFocusBox->GetViewType() : 0;
+ // nur Vorlagen anlegen
+ pMenu->EnableItem( ID_NEW, bEnable && 0 == nDepth && SfxOrganizeListBox_Impl::VIEW_TEMPLATES == eVT );
+ // Vorlagen: Loeschen Ebene 0,1,3ff
+ // ein Bereich mu"s mindestens erhalten bleiben
+ // Dateien : Loeschen Ebene > 2
+
+ pMenu->EnableItem( ID_DELETE, bEnable && !DontDelete_Impl( pEntry ) );
+ pMenu->EnableItem( ID_EDIT,
+ bEnable && eVT == SfxOrganizeListBox_Impl::VIEW_TEMPLATES && nDepth == nDocLevel
+ && !DontDelete_Impl( pEntry ) );
+ pMenu->EnableItem( ID_COPY_FROM,
+ bEnable && eVT == SfxOrganizeListBox_Impl::VIEW_TEMPLATES &&
+ ( nDepth == nDocLevel || nDepth == nDocLevel - 1 ) );
+ pMenu->EnableItem( ID_COPY_TO,
+ bEnable && eVT == SfxOrganizeListBox_Impl::VIEW_TEMPLATES &&
+ nDepth == nDocLevel );
+ pMenu->EnableItem( ID_RESCAN,
+ SfxOrganizeListBox_Impl::VIEW_TEMPLATES == aRightLb.GetViewType() ||
+ SfxOrganizeListBox_Impl::VIEW_TEMPLATES == aLeftLb.GetViewType() );
+ BOOL bPrint = bEnable && nDepth > pFocusBox->GetDocLevel();
+ if ( bPrint && pPrt )
+ bPrint = !pPrt->IsPrinting() && !pPrt->IsJobActive();
+ if ( bPrint && bEnable )
+ {
+ // only styles printable
+ Path aPath( pFocusBox, pFocusBox->FirstSelected() );
+ USHORT nIndex = aPath[ nDocLevel + 1 ];
+ bPrint = ( nIndex == CONTENT_STYLE );
+ }
+ pMenu->EnableItem( ID_PRINT, bPrint );
+
+ if ( bEnable && eVT == SfxOrganizeListBox_Impl::VIEW_TEMPLATES && nDepth == nDocLevel )
+ {
+ String aFactoryURL, aFileURL;
+ bEnable = GetServiceName_Impl( aFactoryURL, aFileURL );
+ }
+ else if ( bEnable )
+ bEnable = FALSE;
+ pMenu->EnableItem( ID_DEFAULT_TEMPLATE, bEnable );
+
+ bEnable = sal_True;
+ SvStringsDtor* pList = GetAllFactoryURLs_Impl();
+ USHORT nCount = pList->Count();
+ if ( nCount > 0 )
+ {
+ PopupMenu* pSubMenu = new PopupMenu;
+ USHORT nItemId = ID_RESET_DEFAULT_TEMPLATE + 1;
+ for ( USHORT i = 0; i < nCount; ++i )
+ {
+ String aObjFacURL( *pList->GetObject(i) );
+ String aTitle = SvFileInformationManager::GetDescription(
+ INetURLObject(aObjFacURL) );
+ pSubMenu->InsertItem( nItemId, aTitle,
+ SvFileInformationManager::GetImage(INetURLObject(aObjFacURL)) );
+ pSubMenu->SetItemCommand( nItemId++, aObjFacURL );
+ DBG_ASSERT( nItemId <= ID_RESET_DEFAULT_TEMPLATE_END, "menu item id overflow" );
+ }
+ pMenu->SetPopupMenu( ID_RESET_DEFAULT_TEMPLATE, pSubMenu );
+ }
+ else
+ bEnable = sal_False;
+
+ delete pList;
+ pMenu->EnableItem( ID_RESET_DEFAULT_TEMPLATE, bEnable );
+
+ return 1;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, GetFocus_Impl, SfxOrganizeListBox_Impl *, pBox )
+
+/* [Beschreibung]
+
+ GetFocus-Handler, wird aus den Select-Handler der Listboxen
+ gerufen.
+ Wird verwendet, im die Listbox, die den Focus besitzt sowie
+ deren Zustand zu ermitteln.
+
+ [Parameter]
+
+ SfxOrganizeListBox *pBox die rufende Box
+
+*/
+
+{
+ if(pFocusBox && pFocusBox != pBox)
+ pFocusBox->SelectAll(FALSE);
+ pFocusBox = pBox;
+ aFilesBtn.Enable( SfxOrganizeListBox_Impl::VIEW_FILES ==
+ pFocusBox->GetViewType() );
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, LeftListBoxSelect_Impl, ListBox *, pBox )
+
+/* [Beschreibung]
+
+ Select-Handler, wird aus den Select-Handler der Listboxen
+ gerufen.
+ Wenn sich der Modus der Boxen (Dokumentsicht, Dokumentvorlagensicht)
+ unterscheiden, werden die Models getrennt; andernfalls zusammengefa"st.
+
+ [Parameter]
+
+ ListBox *pBox die rufende Box
+
+*/
+{
+ const SfxOrganizeListBox_Impl::DataEnum
+ eViewType = pBox->GetSelectEntryPos() == 0 ?
+ SfxOrganizeListBox_Impl::VIEW_TEMPLATES : SfxOrganizeListBox_Impl::VIEW_FILES;
+ if(eViewType!= aLeftLb.GetViewType()) {
+ aLeftLb.SetViewType(eViewType);
+ if(aRightLb.GetViewType() == eViewType)
+ aLeftLb.SetModel(aRightLb.GetModel());
+ else {
+ // Models trennen
+ aLeftLb.DisconnectFromModel();
+ aLeftLb.Reset();
+ }
+ }
+ GetFocus_Impl(&aLeftLb);
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, RightListBoxSelect_Impl, ListBox *, pBox )
+
+/* [Beschreibung]
+
+ Select-Handler, wird aus den Select-Handler der Listboxen
+ gerufen.
+ Wenn sich der Modus der Boxen (Dokumentsicht, Dokumentvorlagensicht)
+ unterscheiden, werden die Models getrennt; andernfalls zusammengefa"st.
+
+ [Parameter]
+
+ ListBox *pBox die rufende Box
+
+*/
+{
+ const SfxOrganizeListBox_Impl::DataEnum eViewType =
+ pBox->GetSelectEntryPos() == 0 ?
+ SfxOrganizeListBox_Impl::VIEW_TEMPLATES : SfxOrganizeListBox_Impl::VIEW_FILES;
+ if(eViewType!= aRightLb.GetViewType())
+ {
+ aRightLb.SetViewType(eViewType);
+ if(aLeftLb.GetViewType() == eViewType)
+ aRightLb.SetModel(aLeftLb.GetModel());
+ else
+ {
+ // Models trennen
+ aRightLb.DisconnectFromModel();
+ aRightLb.Reset();
+ }
+ }
+ aRightLb.GrabFocus();
+ GetFocus_Impl(&aRightLb);
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, OnAddressTemplateClicked, Button *, pButton )
+{
+ (void)pButton; //unused
+ svt::AddressBookSourceDialog aDialog(pDialog, ::comphelper::getProcessServiceFactory());
+ aDialog.Execute();
+ return 0L;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, AddFiles_Impl, Button *, pButton )
+
+/* [Beschreibung]
+
+ Handler des Buttons f"ur das Hinzuf"ugen von Dateien per Dialog.
+
+ [Parameter]
+
+ Button * der Button, der dieses Events ausgel"ost hat.
+
+*/
+{
+ (void)pButton; //unused
+ if ( pFileDlg )
+ delete pFileDlg;
+ pFileDlg = new sfx2::FileDialogHelper( WB_OPEN, String() );
+
+ // add config and basic filter
+ static String sOpenBracket( DEFINE_CONST_UNICODE( " (" ) );
+ static String sCloseBracket( DEFINE_CONST_UNICODE( ")" ) );
+ static String sConfigExt( DEFINE_CONST_UNICODE( "*.cfg" ) );
+ static String sBasicExt( DEFINE_CONST_UNICODE( "*.sbl" ) );
+
+ String sFilterName( SfxResId( RID_STR_FILTCONFIG ) );
+ sFilterName += sOpenBracket;
+ sFilterName += sConfigExt;
+ sFilterName += sCloseBracket;
+ pFileDlg->AddFilter( sFilterName, sConfigExt );
+
+ sFilterName = String( SfxResId( RID_STR_FILTBASIC ) );
+ sFilterName += sOpenBracket;
+ sFilterName += sBasicExt;
+ sFilterName += sCloseBracket;
+ pFileDlg->AddFilter( sFilterName, sBasicExt );
+
+ // set "All" filter as current
+ pFileDlg->SetCurrentFilter( String( SfxResId( STR_SFX_FILTERNAME_ALL ) ) );
+
+ if ( aLastDir.Len() )
+ pFileDlg->SetDisplayDirectory( aLastDir );
+
+ pFileDlg->StartExecuteModal( LINK( this, SfxOrganizeDlg_Impl, AddFilesHdl ) );
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, ImportHdl, sfx2::FileDialogHelper *, EMPTYARG )
+{
+ DBG_ASSERT( pFileDlg, "SfxOrganizeDlg_Impl::ImportHdl(): no file dialog" );
+
+ if ( ERRCODE_NONE == pFileDlg->GetError() )
+ {
+ String aPath = pFileDlg->GetPath();
+ INetURLObject aObj( aPath );
+
+ // we want to keep the original extension when exporting, the file open dialog
+ // always sets the extension to *.vor
+ if ( pFileDlg->GetDialogType() ==
+ com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE )
+ {
+ if ( aObj.hasExtension() )
+ aObj.removeExtension();
+
+ aObj.setExtension( m_sExtension4Save );
+ aPath = aObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ }
+
+ aObj.removeSegment();
+ aLastDir = aObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+
+ if ( aPath.Len() && !aMgr.CopyTo( m_nRegion, m_nIndex, aPath ) )
+ {
+ String aText( SfxResId( STR_ERROR_COPY_TEMPLATE ) );
+ aText.SearchAndReplaceAscii( "$1", aPath );
+ ErrorBox( pDialog, WB_OK, aText ).Execute();
+ }
+ }
+
+ return 0L;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, ExportHdl, sfx2::FileDialogHelper *, EMPTYARG )
+{
+ DBG_ASSERT( pFileDlg, "SfxOrganizeDlg_Impl::ImportHdl(): no file dialog" );
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > aPaths;
+
+ if ( ERRCODE_NONE == pFileDlg->GetError() )
+ {
+ aPaths = pFileDlg->GetMPath();
+ sal_Int32 lastCount = aPaths.getLength() - 1;
+ INetURLObject aObj( aPaths.getArray()[ lastCount ] );
+
+ aObj.removeSegment();
+ aLastDir = aObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ }
+
+ sal_Int32 nCount = aPaths.getLength();
+ if ( 1 == nCount )
+ {
+ String aPath = String( aPaths.getArray()[0] );
+ if ( aPath.Len() && !aMgr.CopyFrom( pFocusBox, m_nRegion, m_nIndex, aPath ) )
+ {
+ String aText( SfxResId( STR_ERROR_COPY_TEMPLATE ) );
+ aText.SearchAndReplaceAscii( "$1", aPath );
+ ErrorBox( pDialog, WB_OK, aText ).Execute();
+ }
+ }
+ else if ( nCount > 1 )
+ {
+ INetURLObject aPathObj( aPaths[0] );
+ aPathObj.setFinalSlash();
+ for ( USHORT i = 1; i < nCount; ++i )
+ {
+ if ( 1 == i )
+ aPathObj.Append( aPaths[i] );
+ else
+ aPathObj.setName( aPaths[i] );
+ String aPath = aPathObj.GetMainURL( INetURLObject::NO_DECODE );
+ if ( aPath.Len() && !aMgr.CopyFrom( pFocusBox, m_nRegion, m_nIndex, aPath ) )
+ {
+ String aText( SfxResId( STR_ERROR_COPY_TEMPLATE ) );
+ aText.SearchAndReplaceAscii( "$1", aPath );
+ ErrorBox( pDialog, WB_OK, aText ).Execute();
+ }
+ }
+ }
+
+ return 0L;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxOrganizeDlg_Impl, AddFilesHdl, sfx2::FileDialogHelper *, EMPTYARG )
+{
+ if ( ERRCODE_NONE == pFileDlg->GetError() )
+ {
+ String aPath = pFileDlg->GetPath();
+ aMgr.InsertFile( pFocusBox, aPath );
+ INetURLObject aObj( aPath );
+ aObj.removeSegment();
+ aObj.setFinalSlash();
+ aLastDir = aObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ }
+
+ return 0L;
+}
+
+//-------------------------------------------------------------------------
+
+short SfxTemplateOrganizeDlg::Execute()
+
+/* [Beschreibung]
+
+ "Uberladene Execute- Methode; speichert gfs. "Anderungen an den
+ Dokumentvorlagen
+ (SV-Methode)
+
+*/
+
+{
+ const short nRet = ModalDialog::Execute();
+ if(RET_CANCEL != nRet)
+ {
+ pImp->aMgr.SaveAll(this);
+ SfxTemplateDialog* pTemplDlg = SFX_APP()->GetTemplateDialog();
+ if(pTemplDlg)
+ pTemplDlg->Update();
+ }
+ return nRet;
+}
+
+
+//-------------------------------------------------------------------------
+
+SfxTemplateOrganizeDlg::SfxTemplateOrganizeDlg(Window * pParent,
+ SfxDocumentTemplates *pTempl)
+: ModalDialog( pParent, SfxResId(DLG_ORGANIZE)),
+ pImp( new SfxOrganizeDlg_Impl(this, pTempl) )
+
+/* [Beschreibung]
+
+ Konstruktor
+
+*/
+{
+ FreeResource();
+}
+
+//-------------------------------------------------------------------------
+
+SfxTemplateOrganizeDlg::~SfxTemplateOrganizeDlg()
+{
+ GetpApp()->RemoveAccel(&pImp->aEditAcc);
+ delete pImp->pPrt;
+ delete pImp;
+}
+
diff --git a/sfx2/source/doc/docvor.hrc b/sfx2/source/doc/docvor.hrc
new file mode 100644
index 000000000000..842aa73fb8a3
--- /dev/null
+++ b/sfx2/source/doc/docvor.hrc
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define IMG_OPENED_FOLDER 2
+#define IMG_CLOSED_FOLDER 1
+#define IMG_OPENED_DOC 3
+#define IMG_CLOSED_DOC 4
+#define IMG_OPENED_FOLDER_HC 5
+#define IMG_CLOSED_FOLDER_HC 6
+#define IMG_OPENED_DOC_HC 7
+#define IMG_CLOSED_DOC_HC 8
+
+#define ACC_EDIT 1
+#define ID_COPY 201
+#define ID_MOVE 202
+#define ID_DELETE 203
+#define ID_EDIT 204
+#define ID_COPY_FROM 211
+#define ID_EXPORT 221
+#define ID_RESCAN 220
+#define ID_COPY_TO 210
+#define ID_NEW 200
+#define ID_PRINT 240
+#define ID_PRINTER_SETUP 2341
+
+#define ID_DEFAULT_TEMPLATE 300
+#define ID_RESET_DEFAULT_TEMPLATE 301
+//!!! dont use the ids from 302 to 350, we need them as dynamic ids
+#define ID_RESET_DEFAULT_TEMPLATE_END (ID_RESET_DEFAULT_TEMPLATE+49)
+
+#define LB_RIGHT_TYP 11
+#define LB_RIGHT 10
+#define LB_LEFT_TYP 2
+#define BTN_EDIT 105
+#define BTN_FILES 3
+#define BTN_ADDRESSTEMPLATE 4
+#define LB_LEFT 1
+#define FT_DEFAULT_TEMPLATE_LABEL 20
+#define FT_DEFAULT_TEMPLATE 21
+#define BTN_HELP 100
+
+#ifdef BTN_OK
+#undef BTN_OK
+#endif
+#define BTN_OK 100
+
+#ifdef BTN_CANCEL
+#undef BTN_CANCEL
+#endif
+#define BTN_CANCEL 101
+
diff --git a/sfx2/source/doc/docvor.src b/sfx2/source/doc/docvor.src
new file mode 100644
index 000000000000..2c9975de9bb8
--- /dev/null
+++ b/sfx2/source/doc/docvor.src
@@ -0,0 +1,315 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+#include <sfx2/sfx.hrc>
+#include "doc.hrc"
+#include "docvor.hrc"
+#include "helpid.hrc"
+// pragma ----------------------------------------------------------------
+
+// DLG_ORGANIZE ----------------------------------------------------------
+
+#define MASKCOLOR MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; }
+
+ModalDialog DLG_ORGANIZE
+{
+ HelpId = SID_ORGANIZER ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 271 , 162 ) ;
+ Text [ en-US ] = "Template Management" ;
+ Moveable = TRUE ;
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 205 , 43 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 205 , 6 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ /* ### ACHTUNG: Neuer Text in Resource? Schließen : Schlie˜en */
+ /* ### ACHTUNG: Neuer Text in Resource? Schließen : Schlie˜en */
+ Text [ en-US ] = "Close" ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ PushButton BTN_FILES
+ {
+ Pos = MAP_APPFONT ( 205 , 143 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ Text [ en-US ] = "~File..." ;
+ TabStop = TRUE ;
+ };
+ PushButton BTN_ADDRESSTEMPLATE
+ {
+ Pos = MAP_APPFONT ( 205 , 124 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ Text [ en-US ] = "~Address Book..." ;
+ };
+ ListBox LB_LEFT_TYP
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 144 ) ;
+ Size = MAP_APPFONT ( 94 , 55 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ CurPos = 0 ;
+ StringList [ en-US ] =
+ {
+ < "Templates" ; Default ; > ;
+ < "Documents" ; Default ; > ;
+ };
+ };
+ ListBox LB_RIGHT_TYP
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 103 , 144 ) ;
+ Size = MAP_APPFONT ( 94 , 55 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ CurPos = 1 ;
+ StringList [ en-US ] =
+ {
+ < "Templates" ; Default ; > ;
+ < "Documents" ; Default ; > ;
+ };
+ };
+ Control LB_LEFT
+ {
+ HelpId = HID_CTL_ORGANIZER_LEFT ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 3 , 6 ) ;
+ Size = MAP_APPFONT ( 94 , 132 ) ;
+ TabStop = TRUE ;
+ ClipChildren = TRUE ;
+ };
+ Control LB_RIGHT
+ {
+ HelpId = HID_CTL_ORGANIZER_RIGHT ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 103 , 6 ) ;
+ Size = MAP_APPFONT ( 94 , 132 ) ;
+ TabStop = TRUE ;
+ ClipChildren = TRUE ;
+ };
+ Accelerator ACC_EDIT
+ {
+ ItemList =
+ {
+ AcceleratorItem
+ {
+ Identifier = ID_NEW ;
+ Key = KeyCode
+ {
+ Code = KEY_INSERT ;
+ };
+ };
+ AcceleratorItem
+ {
+ Identifier = ID_DELETE ;
+ Key = KeyCode
+ {
+ Code = KEY_DELETE ;
+ };
+ };
+ };
+ };
+ MenuButton BTN_EDIT
+ {
+ Pos = MAP_APPFONT ( 205 , 23 ) ;
+ Size = MAP_APPFONT ( 60 , 14 ) ;
+ Text [ en-US ] = "Commands" ;
+ TabStop = TRUE ;
+ ButtonMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = ID_NEW ;
+ HelpId = HID_ORGANIZE_NEW ;
+ Text [ en-US ] = "~New" ;
+ AccelKey = KeyCode
+ {
+ Code = KEY_INSERT ;
+ };
+ };
+ MenuItem
+ {
+ Identifier = ID_DELETE ;
+ HelpId = HID_ORGANIZE_DELETE ;
+ /* ### ACHTUNG: Neuer Text in Resource? ~Löschen : ~L÷schen */
+ /* ### ACHTUNG: Neuer Text in Resource? ~Löschen : ~L÷schen */
+ Text [ en-US ] = "~Delete" ;
+ AccelKey = KeyCode
+ {
+ Code = KEY_DELETE ;
+ };
+ };
+ MenuItem
+ {
+ Identifier = ID_EDIT ;
+ HelpId = HID_ORGANIZE_EDIT ;
+ Text [ en-US ] = "~Edit" ;
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = ID_COPY_FROM ;
+ HelpId = HID_ORGANIZE_COPY_FROM ;
+ Text [ en-US ] = "Import Template..." ;
+ };
+ MenuItem
+ {
+ Identifier = ID_COPY_TO ;
+ HelpId = HID_ORGANIZE_COPY_TO ;
+ Text [ en-US ] = "Export Template..." ;
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = ID_PRINT ;
+ HelpId = HID_ORGANIZE_PRINT ;
+ Text [ en-US ] = "~Print" ;
+ };
+ MenuItem
+ {
+ Identifier = ID_PRINTER_SETUP ;
+ HelpId = HID_ORGANIZE_PRINTER_SETUP ;
+ Text [ en-US ] = "Printer Settings..." ;
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = ID_RESCAN ;
+ HelpId = HID_ORGANIZE_RESCAN ;
+ Text [ en-US ] = "Update" ;
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = ID_DEFAULT_TEMPLATE ;
+ HelpId = HID_ORGANIZE_STDTEMPLATE_ADD ;
+ Text [ en-US ] = "Set As Default Template" ;
+ };
+ MenuItem
+ {
+ Identifier = ID_RESET_DEFAULT_TEMPLATE ;
+ HelpId = HID_ORGANIZE_STDTEMPLATE_DEL ;
+ Text [ en-US ] = "Reset Default Template" ;
+ };
+ };
+ };
+ };
+ Image IMG_OPENED_FOLDER
+ {
+ MASKCOLOR ;
+ ImageBitmap = Bitmap { File = "folderop.bmp" ; } ;
+ };
+ Image IMG_CLOSED_FOLDER
+ {
+ MASKCOLOR ;
+ ImageBitmap = Bitmap { File = "foldercl.bmp" ; } ;
+ };
+ Image IMG_OPENED_DOC
+ {
+ MASKCOLOR ;
+ ImageBitmap = Bitmap { File = "doccl.bmp" ; } ;
+ };
+ Image IMG_CLOSED_DOC
+ {
+ MASKCOLOR ;
+ ImageBitmap = Bitmap { File = "doccl.bmp" ; } ;
+ };
+ Image IMG_OPENED_FOLDER_HC
+ {
+ MASKCOLOR ;
+ ImageBitmap = Bitmap { File = "folderop_h.bmp" ; } ;
+ };
+ Image IMG_CLOSED_FOLDER_HC
+ {
+ MASKCOLOR ;
+ ImageBitmap = Bitmap { File = "foldercl_h.bmp" ; } ;
+ };
+ Image IMG_OPENED_DOC_HC
+ {
+ MASKCOLOR ;
+ ImageBitmap = Bitmap { File = "doccl_h.bmp" ; } ;
+ };
+ Image IMG_CLOSED_DOC_HC
+ {
+ MASKCOLOR ;
+ ImageBitmap = Bitmap { File = "doccl_h.bmp" ; } ;
+ };
+ /* FixedText FT_DEFAULT_TEMPLATE_LABEL
+ {
+ Pos = MAP_APPFONT ( 3 , 161 ) ;
+ Size = MAP_APPFONT ( 61 , 10 ) ;
+ Text [ en-US ] = "Default template:" ;
+ };
+ FixedText FT_DEFAULT_TEMPLATE
+ {
+ Pos = MAP_APPFONT ( 66 , 161 ) ;
+ Size = MAP_APPFONT ( 131 , 10 ) ;
+ };*/
+};
+ // ********************************************************************** EOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sfx2/source/doc/frmdescr.cxx b/sfx2/source/doc/frmdescr.cxx
new file mode 100644
index 000000000000..04c3e78a7e7b
--- /dev/null
+++ b/sfx2/source/doc/frmdescr.cxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <sot/object.hxx>
+#include <tools/stream.hxx>
+#include <vcl/splitwin.hxx>
+#include <svl/itemset.hxx>
+#ifndef GCC
+#endif
+
+#include <sfx2/frmdescr.hxx>
+#include <sfx2/app.hxx>
+
+DBG_NAME(SfxFrameDescriptor);
+
+#define VERSION (USHORT) 3
+
+struct SfxFrameDescriptor_Impl
+{
+ Wallpaper* pWallpaper;
+ SfxItemSet* pArgs;
+ BOOL bEditable;
+
+ SfxFrameDescriptor_Impl() : pWallpaper( NULL ), pArgs( NULL ), bEditable( TRUE ) {}
+ ~SfxFrameDescriptor_Impl()
+ {
+ delete pWallpaper;
+ delete pArgs;
+ }
+};
+
+SfxFrameDescriptor::SfxFrameDescriptor() :
+ aMargin( -1, -1 ),
+ nWidth( 0L ),
+ eScroll( ScrollingAuto ),
+ eSizeSelector( SIZE_ABS ),
+ nHasBorder( BORDER_YES ),
+ nItemId( 0 ),
+ bResizeHorizontal( TRUE ),
+ bResizeVertical( TRUE ),
+ bHasUI( TRUE ),
+ bReadOnly( FALSE )
+{
+ DBG_CTOR(SfxFrameDescriptor, 0);
+
+ pImp = new SfxFrameDescriptor_Impl;
+}
+
+SfxFrameDescriptor::~SfxFrameDescriptor()
+{
+ DBG_DTOR(SfxFrameDescriptor, 0);
+ delete pImp;
+}
+
+SfxItemSet* SfxFrameDescriptor::GetArgs()
+{
+ if( !pImp->pArgs )
+ pImp->pArgs = new SfxAllItemSet( SFX_APP()->GetPool() );
+ return pImp->pArgs;
+}
+
+void SfxFrameDescriptor::SetURL( const String& rURL )
+{
+ aURL = INetURLObject(rURL);
+ SetActualURL( aURL );
+}
+
+void SfxFrameDescriptor::SetURL( const INetURLObject& rURL )
+{
+ aURL = rURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ SetActualURL( aURL );
+}
+
+void SfxFrameDescriptor::SetActualURL( const String& rURL )
+{
+ aActualURL = INetURLObject(rURL);
+ if ( pImp->pArgs )
+ pImp->pArgs->ClearItem();
+}
+
+void SfxFrameDescriptor::SetActualURL( const INetURLObject& rURL )
+{
+ SetActualURL(String(rURL.GetMainURL( INetURLObject::DECODE_TO_IURI )));
+}
+
+void SfxFrameDescriptor::SetEditable( BOOL bSet )
+{
+ pImp->bEditable = bSet;
+}
+
+BOOL SfxFrameDescriptor::IsEditable() const
+{
+ return pImp->bEditable;
+}
+
+BOOL SfxFrameDescriptor::CompareOriginal( SfxFrameDescriptor& rDescr ) const
+{
+ if( aURL != rDescr.aURL )
+ return FALSE;
+ else
+ return TRUE;
+}
+
+BOOL SfxFrameDescriptor::CheckContent() const
+{
+ BOOL bRet = !( aURL == aActualURL );
+ return bRet;
+}
+
+void SfxFrameDescriptor::UnifyContent( BOOL bTakeActual )
+{
+ if ( bTakeActual )
+ aURL = aActualURL;
+ else
+ aActualURL = aURL;
+}
+
+SfxFrameDescriptor* SfxFrameDescriptor::Clone( BOOL bWithIds ) const
+{
+ SfxFrameDescriptor *pFrame = new SfxFrameDescriptor;
+
+ pFrame->aURL = aURL;
+ pFrame->aActualURL = aActualURL;
+ pFrame->aName = aName;
+ pFrame->aMargin = aMargin;
+ pFrame->nWidth = nWidth;
+ pFrame->eSizeSelector = eSizeSelector;
+ pFrame->eScroll = eScroll;
+ pFrame->bResizeHorizontal = bResizeHorizontal;
+ pFrame->bResizeVertical = bResizeVertical;
+ pFrame->nHasBorder = nHasBorder;
+ pFrame->bHasUI = bHasUI;
+ pFrame->SetReadOnly( IsReadOnly() );
+ pFrame->SetEditable( IsEditable() );
+ if ( pImp->pWallpaper )
+ pFrame->pImp->pWallpaper = new Wallpaper( *pImp->pWallpaper );
+ if( pImp->pArgs )
+ {
+ // Aktuell ist im Clone von SfxAllItemSets noch ein Bug...
+ pFrame->pImp->pArgs = new SfxAllItemSet( SFX_APP()->GetPool() );
+ pFrame->pImp->pArgs->Put(*pImp->pArgs);
+ }
+
+ if ( bWithIds )
+ pFrame->nItemId = nItemId;
+ else
+ pFrame->nItemId = 0;
+
+ return pFrame;
+}
+
+USHORT SfxFrameDescriptor::GetWinBits() const
+{
+ USHORT nBits = 0;
+ if ( eSizeSelector == SIZE_REL )
+ nBits |= SWIB_RELATIVESIZE;
+ if ( eSizeSelector == SIZE_PERCENT )
+ nBits |= SWIB_PERCENTSIZE;
+ if ( !IsResizable() )
+ nBits |= SWIB_FIXED;
+ if ( !nWidth )
+ nBits |= SWIB_INVISIBLE;
+ return nBits;
+}
+
+BOOL SfxFrameDescriptor::HasFrameBorder() const
+{
+ return (nHasBorder & BORDER_YES) != 0;
+}
+
+long SfxFrameDescriptor::GetSize() const
+{
+ return nWidth;
+}
+
+void SfxFrameDescriptor::TakeProperties( const SfxFrameProperties& rProp )
+{
+ aURL = aActualURL = INetURLObject(rProp.aURL);
+ aName = rProp.aName;
+ aMargin.Width() = rProp.lMarginWidth;
+ aMargin.Height() = rProp.lMarginHeight;
+ nWidth = rProp.lSize;
+ eScroll = rProp.eScroll;
+ eSizeSelector = rProp.eSizeSelector;
+ nHasBorder = rProp.bHasBorder ? BORDER_YES : BORDER_NO;
+ if ( rProp.bBorderSet )
+ nHasBorder |= BORDER_SET;
+ bResizeHorizontal = bResizeVertical = rProp.bResizable;
+}
+
+void SfxFrameDescriptor::SetWallpaper( const Wallpaper& rWallpaper )
+{
+ DELETEZ( pImp->pWallpaper );
+
+ if ( rWallpaper.GetStyle() != WALLPAPER_NULL )
+ pImp->pWallpaper = new Wallpaper( rWallpaper );
+}
+
+const Wallpaper* SfxFrameDescriptor::GetWallpaper() const
+{
+ return pImp->pWallpaper;
+}
+
+USHORT SfxFrameDescriptor::GetItemPos() const
+{
+ return USHRT_MAX;
+}
+
+
+SfxFrameProperties::SfxFrameProperties( const SfxFrameDescriptor *pD )
+ : aURL( pD->GetURL().GetMainURL( INetURLObject::DECODE_TO_IURI ) )
+ , aName( pD->GetName() )
+ , lMarginWidth( pD->GetMargin().Width() )
+ , lMarginHeight( pD->GetMargin().Height() )
+ , lSize( pD->GetWidth() )
+ , lSetSize( SIZE_NOT_SET )
+ , lFrameSpacing( SPACING_NOT_SET )
+ , lInheritedFrameSpacing( SPACING_NOT_SET )
+ , eScroll( pD->GetScrollingMode() )
+ , eSizeSelector( pD->GetSizeSelector() )
+ , eSetSizeSelector( SIZE_REL )
+ , bHasBorder( pD->HasFrameBorder() )
+ , bBorderSet( pD->IsFrameBorderSet() )
+ , bResizable( pD->IsResizable() )
+ , bSetResizable( FALSE )
+ , bIsRootSet( FALSE )
+ , bIsInColSet( FALSE )
+ , bHasBorderInherited( FALSE )
+ , pFrame( pD->Clone() )
+{
+ bBorderSet = TRUE;
+}
+
+SfxFrameProperties& SfxFrameProperties::operator =(
+ const SfxFrameProperties &rProp )
+{
+ aURL = rProp.aURL;
+ aName = rProp.aName;
+ lMarginWidth = rProp.lMarginWidth;
+ lMarginHeight = rProp.lMarginHeight;
+ lSize = rProp.lSize;
+ lSetSize = rProp.lSetSize;
+ lFrameSpacing = rProp.lFrameSpacing;
+ lInheritedFrameSpacing = rProp.lInheritedFrameSpacing;
+ eScroll = rProp.eScroll;
+ eSizeSelector = rProp.eSizeSelector;
+ eSetSizeSelector = rProp.eSetSizeSelector;
+ bHasBorder = rProp.bHasBorder;
+ bBorderSet = rProp.bBorderSet;
+ bResizable = rProp.bResizable;
+ bSetResizable = rProp.bSetResizable;
+ bIsRootSet = rProp.bIsRootSet;
+ bIsInColSet = rProp.bIsInColSet;
+ bHasBorderInherited = rProp.bHasBorderInherited;
+ pFrame = rProp.pFrame->Clone();
+ return *this;
+}
+
+int SfxFrameProperties::operator ==( const SfxFrameProperties& rProp ) const
+{
+ return aURL == rProp.aURL && aName == rProp.aName && lMarginWidth == rProp.lMarginWidth && lMarginHeight == rProp.lMarginHeight &&
+ lSize == rProp.lSize && eScroll == rProp.eScroll && eSizeSelector == rProp.eSizeSelector &&
+ lSetSize == rProp.lSetSize && lFrameSpacing == rProp.lFrameSpacing && eSetSizeSelector == rProp.eSetSizeSelector &&
+ bHasBorder == rProp.bHasBorder && bBorderSet == rProp.bBorderSet &&
+ bResizable == rProp.bResizable && bSetResizable == rProp.bSetResizable;
+}
+
+TYPEINIT1(SfxFrameDescriptorItem, SfxPoolItem);
+
+SfxFrameDescriptorItem::~SfxFrameDescriptorItem()
+{}
+
+int SfxFrameDescriptorItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" );
+
+ return aProperties == ((SfxFrameDescriptorItem&)rAttr).aProperties;
+}
+
+// -----------------------------------------------------------------------
+
+SfxPoolItem* SfxFrameDescriptorItem::Clone( SfxItemPool* ) const
+{
+ return new SfxFrameDescriptorItem( *this );
+}
+
+//------------------------------------------------------------------------
+
+SfxItemPresentation SfxFrameDescriptorItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ SfxMapUnit /*eCoreUnit*/,
+ SfxMapUnit /*ePresUnit*/,
+ XubString& rText,
+ const IntlWrapper *
+) const
+{
+ rText.Erase();
+ return SFX_ITEM_PRESENTATION_NONE;
+}
+
+
diff --git a/sfx2/source/doc/graphhelp.cxx b/sfx2/source/doc/graphhelp.cxx
new file mode 100644
index 000000000000..388d85cefc25
--- /dev/null
+++ b/sfx2/source/doc/graphhelp.cxx
@@ -0,0 +1,529 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#ifdef WNT
+
+#undef WB_LEFT
+#undef WB_RIGHT
+
+#define UINT64 USE_WIN_UINT64
+#define INT64 USE_WIN_INT64
+#define UINT32 USE_WIN_UINT32
+#define INT32 USE_WIN_INT32
+
+#include <tools/presys.h>
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <tools/postsys.h>
+
+#undef UINT64
+#undef INT64
+#undef UINT32
+#undef INT32
+
+#endif
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/io/XStream.hpp>
+
+
+#include <osl/thread.h>
+#include <vcl/gdimtf.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/salbtype.hxx>
+
+#include <tools/stream.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/streamwrap.hxx>
+#include <comphelper/processfactory.hxx>
+
+
+#include "sfxresid.hxx"
+#include "graphhelp.hxx"
+#include "doc.hrc"
+
+using namespace ::com::sun::star;
+
+#define THUMBNAIL_RESOLUTION 256
+
+//---------------------------------------------------------------
+// static
+SvMemoryStream* GraphicHelper::getFormatStrFromGDI_Impl( const GDIMetaFile* pGDIMeta, sal_uInt32 nFormat )
+{
+ SvMemoryStream* pResult = NULL;
+ if ( pGDIMeta )
+ {
+ SvMemoryStream* pStream = new SvMemoryStream( 65535, 65535 );
+ if ( pStream )
+ {
+ Graphic aGraph( *pGDIMeta );
+ if ( GraphicConverter::Export( *pStream, aGraph, nFormat ) == 0 )
+ pResult = pStream;
+ else
+ delete pStream;
+ }
+ }
+
+ return pResult;
+}
+
+//---------------------------------------------------------------
+// static
+void* GraphicHelper::getEnhMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta )
+{
+ (void)pGDIMeta; // unused
+ void* pResult = NULL;
+
+#ifdef WNT
+ if ( pGDIMeta )
+ {
+ String aStr = ::rtl::OUString::createFromAscii( ".emf" );
+ ::utl::TempFile aTempFile( ::rtl::OUString(),
+ &aStr,
+ NULL,
+ sal_False );
+
+ ::rtl::OUString aMetaFile = aTempFile.GetFileName();
+ ::rtl::OUString aMetaURL = aTempFile.GetURL();
+ ::rtl::OString aWinFile = ::rtl::OUStringToOString( aMetaFile, osl_getThreadTextEncoding() );
+
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMetaURL, STREAM_STD_READWRITE );
+ if ( pStream )
+ {
+ Graphic aGraph( *pGDIMeta );
+ sal_Bool bFailed = (sal_Bool)GraphicConverter::Export( *pStream, aGraph, CVT_EMF );
+ pStream->Flush();
+ delete pStream;
+
+ if ( !bFailed )
+ pResult = GetEnhMetaFileA( aWinFile.getStr() );
+ }
+ }
+#endif
+
+ return pResult;
+}
+
+//---------------------------------------------------------------
+// static
+void* GraphicHelper::getWinMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta, const Size& aMetaSize )
+{
+ (void)pGDIMeta; // unused
+ (void)aMetaSize; // unused
+ void* pResult = NULL;
+
+#ifdef WNT
+ if ( pGDIMeta )
+ {
+ SvMemoryStream* pStream = new SvMemoryStream( 65535, 65535 );
+ if ( pStream )
+ {
+ Graphic aGraph( *pGDIMeta );
+ sal_Bool bFailed = (sal_Bool)GraphicConverter::Export( *pStream, aGraph, CVT_WMF );
+ pStream->Flush();
+ if ( !bFailed )
+ {
+ sal_Int32 nLength = pStream->Seek( STREAM_SEEK_TO_END );
+ if ( nLength > 22 )
+ {
+ HMETAFILE hMeta = SetMetaFileBitsEx( nLength - 22,
+ ( reinterpret_cast< const sal_uChar*>( pStream->GetData() ) ) + 22 );
+
+ if ( hMeta )
+ {
+ HGLOBAL hMemory = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, sizeof( METAFILEPICT ) );
+
+ if ( hMemory )
+ {
+ METAFILEPICT* pMF = (METAFILEPICT*)GlobalLock( hMemory );
+
+ pMF->hMF = hMeta;
+ pMF->mm = MM_ANISOTROPIC;
+
+ MapMode aMetaMode = pGDIMeta->GetPrefMapMode();
+ MapMode aWinMode( MAP_100TH_MM );
+
+ if ( aWinMode == pGDIMeta->GetPrefMapMode() )
+ {
+ pMF->xExt = aMetaSize.Width();
+ pMF->yExt = aMetaSize.Height();
+ }
+ else
+ {
+ Size aWinSize = OutputDevice::LogicToLogic( Size( aMetaSize.Width(), aMetaSize.Height() ),
+ pGDIMeta->GetPrefMapMode(),
+ aWinMode );
+ pMF->xExt = aWinSize.Width();
+ pMF->yExt = aWinSize.Height();
+ }
+
+ GlobalUnlock( hMemory );
+ pResult = (void*)hMemory;
+ }
+ else
+ DeleteMetaFile( hMeta );
+ }
+ }
+ }
+
+ delete pStream;
+ }
+ }
+
+#endif
+
+
+ return pResult;
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::supportsMetaFileHandle_Impl()
+{
+#ifdef WNT
+ return sal_True;
+#else
+ return sal_False;
+#endif
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::mergeBitmaps_Impl( const BitmapEx& rBmpEx, const BitmapEx& rOverlay,
+ const Rectangle& rOverlayRect, BitmapEx& rReturn )
+{
+ // the implementation is provided by KA
+
+ Point aNullPt;
+ Rectangle aBmpRect( aNullPt, rBmpEx.GetSizePixel() );
+ VirtualDevice aVDev;
+
+ if( !rReturn.IsEmpty() )
+ rReturn.SetEmpty();
+
+ if( !rBmpEx.IsEmpty() && aVDev.SetOutputSizePixel( aBmpRect.GetSize() ) )
+ {
+ Rectangle aOverlayRect( rOverlayRect );
+
+ aOverlayRect.Intersection( aBmpRect );
+
+ if( rOverlay.IsEmpty() || rOverlayRect.IsEmpty() )
+ rReturn = rBmpEx;
+ else
+ {
+ aVDev.DrawBitmap( aNullPt, aVDev.GetOutputSizePixel(), rBmpEx.GetBitmap() );
+ aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), rOverlay );
+
+ Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
+ aBmp.Convert( BMP_CONVERSION_24BIT );
+
+ if( !rBmpEx.IsTransparent() )
+ rReturn = aBmp;
+ else
+ {
+ aVDev.DrawBitmap( aNullPt, aVDev.GetOutputSizePixel(), rBmpEx.GetMask() );
+ Bitmap aOverlayMergeBmp( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ) );
+
+ if( rOverlay.IsTransparent() )
+ aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), rOverlay.GetMask() );
+ else
+ {
+ aVDev.SetLineColor( COL_BLACK );
+ aVDev.SetFillColor( COL_BLACK );
+ aVDev.DrawRect( aOverlayRect);
+ }
+
+ aOverlayMergeBmp.CombineSimple( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ), BMP_COMBINE_AND );
+ aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), aOverlayMergeBmp );
+ rReturn = BitmapEx( aBmp, aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
+ }
+ }
+ }
+
+ return !rReturn.IsEmpty();
+}
+
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::createThumb_Impl( const GDIMetaFile& rMtf,
+ sal_uInt32 nMaximumExtent,
+ BitmapEx& rBmpEx,
+ const BitmapEx* pOverlay,
+ const Rectangle* pOverlayRect )
+{
+ // the implementation is provided by KA
+
+ // initialization seems to be complicated but is used to avoid rounding errors
+ VirtualDevice aVDev;
+ const Point aNullPt;
+ const Point aTLPix( aVDev.LogicToPixel( aNullPt, rMtf.GetPrefMapMode() ) );
+ const Point aBRPix( aVDev.LogicToPixel( Point( rMtf.GetPrefSize().Width() - 1, rMtf.GetPrefSize().Height() - 1 ), rMtf.GetPrefMapMode() ) );
+ Size aDrawSize( aVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
+ Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 );
+ Point aPosPix;
+
+ if ( !rBmpEx.IsEmpty() )
+ rBmpEx.SetEmpty();
+
+ // determine size that has the same aspect ratio as image size and
+ // fits into the rectangle determined by nMaximumExtent
+ if ( aSizePix.Width() && aSizePix.Height() &&
+ ( sal::static_int_cast<sal_uInt32>(aSizePix.Width()) > nMaximumExtent ||
+ sal::static_int_cast<sal_uInt32>(aSizePix.Height()) > nMaximumExtent ) )
+ {
+ const Size aOldSizePix( aSizePix );
+ double fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height();
+
+ if ( fWH <= 1.0 )
+ {
+ aSizePix.Width() = FRound( nMaximumExtent * fWH );
+ aSizePix.Height() = nMaximumExtent;
+ }
+ else
+ {
+ aSizePix.Width() = nMaximumExtent;
+ aSizePix.Height() = FRound( nMaximumExtent / fWH );
+ }
+
+ aDrawSize.Width() = FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() );
+ aDrawSize.Height() = FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() );
+ }
+
+ Size aFullSize;
+ Point aBackPosPix;
+ Rectangle aOverlayRect;
+
+ // calculate addigtional positions and sizes if an overlay image is used
+ if ( pOverlay )
+ {
+ aFullSize = Size( nMaximumExtent, nMaximumExtent );
+ aOverlayRect = Rectangle( aNullPt, aFullSize );
+
+ aOverlayRect.Intersection( pOverlayRect ? *pOverlayRect : Rectangle( aNullPt, pOverlay->GetSizePixel() ) );
+
+ if ( !aOverlayRect.IsEmpty() )
+ aBackPosPix = Point( ( nMaximumExtent - aSizePix.Width() ) >> 1, ( nMaximumExtent - aSizePix.Height() ) >> 1 );
+ else
+ pOverlay = NULL;
+ }
+ else
+ {
+ aFullSize = aSizePix;
+ pOverlay = NULL;
+ }
+
+ // draw image(s) into VDev and get resulting image
+ if ( aVDev.SetOutputSizePixel( aFullSize ) )
+ {
+ // draw metafile into VDev
+ const_cast< GDIMetaFile& >( rMtf ).WindStart();
+ const_cast< GDIMetaFile& >( rMtf ).Play( &aVDev, aBackPosPix, aDrawSize );
+
+ // draw overlay if neccessary
+ if ( pOverlay )
+ aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), *pOverlay );
+
+ // get paint bitmap
+ Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
+
+ // assure that we have a true color image
+ if ( aBmp.GetBitCount() != 24 )
+ aBmp.Convert( BMP_CONVERSION_24BIT );
+
+ rBmpEx = BitmapEx( aBmp );
+ }
+
+ return !rBmpEx.IsEmpty();
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::getThumbnailFormatFromGDI_Impl( GDIMetaFile* pMetaFile,
+ sal_Bool bSigned,
+ const uno::Reference< io::XStream >& xStream )
+{
+ sal_Bool bResult = sal_False;
+ SvStream* pStream = NULL;
+
+ if ( xStream.is() )
+ pStream = ::utl::UcbStreamHelper::CreateStream( xStream );
+
+ if ( pMetaFile && pStream && !pStream->GetError() )
+ {
+ BitmapEx aResultBitmap;
+ BitmapEx* pSignatureBitmap = NULL;
+
+ if ( bSigned )
+ pSignatureBitmap = new BitmapEx( SfxResId( BMP_SIGNATURE ) );
+
+ bResult = createThumb_Impl( *pMetaFile,
+ THUMBNAIL_RESOLUTION,
+ aResultBitmap,
+ pSignatureBitmap );
+ if ( bResult )
+ bResult = ( !aResultBitmap.IsEmpty()
+ && GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0
+ && ( pStream->Flush(), !pStream->GetError() ) );
+
+ if ( pSignatureBitmap )
+ delete pSignatureBitmap;
+
+ delete pStream;
+ }
+
+ return bResult;
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::getSignedThumbnailFormatFromBitmap_Impl( const BitmapEx& aBitmap,
+ const uno::Reference< io::XStream >& xStream )
+{
+ sal_Bool bResult = sal_False;
+ SvStream* pStream = NULL;
+
+ if ( xStream.is() )
+ pStream = ::utl::UcbStreamHelper::CreateStream( xStream );
+
+ if ( pStream && !pStream->GetError() )
+ {
+ BitmapEx aResultBitmap;
+ BitmapEx aSignatureBitmap( SfxResId( BMP_SIGNATURE ) );
+
+ bResult = mergeBitmaps_Impl( aBitmap,
+ aSignatureBitmap,
+ Rectangle( Point(), aBitmap.GetSizePixel() ),
+ aResultBitmap );
+
+ if ( bResult )
+ {
+ bResult = ( !aResultBitmap.IsEmpty()
+ && GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0
+ && ( pStream->Flush(), !pStream->GetError() ) );
+ }
+
+ delete pStream;
+ }
+
+ return bResult;
+}
+
+//---------------------------------------------------------------
+// static
+sal_Bool GraphicHelper::getThumbnailReplacement_Impl( sal_Int32 nResID, const uno::Reference< io::XStream >& xStream )
+{
+ sal_Bool bResult = sal_False;
+ if ( nResID && xStream.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+ if ( xServiceManager.is() )
+ {
+ try
+ {
+ uno::Reference< graphic::XGraphicProvider > xGraphProvider(
+ xServiceManager->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ),
+ uno::UNO_QUERY );
+ if ( xGraphProvider.is() )
+ {
+ ::rtl::OUString aURL = ::rtl::OUString::createFromAscii( "private:resource/sfx/bitmapex/" );
+ aURL += ::rtl::OUString::valueOf( nResID );
+
+ uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
+ aMediaProps[0].Name = ::rtl::OUString::createFromAscii( "URL" );
+ aMediaProps[0].Value <<= aURL;
+
+ uno::Reference< graphic::XGraphic > xGraphic = xGraphProvider->queryGraphic( aMediaProps );
+ if ( xGraphic.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aStoreProps( 2 );
+ aStoreProps[0].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
+ aStoreProps[0].Value <<= xStream;
+ aStoreProps[1].Name = ::rtl::OUString::createFromAscii( "MimeType" );
+ aStoreProps[1].Value <<= ::rtl::OUString::createFromAscii( "image/png" );
+
+ xGraphProvider->storeGraphic( xGraphic, aStoreProps );
+ bResult = sal_True;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ return bResult;
+}
+
+//---------------------------------------------------------------
+// static
+sal_uInt16 GraphicHelper::getThumbnailReplacementIDByFactoryName_Impl( const ::rtl::OUString& aFactoryShortName, sal_Bool /*bIsTemplate*/ )
+{
+ sal_uInt16 nResult = 0;
+
+ if ( aFactoryShortName.equalsAscii( "scalc" ) )
+ {
+ nResult = BMP_128X128_CALC_DOC;
+ }
+ else if ( aFactoryShortName.equalsAscii( "sdraw" ) )
+ {
+ nResult = BMP_128X128_DRAW_DOC;
+ }
+ else if ( aFactoryShortName.equalsAscii( "simpress" ) )
+ {
+ nResult = BMP_128X128_IMPRESS_DOC;
+ }
+ else if ( aFactoryShortName.equalsAscii( "smath" ) )
+ {
+ nResult = BMP_128X128_MATH_DOC;
+ }
+ else if ( aFactoryShortName.equalsAscii( "swriter" ) || aFactoryShortName.compareToAscii( "swriter/", 8 ) == 0 )
+ {
+ nResult = BMP_128X128_WRITER_DOC;
+ }
+
+ return nResult;
+}
+
diff --git a/sfx2/source/doc/graphhelp.hxx b/sfx2/source/doc/graphhelp.hxx
new file mode 100644
index 000000000000..22f8ad5a115e
--- /dev/null
+++ b/sfx2/source/doc/graphhelp.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/io/XStream.hpp>
+
+#include <rtl/ustring.hxx>
+class SvMemoryStream;
+class GDIMetaFile;
+class BitmapEx;
+
+class GraphicHelper
+{
+
+ static sal_Bool mergeBitmaps_Impl( const BitmapEx& rBmpEx, const BitmapEx& rOverlay,
+ const Rectangle& rOverlayRect, BitmapEx& rReturn );
+
+ static sal_Bool createThumb_Impl( const GDIMetaFile& rMtf,
+ sal_uInt32 nMaximumExtent,
+ BitmapEx& rBmpEx,
+ const BitmapEx* pOverlay = NULL,
+ const Rectangle* pOverlayRect = NULL );
+
+public:
+
+ static SvMemoryStream* getFormatStrFromGDI_Impl( const GDIMetaFile* pGDIMeta, sal_uInt32 nFormat );
+
+ static void* getEnhMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta );
+
+ static void* getWinMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta, const Size& aMetaSize );
+
+ static sal_Bool supportsMetaFileHandle_Impl();
+
+ static sal_Bool getThumbnailFormatFromGDI_Impl(
+ GDIMetaFile* pMetaFile,
+ sal_Bool bSigned,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xStream );
+
+ static sal_Bool getSignedThumbnailFormatFromBitmap_Impl(
+ const BitmapEx& aBitmap,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xStream );
+
+ static sal_uInt16 getThumbnailReplacementIDByFactoryName_Impl( const ::rtl::OUString& aFactoryShortName,
+ sal_Bool bIsTemplate );
+
+ static sal_Bool getThumbnailReplacement_Impl(
+ sal_Int32 nResID,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xStream );
+
+};
+
diff --git a/sfx2/source/doc/graphhelp.src b/sfx2/source/doc/graphhelp.src
new file mode 100644
index 000000000000..1936a8460d25
--- /dev/null
+++ b/sfx2/source/doc/graphhelp.src
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "doc.hrc"
+
+Bitmap BMP_SIGNATURE
+{
+ File = "signet.png";
+};
+
+Bitmap BMP_128X128_CALC_DOC
+{
+ File = "128x128_calc_doc-p.png";
+};
+
+Bitmap BMP_128X128_DRAW_DOC
+{
+ File = "128x128_draw_doc-p.png";
+};
+
+Bitmap BMP_128X128_IMPRESS_DOC
+{
+ File = "128x128_impress_doc-p.png";
+};
+
+Bitmap BMP_128X128_MATH_DOC
+{
+ File = "128x128_math_doc-p.png";
+};
+
+Bitmap BMP_128X128_WRITER_DOC
+{
+ File = "128x128_writer_doc-p.png";
+};
+
diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx
new file mode 100644
index 000000000000..3c4df7276d6b
--- /dev/null
+++ b/sfx2/source/doc/guisaveas.cxx
@@ -0,0 +1,1842 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/document/XDocumentInfoSupplier.hpp>
+#include <com/sun/star/document/XDocumentInfo.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/frame/XStorable2.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <com/sun/star/util/XModifyListener.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/io/IOException.hpp>
+
+#include "guisaveas.hxx"
+
+#include <unotools/pathoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/itemset.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <unotools/useroptions.hxx>
+#include <unotools/saveopt.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/configurationhelper.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/window.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+
+#include <sfx2/sfxsids.hrc>
+#include <doc.hrc>
+#include <sfxresid.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/dinfdlg.hxx>
+#include <sfx2/request.hxx>
+#include <sfxtypes.hxx>
+#include "alienwarn.hxx"
+
+#include "../appl/app.hrc"
+
+#define DOCPROPSNUM 17
+
+// flags that specify requested operation
+#define EXPORT_REQUESTED 1
+#define PDFEXPORT_REQUESTED 2
+#define PDFDIRECTEXPORT_REQUESTED 4
+#define WIDEEXPORT_REQUESTED 8
+#define SAVE_REQUESTED 16
+#define SAVEAS_REQUESTED 32
+
+// possible statuses of save operation
+#define STATUS_NO_ACTION 0
+#define STATUS_SAVE 1
+#define STATUS_SAVEAS 2
+#define STATUS_SAVEAS_STANDARDNAME 3
+
+const ::rtl::OUString aFilterNameString = ::rtl::OUString::createFromAscii( "FilterName" );
+const ::rtl::OUString aFilterOptionsString = ::rtl::OUString::createFromAscii( "FilterOptions" );
+const ::rtl::OUString aFilterDataString = ::rtl::OUString::createFromAscii( "FilterData" );
+const ::rtl::OUString aFilterFlagsString = ::rtl::OUString::createFromAscii( "FilterFlags" );
+
+using namespace ::com::sun::star;
+
+namespace {
+//-------------------------------------------------------------------------
+static sal_uInt16 getSlotIDFromMode( sal_Int8 nStoreMode )
+{
+ // This is a temporary hardcoded solution must be removed when
+ // dialogs do not need parameters in SidSet representation any more
+
+ sal_uInt16 nResult = 0;
+ if ( nStoreMode == EXPORT_REQUESTED )
+ nResult = SID_EXPORTDOC;
+ else if ( nStoreMode == ( EXPORT_REQUESTED | PDFEXPORT_REQUESTED ) )
+ nResult = SID_EXPORTDOCASPDF;
+ else if ( nStoreMode == ( EXPORT_REQUESTED | PDFEXPORT_REQUESTED | PDFDIRECTEXPORT_REQUESTED ) )
+ nResult = SID_DIRECTEXPORTDOCASPDF;
+ else if ( nStoreMode == SAVEAS_REQUESTED || nStoreMode == ( EXPORT_REQUESTED | WIDEEXPORT_REQUESTED ) )
+ nResult = SID_SAVEASDOC;
+ else {
+ DBG_ASSERT( sal_False, "Unacceptable slot name is provided!\n" );
+ }
+
+ return nResult;
+}
+
+//-------------------------------------------------------------------------
+static sal_uInt8 getStoreModeFromSlotName( const ::rtl::OUString& aSlotName )
+{
+ sal_uInt8 nResult = 0;
+ if ( aSlotName.equalsAscii( "ExportTo" ) )
+ nResult = EXPORT_REQUESTED;
+ else if ( aSlotName.equalsAscii( "ExportToPDF" ) )
+ nResult = EXPORT_REQUESTED | PDFEXPORT_REQUESTED;
+ else if ( aSlotName.equalsAscii( "ExportDirectToPDF" ) )
+ nResult = EXPORT_REQUESTED | PDFEXPORT_REQUESTED | PDFDIRECTEXPORT_REQUESTED;
+ else if ( aSlotName.equalsAscii( "Save" ) )
+ nResult = SAVE_REQUESTED;
+ else if ( aSlotName.equalsAscii( "SaveAs" ) )
+ nResult = SAVEAS_REQUESTED;
+ else
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ ERRCODE_IO_INVALIDPARAMETER );
+
+ return nResult;
+}
+
+//-------------------------------------------------------------------------
+static sal_Int32 getMustFlags( sal_Int8 nStoreMode )
+{
+ return ( SFX_FILTER_EXPORT
+ | ( ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) ? 0 : SFX_FILTER_IMPORT ) );
+}
+
+//-------------------------------------------------------------------------
+static sal_Int32 getDontFlags( sal_Int8 nStoreMode )
+{
+ return ( SFX_FILTER_INTERNAL
+ | SFX_FILTER_NOTINFILEDLG
+ | ( ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) ? SFX_FILTER_IMPORT : 0 ) );
+}
+
+//=========================================================================
+// class DocumentSettingsGuard
+//=========================================================================
+
+class DocumentSettingsGuard
+{
+ uno::Reference< beans::XPropertySet > m_xDocumentSettings;
+ sal_Bool m_bPreserveReadOnly;
+ sal_Bool m_bReadOnlySupported;
+
+ sal_Bool m_bRestoreSettings;
+public:
+ DocumentSettingsGuard( const uno::Reference< frame::XModel >& xModel, sal_Bool bReadOnly, sal_Bool bRestore )
+ : m_bPreserveReadOnly( sal_False )
+ , m_bReadOnlySupported( sal_False )
+ , m_bRestoreSettings( bRestore )
+ {
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xDocSettingsSupplier( xModel, uno::UNO_QUERY_THROW );
+ m_xDocumentSettings.set(
+ xDocSettingsSupplier->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.Settings" ) ) ),
+ uno::UNO_QUERY_THROW );
+
+ ::rtl::OUString aLoadReadonlyString( RTL_CONSTASCII_USTRINGPARAM( "LoadReadonly" ) );
+
+ try
+ {
+ m_xDocumentSettings->getPropertyValue( aLoadReadonlyString ) >>= m_bPreserveReadOnly;
+ m_xDocumentSettings->setPropertyValue( aLoadReadonlyString, uno::makeAny( bReadOnly ) );
+ m_bReadOnlySupported = sal_True;
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ catch( uno::Exception& )
+ {}
+
+ if ( ( bReadOnly && !m_bReadOnlySupported ) )
+ throw uno::RuntimeException(); // the user could provide the data, so it must be stored
+ }
+
+ ~DocumentSettingsGuard()
+ {
+ if ( m_bRestoreSettings )
+ {
+ ::rtl::OUString aLoadReadonlyString( RTL_CONSTASCII_USTRINGPARAM( "LoadReadonly" ) );
+
+ try
+ {
+ if ( m_bReadOnlySupported )
+ m_xDocumentSettings->setPropertyValue( aLoadReadonlyString, uno::makeAny( m_bPreserveReadOnly ) );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ASSERT( "Unexpected exception!" );
+ }
+ }
+ }
+};
+} // anonymous namespace
+
+//=========================================================================
+// class ModelData_Impl
+//=========================================================================
+class ModelData_Impl
+{
+ SfxStoringHelper* m_pOwner;
+ uno::Reference< frame::XModel > m_xModel;
+ uno::Reference< frame::XStorable > m_xStorable;
+ uno::Reference< frame::XStorable2 > m_xStorable2;
+ uno::Reference< util::XModifiable > m_xModifiable;
+
+ ::rtl::OUString m_aModuleName;
+ ::comphelper::SequenceAsHashMap* m_pDocumentPropsHM;
+ ::comphelper::SequenceAsHashMap* m_pModulePropsHM;
+
+ ::comphelper::SequenceAsHashMap m_aMediaDescrHM;
+
+ sal_Bool m_bRecommendReadOnly;
+
+public:
+ ModelData_Impl( SfxStoringHelper& aOwner,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Sequence< beans::PropertyValue >& aMediaDescr );
+
+ ~ModelData_Impl();
+
+ void FreeDocumentProps();
+
+ uno::Reference< frame::XModel > GetModel();
+ uno::Reference< frame::XStorable > GetStorable();
+ uno::Reference< frame::XStorable2 > GetStorable2();
+ uno::Reference< util::XModifiable > GetModifiable();
+
+ ::comphelper::SequenceAsHashMap& GetMediaDescr() { return m_aMediaDescrHM; }
+
+ sal_Bool IsRecommendReadOnly() { return m_bRecommendReadOnly; }
+
+ const ::comphelper::SequenceAsHashMap& GetDocProps();
+
+ ::rtl::OUString GetModuleName();
+ const ::comphelper::SequenceAsHashMap& GetModuleProps();
+
+ void CheckInteractionHandler();
+
+
+ ::rtl::OUString GetDocServiceName();
+ uno::Sequence< beans::PropertyValue > GetDocServiceDefaultFilterCheckFlags( sal_Int32 nMust, sal_Int32 nDont );
+ uno::Sequence< beans::PropertyValue > GetDocServiceAnyFilter( sal_Int32 nMust, sal_Int32 nDont );
+ uno::Sequence< beans::PropertyValue > GetPreselectedFilter_Impl( sal_Int8 nStoreMode );
+ uno::Sequence< beans::PropertyValue > GetDocServiceDefaultFilter();
+
+ sal_Bool ExecuteFilterDialog_Impl( const ::rtl::OUString& aFilterName );
+
+ sal_Int8 CheckSaveAcceptable( sal_Int8 nCurStatus );
+ sal_Int8 CheckStateForSave();
+
+ sal_Int8 CheckFilter( const ::rtl::OUString& );
+
+ sal_Bool CheckFilterOptionsDialogExistence();
+
+ sal_Bool OutputFileDialog( sal_Int8 nStoreMode,
+ const ::comphelper::SequenceAsHashMap& aPreselectedFilterPropsHM,
+ sal_Bool bSetStandardName,
+ ::rtl::OUString& aSuggestedName,
+ sal_Bool bPreselectPassword,
+ const ::rtl::OUString& aSuggestedDir,
+ sal_Int16 nDialog,
+ const ::rtl::OUString& rStandardDir,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList
+ );
+
+ sal_Bool ShowDocumentInfoDialog();
+
+ ::rtl::OUString GetReccomendedDir( const ::rtl::OUString& aSuggestedDir,
+ const sfx2::FileDialogHelper::Context& aCtxt );
+ ::rtl::OUString GetReccomendedName( const ::rtl::OUString& aSuggestedName,
+ const ::rtl::OUString& aTypeName );
+
+};
+
+//-------------------------------------------------------------------------
+ModelData_Impl::ModelData_Impl( SfxStoringHelper& aOwner,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Sequence< beans::PropertyValue >& aMediaDescr )
+: m_pOwner( &aOwner )
+, m_xModel( xModel )
+, m_pDocumentPropsHM( NULL )
+, m_pModulePropsHM( NULL )
+, m_aMediaDescrHM( aMediaDescr )
+, m_bRecommendReadOnly( sal_False )
+{
+ CheckInteractionHandler();
+}
+
+//-------------------------------------------------------------------------
+ModelData_Impl::~ModelData_Impl()
+{
+ FreeDocumentProps();
+ if ( m_pDocumentPropsHM )
+ delete m_pDocumentPropsHM;
+
+ if ( m_pModulePropsHM )
+ delete m_pModulePropsHM;
+}
+
+//-------------------------------------------------------------------------
+void ModelData_Impl::FreeDocumentProps()
+{
+ if ( m_pDocumentPropsHM )
+ {
+ delete m_pDocumentPropsHM;
+ m_pDocumentPropsHM = NULL;
+ }
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< frame::XModel > ModelData_Impl::GetModel()
+{
+ if ( !m_xModel.is() )
+ throw uno::RuntimeException();
+
+ return m_xModel;
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< frame::XStorable > ModelData_Impl::GetStorable()
+{
+ if ( !m_xStorable.is() )
+ {
+ m_xStorable = uno::Reference< frame::XStorable >( m_xModel, uno::UNO_QUERY );
+ if ( !m_xStorable.is() )
+ throw uno::RuntimeException();
+ }
+
+ return m_xStorable;
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< frame::XStorable2 > ModelData_Impl::GetStorable2()
+{
+ if ( !m_xStorable2.is() )
+ {
+ m_xStorable2 = uno::Reference< frame::XStorable2 >( m_xModel, uno::UNO_QUERY );
+ if ( !m_xStorable2.is() )
+ throw uno::RuntimeException();
+ }
+
+ return m_xStorable2;
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< util::XModifiable > ModelData_Impl::GetModifiable()
+{
+ if ( !m_xModifiable.is() )
+ {
+ m_xModifiable = uno::Reference< util::XModifiable >( m_xModel, uno::UNO_QUERY );
+ if ( !m_xModifiable.is() )
+ throw uno::RuntimeException();
+ }
+
+ return m_xModifiable;
+}
+
+//-------------------------------------------------------------------------
+const ::comphelper::SequenceAsHashMap& ModelData_Impl::GetDocProps()
+{
+ if ( !m_pDocumentPropsHM )
+ m_pDocumentPropsHM = new ::comphelper::SequenceAsHashMap( GetModel()->getArgs() );
+
+ return *m_pDocumentPropsHM;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString ModelData_Impl::GetModuleName()
+{
+ if ( !m_aModuleName.getLength() )
+ {
+ m_aModuleName = m_pOwner->GetModuleManager()->identify(
+ uno::Reference< uno::XInterface >( m_xModel, uno::UNO_QUERY ) );
+ if ( !m_aModuleName.getLength() )
+ throw uno::RuntimeException(); // TODO:
+ }
+ return m_aModuleName;
+}
+
+//-------------------------------------------------------------------------
+const ::comphelper::SequenceAsHashMap& ModelData_Impl::GetModuleProps()
+{
+ if ( !m_pModulePropsHM )
+ {
+ uno::Sequence< beans::PropertyValue > aModuleProps;
+ m_pOwner->GetNamedModuleManager()->getByName( GetModuleName() ) >>= aModuleProps;
+ if ( !aModuleProps.getLength() )
+ throw uno::RuntimeException(); // TODO;
+ m_pModulePropsHM = new ::comphelper::SequenceAsHashMap( aModuleProps );
+ }
+
+ return *m_pModulePropsHM;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString ModelData_Impl::GetDocServiceName()
+{
+ return GetModuleProps().getUnpackedValueOrDefault(::rtl::OUString::createFromAscii( "ooSetupFactoryDocumentService" ), ::rtl::OUString());
+}
+
+//-------------------------------------------------------------------------
+void ModelData_Impl::CheckInteractionHandler()
+{
+ ::comphelper::SequenceAsHashMap::const_iterator aInteractIter =
+ m_aMediaDescrHM.find( ::rtl::OUString::createFromAscii( "InteractionHandler" ) );
+
+ if ( aInteractIter == m_aMediaDescrHM.end() )
+ {
+ try {
+ m_aMediaDescrHM[ ::rtl::OUString::createFromAscii( "InteractionHandler" ) ]
+ <<= uno::Reference< task::XInteractionHandler >(
+ m_pOwner->GetServiceFactory()->createInstance(
+ DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ),
+ uno::UNO_QUERY );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ else
+ {
+ uno::Reference< task::XInteractionHandler > xInteract;
+ DBG_ASSERT( ( aInteractIter->second >>= xInteract ) && xInteract.is(), "Broken interaction handler is provided!\n" );
+ }
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceDefaultFilter()
+{
+ uno::Sequence< beans::PropertyValue > aProps;
+
+ ::rtl::OUString aFilterName = GetModuleProps().getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "ooSetupFactoryDefaultFilter" ),
+ ::rtl::OUString() );
+
+ m_pOwner->GetFilterConfiguration()->getByName( aFilterName ) >>= aProps;
+
+ return aProps;
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceDefaultFilterCheckFlags( sal_Int32 nMust,
+ sal_Int32 nDont )
+{
+ uno::Sequence< beans::PropertyValue > aFilterProps;
+ uno::Sequence< beans::PropertyValue > aProps = GetDocServiceDefaultFilter();
+ if ( aProps.getLength() )
+ {
+ ::comphelper::SequenceAsHashMap aFiltHM( aProps );
+ sal_Int32 nFlags = aFiltHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ),
+ (sal_Int32)0 );
+ if ( ( ( nFlags & nMust ) == nMust ) && !( nFlags & nDont ) )
+ aFilterProps = aProps;
+ }
+
+ return aFilterProps;
+}
+
+
+//-------------------------------------------------------------------------
+uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceAnyFilter( sal_Int32 nMust, sal_Int32 nDont )
+{
+ uno::Sequence< beans::NamedValue > aSearchRequest( 1 );
+ aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "DocumentService" );
+ aSearchRequest[0].Value <<= GetDocServiceName();
+
+ return SfxStoringHelper::SearchForFilter( m_pOwner->GetFilterQuery(), aSearchRequest, nMust, nDont );
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< beans::PropertyValue > ModelData_Impl::GetPreselectedFilter_Impl( sal_Int8 nStoreMode )
+{
+ uno::Sequence< beans::PropertyValue > aFilterProps;
+
+ sal_Int32 nMust = getMustFlags( nStoreMode );
+ sal_Int32 nDont = getDontFlags( nStoreMode );
+
+ if ( nStoreMode & PDFEXPORT_REQUESTED )
+ {
+ // Preselect PDF-Filter for EXPORT
+ uno::Sequence< beans::NamedValue > aSearchRequest( 2 );
+ aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "Type" );
+ aSearchRequest[0].Value <<= ::rtl::OUString::createFromAscii( "pdf_Portable_Document_Format" );
+ aSearchRequest[1].Name = ::rtl::OUString::createFromAscii( "DocumentService" );
+ aSearchRequest[1].Value <<= GetDocServiceName();
+
+ aFilterProps = SfxStoringHelper::SearchForFilter( m_pOwner->GetFilterQuery(), aSearchRequest, nMust, nDont );
+ }
+ else
+ {
+ aFilterProps = GetDocServiceDefaultFilterCheckFlags( nMust, nDont );
+
+ if ( !aFilterProps.getLength() )
+ {
+ // the default filter was not faund, use just the first acceptable one
+ aFilterProps = GetDocServiceAnyFilter( nMust, nDont );
+ }
+ }
+
+ return aFilterProps;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool ModelData_Impl::ExecuteFilterDialog_Impl( const ::rtl::OUString& aFilterName )
+{
+ sal_Bool bDialogUsed = sal_False;
+
+ try {
+ uno::Sequence < beans::PropertyValue > aProps;
+ uno::Any aAny = m_pOwner->GetFilterConfiguration()->getByName( aFilterName );
+ if ( aAny >>= aProps )
+ {
+ sal_Int32 nPropertyCount = aProps.getLength();
+ for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty )
+ if( aProps[nProperty].Name.equals( ::rtl::OUString::createFromAscii("UIComponent")) )
+ {
+ ::rtl::OUString aServiceName;
+ aProps[nProperty].Value >>= aServiceName;
+ if( aServiceName.getLength() )
+ {
+ uno::Reference< ui::dialogs::XExecutableDialog > xFilterDialog(
+ m_pOwner->GetServiceFactory()->createInstance( aServiceName ), uno::UNO_QUERY );
+ uno::Reference< beans::XPropertyAccess > xFilterProperties( xFilterDialog, uno::UNO_QUERY );
+
+ if( xFilterDialog.is() && xFilterProperties.is() )
+ {
+ bDialogUsed = sal_True;
+
+ uno::Reference< document::XExporter > xExporter( xFilterDialog, uno::UNO_QUERY );
+ if( xExporter.is() )
+ xExporter->setSourceDocument(
+ uno::Reference< lang::XComponent >( GetModel(), uno::UNO_QUERY ) );
+
+ uno::Sequence< beans::PropertyValue > aPropsForDialog;
+ GetMediaDescr() >> aPropsForDialog;
+ xFilterProperties->setPropertyValues( aPropsForDialog );
+
+ if( xFilterDialog->execute() )
+ {
+ uno::Sequence< beans::PropertyValue > aPropsFromDialog =
+ xFilterProperties->getPropertyValues();
+ for ( sal_Int32 nInd = 0; nInd < aPropsFromDialog.getLength(); nInd++ )
+ GetMediaDescr()[aPropsFromDialog[nInd].Name] = aPropsFromDialog[nInd].Value;
+ }
+ else
+ {
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ ERRCODE_IO_ABORT );
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ catch( container::NoSuchElementException& )
+ {
+ // the filter name is unknown
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ ERRCODE_IO_INVALIDPARAMETER );
+ }
+ catch( task::ErrorCodeIOException& )
+ {
+ throw;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return bDialogUsed;
+}
+
+//-------------------------------------------------------------------------
+sal_Int8 ModelData_Impl::CheckSaveAcceptable( sal_Int8 nCurStatus )
+{
+ sal_Int8 nResult = nCurStatus;
+
+ if ( nResult != STATUS_NO_ACTION && GetStorable()->hasLocation() )
+ {
+ // check whether save is acceptable by the configuration
+ // it is done only for documents that have persistence already
+ uno::Reference< uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig(
+ m_pOwner->GetServiceFactory(),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
+ ::comphelper::ConfigurationHelper::E_STANDARD );
+ if ( !xCommonConfig.is() )
+ throw uno::RuntimeException(); // should the saving proceed as usual instead?
+
+ try
+ {
+ sal_Bool bAlwaysSaveAs = sal_False;
+
+ // the saving is acceptable
+ // in case the configuration entry is not set or set to false
+ // or in case of version creation
+ ::rtl::OUString aVersionCommentString = ::rtl::OUString::createFromAscii( "VersionComment" );
+ if ( ( ::comphelper::ConfigurationHelper::readRelativeKey(
+ xCommonConfig,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Save/Document/" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AlwaysSaveAs" ) ) ) >>= bAlwaysSaveAs )
+ && bAlwaysSaveAs
+ && GetMediaDescr().find( aVersionCommentString ) == GetMediaDescr().end() )
+ {
+ // notify the user that SaveAs is going to be done
+ String aString( SfxResId( STR_NEW_FILENAME_SAVE ) );
+ Window* pWin = SfxStoringHelper::GetModelWindow( m_xModel );
+ QueryBox aMessageBox( pWin, WB_OK_CANCEL | WB_DEF_OK, aString );
+ if ( aMessageBox.Execute() == RET_OK )
+ nResult = STATUS_SAVEAS;
+ else
+ nResult = STATUS_NO_ACTION;
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // impossibility to get the configuration access means normal saving flow for now
+ }
+ }
+
+ return nResult;
+}
+
+//-------------------------------------------------------------------------
+sal_Int8 ModelData_Impl::CheckStateForSave()
+{
+ // check acceptable entries for media descriptor
+ sal_Bool bVersInfoNeedsStore = sal_False;
+ ::comphelper::SequenceAsHashMap aAcceptedArgs;
+
+ ::rtl::OUString aVersionCommentString = ::rtl::OUString::createFromAscii( "VersionComment" );
+ ::rtl::OUString aAuthorString = ::rtl::OUString::createFromAscii( "Author" );
+ ::rtl::OUString aInteractionHandlerString = ::rtl::OUString::createFromAscii( "InteractionHandler" );
+ ::rtl::OUString aStatusIndicatorString = ::rtl::OUString::createFromAscii( "StatusIndicator" );
+
+ if ( GetMediaDescr().find( aVersionCommentString ) != GetMediaDescr().end() )
+ {
+ bVersInfoNeedsStore = sal_True;
+ aAcceptedArgs[ aVersionCommentString ] = GetMediaDescr()[ aVersionCommentString ];
+ }
+ if ( GetMediaDescr().find( aAuthorString ) != GetMediaDescr().end() )
+ aAcceptedArgs[ aAuthorString ] = GetMediaDescr()[ aAuthorString ];
+ if ( GetMediaDescr().find( aInteractionHandlerString ) != GetMediaDescr().end() )
+ aAcceptedArgs[ aInteractionHandlerString ] = GetMediaDescr()[ aInteractionHandlerString ];
+ if ( GetMediaDescr().find( aStatusIndicatorString ) != GetMediaDescr().end() )
+ aAcceptedArgs[ aStatusIndicatorString ] = GetMediaDescr()[ aStatusIndicatorString ];
+
+ // remove unacceptable entry if there is any
+ DBG_ASSERT( GetMediaDescr().size() == aAcceptedArgs.size(),
+ "Unacceptable parameters are provided in Save request!\n" );
+ if ( GetMediaDescr().size() != aAcceptedArgs.size() )
+ GetMediaDescr() = aAcceptedArgs;
+
+ // the document must be modified
+ if ( !GetModifiable()->isModified() && !bVersInfoNeedsStore )
+ return STATUS_NO_ACTION;
+
+ // if the document is readonly or a new one a SaveAs operation must be used
+ if ( !GetStorable()->hasLocation() || GetStorable()->isReadonly() )
+ return STATUS_SAVEAS;
+
+ // check that the old filter is acceptable
+ ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault(
+ aFilterNameString,
+ ::rtl::OUString() );
+ sal_Int8 nResult = CheckFilter( aOldFilterName );
+
+ return nResult;
+}
+
+sal_Int8 ModelData_Impl::CheckFilter( const ::rtl::OUString& aFilterName )
+{
+ ::comphelper::SequenceAsHashMap aFiltPropsHM;
+ sal_Int32 nFiltFlags = 0;
+ if ( aFilterName.getLength() )
+ {
+ // get properties of filter
+ uno::Sequence< beans::PropertyValue > aFilterProps;
+ if ( aFilterName.getLength() )
+ m_pOwner->GetFilterConfiguration()->getByName( aFilterName ) >>= aFilterProps;
+
+ aFiltPropsHM = ::comphelper::SequenceAsHashMap( aFilterProps );
+ nFiltFlags = aFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 );
+ }
+
+ // only a temporary solution until default filter retrieving feature is implemented
+ // then GetDocServiceDefaultFilter() must be used
+ ::comphelper::SequenceAsHashMap aDefFiltPropsHM = GetDocServiceDefaultFilterCheckFlags( 3, 0 );
+ sal_Int32 nDefFiltFlags = aDefFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 );
+
+ // if the old filter is not acceptable
+ // and there is no default filter or it is not acceptable for requested parameters then proceed with saveAs
+ if ( ( !aFiltPropsHM.size() || !( nFiltFlags & SFX_FILTER_EXPORT ) )
+ && ( !aDefFiltPropsHM.size() || !( nDefFiltFlags & SFX_FILTER_EXPORT ) || nDefFiltFlags & SFX_FILTER_INTERNAL ) )
+ return STATUS_SAVEAS;
+
+ // so at this point there is either an acceptable old filter or default one
+ if ( !aFiltPropsHM.size() || !( nFiltFlags & SFX_FILTER_EXPORT ) )
+ {
+ // so the default filter must be acceptable
+ return STATUS_SAVEAS_STANDARDNAME;
+ }
+ else if ( ( !( nFiltFlags & SFX_FILTER_OWN ) || ( nFiltFlags & SFX_FILTER_ALIEN ) )
+ && !( nFiltFlags & SFX_FILTER_SILENTEXPORT ) && aDefFiltPropsHM.size()
+ && ( nDefFiltFlags & SFX_FILTER_EXPORT ) && !( nDefFiltFlags & SFX_FILTER_INTERNAL ))
+ {
+ // the default filter is acceptable and the old filter is alian one
+ // so ask to make a saveAs operation
+ ::rtl::OUString aUIName = aFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "UIName" ),
+ ::rtl::OUString() );
+ ::rtl::OUString aDefUIName = aDefFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "UIName" ),
+ ::rtl::OUString() );
+ ::rtl::OUString aPreusedFilterName = GetDocProps().getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "PreusedFilterName" ),
+ ::rtl::OUString() );
+ if ( !aPreusedFilterName.equals( aFilterName ) && !aUIName.equals( aDefUIName ) )
+ {
+ if ( !SfxStoringHelper::WarnUnacceptableFormat( GetModel(), aUIName, aDefUIName, sal_True ) )
+ return STATUS_SAVEAS_STANDARDNAME;
+ }
+ }
+
+ return STATUS_SAVE;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool ModelData_Impl::CheckFilterOptionsDialogExistence()
+{
+ uno::Sequence< beans::NamedValue > aSearchRequest( 1 );
+ aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "DocumentService" );
+ aSearchRequest[0].Value <<= GetDocServiceName();
+
+ uno::Reference< container::XEnumeration > xFilterEnum =
+ m_pOwner->GetFilterQuery()->createSubSetEnumerationByProperties( aSearchRequest );
+
+ while ( xFilterEnum->hasMoreElements() )
+ {
+ uno::Sequence< beans::PropertyValue > pProps;
+ if ( xFilterEnum->nextElement() >>= pProps )
+ {
+ ::comphelper::SequenceAsHashMap aPropsHM( pProps );
+ ::rtl::OUString aUIServName = aPropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "UIComponent" ),
+ ::rtl::OUString() );
+ if ( aUIServName.getLength() )
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool ModelData_Impl::OutputFileDialog( sal_Int8 nStoreMode,
+ const ::comphelper::SequenceAsHashMap& aPreselectedFilterPropsHM,
+ sal_Bool bSetStandardName,
+ ::rtl::OUString& aSuggestedName,
+ sal_Bool bPreselectPassword,
+ const ::rtl::OUString& aSuggestedDir,
+ sal_Int16 nDialog,
+ const ::rtl::OUString& rStandardDir,
+ const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList)
+{
+ sal_Bool bUseFilterOptions = sal_False;
+
+ ::comphelper::SequenceAsHashMap::const_iterator aOverwriteIter =
+ GetMediaDescr().find( ::rtl::OUString::createFromAscii( "Overwrite" ) );
+
+ // the file name must be specified if overwrite option is set
+ if ( aOverwriteIter != GetMediaDescr().end() )
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ ERRCODE_IO_INVALIDPARAMETER );
+
+ // no target file name is specified
+ // we need to show the file dialog
+
+ // check if we have a filter which allows for filter options, so we need a corresponding checkbox in the dialog
+ sal_Bool bAllowOptions = sal_False;
+
+ // in case of Export, filter options dialog is used if available
+ if( !( nStoreMode & EXPORT_REQUESTED ) || ( nStoreMode & WIDEEXPORT_REQUESTED ) )
+ bAllowOptions = CheckFilterOptionsDialogExistence();
+
+ // get the filename by dialog ...
+ // create the file dialog
+ sal_Int16 aDialogMode = bAllowOptions
+ ? (com::sun::star::ui::dialogs::TemplateDescription::
+ FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS)
+ : (com::sun::star::ui::dialogs::TemplateDescription::
+ FILESAVE_AUTOEXTENSION_PASSWORD);
+ sal_Int64 aDialogFlags = 0;
+
+ if( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) )
+ {
+ if ( nStoreMode & PDFEXPORT_REQUESTED )
+ aDialogMode = com::sun::star::ui::dialogs::TemplateDescription::
+ FILESAVE_AUTOEXTENSION;
+ else
+ aDialogMode = com::sun::star::ui::dialogs::TemplateDescription::
+ FILESAVE_AUTOEXTENSION_SELECTION;
+ aDialogFlags = SFXWB_EXPORT;
+ }
+
+ sfx2::FileDialogHelper* pFileDlg = NULL;
+
+ ::rtl::OUString aDocServiceName = GetDocServiceName();
+ DBG_ASSERT( aDocServiceName.getLength(), "No document service for this module set!" );
+
+ sal_Int32 nMust = getMustFlags( nStoreMode );
+ sal_Int32 nDont = getDontFlags( nStoreMode );
+ sfx2::FileDialogHelper::Context eCtxt = sfx2::FileDialogHelper::UNKNOWN_CONTEXT;
+
+ if ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) )
+ {
+ if ( ( nStoreMode & PDFEXPORT_REQUESTED ) && aPreselectedFilterPropsHM.size() )
+ {
+ // this is a PDF export
+ // the filter options has been shown already
+ ::rtl::OUString aFilterUIName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "UIName" ),
+ ::rtl::OUString() );
+
+ pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aFilterUIName, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "pdf" ) ), rStandardDir, rBlackList );
+ pFileDlg->SetCurrentFilter( aFilterUIName );
+ }
+ else
+ {
+ // This is the normal dialog
+ pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aDocServiceName, nDialog, nMust, nDont, rStandardDir, rBlackList );
+ }
+
+ if( aDocServiceName.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) )
+ eCtxt = sfx2::FileDialogHelper::SD_EXPORT;
+ if( aDocServiceName.equalsAscii( "com.sun.star.presentation.PresentationDocument" ) )
+ eCtxt = sfx2::FileDialogHelper::SI_EXPORT;
+ if( aDocServiceName.equalsAscii( "com.sun.star.text.TextDocument" ) )
+ eCtxt = sfx2::FileDialogHelper::SW_EXPORT;
+
+ if ( eCtxt != sfx2::FileDialogHelper::UNKNOWN_CONTEXT )
+ pFileDlg->SetContext( eCtxt );
+
+ pFileDlg->CreateMatcher( aDocServiceName );
+
+ uno::Reference< ui::dialogs::XFilePicker > xFilePicker = pFileDlg->GetFilePicker();
+ uno::Reference< ui::dialogs::XFilePickerControlAccess > xControlAccess =
+ uno::Reference< ui::dialogs::XFilePickerControlAccess >( xFilePicker, uno::UNO_QUERY );
+
+ if ( xControlAccess.is() )
+ {
+ ::rtl::OUString aCtrlText = String( SfxResId( STR_EXPORTBUTTON ) );
+ xControlAccess->setLabel( ui::dialogs::CommonFilePickerElementIds::PUSHBUTTON_OK, aCtrlText );
+
+ aCtrlText = ::rtl::OUString( String( SfxResId( STR_LABEL_FILEFORMAT ) ) );
+ xControlAccess->setLabel( ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER_LABEL, aCtrlText );
+ }
+ }
+ else
+ {
+ // This is the normal dialog
+ pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aDocServiceName, nDialog, nMust, nDont, rStandardDir, rBlackList );
+ pFileDlg->CreateMatcher( aDocServiceName );
+ }
+
+ ::rtl::OUString aAdjustToType;
+
+ if ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) )
+ {
+ // it is export, set the preselected filter
+ ::rtl::OUString aFilterUIName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "UIName" ),
+ ::rtl::OUString() );
+ pFileDlg->SetCurrentFilter( aFilterUIName );
+ }
+ // it is no export, bSetStandardName == true means that user agreed to store document in the default (default default ;-)) format
+ else if ( bSetStandardName || GetStorable()->hasLocation() )
+ {
+ uno::Sequence< beans::PropertyValue > aOldFilterProps;
+ ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault(
+ aFilterNameString,
+ ::rtl::OUString() );
+
+ if ( aOldFilterName.getLength() )
+ m_pOwner->GetFilterConfiguration()->getByName( aOldFilterName ) >>= aOldFilterProps;
+
+ ::comphelper::SequenceAsHashMap aOldFiltPropsHM( aOldFilterProps );
+ sal_Int32 nOldFiltFlags = aOldFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 );
+
+ if ( bSetStandardName || ( nOldFiltFlags & nMust ) != nMust || nOldFiltFlags & nDont )
+ {
+ // the suggested type will be changed, the extension should be adjusted
+ aAdjustToType = aPreselectedFilterPropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "Type" ),
+ ::rtl::OUString() );
+
+ ::rtl::OUString aFilterUIName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "UIName" ),
+ ::rtl::OUString() );
+ pFileDlg->SetCurrentFilter( aFilterUIName );
+ }
+ else
+ {
+ pFileDlg->SetCurrentFilter( aOldFiltPropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "UIName" ),
+ ::rtl::OUString() ) );
+ }
+ }
+
+ ::rtl::OUString aReccomendedDir = GetReccomendedDir( aSuggestedDir, eCtxt );
+ if ( aReccomendedDir.getLength() )
+ pFileDlg->SetDisplayDirectory( aReccomendedDir );
+ ::rtl::OUString aReccomendedName = GetReccomendedName( aSuggestedName, aAdjustToType );
+ if ( aReccomendedName.getLength() )
+ pFileDlg->SetFileName( aReccomendedName );
+
+ uno::Reference < view::XSelectionSupplier > xSel( GetModel()->getCurrentController(), uno::UNO_QUERY );
+ if ( xSel.is() && xSel->getSelection().hasValue() )
+ GetMediaDescr()[::rtl::OUString::createFromAscii( "SelectionOnly" )] <<= sal_True;
+
+ // This is a temporary hardcoded solution must be removed when
+ // dialogs do not need parameters in SidSet representation any more
+ sal_uInt16 nSlotID = getSlotIDFromMode( nStoreMode );
+ if ( !nSlotID )
+ throw lang::IllegalArgumentException(); // TODO:
+
+ // generate SidSet from MediaDescriptor and provide it into FileDialog
+ // than merge changed SidSet back
+ SfxAllItemSet aDialogParams( SFX_APP()->GetPool() );
+ SfxItemSet* pDialogParams = &aDialogParams;
+ TransformParameters( nSlotID,
+ GetMediaDescr().getAsConstPropertyValueList(),
+ aDialogParams,
+ NULL );
+
+ const SfxPoolItem* pItem = NULL;
+ if ( bPreselectPassword && aDialogParams.GetItemState( SID_PASSWORD, sal_True, &pItem ) != SFX_ITEM_SET )
+ {
+ // the file dialog preselects the password checkbox if the provided mediadescriptor has password entry
+ // after dialog execution the password entry will be either removed or replaced with the password
+ // entered by the user
+ aDialogParams.Put( SfxStringItem( SID_PASSWORD, String() ) );
+ }
+
+ // aStringTypeFN is a pure output parameter, pDialogParams is an in/out parameter
+ String aStringTypeFN;
+ if ( pFileDlg->Execute( pDialogParams, aStringTypeFN ) != ERRCODE_NONE )
+ {
+ delete pFileDlg;
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT );
+ }
+
+ ::rtl::OUString aFilterName = aStringTypeFN;
+
+ // the following two arguments can not be converted in MediaDescriptor,
+ // so they should be removed from the ItemSet after retrieving
+ SFX_ITEMSET_ARG( pDialogParams, pRecommendReadOnly, SfxBoolItem, SID_RECOMMENDREADONLY, sal_False );
+ m_bRecommendReadOnly = ( pRecommendReadOnly && pRecommendReadOnly->GetValue() );
+ pDialogParams->ClearItem( SID_RECOMMENDREADONLY );
+
+ uno::Sequence< beans::PropertyValue > aPropsFromDialog;
+ TransformItems( nSlotID, *pDialogParams, aPropsFromDialog, NULL );
+ GetMediaDescr() << aPropsFromDialog;
+
+ // get the path from the dialog
+ INetURLObject aURL( pFileDlg->GetPath() );
+ // the path should be provided outside since it might be used for further calls to the dialog
+ aSuggestedName = aURL.GetName( INetURLObject::DECODE_WITH_CHARSET );
+
+ // old filter options should be cleared in case different filter is used
+
+ ::rtl::OUString aFilterFromMediaDescr = GetMediaDescr().getUnpackedValueOrDefault(
+ aFilterNameString,
+ ::rtl::OUString() );
+ ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault(
+ aFilterNameString,
+ ::rtl::OUString() );
+ if ( aFilterName.equals( aFilterFromMediaDescr ) )
+ {
+ // preserv current settings if any
+ // if there no current settings and the name is the same
+ // as old filter name use old filter settings
+
+ if ( aFilterFromMediaDescr.equals( aOldFilterName ) )
+ {
+ ::comphelper::SequenceAsHashMap::const_iterator aIter =
+ GetDocProps().find( aFilterOptionsString );
+ if ( aIter != GetDocProps().end()
+ && GetMediaDescr().find( aFilterOptionsString ) == GetMediaDescr().end() )
+ GetMediaDescr()[aIter->first] = aIter->second;
+
+ aIter = GetDocProps().find( aFilterDataString );
+ if ( aIter != GetDocProps().end()
+ && GetMediaDescr().find( aFilterDataString ) == GetMediaDescr().end() )
+ GetMediaDescr()[aIter->first] = aIter->second;
+ }
+ }
+ else
+ {
+ GetMediaDescr().erase( aFilterDataString );
+ GetMediaDescr().erase( aFilterOptionsString );
+
+ if ( aFilterName.equals( aOldFilterName ) )
+ {
+ // merge filter option of the document filter
+
+ ::comphelper::SequenceAsHashMap::const_iterator aIter =
+ GetDocProps().find( aFilterOptionsString );
+ if ( aIter != GetDocProps().end() )
+ GetMediaDescr()[aIter->first] = aIter->second;
+
+ aIter = GetDocProps().find( aFilterDataString );
+ if ( aIter != GetDocProps().end() )
+ GetMediaDescr()[aIter->first] = aIter->second;
+ }
+ }
+
+ uno::Reference< ui::dialogs::XFilePickerControlAccess > xExtFileDlg( pFileDlg->GetFilePicker(), uno::UNO_QUERY );
+ if ( xExtFileDlg.is() )
+ {
+ if ( SfxStoringHelper::CheckFilterOptionsAppearence( m_pOwner->GetFilterConfiguration(), aFilterName ) )
+ bUseFilterOptions = sal_True;
+
+ if ( ( !( nStoreMode & EXPORT_REQUESTED ) || ( nStoreMode & WIDEEXPORT_REQUESTED ) ) && bUseFilterOptions )
+ {
+ try
+ {
+ // for exporters: always show dialog if format uses options
+ // for save: show dialog if format uses options and no options given or if forced by user
+ uno::Any aVal =
+ xExtFileDlg->getValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS, 0 );
+
+ aVal >>= bUseFilterOptions;
+ if ( !bUseFilterOptions )
+ bUseFilterOptions =
+ ( GetMediaDescr().find( aFilterDataString ) == GetMediaDescr().end()
+ && GetMediaDescr().find( aFilterOptionsString ) == GetMediaDescr().end() );
+ }
+ catch( lang::IllegalArgumentException& )
+ {}
+ }
+ }
+
+ delete pFileDlg;
+
+ // merge in results of the dialog execution
+ GetMediaDescr()[::rtl::OUString::createFromAscii( "URL" )] <<=
+ ::rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ));
+ GetMediaDescr()[aFilterNameString] <<= aFilterName;
+
+ return bUseFilterOptions;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool ModelData_Impl::ShowDocumentInfoDialog()
+{
+ sal_Bool bDialogUsed = sal_False;
+
+ try {
+ uno::Reference< frame::XController > xController = GetModel()->getCurrentController();
+ if ( xController.is() )
+ {
+ uno::Reference< frame::XDispatchProvider > xFrameDispatch( xController->getFrame(), uno::UNO_QUERY );
+ if ( xFrameDispatch.is() )
+ {
+ util::URL aURL;
+ aURL.Complete = ::rtl::OUString::createFromAscii( ".uno:SetDocumentProperties" );
+
+ uno::Reference< util::XURLTransformer > xTransformer(
+ m_pOwner->GetServiceFactory()->createInstance(
+ DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer") ),
+ uno::UNO_QUERY );
+ if ( xTransformer.is() && xTransformer->parseStrict( aURL ) )
+ {
+ uno::Reference< frame::XDispatch > xDispatch = xFrameDispatch->queryDispatch(
+ aURL,
+ ::rtl::OUString::createFromAscii( "_self" ),
+ 0 );
+ if ( xDispatch.is() )
+ {
+ xDispatch->dispatch( aURL, uno::Sequence< beans::PropertyValue >() );
+ bDialogUsed = sal_True;
+ }
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ return bDialogUsed;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString ModelData_Impl::GetReccomendedDir( const ::rtl::OUString& aSuggestedDir, const sfx2::FileDialogHelper::Context& aCtxt )
+{
+ ::rtl::OUString aReccomendedDir;
+
+ if ( ( aSuggestedDir.getLength() || GetStorable()->hasLocation() )
+ && !GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "RepairPackage" ),
+ sal_False ) )
+ {
+ INetURLObject aLocation;
+ if ( aSuggestedDir.getLength() )
+ aLocation = INetURLObject( aSuggestedDir );
+ else
+ {
+ ::rtl::OUString aOldURL = GetStorable()->getLocation();
+ if ( aOldURL.getLength() )
+ {
+ INetURLObject aTmp( aOldURL );
+ if ( aTmp.removeSegment() )
+ aLocation = aTmp;
+ }
+
+ if ( aLocation.HasError() )
+ aLocation = INetURLObject( SvtPathOptions().GetWorkPath() );
+ }
+
+ aLocation.setFinalSlash();
+ if ( !aLocation.HasError() )
+ aReccomendedDir = aLocation.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ {
+ // pb: set graphic path if context == SD_EXPORT or SI_EXPORT else work path
+ ::rtl::OUString aConfigSuggestion( ( aCtxt != sfx2::FileDialogHelper::UNKNOWN_CONTEXT ) ? SvtPathOptions().GetGraphicPath() : SvtPathOptions().GetWorkPath() );
+ aReccomendedDir = INetURLObject( aConfigSuggestion ).GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ return aReccomendedDir;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString ModelData_Impl::GetReccomendedName( const ::rtl::OUString& aSuggestedName, const ::rtl::OUString& aTypeName )
+{
+ // the last used name might be provided by aSuggestedName from the old selection, or from the MediaDescriptor
+ ::rtl::OUString aReccomendedName;
+
+ if ( aSuggestedName.getLength() )
+ aReccomendedName = aSuggestedName;
+ else
+ {
+ aReccomendedName = INetURLObject( GetStorable()->getLocation() ).GetName( INetURLObject::DECODE_WITH_CHARSET );
+ if ( !aReccomendedName.getLength() )
+ {
+ try {
+ uno::Reference< frame::XTitle > xTitle( GetModel(), uno::UNO_QUERY_THROW );
+ aReccomendedName = xTitle->getTitle();
+ } catch( uno::Exception& ) {}
+ }
+
+ if ( aReccomendedName.getLength() && aTypeName.getLength() )
+ {
+ // adjust the extension to the type
+ uno::Reference< container::XNameAccess > xTypeDetection = uno::Reference< container::XNameAccess >(
+ m_pOwner->GetServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
+ uno::UNO_QUERY );
+ if ( xTypeDetection.is() )
+ {
+ INetURLObject aObj( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///c:/" ) ) + aReccomendedName );
+
+ uno::Sequence< beans::PropertyValue > aTypeNameProps;
+ if ( ( xTypeDetection->getByName( aTypeName ) >>= aTypeNameProps ) && aTypeNameProps.getLength() )
+ {
+ ::comphelper::SequenceAsHashMap aTypeNamePropsHM( aTypeNameProps );
+ uno::Sequence< ::rtl::OUString > aExtensions = aTypeNamePropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "Extensions" ),
+ ::uno::Sequence< ::rtl::OUString >() );
+ if ( aExtensions.getLength() )
+ aObj.SetExtension( aExtensions[0] );
+ }
+
+ aReccomendedName = aObj.GetName( INetURLObject::DECODE_WITH_CHARSET );
+ }
+ }
+ }
+
+ return aReccomendedName;
+}
+
+
+//=========================================================================
+// class SfxStoringHelper
+//=========================================================================
+//-------------------------------------------------------------------------
+SfxStoringHelper::SfxStoringHelper( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+: m_xFactory( xFactory )
+{
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< lang::XMultiServiceFactory > SfxStoringHelper::GetServiceFactory()
+{
+ if ( !m_xFactory.is() )
+ {
+ m_xFactory = ::comphelper::getProcessServiceFactory();
+ if( !m_xFactory.is() )
+ throw uno::RuntimeException(); // TODO:
+ }
+
+ return m_xFactory;
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< container::XNameAccess > SfxStoringHelper::GetFilterConfiguration()
+{
+ if ( !m_xFilterCFG.is() )
+ {
+ m_xFilterCFG = uno::Reference< container::XNameAccess >(
+ GetServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
+ uno::UNO_QUERY );
+
+ if ( !m_xFilterCFG.is() )
+ throw uno::RuntimeException();
+ }
+
+ return m_xFilterCFG;
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< container::XContainerQuery > SfxStoringHelper::GetFilterQuery()
+{
+ if ( !m_xFilterQuery.is() )
+ {
+ m_xFilterQuery = uno::Reference< container::XContainerQuery >( GetFilterConfiguration(), uno::UNO_QUERY );
+ if ( !m_xFilterQuery.is() )
+ throw uno::RuntimeException();
+ }
+
+ return m_xFilterQuery;
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< ::com::sun::star::frame::XModuleManager > SfxStoringHelper::GetModuleManager()
+{
+ if ( !m_xModuleManager.is() )
+ {
+ m_xModuleManager = uno::Reference< ::com::sun::star::frame::XModuleManager >(
+ GetServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.frame.ModuleManager" ) ),
+ uno::UNO_QUERY );
+
+ if ( !m_xModuleManager.is() )
+ throw uno::RuntimeException();
+ }
+
+ return m_xModuleManager;
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< container::XNameAccess > SfxStoringHelper::GetNamedModuleManager()
+{
+ if ( !m_xNamedModManager.is() )
+ {
+ m_xNamedModManager = uno::Reference< container::XNameAccess >( GetModuleManager(), uno::UNO_QUERY );
+ if ( !m_xNamedModManager.is() )
+ throw uno::RuntimeException();
+ }
+
+ return m_xNamedModManager;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel >& xModel,
+ const ::rtl::OUString& aSlotName,
+ uno::Sequence< beans::PropertyValue >& aArgsSequence,
+ sal_Bool bPreselectPassword,
+ ::rtl::OUString aSuggestedName,
+ sal_uInt16 nDocumentSignatureState )
+{
+ ModelData_Impl aModelData( *this, xModel, aArgsSequence );
+
+ sal_Bool bDialogUsed = sal_False;
+
+ INetURLObject aURL;
+
+ sal_Bool bSetStandardName = sal_False; // can be set only for SaveAs
+
+ // parse the slot name
+ sal_Int8 nStoreMode = getStoreModeFromSlotName( aSlotName );
+ sal_Int8 nStatusSave = STATUS_NO_ACTION;
+
+ // handle the special cases
+ if ( nStoreMode & SAVEAS_REQUESTED )
+ {
+ ::comphelper::SequenceAsHashMap::const_iterator aSaveToIter =
+ aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "SaveTo" ) );
+ if ( aSaveToIter != aModelData.GetMediaDescr().end() )
+ {
+ sal_Bool bWideExport = sal_False;
+ aSaveToIter->second >>= bWideExport;
+ if ( bWideExport )
+ nStoreMode = EXPORT_REQUESTED | WIDEEXPORT_REQUESTED;
+ }
+
+ // if saving is not acceptable the warning must be shown even in case of SaveAs operation
+ if ( ( nStoreMode & SAVEAS_REQUESTED ) && aModelData.CheckSaveAcceptable( STATUS_SAVEAS ) == STATUS_NO_ACTION )
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT );
+ }
+ else if ( nStoreMode & SAVE_REQUESTED )
+ {
+ // if saving is not acceptable by the configuration the warning must be shown
+ nStatusSave = aModelData.CheckSaveAcceptable( STATUS_SAVE );
+
+ if ( nStatusSave == STATUS_NO_ACTION )
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT );
+ else if ( nStatusSave == STATUS_SAVE )
+ {
+ // check whether it is possible to use save operation
+ nStatusSave = aModelData.CheckStateForSave();
+ }
+
+ if ( nStatusSave == STATUS_NO_ACTION )
+ {
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT );
+ }
+ else if ( nStatusSave != STATUS_SAVE )
+ {
+ // this should be a usual SaveAs operation
+ nStoreMode = SAVEAS_REQUESTED;
+ if ( nStatusSave == STATUS_SAVEAS_STANDARDNAME )
+ bSetStandardName = sal_True;
+ }
+ }
+
+ if ( !( nStoreMode & EXPORT_REQUESTED ) )
+ {
+ // if it is no export, warn user that the signature will be removed
+ if ( SIGNATURESTATE_SIGNATURES_OK == nDocumentSignatureState
+ || SIGNATURESTATE_SIGNATURES_INVALID == nDocumentSignatureState
+ || SIGNATURESTATE_SIGNATURES_NOTVALIDATED == nDocumentSignatureState
+ || SIGNATURESTATE_SIGNATURES_PARTIAL_OK == nDocumentSignatureState)
+ {
+ if ( QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_LOSINGSIGNATURE ) ).Execute() != RET_YES )
+ {
+ // the user has decided not to store the document
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ ERRCODE_IO_ABORT );
+ }
+ }
+ }
+
+ if ( nStoreMode & SAVE_REQUESTED && nStatusSave == STATUS_SAVE )
+ {
+ // Document properties can contain streams that should be freed before storing
+ aModelData.FreeDocumentProps();
+
+ if ( aModelData.GetStorable2().is() )
+ {
+ try
+ {
+ aModelData.GetStorable2()->storeSelf( aModelData.GetMediaDescr().getAsConstPropertyValueList() );
+ }
+ catch( lang::IllegalArgumentException& )
+ {
+ OSL_ENSURE( sal_False, "ModelData didn't handle illegal parameters, all the parameters are ignored!\n" );
+ aModelData.GetStorable()->store();
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "XStorable2 is not supported by the model!\n" );
+ aModelData.GetStorable()->store();
+ }
+
+ return sal_False;
+ }
+
+ // preselect a filter for the storing process
+ uno::Sequence< beans::PropertyValue > aFilterProps = aModelData.GetPreselectedFilter_Impl( nStoreMode );
+
+ DBG_ASSERT( aFilterProps.getLength(), "No filter for storing!\n" );
+ if ( !aFilterProps.getLength() )
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ ERRCODE_IO_INVALIDPARAMETER );
+
+ ::comphelper::SequenceAsHashMap aFilterPropsHM( aFilterProps );
+ ::rtl::OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "Name" ),
+ ::rtl::OUString() );
+
+ ::rtl::OUString aFilterFromMediaDescr = aModelData.GetMediaDescr().getUnpackedValueOrDefault(
+ aFilterNameString,
+ ::rtl::OUString() );
+ ::rtl::OUString aOldFilterName = aModelData.GetDocProps().getUnpackedValueOrDefault(
+ aFilterNameString,
+ ::rtl::OUString() );
+
+ sal_Bool bUseFilterOptions = sal_False;
+ ::comphelper::SequenceAsHashMap::const_iterator aFileNameIter = aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "URL" ) );
+
+ if ( ( nStoreMode & EXPORT_REQUESTED ) && ( nStoreMode & PDFEXPORT_REQUESTED ) && !( nStoreMode & PDFDIRECTEXPORT_REQUESTED ) )
+ {
+ // this is PDF export, the filter options dialog should be shown before the export
+ aModelData.GetMediaDescr()[aFilterNameString] <<= aFilterName;
+ if ( aModelData.GetMediaDescr().find( aFilterFlagsString ) == aModelData.GetMediaDescr().end()
+ && aModelData.GetMediaDescr().find( aFilterOptionsString ) == aModelData.GetMediaDescr().end()
+ && aModelData.GetMediaDescr().find( aFilterDataString ) == aModelData.GetMediaDescr().end() )
+ {
+ // execute filter options dialog since no options are set in the media descriptor
+ if ( aModelData.ExecuteFilterDialog_Impl( aFilterName ) )
+ bDialogUsed = sal_True;
+ }
+ }
+
+ if ( aFileNameIter == aModelData.GetMediaDescr().end() )
+ {
+ sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG;
+ ::comphelper::SequenceAsHashMap::const_iterator aDlgIter =
+ aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "UseSystemDialog" ) );
+ if ( aDlgIter != aModelData.GetMediaDescr().end() )
+ {
+ sal_Bool bUseSystemDialog = sal_True;
+ if ( aDlgIter->second >>= bUseSystemDialog )
+ {
+ if ( bUseSystemDialog )
+ nDialog = SFX2_IMPL_DIALOG_SYSTEM;
+ else
+ nDialog = SFX2_IMPL_DIALOG_OOO;
+ }
+ }
+
+ // The Dispatch supports parameter FolderName that overwrites SuggestedSaveAsDir
+ ::rtl::OUString aSuggestedDir = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FolderName" ) ), ::rtl::OUString() );
+ if ( !aSuggestedDir.getLength() )
+ {
+ aSuggestedDir = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsDir" ) ), ::rtl::OUString() );
+ if ( !aSuggestedDir.getLength() )
+ aSuggestedDir = aModelData.GetDocProps().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsDir" ) ), ::rtl::OUString() );
+ }
+
+ aSuggestedName = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsName" ) ), ::rtl::OUString() );
+ if ( !aSuggestedName.getLength() )
+ aSuggestedName = aModelData.GetDocProps().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsName" ) ), ::rtl::OUString() );
+
+ ::rtl::OUString sStandardDir;
+ ::comphelper::SequenceAsHashMap::const_iterator aStdDirIter =
+ aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "StandardDir" ) );
+ if ( aStdDirIter != aModelData.GetMediaDescr().end() )
+ aStdDirIter->second >>= sStandardDir;
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > aBlackList;
+
+ ::comphelper::SequenceAsHashMap::const_iterator aBlackListIter =
+ aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "BlackList" ) );
+ if ( aBlackListIter != aModelData.GetMediaDescr().end() )
+ aBlackListIter->second >>= aBlackList;
+
+ sal_Bool bExit = sal_False;
+ while ( !bExit )
+ {
+ bUseFilterOptions = aModelData.OutputFileDialog( nStoreMode, aFilterProps, bSetStandardName, aSuggestedName, bPreselectPassword, aSuggestedDir, nDialog, sStandardDir, aBlackList );
+
+ // in case the dialog is opend a second time the folder should be the same as before, not what was handed over by parameters
+ aSuggestedDir = ::rtl::OUString();
+ if ( nStoreMode == SAVEAS_REQUESTED )
+ {
+ // in case of saving check filter for possible alien warning
+ ::rtl::OUString aSelFilterName = aModelData.GetMediaDescr().getUnpackedValueOrDefault(
+ aFilterNameString,
+ ::rtl::OUString() );
+ sal_Int8 nStatusFilterSave = aModelData.CheckFilter( aSelFilterName );
+ if ( nStatusFilterSave == STATUS_SAVEAS_STANDARDNAME )
+ {
+ // switch to best filter
+ bSetStandardName = sal_True;
+ }
+ else if ( nStatusFilterSave == STATUS_SAVE )
+ {
+ // user confirmed alien filter or "good" filter is used
+ bExit = sal_True;
+ }
+ }
+ else
+ bExit = sal_True;
+ }
+
+ bDialogUsed = sal_True;
+ aFileNameIter = aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "URL" ) );
+ }
+ else
+ {
+ // the target file name is provided so check if new filter options
+ // are provided or old options can be used
+ if ( aFilterFromMediaDescr.equals( aOldFilterName ) )
+ {
+ ::comphelper::SequenceAsHashMap::const_iterator aIter =
+ aModelData.GetDocProps().find( aFilterOptionsString );
+ if ( aIter != aModelData.GetDocProps().end()
+ && aModelData.GetMediaDescr().find( aFilterOptionsString ) == aModelData.GetMediaDescr().end() )
+ aModelData.GetMediaDescr()[aIter->first] = aIter->second;
+
+ aIter = aModelData.GetDocProps().find( aFilterDataString );
+ if ( aIter != aModelData.GetDocProps().end()
+ && aModelData.GetMediaDescr().find( aFilterDataString ) == aModelData.GetMediaDescr().end() )
+ aModelData.GetMediaDescr()[aIter->first] = aIter->second;
+ }
+ }
+
+ if ( aFileNameIter != aModelData.GetMediaDescr().end() )
+ {
+ ::rtl::OUString aFileName;
+ aFileNameIter->second >>= aFileName;
+ aURL.SetURL( aFileName );
+ DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" );
+
+ ::comphelper::SequenceAsHashMap::const_iterator aIter =
+ aModelData.GetMediaDescr().find( aFilterNameString );
+
+ if ( aIter != aModelData.GetMediaDescr().end() )
+ aIter->second >>= aFilterName;
+ else
+ aModelData.GetMediaDescr()[aFilterNameString] <<= aFilterName;
+
+ DBG_ASSERT( aFilterName.getLength(), "Illegal filter!" );
+ }
+ else
+ {
+ DBG_ASSERT( sal_False, "This code must be unreachable!\n" );
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ ERRCODE_IO_INVALIDPARAMETER );
+ }
+
+ ::comphelper::SequenceAsHashMap::const_iterator aIter =
+ aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "FilterFlags" ) );
+ sal_Bool bFilterFlagsSet = ( aIter != aModelData.GetMediaDescr().end() );
+
+ if( !( nStoreMode & PDFEXPORT_REQUESTED ) && !bFilterFlagsSet
+ && ( ( nStoreMode & EXPORT_REQUESTED ) || bUseFilterOptions ) )
+ {
+ // execute filter options dialog
+ if ( aModelData.ExecuteFilterDialog_Impl( aFilterName ) )
+ bDialogUsed = sal_True;
+ }
+
+ // so the arguments will not change any more and can be stored to the main location
+ aArgsSequence = aModelData.GetMediaDescr().getAsConstPropertyValueList();
+
+ // store the document and handle it's docinfo
+ SvtSaveOptions aOptions;
+
+ DocumentSettingsGuard aSettingsGuard( aModelData.GetModel(), aModelData.IsRecommendReadOnly(), nStoreMode & EXPORT_REQUESTED );
+
+ if ( aOptions.IsDocInfoSave()
+ && ( !aModelData.GetStorable()->hasLocation()
+ || INetURLObject( aModelData.GetStorable()->getLocation() ) != aURL ) )
+ {
+ // this is defenitly not a Save operation
+ // so the document info can be updated
+
+ // on export document info must be preserved
+ uno::Reference<document::XDocumentInfoSupplier> xDIS(
+ aModelData.GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<util::XCloneable> xCloneable(
+ xDIS->getDocumentInfo(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentInfo> xOldDocInfo(
+ xCloneable->createClone(), uno::UNO_QUERY_THROW);
+
+ // use dispatch API to show document info dialog
+ if ( aModelData.ShowDocumentInfoDialog() )
+ bDialogUsed = sal_True;
+ else
+ {
+ DBG_ERROR( "Can't execute document info dialog!\n" );
+ }
+
+ try {
+ // Document properties can contain streams that should be freed before storing
+ aModelData.FreeDocumentProps();
+ if ( ( nStoreMode & EXPORT_REQUESTED ) )
+ aModelData.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence );
+ else
+ aModelData.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence );
+ }
+ catch( uno::Exception& )
+ {
+ if ( ( nStoreMode & EXPORT_REQUESTED ) )
+ SetDocInfoState( aModelData.GetModel(), xOldDocInfo, sal_True );
+
+ throw;
+ }
+
+ if ( ( nStoreMode & EXPORT_REQUESTED ) )
+ SetDocInfoState( aModelData.GetModel(), xOldDocInfo, sal_True );
+ }
+ else
+ {
+ // Document properties can contain streams that should be freed before storing
+ aModelData.FreeDocumentProps();
+
+ // this is actually a save operation with different parameters
+ // so storeTo or storeAs without DocInfo operations are used
+ if ( ( nStoreMode & EXPORT_REQUESTED ) )
+ aModelData.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence );
+ else
+ aModelData.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence );
+ }
+
+ return bDialogUsed;
+}
+
+//-------------------------------------------------------------------------
+// static
+uno::Sequence< beans::PropertyValue > SfxStoringHelper::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 )
+ {
+ ::comphelper::SequenceAsHashMap aPropsHM( aProps );
+ sal_Int32 nFlags = aPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "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;
+}
+
+//-------------------------------------------------------------------------
+// static
+sal_Bool SfxStoringHelper::CheckFilterOptionsAppearence(
+ const uno::Reference< container::XNameAccess >& xFilterCFG,
+ const ::rtl::OUString& aFilterName )
+{
+ sal_Bool bUseFilterOptions = sal_False;
+
+ DBG_ASSERT( xFilterCFG.is(), "No filter configuration!\n" );
+ if( xFilterCFG.is() )
+ {
+ try {
+ uno::Sequence < beans::PropertyValue > aProps;
+ uno::Any aAny = xFilterCFG->getByName( aFilterName );
+ if ( aAny >>= aProps )
+ {
+ ::comphelper::SequenceAsHashMap aPropsHM( aProps );
+ ::rtl::OUString aServiceName = aPropsHM.getUnpackedValueOrDefault(
+ ::rtl::OUString::createFromAscii( "UIComponent" ),
+ ::rtl::OUString() );
+ if( aServiceName.getLength() )
+ bUseFilterOptions = sal_True;
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+
+ return bUseFilterOptions;
+}
+
+//-------------------------------------------------------------------------
+// static
+void SfxStoringHelper::SetDocInfoState(
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< document::XDocumentInfo >& i_xOldDocInfo,
+ sal_Bool bNoModify )
+{
+ uno::Reference< document::XDocumentInfoSupplier > xModelDocInfoSupplier( xModel, uno::UNO_QUERY );
+ if ( !xModelDocInfoSupplier.is() )
+ throw uno::RuntimeException(); // TODO:
+
+ uno::Reference< document::XDocumentInfo > xDocInfoToFill = xModelDocInfoSupplier->getDocumentInfo();
+ uno::Reference< beans::XPropertySet > xPropSet( i_xOldDocInfo,
+ uno::UNO_QUERY_THROW );
+
+ uno::Reference< util::XModifiable > xModifiable( xModel, uno::UNO_QUERY );
+ if ( bNoModify && !xModifiable.is() )
+ throw uno::RuntimeException();
+
+ sal_Bool bIsModified = bNoModify && xModifiable->isModified();
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xSet( xDocInfoToFill, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertyContainer > xContainer( xSet, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
+ uno::Sequence< beans::Property > lProps = xSetInfo->getProperties();
+ const beans::Property* pProps = lProps.getConstArray();
+ sal_Int32 c = lProps.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ uno::Any aValue = xPropSet->getPropertyValue( pProps[i].Name );
+ if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE )
+ // QUESTION: DefaultValue?!
+ xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue );
+ try
+ {
+ // it is possible that the propertysets from XML and binary files differ; we shouldn't break then
+ xSet->setPropertyValue( pProps[i].Name, aValue );
+ }
+ catch ( uno::Exception& ) {}
+ }
+
+ sal_Int16 nCount = i_xOldDocInfo->getUserFieldCount();
+ sal_Int16 nSupportedCount = xDocInfoToFill->getUserFieldCount();
+ for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ )
+ {
+ ::rtl::OUString aPropName = i_xOldDocInfo->getUserFieldName( nInd );
+ xDocInfoToFill->setUserFieldName( nInd, aPropName );
+ ::rtl::OUString aPropVal = i_xOldDocInfo->getUserFieldValue( nInd );
+ xDocInfoToFill->setUserFieldValue( nInd, aPropVal );
+ }
+ }
+ catch ( uno::Exception& ) {}
+
+ // set the modified flag back if required
+ if ( bNoModify && bIsModified != xModifiable->isModified() )
+ xModifiable->setModified( bIsModified );
+}
+
+//-------------------------------------------------------------------------
+// static
+sal_Bool SfxStoringHelper::WarnUnacceptableFormat( const uno::Reference< frame::XModel >& xModel,
+ ::rtl::OUString aOldUIName,
+ ::rtl::OUString /*aDefUIName*/,
+ sal_Bool /*bCanProceedFurther*/ )
+{
+ if ( !SvtSaveOptions().IsWarnAlienFormat() )
+ return sal_True;
+
+ Window* pWin = SfxStoringHelper::GetModelWindow( xModel );
+ SfxAlienWarningDialog aDlg( pWin, aOldUIName );
+
+ return aDlg.Execute() == RET_OK;
+}
+
+// static
+void SfxStoringHelper::ExecuteFilterDialog( SfxStoringHelper& _rStorageHelper
+ ,const ::rtl::OUString& _sFilterName
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _xModel
+ ,/*OUT*/::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArgsSequence)
+{
+ ModelData_Impl aModelData( _rStorageHelper, _xModel, _rArgsSequence );
+ if ( aModelData.ExecuteFilterDialog_Impl( _sFilterName ) )
+ _rArgsSequence = aModelData.GetMediaDescr().getAsConstPropertyValueList();
+}
+
+// static
+Window* SfxStoringHelper::GetModelWindow( const uno::Reference< frame::XModel >& xModel )
+{
+ Window* pWin = 0;
+ try {
+ if ( xModel.is() )
+ {
+ uno::Reference< frame::XController > xController = xModel->getCurrentController();
+ if ( xController.is() )
+ {
+ uno::Reference< frame::XFrame > xFrame = xController->getFrame();
+ if ( xFrame.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow = xFrame->getContainerWindow();
+ if ( xWindow.is() )
+ {
+ VCLXWindow* pVCLWindow = VCLXWindow::GetImplementation( xWindow );
+ if ( pVCLWindow )
+ pWin = pVCLWindow->GetWindow();
+ }
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ return pWin;
+}
+
diff --git a/sfx2/source/doc/iframe.cxx b/sfx2/source/doc/iframe.cxx
new file mode 100644
index 000000000000..3ad0cc51a923
--- /dev/null
+++ b/sfx2/source/doc/iframe.cxx
@@ -0,0 +1,397 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "iframe.hxx"
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <rtl/ustring.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svtools/miscopt.hxx>
+#include <vcl/window.hxx>
+
+using namespace ::com::sun::star;
+
+namespace sfx2
+{
+
+class IFrameWindow_Impl : public Window
+{
+ uno::Reference < frame::XFrame > mxFrame;
+ sal_Bool bActive;
+ sal_Bool bBorder;
+
+public:
+ IFrameWindow_Impl( Window *pParent,
+ sal_Bool bHasBorder,
+ WinBits nWinBits = 0 );
+
+public:
+ void SetBorder( sal_Bool bNewBorder = sal_True );
+ sal_Bool HasBorder() const { return bBorder; }
+};
+
+IFrameWindow_Impl::IFrameWindow_Impl( Window *pParent, sal_Bool bHasBorder, WinBits nWinBits )
+ : Window( pParent, nWinBits | WB_CLIPCHILDREN | WB_NODIALOGCONTROL | WB_DOCKBORDER )
+ , bActive(sal_False)
+ , bBorder(bHasBorder)
+{
+ if ( !bHasBorder )
+ SetBorderStyle( WINDOW_BORDER_NOBORDER );
+ else
+ SetBorderStyle( WINDOW_BORDER_NORMAL );
+ //SetActivateMode( ACTIVATE_MODE_GRABFOCUS );
+}
+
+void IFrameWindow_Impl::SetBorder( sal_Bool bNewBorder )
+{
+ if ( bBorder != bNewBorder )
+ {
+ Size aSize = GetSizePixel();
+ bBorder = bNewBorder;
+ if ( bBorder )
+ SetBorderStyle( WINDOW_BORDER_NORMAL );
+ else
+ SetBorderStyle( WINDOW_BORDER_NOBORDER );
+ if ( GetSizePixel() != aSize )
+ SetSizePixel( aSize );
+ }
+}
+
+#define PROPERTY_UNBOUND 0
+
+#define WID_FRAME_URL 1
+#define WID_FRAME_NAME 2
+#define WID_FRAME_IS_AUTO_SCROLL 3
+#define WID_FRAME_IS_SCROLLING_MODE 4
+#define WID_FRAME_IS_BORDER 5
+#define WID_FRAME_IS_AUTO_BORDER 6
+#define WID_FRAME_MARGIN_WIDTH 7
+#define WID_FRAME_MARGIN_HEIGHT 8
+
+const SfxItemPropertyMapEntry* lcl_GetIFramePropertyMap_Impl()
+{
+ static SfxItemPropertyMapEntry aIFramePropertyMap_Impl[] =
+ {
+ { MAP_CHAR_LEN("FrameIsAutoBorder"), WID_FRAME_IS_AUTO_BORDER, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("FrameIsAutoScroll"), WID_FRAME_IS_AUTO_SCROLL, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("FrameIsBorder"), WID_FRAME_IS_BORDER, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("FrameIsScrollingMode"), WID_FRAME_IS_SCROLLING_MODE, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("FrameMarginHeight"), WID_FRAME_MARGIN_HEIGHT, &::getCppuType( (sal_Int32*)0 ), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("FrameMarginWidth"), WID_FRAME_MARGIN_WIDTH, &::getCppuType( (sal_Int32*)0 ), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("FrameName"), WID_FRAME_NAME, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("FrameURL"), WID_FRAME_URL, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aIFramePropertyMap_Impl;
+}
+
+SFX_IMPL_XSERVICEINFO( IFrameObject, "com.sun.star.embed.SpecialEmbeddedObject", "com.sun.star.comp.sfx2.IFrameObject" )
+SFX_IMPL_SINGLEFACTORY( IFrameObject );
+
+IFrameObject::IFrameObject( const uno::Reference < lang::XMultiServiceFactory >& rFact )
+ : mxFact( rFact )
+ , maPropMap( lcl_GetIFramePropertyMap_Impl() )
+{
+}
+
+IFrameObject::~IFrameObject()
+{
+}
+
+
+void SAL_CALL IFrameObject::initialize( const uno::Sequence< uno::Any >& aArguments ) throw ( uno::Exception, uno::RuntimeException )
+{
+ if ( aArguments.getLength() )
+ aArguments[0] >>= mxObj;
+}
+
+sal_Bool SAL_CALL IFrameObject::load(
+ const uno::Sequence < com::sun::star::beans::PropertyValue >& /*lDescriptor*/,
+ const uno::Reference < frame::XFrame >& xFrame )
+throw( uno::RuntimeException )
+{
+ if ( SvtMiscOptions().IsPluginsEnabled() )
+ {
+ DBG_ASSERT( !mxFrame.is(), "Frame already existing!" );
+ Window* pParent = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ IFrameWindow_Impl* pWin = new IFrameWindow_Impl( pParent, maFrmDescr.IsFrameBorderOn() );
+ pWin->SetSizePixel( pParent->GetOutputSizePixel() );
+ pWin->SetBackground();
+ pWin->Show();
+
+ uno::Reference < awt::XWindow > xWindow( pWin->GetComponentInterface(), uno::UNO_QUERY );
+ xFrame->setComponent( xWindow, uno::Reference < frame::XController >() );
+
+ // we must destroy the IFrame before the parent is destroyed
+ xWindow->addEventListener( this );
+
+ mxFrame = uno::Reference< frame::XFrame >( mxFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Frame" ) ),
+ uno::UNO_QUERY );
+ uno::Reference < awt::XWindow > xWin( pWin->GetComponentInterface(), uno::UNO_QUERY );
+ mxFrame->initialize( xWin );
+ mxFrame->setName( maFrmDescr.GetName() );
+
+ uno::Reference < frame::XFramesSupplier > xFramesSupplier( xFrame, uno::UNO_QUERY );
+ if ( xFramesSupplier.is() )
+ mxFrame->setCreator( xFramesSupplier );
+
+ uno::Reference< frame::XDispatchProvider > xProv( mxFrame, uno::UNO_QUERY );
+
+ util::URL aTargetURL;
+ aTargetURL.Complete = ::rtl::OUString( maFrmDescr.GetURL().GetMainURL( INetURLObject::NO_DECODE ) );
+ uno::Reference < util::XURLTransformer > xTrans( mxFact->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), uno::UNO_QUERY );
+ xTrans->parseStrict( aTargetURL );
+
+ uno::Sequence < beans::PropertyValue > aProps(2);
+ aProps[0].Name = ::rtl::OUString::createFromAscii("PluginMode");
+ aProps[0].Value <<= (sal_Int16) 2;
+ aProps[1].Name = ::rtl::OUString::createFromAscii("ReadOnly");
+ aProps[1].Value <<= (sal_Bool) sal_True;
+ uno::Reference < frame::XDispatch > xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString::createFromAscii("_self"), 0 );
+ if ( xDisp.is() )
+ xDisp->dispatch( aTargetURL, aProps );
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void SAL_CALL IFrameObject::cancel() throw( com::sun::star::uno::RuntimeException )
+{
+ try
+ {
+ uno::Reference < util::XCloseable > xClose( mxFrame, uno::UNO_QUERY );
+ if ( xClose.is() )
+ xClose->close( sal_True );
+ mxFrame = 0;
+ }
+ catch ( uno::Exception& )
+ {}
+}
+
+void SAL_CALL IFrameObject::close( sal_Bool /*bDeliverOwnership*/ ) throw( com::sun::star::util::CloseVetoException, com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL IFrameObject::addCloseListener( const com::sun::star::uno::Reference < com::sun::star::util::XCloseListener >& ) throw( com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL IFrameObject::removeCloseListener( const com::sun::star::uno::Reference < com::sun::star::util::XCloseListener >& ) throw( com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL IFrameObject::disposing( const com::sun::star::lang::EventObject& ) throw (com::sun::star::uno::RuntimeException)
+{
+ cancel();
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL IFrameObject::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException )
+{
+ static uno::Reference< beans::XPropertySetInfo > xInfo = new SfxItemPropertySetInfo( &maPropMap );
+ return xInfo;
+}
+
+void SAL_CALL IFrameObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aAny)
+ throw ( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ const SfxItemPropertySimpleEntry* pEntry = maPropMap.getByName( aPropertyName );
+ if( !pEntry )
+ throw beans::UnknownPropertyException();
+ switch( pEntry->nWID )
+ {
+ case WID_FRAME_URL:
+ {
+ ::rtl::OUString aURL;
+ aAny >>= aURL;
+ maFrmDescr.SetURL( String(aURL) );
+ }
+ break;
+ case WID_FRAME_NAME:
+ {
+ ::rtl::OUString aName;
+ if ( aAny >>= aName )
+ maFrmDescr.SetName( aName );
+ }
+ break;
+ case WID_FRAME_IS_AUTO_SCROLL:
+ {
+ sal_Bool bIsAutoScroll = sal_Bool();
+ if ( (aAny >>= bIsAutoScroll) && bIsAutoScroll )
+ maFrmDescr.SetScrollingMode( ScrollingAuto );
+ }
+ break;
+ case WID_FRAME_IS_SCROLLING_MODE:
+ {
+ sal_Bool bIsScroll = sal_Bool();
+ if ( aAny >>= bIsScroll )
+ maFrmDescr.SetScrollingMode( bIsScroll ? ScrollingYes : ScrollingNo );
+ }
+ break;
+ case WID_FRAME_IS_BORDER:
+ {
+ sal_Bool bIsBorder = sal_Bool();
+ if ( aAny >>= bIsBorder )
+ maFrmDescr.SetFrameBorder( bIsBorder );
+ }
+ break;
+ case WID_FRAME_IS_AUTO_BORDER:
+ {
+ sal_Bool bIsAutoBorder = sal_Bool();
+ if ( (aAny >>= bIsAutoBorder) )
+ {
+ BOOL bBorder = maFrmDescr.IsFrameBorderOn();
+ maFrmDescr.ResetBorder();
+ if ( bIsAutoBorder )
+ maFrmDescr.SetFrameBorder( bBorder );
+ }
+ }
+ break;
+ case WID_FRAME_MARGIN_WIDTH:
+ {
+ sal_Int32 nMargin = 0;
+ Size aSize = maFrmDescr.GetMargin();
+ if ( aAny >>= nMargin )
+ {
+ aSize.Width() = nMargin;
+ maFrmDescr.SetMargin( aSize );
+ }
+ }
+ break;
+ case WID_FRAME_MARGIN_HEIGHT:
+ {
+ sal_Int32 nMargin = 0;
+ Size aSize = maFrmDescr.GetMargin();
+ if ( aAny >>= nMargin )
+ {
+ aSize.Height() = nMargin;
+ maFrmDescr.SetMargin( aSize );
+ }
+ }
+ break;
+ default: ;
+ }
+}
+
+uno::Any SAL_CALL IFrameObject::getPropertyValue(const ::rtl::OUString& aPropertyName)
+ throw ( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ const SfxItemPropertySimpleEntry* pEntry = maPropMap.getByName( aPropertyName );
+ if( !pEntry )
+ throw beans::UnknownPropertyException();
+ uno::Any aAny;
+ switch( pEntry->nWID )
+ {
+ case WID_FRAME_URL:
+ {
+ aAny <<= ::rtl::OUString( maFrmDescr.GetURL().GetMainURL( INetURLObject::NO_DECODE ) );
+ }
+ break;
+ case WID_FRAME_NAME:
+ {
+ aAny <<= ::rtl::OUString( maFrmDescr.GetName() );
+ }
+ break;
+ case WID_FRAME_IS_AUTO_SCROLL:
+ {
+ sal_Bool bIsAutoScroll = ( maFrmDescr.GetScrollingMode() == ScrollingAuto );
+ aAny <<= bIsAutoScroll;
+ }
+ break;
+ case WID_FRAME_IS_SCROLLING_MODE:
+ {
+ sal_Bool bIsScroll = ( maFrmDescr.GetScrollingMode() == ScrollingYes );
+ aAny <<= bIsScroll;
+ }
+ break;
+ case WID_FRAME_IS_BORDER:
+ {
+ sal_Bool bIsBorder = maFrmDescr.IsFrameBorderOn();
+ aAny <<= bIsBorder;
+ }
+ break;
+ case WID_FRAME_IS_AUTO_BORDER:
+ {
+ sal_Bool bIsAutoBorder = !maFrmDescr.IsFrameBorderSet();
+ aAny <<= bIsAutoBorder;
+ }
+ break;
+ case WID_FRAME_MARGIN_WIDTH:
+ {
+ aAny <<= (sal_Int32 ) maFrmDescr.GetMargin().Width();
+ }
+ break;
+ case WID_FRAME_MARGIN_HEIGHT:
+ {
+ aAny <<= (sal_Int32 ) maFrmDescr.GetMargin().Height();
+ }
+ default: ;
+ }
+ return aAny;
+}
+
+void SAL_CALL IFrameObject::addPropertyChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL IFrameObject::removePropertyChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL IFrameObject::addVetoableChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL IFrameObject::removeVetoableChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+::sal_Int16 SAL_CALL IFrameObject::execute() throw (::com::sun::star::uno::RuntimeException)
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ VclAbstractDialog* pDlg = pFact->CreateEditObjectDialog( NULL, SID_INSERT_FLOATINGFRAME, mxObj );
+ if ( pDlg )
+ pDlg->Execute();
+ return 0;
+}
+
+void SAL_CALL IFrameObject::setTitle( const ::rtl::OUString& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+}
diff --git a/sfx2/source/doc/makefile.mk b/sfx2/source/doc/makefile.mk
new file mode 100644
index 000000000000..b1bddf82e428
--- /dev/null
+++ b/sfx2/source/doc/makefile.mk
@@ -0,0 +1,105 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General 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=sfx2
+TARGET=doc
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+.IF "$(SYSTEM_LIBXML)" == "YES"
+CFLAGS+=-DSYSTEM_LIBXML $(LIBXML_CFLAGS)
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ doc.src new.src doctdlg.src docvor.src doctempl.src graphhelp.src
+
+SLOFILES = \
+ $(SLO)$/printhelper.obj \
+ $(SLO)$/docinf.obj \
+ $(SLO)$/oleprops.obj \
+ $(SLO)$/iframe.obj \
+ $(SLO)$/plugin.obj \
+ $(SLO)$/docfile.obj \
+ $(SLO)$/objuno.obj \
+ $(SLO)$/frmdescr.obj \
+ $(SLO)$/objxtor.obj \
+ $(SLO)$/objmisc.obj \
+ $(SLO)$/objstor.obj \
+ $(SLO)$/objcont.obj \
+ $(SLO)$/objserv.obj \
+ $(SLO)$/objitem.obj \
+ $(SLO)$/ownsubfilterservice.obj \
+ $(SLO)$/docfac.obj \
+ $(SLO)$/docfilt.obj \
+ $(SLO)$/doctempl.obj \
+ $(SLO)$/doctemplates.obj \
+ $(SLO)$/doctemplateslocal.obj \
+ $(SLO)$/docvor.obj \
+ $(SLO)$/new.obj \
+ $(SLO)$/doctdlg.obj \
+ $(SLO)$/sfxbasemodel.obj \
+ $(SLO)$/guisaveas.obj\
+ $(SLO)$/objembed.obj\
+ $(SLO)$/graphhelp.obj \
+ $(SLO)$/QuerySaveDocument.obj \
+ $(SLO)$/docinsert.obj \
+ $(SLO)$/docmacromode.obj \
+ $(SLO)$/SfxDocumentMetaData.obj \
+ $(SLO)$/DocumentMetadataAccess.obj \
+ $(SLO)$/Metadatable.obj \
+ $(SLO)$/sfxmodelfactory.obj \
+ $(SLO)$/sfxacldetect.obj \
+ $(SLO)$/docstoragemodifylistener.obj \
+ $(SLO)$/querytemplate.obj \
+ $(SLO)$/syspath.obj \
+ $(SLO)$/syspathw32.obj
+
+# $(SLO)$/applet.obj \
+
+.IF "$(GUI)" == "WNT"
+
+#HACK TO DISABLE PCH
+NOOPTFILES= \
+ $(SLO)$/sfxacldetect.obj \
+ $(SLO)$/syspathw32.obj
+.ENDIF
+
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/sfx2/source/doc/new.cxx b/sfx2/source/doc/new.cxx
new file mode 100644
index 000000000000..d3235b1c7a7f
--- /dev/null
+++ b/sfx2/source/doc/new.cxx
@@ -0,0 +1,745 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <sfx2/new.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/morebtn.hxx>
+#ifndef _SVMEDIT_HXX
+#include <svtools/svmedit.hxx>
+#endif
+#include <svl/itemset.hxx>
+#include <svl/eitem.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/localfilehelper.hxx>
+
+#include "new.hrc"
+#ifndef _SFX_DOC_HRC
+#include "doc.hrc"
+#endif
+#include <sfx2/sfx.hrc>
+#include "helpid.hrc"
+#include "sfxtypes.hxx"
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/objsh.hxx>
+#include "fltfnc.hxx"
+#include <sfx2/viewsh.hxx>
+#include "viewfac.hxx"
+#include "sfxresid.hxx"
+#include <sfx2/docfile.hxx>
+#include "preview.hxx"
+#include <sfx2/printer.hxx>
+#include <vcl/waitobj.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/jobset.hxx>
+#include <svtools/accessibilityoptions.hxx>
+
+// Draw modes
+#define OUTPUT_DRAWMODE_COLOR (DRAWMODE_DEFAULT)
+#define OUTPUT_DRAWMODE_GRAYSCALE (DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_BLACKTEXT | DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT)
+#define OUTPUT_DRAWMODE_BLACKWHITE (DRAWMODE_BLACKLINE | DRAWMODE_BLACKTEXT | DRAWMODE_WHITEFILL | DRAWMODE_GRAYBITMAP | DRAWMODE_WHITEGRADIENT)
+#define OUTPUT_DRAWMODE_CONTRAST (DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT)
+
+//========================================================================
+
+#define MORE_BTN(x) pMoreBt->x
+
+//========================================================================
+
+void SfxPreviewBase_Impl::SetObjectShell( SfxObjectShell* pObj )
+{
+ ::boost::shared_ptr<GDIMetaFile> pFile = pObj
+ ? pObj->GetPreviewMetaFile()
+ : ::boost::shared_ptr<GDIMetaFile>();
+ pMetaFile = pFile;
+ Invalidate();
+}
+
+SfxPreviewBase_Impl::SfxPreviewBase_Impl(
+ Window* pParent, const ResId& rResId )
+ : Window(pParent, rResId), pMetaFile()
+{
+}
+
+SfxPreviewBase_Impl::SfxPreviewBase_Impl( Window* pParent )
+ : Window(pParent, 0 ), pMetaFile()
+{
+ Resize();
+ Show();
+}
+
+SfxPreviewBase_Impl::~SfxPreviewBase_Impl()
+{
+}
+
+void SfxPreviewBase_Impl::Resize()
+{
+ Invalidate();
+}
+
+void SfxPreviewBase_Impl::SetGDIFile( ::boost::shared_ptr<GDIMetaFile> pFile )
+{
+ pMetaFile = pFile;
+ Invalidate();
+}
+
+SfxFrameWindow* SfxPreviewWin_Impl::PreviewFactory(
+ SfxFrame* pFrame, const String& /*rName*/ )
+{
+ return new SfxFrameWindow( new SfxPreviewWin_Impl(
+ &pFrame->GetCurrentViewFrame()->GetWindow() ) );
+}
+
+void SfxPreviewWin_Impl::ImpPaint(
+ const Rectangle&, GDIMetaFile* pFile, Window* pWindow )
+{
+ Size aTmpSize = pFile ? pFile->GetPrefSize() : Size(1,1 );
+ DBG_ASSERT( aTmpSize.Height()*aTmpSize.Width(),
+ "size of first page is 0, overload GetFirstPageSize or set vis-area!" );
+#define FRAME 4
+ long nWidth = pWindow->GetOutputSize().Width() - 2*FRAME;
+ long nHeight = pWindow->GetOutputSize().Height() - 2*FRAME;
+ if( nWidth < 0 ) nWidth = 0;
+ if( nHeight < 0 ) nHeight = 0;
+
+ double dRatio=((double)aTmpSize.Width())/aTmpSize.Height();
+ double dRatioPreV=((double) nWidth ) / nHeight;
+ Size aSize;
+ Point aPoint;
+ if (dRatio>dRatioPreV)
+ {
+ aSize=Size(nWidth, (USHORT)(nWidth/dRatio));
+ aPoint=Point( 0, (USHORT)((nHeight-aSize.Height())/2));
+ }
+ else
+ {
+ aSize=Size((USHORT)(nHeight*dRatio), nHeight);
+ aPoint=Point((USHORT)((nWidth-aSize.Width())/2),0);
+ }
+ Point bPoint=Point(nWidth,nHeight)-aPoint;
+
+
+ pWindow->SetLineColor();
+ Color aLightGrayCol( COL_LIGHTGRAY );
+ pWindow->SetFillColor( aLightGrayCol );
+ pWindow->DrawRect( Rectangle( Point( 0,0 ), pWindow->GetOutputSize() ) );
+ if ( pFile )
+ {
+ Color aBlackCol( COL_BLACK );
+ Color aWhiteCol( COL_WHITE );
+ pWindow->SetLineColor( aBlackCol );
+ pWindow->SetFillColor( aWhiteCol );
+ pWindow->DrawRect( Rectangle( aPoint + Point( FRAME, FRAME ), bPoint + Point( FRAME, FRAME ) ) );
+//! pFile->Move( Point( FRAME, FRAME ) );
+//! pFile->Scale( Fraction( aTmpSize.Width(), aSize.Width() ),
+//! Fraction( aTmpSize.Height(), aSize.Height() ) );
+ pFile->WindStart();
+ pFile->Play( pWindow, aPoint + Point( FRAME, FRAME ), aSize );
+ }
+}
+
+void SfxPreviewWin_Impl::Paint( const Rectangle& rRect )
+{
+ ImpPaint( rRect, pMetaFile.get(), this );
+}
+
+SfxPreviewWin::SfxPreviewWin(
+ Window* pParent, const ResId& rResId, SfxObjectShellLock &rDocSh )
+ : Window(pParent, rResId), rDocShell( rDocSh )
+{
+ SetHelpId( HID_PREVIEW_FRAME );
+
+ // adjust contrast mode initially
+ bool bUseContrast = UseHighContrastSetting();
+ SetDrawMode( bUseContrast ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR );
+
+ // #107818# This preview window is for document previews. Therefore
+ // right-to-left mode should be off
+ EnableRTL( FALSE );
+}
+
+void SfxPreviewWin::Paint( const Rectangle& rRect )
+{
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( &rDocShell );
+ if ( pFrame && pFrame->GetViewShell() &&
+ pFrame->GetViewShell()->GetPrinter() &&
+ pFrame->GetViewShell()->GetPrinter()->IsPrinting() )
+ {
+ return;
+ }
+
+ Size aTmpSize( rDocShell->GetFirstPageSize() );
+ GDIMetaFile aMtf;
+ VirtualDevice aDevice;
+
+ DBG_ASSERT( aTmpSize.Height() * aTmpSize.Width(), "size of first page is 0, overload GetFirstPageSize or set vis-area!" );
+
+ aMtf.SetPrefSize( aTmpSize );
+ aDevice.EnableOutput( FALSE );
+ aDevice.SetMapMode( rDocShell->GetMapUnit() );
+ aDevice.SetDrawMode( GetDrawMode() );
+ aMtf.Record( &aDevice );
+ rDocShell->DoDraw( &aDevice, Point(0,0), aTmpSize, JobSetup(), ASPECT_THUMBNAIL );
+ aMtf.Stop();
+ aMtf.WindStart();
+ SfxPreviewWin_Impl::ImpPaint( rRect, &aMtf, this );
+}
+
+void SfxPreviewWin::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ // adjust contrast mode
+ bool bUseContrast = UseHighContrastSetting();
+ SetDrawMode( bUseContrast ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR );
+ }
+}
+
+bool SfxPreviewWin::UseHighContrastSetting() const
+{
+ return GetSettings().GetStyleSettings().GetHighContrastMode();
+}
+
+
+class SfxNewFileDialog_Impl
+{
+ FixedText aRegionFt;
+ ListBox aRegionLb;
+ FixedText aTemplateFt;
+ ListBox aTemplateLb;
+
+ CheckBox aPreviewBtn;
+ SfxPreviewWin_Impl aPreviewWin;
+
+ FixedText aTitleFt;
+ Edit aTitleEd;
+ FixedText aThemaFt;
+ Edit aThemaEd;
+ FixedText aKeywordsFt;
+ Edit aKeywordsEd;
+ FixedText aDescFt;
+ MultiLineEdit aDescEd;
+ FixedLine aDocinfoGb;
+
+ CheckBox aTextStyleCB;
+ CheckBox aFrameStyleCB;
+ CheckBox aPageStyleCB;
+ CheckBox aNumStyleCB;
+ CheckBox aMergeStyleCB;
+ PushButton aLoadFilePB;
+
+ OKButton aOkBt;
+ CancelButton aCancelBt;
+ HelpButton aHelpBt;
+ MoreButton* pMoreBt;
+ Timer aPrevTimer;
+ String aNone;
+ String sLoadTemplate;
+
+ USHORT nFlags;
+ SfxDocumentTemplates aTemplates;
+ SfxObjectShellLock xDocShell;
+ SfxNewFileDialog* pAntiImpl;
+
+ void ClearInfo();
+ DECL_LINK( Update, void * );
+
+ DECL_LINK( RegionSelect, ListBox * );
+ DECL_LINK( TemplateSelect, ListBox * );
+ DECL_LINK( DoubleClick, ListBox * );
+ void TogglePreview(CheckBox *);
+ DECL_LINK( Expand, MoreButton * );
+ DECL_LINK( PreviewClick, CheckBox * );
+ DECL_LINK( LoadFile, PushButton* );
+ USHORT GetSelectedTemplatePos() const;
+
+public:
+
+ SfxNewFileDialog_Impl( SfxNewFileDialog* pAntiImplP, USHORT nFlags );
+ ~SfxNewFileDialog_Impl();
+
+ // Liefert FALSE, wenn '- Keine -' als Vorlage eingestellt ist
+ // Nur wenn IsTemplate() TRUE liefert, koennen Vorlagennamen
+ // erfragt werden
+ BOOL IsTemplate() const;
+ String GetTemplateRegion() const;
+ String GetTemplateName() const;
+ String GetTemplateFileName() const;
+
+ USHORT GetTemplateFlags()const;
+ void SetTemplateFlags(USHORT nSet);
+};
+
+
+//-------------------------------------------------------------------------
+
+void SfxNewFileDialog_Impl::ClearInfo()
+{
+ const String aNo;
+ aTitleEd.SetText(aNo);
+ aThemaEd.SetText(aNo);
+ aKeywordsEd.SetText(aNo);
+ aDescEd.SetText(aNo);
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxNewFileDialog_Impl, Update, void *, EMPTYARG )
+{
+ if ( xDocShell.Is() )
+ {
+ if ( xDocShell->GetProgress() )
+ return FALSE;
+ xDocShell.Clear();
+ }
+
+ const USHORT nEntry = GetSelectedTemplatePos();
+ if(!nEntry)
+ {
+ ClearInfo();
+ aPreviewWin.Invalidate();
+ aPreviewWin.SetObjectShell( 0);
+ return 0;
+ }
+
+ if ( aPreviewBtn.IsChecked() && (nFlags & SFXWB_PREVIEW) == SFXWB_PREVIEW)
+ {
+
+ String aFileName = aTemplates.GetPath( aRegionLb.GetSelectEntryPos(), nEntry-1);
+ INetURLObject aTestObj( aFileName );
+ if( aTestObj.GetProtocol() == INET_PROT_NOT_VALID )
+ {
+ // temp. fix until Templates are managed by UCB compatible service
+ // does NOT work with locally cached components !
+ String aTemp;
+ utl::LocalFileHelper::ConvertPhysicalNameToURL( aFileName, aTemp );
+ aFileName = aTemp;
+ }
+
+ INetURLObject aObj( aFileName );
+ for ( SfxObjectShell* pTmp = SfxObjectShell::GetFirst();
+ pTmp;
+ pTmp = SfxObjectShell::GetNext(*pTmp) )
+ {
+ //! fsys bug op==
+ if ( pTmp->GetMedium())
+ // ??? HasName() MM
+ if( INetURLObject( pTmp->GetMedium()->GetName() ) == aObj )
+ {
+ xDocShell = pTmp;
+ break;
+ }
+ }
+
+ if ( !xDocShell.Is() )
+ {
+ Window *pParent = Application::GetDefDialogParent();
+ Application::SetDefDialogParent( pAntiImpl );
+ SfxErrorContext eEC(ERRCTX_SFX_LOADTEMPLATE,pAntiImpl);
+ SfxApplication *pSfxApp = SFX_APP();
+ ULONG lErr;
+ SfxItemSet* pSet = new SfxAllItemSet( pSfxApp->GetPool() );
+ pSet->Put( SfxBoolItem( SID_TEMPLATE, TRUE ) );
+ pSet->Put( SfxBoolItem( SID_PREVIEW, TRUE ) );
+ lErr = pSfxApp->LoadTemplate( xDocShell, aFileName, TRUE, pSet );
+ if( lErr )
+ ErrorHandler::HandleError(lErr);
+ Application::SetDefDialogParent( pParent );
+ if ( !xDocShell.Is() )
+ {
+ aPreviewWin.SetObjectShell( 0 );
+ return FALSE;
+ }
+ }
+
+ aPreviewWin.SetObjectShell( xDocShell );
+ }
+ return TRUE;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxNewFileDialog_Impl, RegionSelect, ListBox *, pBox )
+{
+ if ( xDocShell.Is() && xDocShell->GetProgress() )
+ return 0;
+
+ const USHORT nRegion = pBox->GetSelectEntryPos();
+ const USHORT nCount = aTemplates.GetRegionCount()? aTemplates.GetCount(nRegion): 0;
+ aTemplateLb.SetUpdateMode(FALSE);
+ aTemplateLb.Clear();
+ String aSel=aRegionLb.GetSelectEntry();
+ USHORT nc=aSel.Search('(');
+ if (nc-1&&nc!=STRING_NOTFOUND)
+ aSel.Erase(nc-1);
+ if (aSel.CompareIgnoreCaseToAscii( String(SfxResId(STR_STANDARD)) )==COMPARE_EQUAL)
+ aTemplateLb.InsertEntry(aNone);
+ for (USHORT i = 0; i < nCount; ++i)
+ aTemplateLb.InsertEntry(aTemplates.GetName(nRegion, i));
+ aTemplateLb.SelectEntryPos(0);
+ aTemplateLb.SetUpdateMode(TRUE);
+ aTemplateLb.Invalidate();
+ aTemplateLb.Update();
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( SfxNewFileDialog_Impl, Expand, MoreButton *, EMPTYARG )
+{
+ TemplateSelect(&aTemplateLb);
+ return 0;
+}
+IMPL_LINK_INLINE_END( SfxNewFileDialog_Impl, Expand, MoreButton *, pMoreButton )
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxNewFileDialog_Impl, PreviewClick, CheckBox *, pBox )
+{
+ if ( xDocShell.Is() && xDocShell->GetProgress() )
+ return 0;
+
+ USHORT nEntry = GetSelectedTemplatePos();
+ if ( nEntry && pBox->IsChecked() )
+ {
+ if(!Update(0))
+ aPreviewWin.Invalidate();
+ }
+ else
+ {
+ if (xDocShell.Is())
+ xDocShell.Clear();
+ aPreviewWin.SetObjectShell( 0 );
+ }
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK( SfxNewFileDialog_Impl, TemplateSelect, ListBox *, EMPTYARG )
+{
+ // noch am Laden
+ if ( xDocShell && xDocShell->GetProgress() )
+ return 0;
+
+ if ( !MORE_BTN(GetState()) )
+ // Dialog nicht aufgeklappt
+ return 0;
+
+ aPrevTimer.Start();
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( SfxNewFileDialog_Impl, DoubleClick, ListBox *, pListBox )
+{
+ (void)pListBox;
+ // noch am Laden
+ if ( !xDocShell.Is() || !xDocShell->GetProgress() )
+ pAntiImpl->EndDialog(RET_OK);
+ return 0;
+}
+IMPL_LINK_INLINE_END( SfxNewFileDialog_Impl, DoubleClick, ListBox *, pListBox )
+
+//-------------------------------------------------------------------------
+
+IMPL_LINK_INLINE_START( SfxNewFileDialog_Impl, LoadFile, PushButton *, EMPTYARG )
+{
+ pAntiImpl->EndDialog(RET_TEMPLATE_LOAD);
+ return 0;
+}
+IMPL_LINK_INLINE_END( SfxNewFileDialog_Impl, LoadFile, PushButton *, EMPTYARG )
+//-------------------------------------------------------------------------
+
+USHORT SfxNewFileDialog_Impl::GetSelectedTemplatePos() const
+{
+ USHORT nEntry=aTemplateLb.GetSelectEntryPos();
+ String aSel=aRegionLb.GetSelectEntry().Copy();
+ USHORT nc=aSel.Search('(');
+ if (nc-1&&nc!=STRING_NOTFOUND)
+ aSel.Erase(nc-1);
+ if (aSel.CompareIgnoreCaseToAscii(String(SfxResId(STR_STANDARD)))!=COMPARE_EQUAL)
+ nEntry++;
+ if (!aTemplateLb.GetSelectEntryCount())
+ nEntry=0;
+ return nEntry;
+}
+
+//-------------------------------------------------------------------------
+
+BOOL SfxNewFileDialog_Impl::IsTemplate() const
+{
+ return GetSelectedTemplatePos()!=0;
+
+}
+
+//-------------------------------------------------------------------------
+
+String SfxNewFileDialog_Impl::GetTemplateFileName() const
+{
+ if(!IsTemplate() || !aTemplates.GetRegionCount())
+ return String();
+ return aTemplates.GetPath(aRegionLb.GetSelectEntryPos(),
+ GetSelectedTemplatePos()-1);
+}
+
+//-------------------------------------------------------------------------
+
+String SfxNewFileDialog_Impl::GetTemplateRegion() const
+{
+ if(!IsTemplate() || !aTemplates.GetRegionCount())
+ return String();
+ return aRegionLb.GetSelectEntry();
+}
+
+//-------------------------------------------------------------------------
+
+String SfxNewFileDialog_Impl::GetTemplateName() const
+{
+ if(!IsTemplate() || !aTemplates.GetRegionCount())
+ return String();
+ return aTemplateLb.GetSelectEntry();
+}
+
+//-------------------------------------------------------------------------
+
+void AdjustPosSize_Impl(Window *pWin, short nMoveOffset, short nSizeOffset)
+{
+ Point aPos(pWin->GetPosPixel());
+ Size aSize(pWin->GetSizePixel());
+ aPos.X() -= nMoveOffset;
+ aSize.Width() += nSizeOffset;
+ pWin->SetPosSizePixel(aPos, aSize);
+}
+//-------------------------------------------------------------------------
+USHORT SfxNewFileDialog_Impl::GetTemplateFlags()const
+{
+ USHORT nRet = aTextStyleCB.IsChecked() ? SFX_LOAD_TEXT_STYLES : 0;
+ if(aFrameStyleCB.IsChecked())
+ nRet |= SFX_LOAD_FRAME_STYLES;
+ if(aPageStyleCB.IsChecked())
+ nRet |= SFX_LOAD_PAGE_STYLES;
+ if(aNumStyleCB.IsChecked())
+ nRet |= SFX_LOAD_NUM_STYLES;
+ if(aMergeStyleCB.IsChecked())
+ nRet |= SFX_MERGE_STYLES;
+ return nRet;
+}
+//-------------------------------------------------------------------------
+void SfxNewFileDialog_Impl::SetTemplateFlags(USHORT nSet)
+{
+ aTextStyleCB.Check( 0 != (nSet&SFX_LOAD_TEXT_STYLES ));
+ aFrameStyleCB.Check( 0 != (nSet&SFX_LOAD_FRAME_STYLES));
+ aPageStyleCB.Check( 0 != (nSet&SFX_LOAD_PAGE_STYLES ));
+ aNumStyleCB.Check( 0 != (nSet&SFX_LOAD_NUM_STYLES ));
+ aMergeStyleCB.Check( 0 != (nSet&SFX_MERGE_STYLES ));
+}
+
+//-------------------------------------------------------------------------
+
+SfxNewFileDialog_Impl::SfxNewFileDialog_Impl(
+ SfxNewFileDialog* pAntiImplP, USHORT nFl)
+ : aRegionFt( pAntiImplP, SfxResId( FT_REGION ) ),
+ aRegionLb( pAntiImplP, SfxResId( LB_REGION ) ),
+ aTemplateFt( pAntiImplP, SfxResId( FT_TEMPLATE ) ),
+ aTemplateLb( pAntiImplP, SfxResId( LB_TEMPLATE ) ),
+ aPreviewBtn( pAntiImplP, SfxResId( BTN_PREVIEW ) ),
+ aPreviewWin( pAntiImplP, SfxResId( WIN_PREVIEW ) ),
+ aTitleFt( pAntiImplP, SfxResId( FT_TITLE ) ),
+ aTitleEd( pAntiImplP, SfxResId( ED_TITLE ) ),
+ aThemaFt( pAntiImplP, SfxResId( FT_THEMA ) ),
+ aThemaEd( pAntiImplP, SfxResId( ED_THEMA ) ),
+ aKeywordsFt( pAntiImplP, SfxResId( FT_KEYWORDS ) ),
+ aKeywordsEd( pAntiImplP, SfxResId( ED_KEYWORDS ) ),
+ aDescFt( pAntiImplP, SfxResId( FT_DESC ) ),
+ aDescEd( pAntiImplP, SfxResId( ED_DESC ) ),
+ aDocinfoGb( pAntiImplP, SfxResId( GB_DOCINFO ) ),
+ aTextStyleCB( pAntiImplP, SfxResId( CB_TEXT_STYLE )),
+ aFrameStyleCB( pAntiImplP, SfxResId( CB_FRAME_STYLE )),
+ aPageStyleCB( pAntiImplP, SfxResId( CB_PAGE_STYLE )),
+ aNumStyleCB( pAntiImplP, SfxResId( CB_NUM_STYLE )),
+ aMergeStyleCB( pAntiImplP, SfxResId( CB_MERGE_STYLE )),
+ aLoadFilePB( pAntiImplP, SfxResId( PB_LOAD_FILE )),
+ aOkBt( pAntiImplP, SfxResId( BT_OK ) ),
+ aCancelBt( pAntiImplP, SfxResId( BT_CANCEL ) ),
+ aHelpBt( pAntiImplP, SfxResId( BT_HELP ) ),
+ pMoreBt( new MoreButton( pAntiImplP, SfxResId( BT_MORE ) ) ),
+ aNone( SfxResId(STR_NONE) ),
+ sLoadTemplate( SfxResId(STR_LOAD_TEMPLATE)),
+ nFlags(nFl),
+ pAntiImpl( pAntiImplP )
+{
+ short nMoveOffset = *(short *)pAntiImplP->GetClassRes();
+ pAntiImplP->IncrementRes(sizeof(short));
+ short nExpandSize= *(short *)pAntiImplP->GetClassRes();
+ pAntiImplP->IncrementRes(sizeof(short));
+ pAntiImplP->FreeResource();
+
+ if (!nFlags)
+ MORE_BTN(Hide());
+ else if(SFXWB_LOAD_TEMPLATE == nFlags)
+ {
+ aLoadFilePB.SetClickHdl(LINK(this, SfxNewFileDialog_Impl, LoadFile));
+ aLoadFilePB.Show();
+ aTextStyleCB.Show();
+ aFrameStyleCB.Show();
+ aPageStyleCB.Show();
+ aNumStyleCB.Show();
+ aMergeStyleCB.Show();
+ Size aSize(pAntiImplP->GetOutputSizePixel());
+ Size aTmp(pAntiImplP->LogicToPixel(Size(16, 16), MAP_APPFONT));
+ aSize.Height() += aTmp.Height();
+ pAntiImplP->SetOutputSizePixel(aSize);
+ pMoreBt->Hide();
+ aTextStyleCB.Check();
+ pAntiImplP->SetText(sLoadTemplate);
+ }
+ else
+ {
+ MORE_BTN(SetClickHdl(LINK(this, SfxNewFileDialog_Impl, Expand)));
+ if((nFlags & SFXWB_PREVIEW) == SFXWB_PREVIEW)
+ {
+ MORE_BTN(AddWindow(&aPreviewBtn));
+ MORE_BTN(AddWindow(&aPreviewWin));
+ aPreviewBtn.SetClickHdl(LINK(this, SfxNewFileDialog_Impl, PreviewClick));
+ }
+ else
+ {
+ aPreviewBtn.Hide();
+ aPreviewWin.Hide();
+ nMoveOffset = (short)pAntiImplP->LogicToPixel(
+ Size(nMoveOffset, nMoveOffset), MAP_APPFONT).Width();
+ nExpandSize = (short)pAntiImplP->LogicToPixel(
+ Size(nExpandSize, nExpandSize), MAP_APPFONT).Width();
+ AdjustPosSize_Impl(&aTitleFt, nMoveOffset, 0);
+ AdjustPosSize_Impl(&aTitleEd, nMoveOffset, nExpandSize);
+ AdjustPosSize_Impl(&aThemaFt, nMoveOffset, 0);
+ AdjustPosSize_Impl(&aThemaEd, nMoveOffset, nExpandSize);
+ AdjustPosSize_Impl(&aKeywordsFt, nMoveOffset, 0);
+ AdjustPosSize_Impl(&aKeywordsEd, nMoveOffset, nExpandSize);
+ AdjustPosSize_Impl(&aDescFt , nMoveOffset, 0);
+ AdjustPosSize_Impl(&aDescEd , nMoveOffset, nExpandSize);
+ AdjustPosSize_Impl(&aDocinfoGb, nMoveOffset, nExpandSize);
+ }
+ }
+
+ String &rExtra = pAntiImplP->GetExtraData();
+ USHORT nTokCount = rExtra.GetTokenCount( '|' );
+ if( nTokCount > 0 && nFlags )
+ MORE_BTN(SetState( rExtra.GetToken( 0, '|' ) == 'Y' ));
+ if( nTokCount > 1 && nFlags )
+ aPreviewBtn.Check( rExtra.GetToken( 1 ,'|' ) == 'Y' );
+
+ aTemplateLb.SetDoubleClickHdl(LINK(this, SfxNewFileDialog_Impl, DoubleClick));
+
+ // update the template configuration if necessary
+ {
+ WaitObject aWaitCursor( pAntiImplP->GetParent() );
+ aTemplates.Update( sal_True /* be smart */ );
+ }
+ // fill the list boxes
+ const USHORT nCount = aTemplates.GetRegionCount();
+ if (nCount)
+ {
+ for(USHORT i = 0; i < nCount; ++i)
+ aRegionLb.InsertEntry(aTemplates.GetFullRegionName(i));
+ aRegionLb.SetSelectHdl(LINK(this, SfxNewFileDialog_Impl, RegionSelect));
+ }
+
+ aPrevTimer.SetTimeout( 500 );
+ aPrevTimer.SetTimeoutHdl( LINK( this, SfxNewFileDialog_Impl, Update));
+
+// else
+// aRegionLb.InsertEntry(String(SfxResId(STR_STANDARD)));
+ aRegionLb.SelectEntryPos(0);
+ RegionSelect(&aRegionLb);
+}
+
+//-------------------------------------------------------------------------
+
+SfxNewFileDialog_Impl::~SfxNewFileDialog_Impl()
+{
+ String &rExtra = pAntiImpl->GetExtraData();
+ rExtra = MORE_BTN(GetState()) ? 'Y' : 'N';
+ rExtra += '|';
+ rExtra += aPreviewBtn.IsChecked() ? 'Y' : 'N';
+
+ delete pMoreBt;
+}
+//-------------------------------------------------------------------------
+SfxNewFileDialog::SfxNewFileDialog(Window *pParent, USHORT nFlags)
+ : SfxModalDialog( pParent, SfxResId( DLG_NEW_FILE ) )
+{
+ pImpl = new SfxNewFileDialog_Impl( this, nFlags );
+}
+//-------------------------------------------------------------------------
+SfxNewFileDialog::~SfxNewFileDialog()
+{
+ delete pImpl;
+}
+//-------------------------------------------------------------------------
+BOOL SfxNewFileDialog::IsTemplate() const
+{
+ return pImpl->IsTemplate();
+}
+//-------------------------------------------------------------------------
+String SfxNewFileDialog::GetTemplateRegion() const
+{
+ return pImpl->GetTemplateRegion();
+}
+//-------------------------------------------------------------------------
+String SfxNewFileDialog::GetTemplateName() const
+{
+ return pImpl->GetTemplateName();
+}
+//-------------------------------------------------------------------------
+String SfxNewFileDialog::GetTemplateFileName() const
+{
+ return pImpl->GetTemplateFileName();
+}
+//-------------------------------------------------------------------------
+USHORT SfxNewFileDialog::GetTemplateFlags()const
+{
+ return pImpl->GetTemplateFlags();
+
+}
+//-------------------------------------------------------------------------
+void SfxNewFileDialog::SetTemplateFlags(USHORT nSet)
+{
+ pImpl->SetTemplateFlags(nSet);
+}
+
diff --git a/sfx2/source/doc/new.hrc b/sfx2/source/doc/new.hrc
new file mode 100644
index 000000000000..dd8878bf0177
--- /dev/null
+++ b/sfx2/source/doc/new.hrc
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#define BTN_PREVIEW 51
+#define WIN_PREVIEW 50
+#define GB_DOCCLASS 1
+#define LB_DOCCLASS 2
+#define GB_DESC 10
+#define FT_DESC 11
+#define FT_STYLESHEETS 19
+#define FT_REGION 20
+#define ED_TITLE 56
+#define ED_KEYWORDS 61
+#define FT_KEYWORDS 60
+#define FT_TITLE 55
+#define ED_DESC 71
+#define FT_DOCINFO 70
+#define LB_REGION 21
+#define BT_OK 30
+#define BT_CANCEL 31
+#define BT_HELP 32
+#define GB_DOCINFO 70
+#define ED_THEMA 55
+#define FT_THEMA 54
+#define FT_TEMPLATE 53
+#define LB_TEMPLATE 52
+#define BT_MORE 32
+#define CB_TEXT_STYLE 33
+#define CB_FRAME_STYLE 34
+#define CB_PAGE_STYLE 35
+#define CB_NUM_STYLE 36
+#define CB_MERGE_STYLE 37
+#define PB_LOAD_FILE 38
+#define STR_LOAD_TEMPLATE 39
diff --git a/sfx2/source/doc/new.src b/sfx2/source/doc/new.src
new file mode 100644
index 000000000000..146f9f630570
--- /dev/null
+++ b/sfx2/source/doc/new.src
@@ -0,0 +1,259 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 ---------------------------------------------------------------
+#include <sfx2/sfx.hrc>
+#include "doc.hrc"
+#include "new.hrc"
+ // pragma ----------------------------------------------------------------
+
+ // DLG_NEW_FILE ----------------------------------------------------------
+ModalDialog DLG_NEW_FILE
+{
+ HelpId = SID_NEWDOC ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 336 , 96 ) ;
+ Text [ en-US ] = "New" ;
+ Moveable = TRUE ;
+ OKButton BT_OK
+ {
+ Pos = MAP_APPFONT ( 274 , 6 ) ;
+ Size = MAP_APPFONT ( 56 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BT_CANCEL
+ {
+ Pos = MAP_APPFONT ( 274 , 23 ) ;
+ Size = MAP_APPFONT ( 56 , 14 ) ;
+ };
+ HelpButton BT_HELP
+ {
+ Pos = MAP_APPFONT ( 274 , 43 ) ;
+ Size = MAP_APPFONT ( 56 , 14 ) ;
+ };
+ ListBox LB_REGION
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 18 ) ;
+ Size = MAP_APPFONT ( 127 , 72 ) ;
+ CurPos = 0 ;
+ };
+ FixedText FT_REGION
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 97 , 10 ) ;
+ Text [ en-US ] = "~Categories" ;
+ Left = TRUE ;
+ };
+ FixedText FT_TEMPLATE
+ {
+ Pos = MAP_APPFONT ( 139 , 6 ) ;
+ Size = MAP_APPFONT ( 97 , 10 ) ;
+ Text [ en-US ] = "T~emplates" ;
+ Left = TRUE ;
+ };
+ ListBox LB_TEMPLATE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 139 , 18 ) ;
+ Size = MAP_APPFONT ( 127 , 72 ) ;
+ CurPos = 0 ;
+ };
+ MoreButton BT_MORE
+ {
+ Pos = MAP_APPFONT ( 274 , 70 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~More" ;
+ Delta = 148 ;
+ MapUnit = MAP_APPFONT ;
+ };
+ Window WIN_PREVIEW
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 110 ) ;
+ Size = MAP_APPFONT ( 127 , 129 ) ;
+ Hide = TRUE ;
+ SVLook = FALSE ;
+ };
+ CheckBox BTN_PREVIEW
+ {
+ Pos = MAP_APPFONT ( 6 , 96 ) ;
+ Size = MAP_APPFONT ( 97 , 10 ) ;
+ Text [ en-US ] = "Pre~view" ;
+ Hide = TRUE ;
+ };
+ FixedLine GB_DOCINFO
+ {
+ Pos = MAP_APPFONT ( 139 , 97 ) ;
+ Size = MAP_APPFONT ( 186 , 8 ) ;
+ Hide = TRUE ;
+ Text [ en-US ] = "Description" ;
+ };
+ CheckBox CB_TEXT_STYLE
+ {
+ Pos = MAP_APPFONT ( 6 , 94 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ Hide = TRUE;
+ Text [ en-US ] = "Te~xt" ;
+ };
+ CheckBox CB_FRAME_STYLE
+ {
+ Pos = MAP_APPFONT ( 60 , 94 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ Hide = TRUE;
+ Text [ en-US ] = "~Frame" ;
+ };
+ CheckBox CB_PAGE_STYLE
+ {
+ Pos = MAP_APPFONT ( 114 , 94 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ Hide = TRUE;
+ Text [ en-US ] = "~Pages" ;
+ };
+ CheckBox CB_NUM_STYLE
+ {
+ Pos = MAP_APPFONT ( 168 , 94 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ Hide = TRUE;
+ Text [ en-US ] = "N~umbering" ;
+ };
+ CheckBox CB_MERGE_STYLE
+ {
+ Pos = MAP_APPFONT ( 222 , 94 ) ;
+ Size = MAP_APPFONT ( 50 , 10 ) ;
+ Hide = TRUE;
+ Text [ en-US ] = "~Overwrite" ;
+ };
+ PushButton PB_LOAD_FILE
+ {
+ Pos = MAP_APPFONT ( 274 , 92 ) ;
+ Size = MAP_APPFONT ( 56 , 14 ) ;
+ Hide = TRUE;
+ Text [ en-US ] = "From File...";
+ };
+ String STR_LOAD_TEMPLATE
+ {
+ Text [ en-US ] = "Load Styles" ;
+ };
+ FixedText FT_TITLE
+ {
+ Pos = MAP_APPFONT ( 145 , 108 ) ;
+ Size = MAP_APPFONT ( 175 , 10 ) ;
+ Text [ en-US ] = "~Title" ;
+ Hide = TRUE ;
+ };
+ Edit ED_TITLE
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 145 , 121 ) ;
+ Size = MAP_APPFONT ( 175 , 12 ) ;
+ ReadOnly = TRUE ;
+ Hide = TRUE ;
+ };
+ FixedText FT_THEMA
+ {
+ Pos = MAP_APPFONT ( 145 , 135 ) ;
+ Size = MAP_APPFONT ( 175 , 10 ) ;
+ Text [ en-US ] = "Subject" ;
+ Hide = TRUE ;
+ };
+ Edit ED_THEMA
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 145 , 148 ) ;
+ Size = MAP_APPFONT ( 175 , 12 ) ;
+ ReadOnly = TRUE ;
+ Hide = TRUE ;
+ };
+ FixedText FT_KEYWORDS
+ {
+ Pos = MAP_APPFONT ( 145 , 162 ) ;
+ Size = MAP_APPFONT ( 175 , 10 ) ;
+ Text [ en-US ] = "~Key words" ;
+ Hide = TRUE ;
+ };
+ Edit ED_KEYWORDS
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 145 , 175 ) ;
+ Size = MAP_APPFONT ( 175 , 12 ) ;
+ ReadOnly = TRUE ;
+ Hide = TRUE ;
+ };
+ FixedText FT_DESC
+ {
+ Pos = MAP_APPFONT ( 145 , 189 ) ;
+ Size = MAP_APPFONT ( 175 , 10 ) ;
+ Text [ en-US ] = "~Description" ;
+ Hide = TRUE ;
+ };
+ MultiLineEdit ED_DESC
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 144 , 202 ) ;
+ Size = MAP_APPFONT ( 175 , 32 ) ;
+ IgnoreTab = TRUE ;
+ ReadOnly = TRUE ;
+ Hide = TRUE ;
+ };
+ ExtraData =
+ {
+ 103;
+ 44;
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sfx2/source/doc/objcont.cxx b/sfx2/source/doc/objcont.cxx
new file mode 100644
index 000000000000..451e33084c07
--- /dev/null
+++ b/sfx2/source/doc/objcont.cxx
@@ -0,0 +1,1292 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/document/XStandaloneDocumentInfo.hpp>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <tools/cachestr.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/style.hxx>
+#include <vcl/wrkwin.hxx>
+
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/rectitem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/urihelper.hxx>
+#include <svl/ctloptions.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/securityoptions.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <tools/datetime.hxx>
+#include <math.h>
+
+#include <unotools/saveopt.hxx>
+#include <unotools/useroptions.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/oldprintadaptor.hxx>
+
+#include <sfx2/app.hxx>
+#include "sfxresid.hxx"
+#include "appdata.hxx"
+#include <sfx2/dinfdlg.hxx>
+#include "fltfnc.hxx"
+#include <sfx2/docfac.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/objsh.hxx>
+#include "objshimp.hxx"
+#include <sfx2/evntconf.hxx>
+#include "sfxhelp.hxx"
+#include <sfx2/dispatch.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewfrm.hxx>
+#include "basmgr.hxx"
+#include <sfx2/doctempl.hxx>
+#include "doc.hrc"
+#include <sfx2/sfxbasemodel.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/request.hxx>
+#include "openflag.hxx"
+#include "querytemplate.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+//====================================================================
+
+//====================================================================
+
+static
+bool operator> (const util::DateTime& i_rLeft, const util::DateTime& i_rRight)
+{
+ if ( i_rLeft.Year != i_rRight.Year )
+ return i_rLeft.Year > i_rRight.Year;
+
+ if ( i_rLeft.Month != i_rRight.Month )
+ return i_rLeft.Month > i_rRight.Month;
+
+ if ( i_rLeft.Day != i_rRight.Day )
+ return i_rLeft.Day > i_rRight.Day;
+
+ if ( i_rLeft.Hours != i_rRight.Hours )
+ return i_rLeft.Hours > i_rRight.Hours;
+
+ if ( i_rLeft.Minutes != i_rRight.Minutes )
+ return i_rLeft.Minutes > i_rRight.Minutes;
+
+ if ( i_rLeft.Seconds != i_rRight.Seconds )
+ return i_rLeft.Seconds > i_rRight.Seconds;
+
+ if ( i_rLeft.HundredthSeconds != i_rRight.HundredthSeconds )
+ return i_rLeft.HundredthSeconds > i_rRight.HundredthSeconds;
+
+ return sal_False;
+}
+
+
+::boost::shared_ptr<GDIMetaFile>
+SfxObjectShell::GetPreviewMetaFile( sal_Bool bFullContent ) const
+{
+ return CreatePreviewMetaFile_Impl( bFullContent, sal_False );
+}
+
+
+::boost::shared_ptr<GDIMetaFile>
+SfxObjectShell::CreatePreviewMetaFile_Impl( sal_Bool bFullContent, sal_Bool bHighContrast ) const
+{
+ // Nur wenn gerade nicht gedruckt wird, darf DoDraw aufgerufen
+ // werden, sonst wird u.U. der Printer abgeschossen !
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
+ if ( pFrame && pFrame->GetViewShell() &&
+ pFrame->GetViewShell()->GetPrinter() &&
+ pFrame->GetViewShell()->GetPrinter()->IsPrinting() )
+ return ::boost::shared_ptr<GDIMetaFile>();
+
+ ::boost::shared_ptr<GDIMetaFile> pFile(new GDIMetaFile);
+
+ VirtualDevice aDevice;
+ aDevice.EnableOutput( FALSE );
+
+ // adjust the output device if HC-metafile is requested
+ if ( bHighContrast )
+ aDevice.SetDrawMode( aDevice.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
+
+ MapMode aMode( ((SfxObjectShell*)this)->GetMapUnit() );
+ aDevice.SetMapMode( aMode );
+ pFile->SetPrefMapMode( aMode );
+
+ Size aTmpSize;
+ sal_Int8 nAspect;
+ if ( bFullContent )
+ {
+ nAspect = ASPECT_CONTENT;
+ aTmpSize = GetVisArea( nAspect ).GetSize();
+ }
+ else
+ {
+ nAspect = ASPECT_THUMBNAIL;
+ aTmpSize = ((SfxObjectShell*)this)->GetFirstPageSize();
+ }
+
+ pFile->SetPrefSize( aTmpSize );
+ DBG_ASSERT( aTmpSize.Height()*aTmpSize.Width(),
+ "size of first page is 0, overload GetFirstPageSize or set vis-area!" );
+
+ pFile->Record( &aDevice );
+
+ LanguageType eLang;
+ SvtCTLOptions* pCTLOptions = new SvtCTLOptions;
+ if ( SvtCTLOptions::NUMERALS_HINDI == pCTLOptions->GetCTLTextNumerals() )
+ eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
+ else if ( SvtCTLOptions::NUMERALS_ARABIC == pCTLOptions->GetCTLTextNumerals() )
+ eLang = LANGUAGE_ENGLISH;
+ else
+ eLang = (LanguageType) Application::GetSettings().GetLanguage();
+
+ aDevice.SetDigitLanguage( eLang );
+
+ ((SfxObjectShell*)this)->DoDraw( &aDevice, Point(0,0), aTmpSize, JobSetup(), nAspect );
+ pFile->Stop();
+
+ return pFile;
+}
+
+//====================================================================
+
+void SfxObjectShell::UpdateDocInfoForSave()
+{
+ uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
+
+ // clear user data if recommend (see 'Tools - Options - Open/StarOffice - Security')
+ if ( SvtSecurityOptions().IsOptionSet(
+ SvtSecurityOptions::E_DOCWARN_REMOVEPERSONALINFO ) )
+ {
+ xDocProps->resetUserData( ::rtl::OUString() );
+ }
+ else if ( IsModified() )
+ {
+ String aUserName = SvtUserOptions().GetFullName();
+ if ( !IsUseUserData() )
+ {
+ // remove all data pointing to the current user
+ if (xDocProps->getAuthor().equals(aUserName)) {
+ xDocProps->setAuthor( ::rtl::OUString() );
+ }
+ xDocProps->setModifiedBy( ::rtl::OUString() );
+ if (xDocProps->getPrintedBy().equals(aUserName)) {
+ xDocProps->setPrintedBy( ::rtl::OUString() );
+ }
+ }
+ else
+ {
+ // update ModificationAuthor, revision and editing time
+ ::DateTime now;
+ xDocProps->setModificationDate( util::DateTime(
+ now.Get100Sec(), now.GetSec(), now.GetMin(),
+ now.GetHour(), now.GetDay(), now.GetMonth(),
+ now.GetYear() ) );
+ xDocProps->setModifiedBy( aUserName );
+ if ( !HasName() || pImp->bIsSaving )
+ // QUESTION: not in case of "real" SaveAs as this is meant to create a new document
+ UpdateTime_Impl( xDocProps );
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+static void
+lcl_add(util::Duration & rDur, Time const& rTime)
+{
+ // here we don't care about overflow: rDur is converted back to seconds
+ // anyway, and Time cannot store more than ~4000 hours
+ rDur.Hours += rTime.GetHour();
+ rDur.Minutes += rTime.GetMin();
+ rDur.Seconds += rTime.GetSec();
+}
+
+// Bearbeitungszeit aktualisieren
+void SfxObjectShell::UpdateTime_Impl(
+ const uno::Reference<document::XDocumentProperties> & i_xDocProps)
+{
+ // Get old time from documentinfo
+ const sal_Int32 secs = i_xDocProps->getEditingDuration();
+ util::Duration editDuration(sal_False, 0, 0, 0,
+ secs/3600, (secs%3600)/60, secs%60, 0);
+
+ // Initialize some local member! Its neccessary for wollow operations!
+ DateTime aNow ; // Date and time at current moment
+ Time n24Time (24,0,0,0) ; // Time-value for 24 hours - see follow calculation
+ ULONG nDays = 0 ; // Count of days between now and last editing
+ Time nAddTime (0) ; // Value to add on aOldTime
+
+ // Safe impossible cases!
+ // User has changed time to the past between last editing and now ... its not possible!!!
+ DBG_ASSERT( !(aNow.GetDate()<pImp->nTime.GetDate()), "Timestamp of last change is in the past ?!..." );
+
+ // Do the follow only, if user has NOT changed time to the past.
+ // Else add a time of 0 to aOldTime ... !!!
+ if (aNow.GetDate()>=pImp->nTime.GetDate())
+ {
+ // Get count of days last editing.
+ nDays = aNow.GetSecFromDateTime(pImp->nTime.GetDate())/86400 ;
+
+ if (nDays==0)
+ {
+ // If no day between now and last editing - calculate time directly.
+ nAddTime = (const Time&)aNow - (const Time&)pImp->nTime ;
+ }
+ else
+ // If time of working without save greater then 1 month (!) ....
+ // we add 0 to aOldTime!
+ if (nDays<=31)
+ {
+ // If 1 or up to 31 days between now and last editing - calculate time indirectly.
+ // nAddTime = (24h - nTime) + (nDays * 24h) + aNow
+ --nDays;
+ nAddTime = nDays*n24Time.GetTime() ;
+ nAddTime += n24Time-(const Time&)pImp->nTime ;
+ nAddTime += aNow ;
+ }
+
+ lcl_add(editDuration, nAddTime);
+ }
+
+ pImp->nTime = aNow;
+ try {
+ const sal_Int32 newSecs( (editDuration.Hours*3600)
+ + (editDuration.Minutes*60) + editDuration.Seconds);
+ i_xDocProps->setEditingDuration(newSecs);
+ i_xDocProps->setEditingCycles(i_xDocProps->getEditingCycles() + 1);
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ // ignore overflow
+ }
+}
+
+//--------------------------------------------------------------------
+
+SfxDocumentInfoDialog* SfxObjectShell::CreateDocumentInfoDialog
+(
+ Window* pParent,
+ const SfxItemSet& rSet
+)
+{
+ return new SfxDocumentInfoDialog(pParent, rSet);
+}
+
+//--------------------------------------------------------------------
+
+SfxStyleSheetBasePool* SfxObjectShell::GetStyleSheetPool()
+{
+ return 0;
+}
+
+void SfxObjectShell::SetOrganizerSearchMask(
+ SfxStyleSheetBasePool* pStylePool) const
+{
+ pStylePool->SetSearchMask(
+ SFX_STYLE_FAMILY_ALL,
+ SFXSTYLEBIT_USERDEF | SFXSTYLEBIT_USED);
+}
+
+//--------------------------------------------------------------------
+
+USHORT SfxObjectShell::GetContentCount(
+ USHORT nIdx1,
+ USHORT /*nIdx2*/)
+{
+ switch(nIdx1)
+ {
+ case INDEX_IGNORE:
+ return DEF_CONTENT_COUNT;
+ case CONTENT_STYLE:
+ {
+ SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool();
+ if(!pStylePool)
+ return 0;
+ SetOrganizerSearchMask(pStylePool);
+ return pStylePool->Count();
+ }
+ case CONTENT_MACRO:
+ break;
+/*
+ case CONTENT_CONFIG:
+ return ( GetConfigManager() ) ?
+ GetConfigManager()->GetItemCount() : 0;
+ break;
+ */
+ }
+ return 0;
+}
+
+
+//--------------------------------------------------------------------
+//TODO/CLEANUP: remove this method (it's virtual)
+void SfxObjectShell::TriggerHelpPI(USHORT nIdx1, USHORT nIdx2, USHORT)
+{
+ if(nIdx1==CONTENT_STYLE && nIdx2 != INDEX_IGNORE) //StyleSheets
+ {
+ SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool();
+ SetOrganizerSearchMask(pStylePool);
+#ifdef WIR_KOENNEN_WIEDER_HILFE_FUER_STYLESHEETS
+ SfxStyleSheetBase *pStyle = (*pStylePool)[nIdx2];
+ if(pStyle)
+ {
+ String aHelpFile;
+ ULONG nHelpId=pStyle->GetHelpId(aHelpFile);
+ SfxHelpPI* pHelpPI = SFX_APP()->GetHelpPI();
+ if ( pHelpPI && nHelpId )
+ pHelpPI->LoadTopic( nHelpId );
+ }
+#endif
+ }
+}
+
+BOOL SfxObjectShell::CanHaveChilds(USHORT nIdx1,
+ USHORT nIdx2)
+{
+ switch(nIdx1) {
+ case INDEX_IGNORE:
+ return TRUE;
+ case CONTENT_STYLE:
+ return INDEX_IGNORE == nIdx2 || !GetStyleSheetPool()? FALSE: TRUE;
+ case CONTENT_MACRO:
+//!! return INDEX_IGNORE == nIdx2? FALSE: TRUE;
+ return FALSE;
+/*
+ case CONTENT_CONFIG:
+ return INDEX_IGNORE == nIdx2 ? FALSE : TRUE;
+ */
+ }
+ return FALSE;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::GetContent(String &rText,
+ Bitmap &rClosedBitmap,
+ Bitmap &rOpenedBitmap,
+ BOOL &bCanDel,
+ USHORT i,
+ USHORT nIdx1,
+ USHORT nIdx2 )
+{
+ DBG_ERRORFILE( "Non high contrast method called. Please update calling code!" );
+ SfxObjectShell::GetContent( rText, rClosedBitmap, rOpenedBitmap, BMP_COLOR_NORMAL, bCanDel, i, nIdx1, nIdx2 );
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::GetContent(String &rText,
+ Bitmap &rClosedBitmap,
+ Bitmap &rOpenedBitmap,
+ BmpColorMode eColorMode,
+ BOOL &bCanDel,
+ USHORT i,
+ USHORT nIdx1,
+ USHORT /*nIdx2*/ )
+{
+ bCanDel=TRUE;
+
+ switch(nIdx1)
+ {
+ case INDEX_IGNORE:
+ {
+ USHORT nTextResId = 0;
+ USHORT nClosedBitmapResId = 0; // evtl. sp"ater mal unterschiedliche
+ USHORT nOpenedBitmapResId = 0; // " " " "
+ switch(i)
+ {
+ case CONTENT_STYLE:
+ nTextResId = STR_STYLES;
+ if ( eColorMode == BMP_COLOR_NORMAL )
+ {
+ nClosedBitmapResId= BMP_STYLES_CLOSED;
+ nOpenedBitmapResId= BMP_STYLES_OPENED;
+ }
+ else
+ {
+ nClosedBitmapResId= BMP_STYLES_CLOSED_HC;
+ nOpenedBitmapResId= BMP_STYLES_OPENED_HC;
+ }
+ break;
+ case CONTENT_MACRO:
+ nTextResId = STR_MACROS;
+ if ( eColorMode == BMP_COLOR_NORMAL )
+ {
+ nClosedBitmapResId= BMP_STYLES_CLOSED;
+ nOpenedBitmapResId= BMP_STYLES_OPENED;
+ }
+ else
+ {
+ nClosedBitmapResId= BMP_STYLES_CLOSED_HC;
+ nOpenedBitmapResId= BMP_STYLES_OPENED_HC;
+ }
+ break;
+/*
+ case CONTENT_CONFIG:
+ nTextResId = STR_CONFIG;
+ nClosedBitmapResId= BMP_STYLES_CLOSED;
+ nOpenedBitmapResId= BMP_STYLES_OPENED;
+ break;
+ */
+ }
+
+ if ( nTextResId )
+ {
+ rText = String(SfxResId(nTextResId));
+ rClosedBitmap = Bitmap(SfxResId(nClosedBitmapResId));
+ rOpenedBitmap = Bitmap(SfxResId(nOpenedBitmapResId));
+ }
+ break;
+ }
+
+ case CONTENT_STYLE:
+ {
+ SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool();
+ SetOrganizerSearchMask(pStylePool);
+ SfxStyleSheetBase *pStyle = (*pStylePool)[i];
+ rText = pStyle->GetName();
+ bCanDel=((pStyle->GetMask() & SFXSTYLEBIT_USERDEF)
+ == SFXSTYLEBIT_USERDEF);
+ rClosedBitmap = rOpenedBitmap =
+ GetStyleFamilyBitmap(pStyle->GetFamily(), eColorMode );
+ }
+ break;
+ case CONTENT_MACRO:
+ break;
+/*
+ case CONTENT_CONFIG:
+ if ( GetConfigManager() )
+ {
+ rText = GetConfigManager()->GetItem(i);
+ bCanDel = GetConfigManager()->CanDelete(i);
+ }
+ else
+ rText = String();
+ rClosedBitmap = Bitmap(SfxResId(BMP_STYLES_CLOSED));
+ rOpenedBitmap = Bitmap(SfxResId(BMP_STYLES_OPENED));
+ break;
+*/
+ }
+}
+
+//--------------------------------------------------------------------
+Bitmap SfxObjectShell::GetStyleFamilyBitmap( SfxStyleFamily eFamily )
+{
+ DBG_ERRORFILE( "Non high contrast method called. Please update calling code!" );
+ return SfxObjectShell::GetStyleFamilyBitmap( eFamily, BMP_COLOR_NORMAL );
+}
+
+//--------------------------------------------------------------------
+
+Bitmap SfxObjectShell::GetStyleFamilyBitmap(SfxStyleFamily eFamily, BmpColorMode eColorMode )
+{
+ USHORT nResId = 0;
+ switch(eFamily)
+ {
+ case SFX_STYLE_FAMILY_CHAR:
+ nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY1 : BMP_STYLES_FAMILY1_HC;
+ break;
+ case SFX_STYLE_FAMILY_PARA:
+ nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY2 : BMP_STYLES_FAMILY2_HC;
+ break;
+ case SFX_STYLE_FAMILY_FRAME:
+ nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY3 : BMP_STYLES_FAMILY3_HC;
+ break;
+ case SFX_STYLE_FAMILY_PAGE :
+ nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY4 : BMP_STYLES_FAMILY4_HC;
+ break;
+ case SFX_STYLE_FAMILY_PSEUDO:
+ case SFX_STYLE_FAMILY_ALL:
+ break;
+ }
+
+ if ( nResId )
+ return Bitmap(SfxResId(nResId));
+ else
+ return Bitmap();
+}
+
+
+//--------------------------------------------------------------------
+
+BOOL SfxObjectShell::Insert(SfxObjectShell &rSource,
+ USHORT nSourceIdx1,
+ USHORT nSourceIdx2,
+ USHORT /*nSourceIdx3*/,
+ USHORT &nIdx1,
+ USHORT &nIdx2,
+ USHORT &/*nIdx3*/,
+ USHORT &/*nDeleted*/)
+{
+ BOOL bRet = FALSE;
+
+ if (INDEX_IGNORE == nIdx1 && CONTENT_STYLE == nSourceIdx1)
+ nIdx1 = CONTENT_STYLE;
+
+ if (CONTENT_STYLE == nSourceIdx1 && CONTENT_STYLE == nIdx1)
+ {
+ SfxStyleSheetBasePool* pHisPool = rSource.GetStyleSheetPool();
+ SfxStyleSheetBasePool* pMyPool = GetStyleSheetPool();
+ SetOrganizerSearchMask(pHisPool);
+ SetOrganizerSearchMask(pMyPool);
+ SfxStyleSheetBase* pHisSheet = NULL;
+
+ if ( pHisPool && pHisPool->Count() > nSourceIdx2 )
+ pHisSheet = (*pHisPool)[nSourceIdx2];
+
+ // Einfuegen ist nur dann noetig, wenn ein StyleSheet
+ // zwischen unterschiedlichen(!) Pools bewegt wird
+
+ if ( pHisSheet && pMyPool != pHisPool )
+ {
+ if (INDEX_IGNORE == nIdx2)
+ {
+ nIdx2 = pMyPool->Count();
+ }
+
+ // wenn so eine Vorlage schon existiert: loeschen!
+ String aOldName(pHisSheet->GetName());
+ SfxStyleFamily eOldFamily = pHisSheet->GetFamily();
+
+ SfxStyleSheetBase* pExist = pMyPool->Find(aOldName, eOldFamily);
+ // USHORT nOldHelpId = pExist->GetHelpId(??? VB ueberlegt sich was);
+ BOOL bUsedOrUserDefined;
+ if( pExist )
+ {
+ bUsedOrUserDefined =
+ pExist->IsUsed() || pExist->IsUserDefined();
+ if( ErrorHandler::HandleError(
+ *new MessageInfo( ERRCODE_SFXMSG_STYLEREPLACE, aOldName ) )
+ != ERRCODE_BUTTON_OK )
+ return FALSE;
+ else
+ {
+ pMyPool->Replace( *pHisSheet, *pExist );
+ SetModified( TRUE );
+ nIdx2 = nIdx1 = INDEX_IGNORE;
+ return TRUE;
+ }
+ }
+
+ SfxStyleSheetBase& rNewSheet = pMyPool->Make(
+ aOldName, eOldFamily,
+ pHisSheet->GetMask(), nIdx2);
+
+ // ItemSet der neuen Vorlage fuellen
+ rNewSheet.GetItemSet().Set(pHisSheet->GetItemSet());
+
+ // wer bekommt den Neuen als Parent? wer benutzt den Neuen als Follow?
+ SfxStyleSheetBase* pTestSheet = pMyPool->First();
+ while (pTestSheet)
+ {
+ if (pTestSheet->GetFamily() == eOldFamily &&
+ pTestSheet->HasParentSupport() &&
+ pTestSheet->GetParent() == aOldName)
+ {
+ pTestSheet->SetParent(aOldName);
+ // Verknuepfung neu aufbauen
+ }
+
+ if (pTestSheet->GetFamily() == eOldFamily &&
+ pTestSheet->HasFollowSupport() &&
+ pTestSheet->GetFollow() == aOldName)
+ {
+ pTestSheet->SetFollow(aOldName);
+ // Verknuepfung neu aufbauen
+ }
+
+ pTestSheet = pMyPool->Next();
+ }
+ bUsedOrUserDefined =
+ rNewSheet.IsUsed() || rNewSheet.IsUserDefined();
+
+
+ // hat der Neue einen Parent? wenn ja, mit gleichem Namen bei uns suchen
+ if (pHisSheet->HasParentSupport())
+ {
+ const String& rParentName = pHisSheet->GetParent();
+ if (0 != rParentName.Len())
+ {
+ SfxStyleSheetBase* pParentOfNew =
+ pMyPool->Find(rParentName, eOldFamily);
+ if (pParentOfNew)
+ rNewSheet.SetParent(rParentName);
+ }
+ }
+
+ // hat der Neue einen Follow? wenn ja, mit gleichem
+ // Namen bei uns suchen
+ if (pHisSheet->HasFollowSupport())
+ {
+ const String& rFollowName = pHisSheet->GetFollow();
+ if (0 != rFollowName.Len())
+ {
+ SfxStyleSheetBase* pFollowOfNew =
+ pMyPool->Find(rFollowName, eOldFamily);
+ if (pFollowOfNew)
+ rNewSheet.SetFollow(rFollowName);
+ }
+ }
+
+ SetModified( TRUE );
+ if( !bUsedOrUserDefined ) nIdx2 = nIdx1 = INDEX_IGNORE;
+
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+ }
+/*
+ else if (nSourceIdx1 == CONTENT_CONFIG)
+ {
+ nIdx1 = CONTENT_CONFIG;
+
+ SfxConfigManager *pCfgMgr = SFX_CFGMANAGER();
+ if ( !GetConfigManager() )
+ {
+ SetConfigManager(new SfxConfigManager(0, pCfgMgr));
+ SetTemplateConfig(FALSE);
+ if (this == Current())
+ GetConfigManager()->Activate(pCfgMgr);
+ }
+
+ if (GetConfigManager()->CopyItem(
+ nSourceIdx2, nIdx2, rSource.GetConfigManager()))
+ {
+ SetModified(TRUE);
+ bRet = TRUE;
+ SFX_APP()->GetDispatcher_Impl()->Update_Impl(TRUE);
+ }
+ }
+*/
+ return bRet;
+}
+
+//--------------------------------------------------------------------
+
+BOOL SfxObjectShell::Remove
+(
+ USHORT nIdx1,
+ USHORT nIdx2,
+ USHORT /*nIdx3*/
+)
+{
+ BOOL bRet = FALSE;
+
+ if (CONTENT_STYLE == nIdx1)
+ {
+ SfxStyleSheetBasePool* pMyPool = GetStyleSheetPool();
+
+ SetOrganizerSearchMask(pMyPool);
+
+ SfxStyleSheetBase* pMySheet = (*pMyPool)[nIdx2];
+ String aName(pMySheet->GetName());
+ String aEmpty;
+ SfxStyleFamily eFamily = pMySheet->GetFamily();
+ pMyPool->Remove(pMySheet);
+ bRet = TRUE;
+
+ SfxStyleSheetBase* pTestSheet = pMyPool->First();
+ while (pTestSheet)
+ {
+ if (pTestSheet->GetFamily() == eFamily &&
+ pTestSheet->HasParentSupport() &&
+ pTestSheet->GetParent() == aName)
+ {
+ pTestSheet->SetParent(aEmpty); // Verknuepfung aufloesen
+ }
+
+ if (pTestSheet->GetFamily() == eFamily &&
+ pTestSheet->HasFollowSupport() &&
+ pTestSheet->GetFollow() == aName)
+ {
+ pTestSheet->SetFollow(aEmpty); // Verknuepfung aufloesen
+ }
+
+ pTestSheet = pMyPool->Next();
+ }
+
+ SetModified( TRUE );
+ }
+
+ return bRet;
+}
+
+//--------------------------------------------------------------------
+
+BOOL SfxObjectShell::Print
+(
+ Printer& rPrt,
+ USHORT nIdx1,
+ USHORT /*nIdx2*/,
+ USHORT /*nIdx3*/,
+ const String* pObjectName
+)
+
+/* [Beschreibung]
+*/
+
+{
+ switch(nIdx1)
+ {
+ case CONTENT_STYLE:
+ {
+ SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool();
+ SetOrganizerSearchMask(pStylePool);
+ SfxStyleSheetIterator* pIter = pStylePool->CreateIterator(
+ pStylePool->GetSearchFamily(), pStylePool->GetSearchMask() );
+ USHORT nStyles = pIter->Count();
+ SfxStyleSheetBase *pStyle = pIter->First();
+ if ( !pStyle )
+ return TRUE;
+
+ // pepare adaptor for old style StartPage/EndPage printing
+ boost::shared_ptr< Printer > pPrinter( new Printer( rPrt.GetJobSetup() ) );
+ vcl::OldStylePrintAdaptor* pAdaptor = new vcl::OldStylePrintAdaptor( pPrinter );
+ boost::shared_ptr< vcl::PrinterController > pController( pAdaptor );
+
+ pAdaptor->StartPage();
+
+ pPrinter->SetMapMode(MapMode(MAP_10TH_MM));
+ Font aFont( DEFINE_CONST_UNICODE( "Arial" ), Size(0, 64)); // 18pt
+ aFont.SetWeight(WEIGHT_BOLD);
+ pPrinter->SetFont(aFont);
+ const Size aPageSize(pPrinter->GetOutputSize());
+ const USHORT nXIndent = 200;
+ USHORT nYIndent = 200;
+ Point aOutPos(nXIndent, nYIndent);
+ String aHeader(SfxResId(STR_PRINT_STYLES_HEADER));
+ if ( pObjectName )
+ aHeader += *pObjectName;
+ else
+ aHeader += GetTitle();
+ long nTextHeight( pPrinter->GetTextHeight() );
+ pPrinter->DrawText(aOutPos, aHeader);
+ aOutPos.Y() += nTextHeight;
+ aOutPos.Y() += nTextHeight/2;
+ aFont.SetSize(Size(0, 35)); // 10pt
+ nStyles = 1;
+ while(pStyle)
+ {
+ // print template name
+ String aStr(pStyle->GetName());
+ aFont.SetWeight(WEIGHT_BOLD);
+ pPrinter->SetFont(aFont);
+ nTextHeight = pPrinter->GetTextHeight();
+ // check for new page
+ if ( aOutPos.Y() + nTextHeight*2 >
+ aPageSize.Height() - (long) nYIndent )
+ {
+ pAdaptor->EndPage();
+ pAdaptor->StartPage();
+ aOutPos.Y() = nYIndent;
+ }
+ pPrinter->DrawText(aOutPos, aStr);
+ aOutPos.Y() += nTextHeight;
+
+ // print template description
+ aFont.SetWeight(WEIGHT_NORMAL);
+ pPrinter->SetFont(aFont);
+ aStr = pStyle->GetDescription();
+ const char cDelim = ' ';
+ USHORT nStart = 0, nIdx = 0;
+
+ nTextHeight = pPrinter->GetTextHeight();
+ // break text into lines
+ while(nIdx < aStr.Len())
+ {
+ USHORT nOld = nIdx;
+ long nTextWidth;
+ nIdx = aStr.Search(cDelim, nStart);
+ nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart);
+ while(nIdx != STRING_NOTFOUND &&
+ aOutPos.X() + nTextWidth <
+ aPageSize.Width() - (long) nXIndent)
+ {
+ nOld = nIdx;
+ nIdx = aStr.Search(cDelim, nIdx+1);
+ nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart);
+ }
+ String aTmp(aStr, nStart, nIdx == STRING_NOTFOUND?
+ STRING_LEN :
+ nOld-nStart);
+ if ( aTmp.Len() )
+ {
+ nStart = nOld+1; // trailing space
+ }
+ else
+ {
+ USHORT nChar = 1;
+ while(
+ nStart + nChar < aStr.Len() &&
+ aOutPos.X() + pPrinter->GetTextWidth(
+ aStr, nStart, nChar) <
+ aPageSize.Width() - nXIndent)
+ ++nChar;
+ aTmp = String(aStr, nStart, nChar-1);
+ nIdx = nStart + nChar;
+ nStart = nIdx;
+ }
+ if ( aOutPos.Y() + nTextHeight*2 >
+ aPageSize.Height() - nYIndent )
+ {
+ pAdaptor->EndPage();
+ pAdaptor->StartPage();
+ aOutPos.Y() = nYIndent;
+ }
+ pPrinter->DrawText(aOutPos, aTmp);
+ aOutPos.Y() += pPrinter->GetTextHeight();
+ }
+ pStyle = pIter->Next();
+ }
+ pAdaptor->EndPage();
+
+ Printer::PrintJob( pController, rPrt.GetJobSetup() );
+
+ delete pIter;
+ break;
+ }
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::LoadStyles
+(
+ SfxObjectShell &rSource /* die Dokument-Vorlage, aus der
+ die Styles geladen werden sollen */
+)
+
+/* [Beschreibung]
+
+ Diese Methode wird vom SFx gerufen, wenn aus einer Dokument-Vorlage
+ Styles nachgeladen werden sollen. Bestehende Styles soll dabei
+ "uberschrieben werden. Das Dokument mu"s daher neu formatiert werden.
+ Daher werden die Applikationen in der Regel diese Methode "uberladen
+ und in ihrer Implementierung die Implementierung der Basisklasse
+ rufen.
+*/
+
+{
+ struct Styles_Impl
+ {
+ SfxStyleSheetBase *pSource;
+ SfxStyleSheetBase *pDest;
+// Styles_Impl () : pSource(0), pDest(0) {}
+ };
+
+ SfxStyleSheetBasePool *pSourcePool = rSource.GetStyleSheetPool();
+ DBG_ASSERT(pSourcePool, "Source-DocumentShell ohne StyleSheetPool");
+ SfxStyleSheetBasePool *pMyPool = GetStyleSheetPool();
+ DBG_ASSERT(pMyPool, "Dest-DocumentShell ohne StyleSheetPool");
+ pSourcePool->SetSearchMask(SFX_STYLE_FAMILY_ALL, 0xffff);
+ Styles_Impl *pFound = new Styles_Impl[pSourcePool->Count()];
+ USHORT nFound = 0;
+
+ SfxStyleSheetBase *pSource = pSourcePool->First();
+ while ( pSource )
+ {
+ SfxStyleSheetBase *pDest =
+ pMyPool->Find( pSource->GetName(), pSource->GetFamily() );
+ if ( !pDest )
+ {
+ pDest = &pMyPool->Make( pSource->GetName(),
+ pSource->GetFamily(), pSource->GetMask());
+ // Setzen des Parents, der Folgevorlage
+ }
+ pFound[nFound].pSource = pSource;
+ pFound[nFound].pDest = pDest;
+ ++nFound;
+ pSource = pSourcePool->Next();
+ }
+
+ for ( USHORT i = 0; i < nFound; ++i )
+ {
+ pFound[i].pDest->GetItemSet().PutExtended(pFound[i].pSource->GetItemSet(), SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT);
+// pFound[i].pDest->SetHelpId(pFound[i].pSource->GetHelpId());
+ if(pFound[i].pSource->HasParentSupport())
+ pFound[i].pDest->SetParent(pFound[i].pSource->GetParent());
+ if(pFound[i].pSource->HasFollowSupport())
+ pFound[i].pDest->SetFollow(pFound[i].pSource->GetParent());
+ }
+ delete [] pFound;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::UpdateFromTemplate_Impl( )
+
+/* [Beschreibung]
+
+ Diese interne Methode pr"uft, ob das Dokument aus einem Template
+ erzeugt wurde, und ob dieses neuer ist als das Dokument. Ist dies
+ der Fall, wird der Benutzer gefragt, ob die Vorlagen (StyleSheets)
+ updated werden sollen. Wird dies positiv beantwortet, werden die
+ StyleSheets updated.
+*/
+
+{
+ // Storage-medium?
+ SfxMedium *pFile = GetMedium();
+ DBG_ASSERT( pFile, "cannot UpdateFromTemplate without medium" );
+ if ( !pFile )
+ return;
+
+ if ( !::utl::LocalFileHelper::IsLocalFile( pFile->GetName() ) )
+ // update only for documents loaded from the local file system
+ return;
+
+ // only for own storage formats
+ uno::Reference< embed::XStorage > xDocStor = pFile->GetStorage();
+ if ( !pFile->GetFilter() || !pFile->GetFilter()->IsOwnFormat() )
+ return;
+
+ SFX_ITEMSET_ARG( pFile->GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
+ sal_Int16 bCanUpdateFromTemplate = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
+
+ // created from template?
+ uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
+ ::rtl::OUString aTemplName( xDocProps->getTemplateName() );
+ ::rtl::OUString aTemplURL( xDocProps->getTemplateURL() );
+ String aFoundName;
+
+ if ( aTemplName.getLength() || (aTemplURL.getLength() && !IsReadOnly()) )
+ {
+ // try to locate template, first using filename
+ // this must be done because writer global document uses this "great" idea to manage the templates of all parts
+ // in the master document
+ // but it is NOT an error if the template filename points not to a valid file
+ SfxDocumentTemplates aTempl;
+ aTempl.Construct();
+ if ( aTemplURL.getLength() )
+ {
+ String aURL;
+ if( ::utl::LocalFileHelper::ConvertSystemPathToURL( aTemplURL, GetMedium()->GetName(), aURL ) )
+ aFoundName = aURL;
+ }
+
+ if( !aFoundName.Len() && aTemplName.getLength() )
+ // if the template filename did not lead to success, try to get a file name for the logical template name
+ aTempl.GetFull( String(), aTemplName, aFoundName );
+ }
+
+ if ( aFoundName.Len() )
+ {
+ // check existence of template storage
+ aTemplURL = aFoundName;
+ BOOL bLoad = FALSE;
+
+ // should the document checked against changes in the template ?
+ if ( IsQueryLoadTemplate() )
+ {
+ // load document info of template
+ BOOL bOK = FALSE;
+ util::DateTime aTemplDate;
+ try
+ {
+ Reference < document::XStandaloneDocumentInfo > xDocInfo (
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.document.StandaloneDocumentInfo") ) ),
+ UNO_QUERY_THROW );
+ Reference < beans::XFastPropertySet > xSet( xDocInfo,
+ UNO_QUERY_THROW );
+ xDocInfo->loadFromURL( aTemplURL );
+ Any aAny = xSet->getFastPropertyValue( WID_DATE_MODIFIED );
+ ::com::sun::star::util::DateTime aTmp;
+ if ( aAny >>= aTemplDate )
+ {
+ // get modify date from document info
+ bOK = TRUE;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ // if modify date was read successfully
+ if ( bOK )
+ {
+ // compare modify data of template with the last check date of the document
+ const util::DateTime aInfoDate( xDocProps->getTemplateDate() );
+ if ( aTemplDate > aInfoDate )
+ {
+ // ask user
+ if( bCanUpdateFromTemplate == document::UpdateDocMode::QUIET_UPDATE
+ || bCanUpdateFromTemplate == document::UpdateDocMode::FULL_UPDATE )
+ bLoad = TRUE;
+ else if ( bCanUpdateFromTemplate == document::UpdateDocMode::ACCORDING_TO_CONFIG )
+ {
+ String sMessage( SfxResId( STR_QRYTEMPL_MESSAGE ) );
+ sMessage.SearchAndReplace( String::CreateFromAscii("$(ARG1)"), aTemplName );
+ sfx2::QueryTemplateBox aBox( GetDialogParent(), sMessage );
+ if ( RET_YES == aBox.Execute() )
+ bLoad = TRUE;
+ }
+
+ if( !bLoad )
+ {
+ // user refuses, so don't ask again for this document
+ SetQueryLoadTemplate(FALSE);
+ SetModified( TRUE );
+ }
+ }
+ }
+
+ if ( bLoad )
+ {
+ // styles should be updated, create document in organizer mode to read in the styles
+ //TODO: testen!
+ SfxObjectShellLock xTemplDoc = CreateObjectByFactoryName( GetFactory().GetFactoryName(), SFX_CREATE_MODE_ORGANIZER );
+ xTemplDoc->DoInitNew(0);
+
+ // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended!
+ //xTemplDoc->SetBaseURL( aFoundName );
+
+ // TODO/LATER: make sure that we don't use binary templates!
+ SfxMedium aMedium( aFoundName, STREAM_STD_READ );
+ if ( xTemplDoc->LoadFrom( aMedium ) )
+ {
+ // transfer styles from xTemplDoc to this document
+ // TODO/MBA: make sure that no BaseURL is needed in *this* document
+ LoadStyles(*xTemplDoc);
+
+ // remember date/time of check
+ xDocProps->setTemplateDate(aTemplDate);
+ // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
+//REPLACE pInfo->Save(xDocStor);
+ }
+ }
+/*
+ SfxConfigManager *pCfgMgr = SFX_CFGMANAGER();
+ {
+ SfxConfigManager *pTemplCfg = new SfxConfigManager(aTemplStor, pCfgMgr);
+ SetConfigManager(pTemplCfg);
+ SetTemplateConfig(TRUE);
+
+ // Falls der gerade zerst"orte CfgMgr des Dokuments der
+ // aktive war, pCfgMgr lieber neu holen
+ pCfgMgr = SFX_CFGMANAGER();
+
+ // ggf. den neuen ConfigManager aktivieren
+ if ( this == SfxObjectShell::Current() )
+ pTemplCfg->Activate(pCfgMgr);
+ }
+*/
+ // Template und Template-DocInfo werden nicht mehr gebraucht
+// delete pTemplInfo;
+ }
+ }
+}
+
+SfxObjectShellRef MakeObjectShellForOrganizer_Impl( const String& aTargetURL, BOOL bForWriting )
+{
+ // check for own format
+ SfxObjectShellRef xDoc;
+ StreamMode nMode = bForWriting ? SFX_STREAM_READWRITE : SFX_STREAM_READONLY;
+ SfxMedium *pMed = new SfxMedium( aTargetURL, nMode, FALSE, 0 );
+ const SfxFilter* pFilter = NULL;
+ pMed->UseInteractionHandler(TRUE);
+ if( SFX_APP()->GetFilterMatcher().GuessFilter( *pMed, &pFilter ) == ERRCODE_NONE && pFilter && pFilter->IsOwnFormat() )
+ {
+ // create document
+ xDoc = SfxObjectShell::CreateObject( pFilter->GetServiceName(), SFX_CREATE_MODE_ORGANIZER );
+ if ( xDoc.Is() )
+ {
+ // partially load, so don't use DoLoad!
+ xDoc->DoInitNew(0);
+ // TODO/LATER: make sure that we don't use binary templates!
+ if( xDoc->LoadFrom( *pMed ) )
+ {
+ // connect to storage, abandon temp. storage
+ xDoc->DoSaveCompleted( pMed );
+ }
+ else
+ xDoc.Clear();
+ }
+ }
+ else
+ delete pMed;
+
+ return xDoc;
+}
+
+sal_Bool SfxObjectShell::IsHelpDocument() const
+{
+ const SfxFilter* pFilter = GetMedium()->GetFilter();
+ return ( pFilter && pFilter->GetFilterName().CompareToAscii("writer_web_HTML_help") == COMPARE_EQUAL );
+}
+
+void SfxObjectShell::ResetFromTemplate( const String& rTemplateName, const String& rFileName )
+{
+ // only care about reseting this data for openoffice formats otherwise
+ if ( IsOwnStorageFormat_Impl( *GetMedium()) )
+ {
+ uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
+ xDocProps->setTemplateURL( ::rtl::OUString() );
+ xDocProps->setTemplateName( ::rtl::OUString() );
+ xDocProps->setTemplateDate( util::DateTime() );
+ xDocProps->resetUserData( ::rtl::OUString() );
+
+ // TODO/REFACTOR:
+ // Title?
+
+ if( ::utl::LocalFileHelper::IsLocalFile( rFileName ) )
+ {
+ String aFoundName;
+ if( SFX_APP()->Get_Impl()->GetDocumentTemplates()->GetFull( String(), rTemplateName, aFoundName ) )
+ {
+ INetURLObject aObj( rFileName );
+ xDocProps->setTemplateURL( aObj.GetMainURL(INetURLObject::DECODE_TO_IURI) );
+ xDocProps->setTemplateName( rTemplateName );
+
+ ::DateTime now;
+ xDocProps->setTemplateDate( util::DateTime(
+ now.Get100Sec(), now.GetSec(), now.GetMin(),
+ now.GetHour(), now.GetDay(), now.GetMonth(),
+ now.GetYear() ) );
+
+ SetQueryLoadTemplate( sal_True );
+ }
+ }
+ }
+}
+
+sal_Bool SfxObjectShell::IsQueryLoadTemplate() const
+{
+ return pImp->bQueryLoadTemplate;
+}
+
+sal_Bool SfxObjectShell::IsUseUserData() const
+{
+ return pImp->bUseUserData;
+}
+
+void SfxObjectShell::SetQueryLoadTemplate( sal_Bool bNew )
+{
+ if ( pImp->bQueryLoadTemplate != bNew )
+ SetModified( TRUE );
+ pImp->bQueryLoadTemplate = bNew;
+}
+
+void SfxObjectShell::SetUseUserData( sal_Bool bNew )
+{
+ if ( pImp->bUseUserData != bNew )
+ SetModified( TRUE );
+ pImp->bUseUserData = bNew;
+}
+
+sal_Bool SfxObjectShell::IsLoadReadonly() const
+{
+ return pImp->bLoadReadonly;
+}
+
+sal_Bool SfxObjectShell::IsSaveVersionOnClose() const
+{
+ return pImp->bSaveVersionOnClose;
+}
+
+void SfxObjectShell::SetLoadReadonly( sal_Bool bNew )
+{
+ if ( pImp->bLoadReadonly != bNew )
+ SetModified( TRUE );
+ pImp->bLoadReadonly = bNew;
+}
+
+void SfxObjectShell::SetSaveVersionOnClose( sal_Bool bNew )
+{
+ if ( pImp->bSaveVersionOnClose != bNew )
+ SetModified( TRUE );
+ pImp->bSaveVersionOnClose = bNew;
+}
+
+sal_uInt32 SfxObjectShell::GetModifyPasswordHash() const
+{
+ return pImp->m_nModifyPasswordHash;
+}
+
+sal_Bool SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash )
+{
+ if ( ( !IsReadOnly() && !IsReadOnlyUI() )
+ || !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ) )
+ {
+ // the hash can be changed only in editable documents,
+ // or during loading of document
+ pImp->m_nModifyPasswordHash = nHash;
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+uno::Sequence< beans::PropertyValue > SfxObjectShell::GetModifyPasswordInfo() const
+{
+ return pImp->m_aModifyPasswordInfo;
+}
+
+sal_Bool SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence< beans::PropertyValue >& aInfo )
+{
+ if ( ( !IsReadOnly() && !IsReadOnlyUI() )
+ || !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ) )
+ {
+ // the hash can be changed only in editable documents,
+ // or during loading of document
+ pImp->m_aModifyPasswordInfo = aInfo;
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void SfxObjectShell::SetModifyPasswordEntered( sal_Bool bEntered )
+{
+ pImp->m_bModifyPasswordEntered = bEntered;
+}
+
+sal_Bool SfxObjectShell::IsModifyPasswordEntered()
+{
+ return pImp->m_bModifyPasswordEntered;
+}
+
diff --git a/sfx2/source/doc/objembed.cxx b/sfx2/source/doc/objembed.cxx
new file mode 100644
index 000000000000..1c2105c210b9
--- /dev/null
+++ b/sfx2/source/doc/objembed.cxx
@@ -0,0 +1,317 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/embed/XEmbedObjectCreator.hpp>
+#include <com/sun/star/embed/XComponentSupplier.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+
+#include <sfx2/objsh.hxx>
+#include <sfx2/app.hxx>
+#include "objshimp.hxx"
+#include <sfx2/sfx.hrc>
+#include <sfx2/event.hxx>
+
+#include <comphelper/seqstream.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <svtools/embedtransfer.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/gdimtf.hxx>
+
+using namespace ::com::sun::star;
+
+// -----------------------------------------------------------------------
+// TODO/LATER: this workaround must be replaced by API in future if possible
+SfxObjectShell* SfxObjectShell::GetParentShellByModel_Impl()
+{
+ SfxObjectShell* pResult = NULL;
+
+ try {
+ uno::Reference< container::XChild > xChildModel( GetModel(), uno::UNO_QUERY );
+ if ( xChildModel.is() )
+ {
+ uno::Reference< lang::XUnoTunnel > xParentTunnel( xChildModel->getParent(), uno::UNO_QUERY );
+ if ( xParentTunnel.is() )
+ {
+ SvGlobalName aSfxIdent( SFX_GLOBAL_CLASSID );
+ pResult = reinterpret_cast<SfxObjectShell*>(xParentTunnel->getSomething(
+ uno::Sequence< sal_Int8 >( aSfxIdent.GetByteSequence() ) ) );
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: error handling
+ }
+
+ return pResult;
+}
+
+// -----------------------------------------------------------------------
+Printer* SfxObjectShell::GetDocumentPrinter()
+{
+ SfxObjectShell* pParent = GetParentShellByModel_Impl();
+ if ( pParent )
+ return pParent->GetDocumentPrinter();
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+OutputDevice* SfxObjectShell::GetDocumentRefDev()
+{
+ SfxObjectShell* pParent = GetParentShellByModel_Impl();
+ if ( pParent )
+ return pParent->GetDocumentRefDev();
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+void SfxObjectShell::OnDocumentPrinterChanged( Printer* /*pNewPrinter*/ )
+{
+ // virtual method
+}
+
+// -----------------------------------------------------------------------
+Rectangle SfxObjectShell::GetVisArea( USHORT nAspect ) const
+{
+ if( nAspect == ASPECT_CONTENT )
+ return pImp->m_aVisArea;
+ else if( nAspect == ASPECT_THUMBNAIL )
+ {
+ Rectangle aRect;
+ aRect.SetSize( OutputDevice::LogicToLogic( Size( 5000, 5000 ),
+ MAP_100TH_MM, GetMapUnit() ) );
+ return aRect;
+ }
+ return Rectangle();
+}
+
+// -----------------------------------------------------------------------
+const Rectangle& SfxObjectShell::GetVisArea() const
+{
+ pImp->m_aVisArea = GetVisArea( ASPECT_CONTENT );
+ return pImp->m_aVisArea;
+}
+
+// -----------------------------------------------------------------------
+void SfxObjectShell::SetVisArea( const Rectangle & rVisArea )
+{
+ if( pImp->m_aVisArea != rVisArea )
+ {
+ pImp->m_aVisArea = rVisArea;
+ if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ if ( IsEnableSetModified() )
+ SetModified( TRUE );
+
+ SFX_APP()->NotifyEvent(SfxEventHint( SFX_EVENT_VISAREACHANGED, GlobalEventConfig::GetEventName(STR_EVENT_VISAREACHANGED), this));
+
+ /*
+ Size aSize (GetVisArea().GetSize());
+ if ( GetIPEnv() && GetIPEnv()->GetEditWin() )
+ ViewChanged( ASPECT_CONTENT );
+ */
+
+
+ // OutPlace die Gr"o\se des MDI-Fensters anpassen
+ // Unbedingt den Gr"o\senvergleich machen, spart nicht nur Zeit, sondern
+ // vermeidet auch Rundungsfehler !
+ /*
+ // in case of ole outplace editing the frame should be found
+ SfxViewFrame* pFrameToResize = pFrame ? pFrame : SfxViewFrame::GetFirst( GetObjectShell() );
+
+ if ( pFrameToResize && !pIPF && rRect.GetSize() != aSize &&
+ !pFrameToResize->IsAdjustPosSizePixelLocked_Impl() )
+
+ {
+ // Zuerst die logischen Koordinaten von IP-Objekt und EditWindow
+ // ber"ucksichtigen
+ SfxViewShell *pShell = pFrameToResize->GetViewShell();
+ Window *pWindow = pShell->GetWindow();
+
+ // Da in den Applikationen bei der R"ucktransformation immer die
+ // Eckpunkte tranformiert werden und nicht die Size (um die Ecken
+ // alignen zu k"onnen), transformieren wir hier auch die Punkte, um
+ // m"oglichst wenig Rundungsfehler zu erhalten.
+ Rectangle aRect = pWindow->LogicToPixel( rRect );
+ Size aSize = aRect.GetSize();
+ pShell->GetWindow()->SetSizePixel( aSize );
+ pFrameToResize->DoAdjustPosSizePixel( pShell, Point(), aSize );
+ }
+
+ // bei InPlace die View skalieren
+ if ( GetIPEnv() && GetIPEnv()->GetEditWin() && !bDisableViewScaling && pIPF )
+ pIPF->GetEnv_Impl()->MakeScale( rRect.GetSize(), GetMapUnit(),
+ pIPF->GetViewShell()->GetWindow()->GetOutputSizePixel() );
+ */
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxObjectShell::SetVisAreaSize( const Size & rVisSize )
+{
+ SetVisArea( Rectangle( GetVisArea().TopLeft(), rVisSize ) );
+}
+
+// -----------------------------------------------------------------------
+ULONG SfxObjectShell::GetMiscStatus() const
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+MapUnit SfxObjectShell::GetMapUnit() const
+{
+ return pImp->m_nMapUnit;
+}
+
+// -----------------------------------------------------------------------
+void SfxObjectShell::SetMapUnit( MapUnit nMapUnit )
+{
+ pImp->m_nMapUnit = nMapUnit;
+}
+
+// -----------------------------------------------------------------------
+void SfxObjectShell::FillTransferableObjectDescriptor( TransferableObjectDescriptor& rDesc ) const
+{
+ sal_uInt32 nClipFormat;
+ String aAppName, aShortName;
+ FillClass( &rDesc.maClassName, &nClipFormat, &aAppName, &rDesc.maTypeName, &aShortName, SOFFICE_FILEFORMAT_CURRENT );
+
+ rDesc.mnViewAspect = ASPECT_CONTENT;
+ rDesc.mnOle2Misc = GetMiscStatus();
+ rDesc.maSize = OutputDevice::LogicToLogic( GetVisArea().GetSize(), GetMapUnit(), MAP_100TH_MM );
+ rDesc.maDragStartPos = Point();
+ rDesc.maDisplayName = String();
+ rDesc.mbCanLink = FALSE;
+}
+
+// -----------------------------------------------------------------------
+void SfxObjectShell::DoDraw( OutputDevice* pDev,
+ const Point & rObjPos,
+ const Size & rSize,
+ const JobSetup & rSetup,
+ USHORT nAspect )
+{
+ MapMode aMod = pDev->GetMapMode();
+ Size aSize = GetVisArea( nAspect ).GetSize();
+ MapMode aWilliMode( GetMapUnit() );
+ aSize = pDev->LogicToLogic( aSize, &aWilliMode, &aMod );
+ if( aSize.Width() && aSize.Height() )
+ {
+ Fraction aXF( rSize.Width(), aSize.Width() );
+ Fraction aYF( rSize.Height(), aSize.Height() );
+
+//REMOVE Point aOrg = rObjPos;
+//REMOVE aMod.SetMapUnit( MAP_100TH_MM );
+//REMOVE aSize = pDev->LogicToLogic( GetVisArea( nAspect ).GetSize(), &aMod, &aWilliMode );
+ DoDraw_Impl( pDev, rObjPos, aXF, aYF, rSetup, nAspect );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxObjectShell::DoDraw_Impl( OutputDevice* pDev,
+ const Point & rViewPos,
+ const Fraction & rScaleX,
+ const Fraction & rScaleY,
+ const JobSetup & rSetup,
+ USHORT nAspect )
+{
+ Rectangle aVisArea = GetVisArea( nAspect );
+ // MapUnit des Ziels
+ MapMode aMapMode( GetMapUnit() );
+ aMapMode.SetScaleX( rScaleX );
+ aMapMode.SetScaleY( rScaleY );
+
+ // Ziel in Pixel
+ Point aOrg = pDev->LogicToLogic( rViewPos, NULL, &aMapMode );
+ Point aDelta = aOrg - aVisArea.TopLeft();
+
+ // Origin entsprechend zum sichtbaren Bereich verschieben
+ // Origin mit Scale setzen
+ aMapMode.SetOrigin( aDelta );
+
+ // Deviceeinstellungen sichern
+ pDev->Push();
+
+ Region aRegion;
+ if( pDev->IsClipRegion() && pDev->GetOutDevType() != OUTDEV_PRINTER )
+ {
+ aRegion = pDev->GetClipRegion();
+ aRegion = pDev->LogicToPixel( aRegion );
+ }
+ pDev->SetRelativeMapMode( aMapMode );
+
+ GDIMetaFile * pMtf = pDev->GetConnectMetaFile();
+ if( pMtf )
+ {
+ if( pMtf->IsRecord() && pDev->GetOutDevType() != OUTDEV_PRINTER )
+ pMtf->Stop();
+ else
+ pMtf = NULL;
+ }
+// #ifndef UNX
+ if( pDev->IsClipRegion() && pDev->GetOutDevType() != OUTDEV_PRINTER )
+// #endif
+ {
+ aRegion = pDev->PixelToLogic( aRegion );
+ pDev->SetClipRegion( aRegion );
+ }
+ if( pMtf )
+ pMtf->Record( pDev );
+
+//REMOVE SvOutPlaceObjectRef xOutRef( this );
+//REMOVE if ( xOutRef.Is() )
+//REMOVE xOutRef->DrawObject( pDev, rSetup, rSize, nAspect );
+//REMOVE else
+ Draw( pDev, rSetup, nAspect );
+//REMOVE DrawHatch( pDev, aVisArea.TopLeft(), aVisArea.GetSize() );
+
+ // Deviceeinstellungen wieder herstellen
+ pDev->Pop();
+
+}
+
+comphelper::EmbeddedObjectContainer& SfxObjectShell::GetEmbeddedObjectContainer() const
+{
+ if ( !pImp->mpObjectContainer )
+ pImp->mpObjectContainer = new comphelper::EmbeddedObjectContainer( ((SfxObjectShell*)this)->GetStorage(), GetModel() );
+ return *pImp->mpObjectContainer;
+}
+
+void SfxObjectShell::ClearEmbeddedObjects()
+{
+ // frees alle space taken by embedded objects
+ DELETEZ( pImp->mpObjectContainer );
+}
+
diff --git a/sfx2/source/doc/objitem.cxx b/sfx2/source/doc/objitem.cxx
new file mode 100644
index 000000000000..2980d984fd78
--- /dev/null
+++ b/sfx2/source/doc/objitem.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#ifndef GCC
+#endif
+
+#include <sfx2/objsh.hxx>
+//#include "objshimp.hxx"
+#include <sfx2/objitem.hxx>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+
+//====================================================================
+
+TYPEINIT1_AUTOFACTORY(SfxObjectShellItem,SfxPoolItem)
+TYPEINIT1_AUTOFACTORY(SfxObjectItem,SfxPoolItem)
+
+//=========================================================================
+
+int SfxObjectShellItem::operator==( const SfxPoolItem &rItem ) const
+{
+ return PTR_CAST(SfxObjectShellItem, &rItem)->pObjSh == pObjSh;
+}
+
+//--------------------------------------------------------------------
+
+String SfxObjectShellItem::GetValueText() const
+{
+ return String();
+}
+
+//--------------------------------------------------------------------
+
+SfxPoolItem* SfxObjectShellItem::Clone( SfxItemPool *) const
+{
+ return new SfxObjectShellItem( Which(), pObjSh );
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SfxObjectShellItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE /*nMemberId*/ ) const
+{
+ if ( pObjSh )
+ {
+ // This item MUST provide a model. Please don't change this, there are UNO-based
+ // implementations which need it!!
+ rVal <<= pObjSh->GetModel();
+ }
+ else
+ {
+ rVal <<= ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >();
+ }
+ return TRUE;
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SfxObjectShellItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE /*nMemberId*/ )
+{
+ // This item MUST have a model. Please don't change this, there are UNO-based
+ // implementations which need it!!
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel;
+
+ if ( rVal >>= xModel )
+ {
+ if ( xModel.is() )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel(
+ xModel, ::com::sun::star::uno::UNO_QUERY );
+ if ( xTunnel.is() )
+ {
+ ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( (sal_Int8*) SvGlobalName( SFX_GLOBAL_CLASSID ).GetBytes(), 16 );
+ sal_Int64 nHandle = xTunnel->getSomething( aSeq );
+ if ( nHandle )
+ {
+ pObjSh = reinterpret_cast< SfxObjectShell* >(sal::static_int_cast<sal_IntPtr>( nHandle ));
+ return TRUE;
+ }
+ }
+ }
+
+ pObjSh = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//=========================================================================
+
+SfxObjectItem::SfxObjectItem( USHORT nWhichId, SfxShell *pSh )
+: SfxPoolItem( nWhichId ),
+ _pSh( pSh )
+{}
+
+//--------------------------------------------------------------------
+
+int SfxObjectItem::operator==( const SfxPoolItem &rItem ) const
+{
+ SfxObjectItem *pOther = PTR_CAST(SfxObjectItem, &rItem);
+ return pOther->_pSh == _pSh;
+}
+
+//--------------------------------------------------------------------
+
+SfxPoolItem* SfxObjectItem::Clone( SfxItemPool *) const
+{
+ return new SfxObjectItem( Which(), _pSh );
+}
diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx
new file mode 100755
index 000000000000..addb648ef2e9
--- /dev/null
+++ b/sfx2/source/doc/objmisc.cxx
@@ -0,0 +1,2590 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#ifndef _INETMSG_HXX //autogen
+#include <svl/inetmsg.hxx>
+#endif
+#include <tools/diagnose_ex.h>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svtools/svparser.hxx> // SvKeyValue
+#include <vos/mutex.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
+#include <com/sun/star/script/FinishEngineEvent.hpp>
+#include <com/sun/star/script/InterruptReason.hpp>
+#include <com/sun/star/script/XEngineListener.hpp>
+#include <com/sun/star/script/XDebugging.hpp>
+#ifndef _COM_SUN_STAR_SCRIPT_XINVOKATION_HPP_
+#include <com/sun/star/script/XInvocation.hpp>
+#endif
+#include <com/sun/star/script/ContextInformation.hpp>
+#include <com/sun/star/script/FinishReason.hpp>
+#include <com/sun/star/script/XEngine.hpp>
+#include <com/sun/star/script/InterruptEngineEvent.hpp>
+#include <com/sun/star/script/XLibraryAccess.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/document/XScriptInvocationContext.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+
+
+#include <com/sun/star/script/provider/XScript.hpp>
+#include <com/sun/star/script/provider/XScriptProvider.hpp>
+#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
+
+#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
+#include <toolkit/unohlp.hxx>
+#endif
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/task/ErrorCodeRequest.hpp>
+#include <unotools/securityoptions.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/configurationhelper.hxx>
+
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+#include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
+#include <com/sun/star/task/InteractionClassification.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::script::provider;
+using namespace ::com::sun::star::container;
+#include <basic/sbuno.hxx>
+#include <basic/sbstar.hxx>
+#ifndef _SB_BASMGR_HXX
+#include <basic/basmgr.hxx>
+#endif
+#ifndef _VCL_MSGBOX_HXX
+#include <vcl/msgbox.hxx>
+#endif
+#include <basic/sbx.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+
+#include <unotools/pathoptions.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <tools/inetmime.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/inettype.hxx>
+#include <svl/sharecontrolfile.hxx>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <vcl/svapp.hxx>
+#include <framework/interaction.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/documentconstants.hxx>
+
+#include <sfx2/signaturestate.hxx>
+#include <sfx2/app.hxx>
+#include "appdata.hxx"
+#include <sfx2/request.hxx>
+#include <sfx2/bindings.hxx>
+#include "sfxresid.hxx"
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/objsh.hxx>
+#include "objshimp.hxx"
+#include <sfx2/event.hxx>
+#include "fltfnc.hxx"
+#include <sfx2/sfx.hrc>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/ctrlitem.hxx>
+#include "arrdecl.hxx"
+#include <sfx2/module.hxx>
+#include <sfx2/macrconf.hxx>
+#include <sfx2/docfac.hxx>
+#include "helper.hxx"
+#include "doc.hrc"
+#include "workwin.hxx"
+#include "helpid.hrc"
+#include "../appl/app.hrc"
+#include <sfx2/sfxdlg.hxx>
+#include "appbaslib.hxx"
+#include <openflag.hxx> // SFX_STREAM_READWRITE
+
+using namespace ::com::sun::star;
+
+// class SfxHeaderAttributes_Impl ----------------------------------------
+
+class SfxHeaderAttributes_Impl : public SvKeyValueIterator
+{
+private:
+ SfxObjectShell* pDoc;
+ SvKeyValueIteratorRef xIter;
+ sal_Bool bAlert;
+
+public:
+ SfxHeaderAttributes_Impl( SfxObjectShell* pSh ) :
+ SvKeyValueIterator(), pDoc( pSh ),
+ xIter( pSh->GetMedium()->GetHeaderAttributes_Impl() ),
+ bAlert( sal_False ) {}
+
+ virtual sal_Bool GetFirst( SvKeyValue& rKV ) { return xIter->GetFirst( rKV ); }
+ virtual sal_Bool GetNext( SvKeyValue& rKV ) { return xIter->GetNext( rKV ); }
+ virtual void Append( const SvKeyValue& rKV );
+
+ void ClearForSourceView() { xIter = new SvKeyValueIterator; bAlert = sal_False; }
+ void SetAttributes();
+ void SetAttribute( const SvKeyValue& rKV );
+};
+
+//=========================================================================
+
+sal_uInt16 __READONLY_DATA aTitleMap_Impl[3][2] =
+{
+ // local remote
+ /* SFX_TITLE_CAPTION */ { SFX_TITLE_FILENAME, SFX_TITLE_TITLE },
+ /* SFX_TITLE_PICKLIST */ { 32, SFX_TITLE_FULLNAME },
+ /* SFX_TITLE_HISTORY */ { 32, SFX_TITLE_FULLNAME }
+};
+
+//=========================================================================
+
+void SfxObjectShell::AbortImport()
+{
+ pImp->bIsAbortingImport = sal_True;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsAbortingImport() const
+{
+ return pImp->bIsAbortingImport;
+}
+
+//-------------------------------------------------------------------------
+
+uno::Reference<document::XDocumentProperties>
+SfxObjectShell::getDocProperties()
+{
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xDPS->getDocumentProperties());
+ DBG_ASSERT(xDocProps.is(),
+ "SfxObjectShell: model has no DocumentProperties");
+ return xDocProps;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::DoFlushDocInfo()
+{
+}
+
+//-------------------------------------------------------------------------
+
+// Note: the only thing that calls this is the modification event handler
+// that is installed at the XDocumentProperties
+void SfxObjectShell::FlushDocInfo()
+{
+ if ( IsLoading() )
+ return;
+
+ SetModified(sal_True);
+ uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
+ DoFlushDocInfo(); // call template method
+ ::rtl::OUString url(xDocProps->getAutoloadURL());
+ sal_Int32 delay(xDocProps->getAutoloadSecs());
+ SetAutoLoad( INetURLObject(url), delay * 1000,
+ (delay > 0) || url.getLength() );
+/*
+ // bitte beachten:
+ // 1. Titel in DocInfo aber nicht am Doc (nach HTML-Import)
+ // => auch am Doc setzen
+ // 2. Titel in DocInfo leer (Briefumschlagsdruck)
+ // => nicht am Doc setzen, da sonst "unbenanntX" daraus wird
+ String aDocInfoTitle = GetDocInfo().GetTitle();
+ if ( aDocInfoTitle.Len() )
+ SetTitle( aDocInfoTitle );
+ else
+ {
+ pImp->aTitle.Erase();
+ SetNamedVisibility_Impl();
+ if ( GetMedium() )
+ {
+ SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
+ Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
+ }
+ }*/
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::SetError( sal_uInt32 lErr, const ::rtl::OUString& aLogMessage )
+{
+ if(pImp->lErr==ERRCODE_NONE)
+ {
+ pImp->lErr=lErr;
+
+ if( lErr != ERRCODE_NONE && aLogMessage.getLength() )
+ AddLog( aLogMessage );
+ }
+}
+
+//-------------------------------------------------------------------------
+
+sal_uInt32 SfxObjectShell::GetError() const
+{
+ return ERRCODE_TOERROR(GetErrorCode());
+}
+
+//-------------------------------------------------------------------------
+
+sal_uInt32 SfxObjectShell::GetErrorCode() const
+{
+ sal_uInt32 lError=pImp->lErr;
+ if(!lError && GetMedium())
+ lError=GetMedium()->GetErrorCode();
+ return lError;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::ResetError()
+{
+ if( pImp->lErr != ERRCODE_NONE )
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Resetting Error." ) ) );
+
+ pImp->lErr=0;
+ SfxMedium * pMed = GetMedium();
+ if( pMed )
+ pMed->ResetError();
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsTemplate() const
+{
+ return pImp->bIsTemplate;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::SetTemplate(sal_Bool bIs)
+{
+ pImp->bIsTemplate=bIs;
+ SfxFilterMatcher aMatcher( GetFactory().GetFactoryName() );
+ SfxFilterMatcherIter aIter( &aMatcher, SFX_FILTER_TEMPLATEPATH );
+ SfxMedium* pMed = GetMedium();
+ if( pMed ) pMed->SetFilter( aIter.First() );
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::EnableSetModified( sal_Bool bEnable )
+{
+#ifdef DBG_UTIL
+ if ( bEnable == pImp->m_bEnableSetModified )
+ DBG_WARNING( "SFX_PERSIST: EnableSetModified 2x mit dem gleichen Wert gerufen" );
+#endif
+ pImp->m_bEnableSetModified = bEnable;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsEnableSetModified() const
+{
+ return pImp->m_bEnableSetModified && !IsReadOnly();
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsModified()
+{
+ if ( pImp->m_bIsModified )
+ return sal_True;
+
+ if ( !pImp->m_xDocStorage.is() || IsReadOnly() )
+ {
+ // if the document still has no storage and is not set to be modified explicitly it is not modified
+ // a readonly document is also not modified
+
+ return sal_False;
+ }
+
+ uno::Sequence < ::rtl::OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
+ for ( sal_Int32 n=0; n<aNames.getLength(); n++ )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( aNames[n] );
+ OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
+ if ( xObj.is() )
+ {
+ try
+ {
+ sal_Int32 nState = xObj->getCurrentState();
+ if ( nState != embed::EmbedStates::LOADED )
+ {
+ uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
+ if ( xModifiable.is() && xModifiable->isModified() )
+ return sal_True;
+ }
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ }
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::SetModified( sal_Bool bModifiedP )
+{
+#ifdef DBG_UTIL
+ if ( !bModifiedP && !IsEnableSetModified() )
+ DBG_WARNING( "SFX_PERSIST: SetModified( sal_False ), obwohl IsEnableSetModified() == sal_False" );
+#endif
+
+ if( !IsEnableSetModified() )
+ return;
+
+ if( pImp->m_bIsModified != bModifiedP )
+ {
+ pImp->m_bIsModified = bModifiedP;
+ ModifyChanged();
+ }
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::ModifyChanged()
+{
+ if ( pImp->bClosing )
+ // SetModified aus dem dispose des Models!
+ return;
+
+ {DBG_CHKTHIS(SfxObjectShell, 0);}
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ pViewFrame->GetBindings().Invalidate( SID_SAVEDOCS );
+
+ Invalidate( SID_SIGNATURE );
+ Invalidate( SID_MACRO_SIGNATURE );
+ Broadcast( SfxSimpleHint( SFX_HINT_TITLECHANGED ) ); // xmlsec05, signed state might change in title...
+
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_MODIFYCHANGED, GlobalEventConfig::GetEventName(STR_EVENT_MODIFYCHANGED), this ) );
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsReadOnlyUI() const
+
+/* [Beschreibung]
+
+ Liefert sal_True, wenn das Dokument fuer die UI wie r/o behandelt werden
+ soll. Dieses ist unabhaengig vom tatsaechlichen r/o, welches per
+ <IsReadOnly()> erfragbar ist.
+*/
+
+{
+ return pImp->bReadOnlyUI;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsReadOnlyMedium() const
+
+/* [Beschreibung]
+
+ Liefert sal_True, wenn das Medium r/o ist bzw. r/o geoeffnet wurde.
+*/
+
+{
+ if ( !pMedium )
+ return sal_True;
+ return pMedium->IsReadOnly();
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::SetReadOnlyUI( sal_Bool bReadOnly )
+
+/* [Beschreibung]
+
+ Schaltet das Dokument in einen r/o bzw. r/w Zustand ohne es neu
+ zu laden und ohne die Open-Modi des Mediums zu aendern.
+*/
+
+{
+ sal_Bool bWasRO = IsReadOnly();
+ pImp->bReadOnlyUI = bReadOnly;
+ if ( bWasRO != IsReadOnly() )
+ {
+ Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
+ //if ( pImp->pDocInfo )
+ // pImp->pDocInfo->SetReadOnly( IsReadOnly() );
+ }
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::SetReadOnly()
+{
+ // Let the document be completely readonly, means that the
+ // medium open mode is adjusted accordingly, and the write lock
+ // on the file is removed.
+
+ if ( pMedium && !IsReadOnlyMedium() )
+ {
+ sal_Bool bWasROUI = IsReadOnly();
+
+ pMedium->UnlockFile( sal_False );
+
+ // the storage-based mediums are already based on the temporary file
+ // so UnlockFile has already closed the locking stream
+ if ( !pMedium->HasStorage_Impl() && IsLoadingFinished() )
+ pMedium->CloseInStream();
+
+ pMedium->SetOpenMode( SFX_STREAM_READONLY, pMedium->IsDirect(), sal_True );
+ pMedium->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
+
+ if ( !bWasROUI )
+ Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
+ }
+}
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsReadOnly() const
+{
+ return pImp->bReadOnlyUI || IsReadOnlyMedium();
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsInModalMode() const
+{
+ return pImp->bModalMode || pImp->bRunningMacro;
+}
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+sal_Bool SfxObjectShell::AcceptStateUpdate() const
+{
+ return !IsInModalMode();
+}
+//-->Added by PengYunQuan for Validity Cell Range Picker
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::HasModalViews() const
+{
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
+ while( pFrame )
+ {
+ if ( pFrame->IsInModalMode() )
+ return sal_True;
+
+ pFrame = SfxViewFrame::GetNext( *pFrame, this );
+ }
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::SetMacroMode_Impl( sal_Bool bModal )
+{
+ if ( !pImp->bRunningMacro != !bModal )
+ {
+ pImp->bRunningMacro = bModal;
+ Broadcast( SfxSimpleHint( SFX_HINT_MODECHANGED ) );
+ }
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::SetModalMode_Impl( sal_Bool bModal )
+{
+ // nur Broadcasten wenn modifiziert, sonst ggf. Endlosrekursion
+ if ( !pImp->bModalMode != !bModal )
+ {
+ // zentral mitz"ahlen
+ sal_uInt16 &rDocModalCount = SFX_APP()->Get_Impl()->nDocModalMode;
+ if ( bModal )
+ ++rDocModalCount;
+ else
+ --rDocModalCount;
+
+ // umschalten
+ pImp->bModalMode = bModal;
+ Broadcast( SfxSimpleHint( SFX_HINT_MODECHANGED ) );
+ }
+}
+
+//--------------------------------------------------------------------
+sal_Bool SfxObjectShell::SwitchToShared( sal_Bool bShared, sal_Bool bSave )
+{
+ sal_Bool bResult = sal_True;
+
+ if ( bShared != IsDocShared() )
+ {
+ ::rtl::OUString aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( !aOrigURL.getLength() && bSave )
+ {
+ // this is a new document, let it be stored before switching to the shared mode;
+ // the storing should be done without shared flag, since it is possible that the
+ // target location does not allow to create sharing control file;
+ // the shared flag will be set later after creation of sharing control file
+ SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
+
+ if ( pViewFrame )
+ {
+ // TODO/LATER: currently the application guards against the reentrance problem
+ const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC );
+ SfxBoolItem* pResult = PTR_CAST( SfxBoolItem, pItem );
+ bResult = ( pResult && pResult->GetValue() );
+ if ( bResult )
+ aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
+ }
+ }
+
+ sal_Bool bOldValue = HasSharedXMLFlagSet();
+ SetSharedXMLFlag( bShared );
+
+ sal_Bool bRemoveEntryOnError = sal_False;
+ if ( bResult && bShared )
+ {
+ try
+ {
+ ::svt::ShareControlFile aControlFile( aOrigURL );
+ aControlFile.InsertOwnEntry();
+ bRemoveEntryOnError = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ bResult = sal_False;
+ }
+ }
+
+ if ( bResult && bSave )
+ {
+ SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
+
+ if ( pViewFrame )
+ {
+ // TODO/LATER: currently the application guards against the reentrance problem
+ SetModified( sal_True ); // the modified flag has to be set to let the document be stored with the shared flag
+ const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC );
+ SfxBoolItem* pResult = PTR_CAST( SfxBoolItem, pItem );
+ bResult = ( pResult && pResult->GetValue() );
+ }
+ }
+
+ if ( bResult )
+ {
+ // TODO/LATER: Is it possible that the following calls fail?
+ if ( bShared )
+ {
+ pImp->m_aSharedFileURL = aOrigURL;
+ GetMedium()->SwitchDocumentToTempFile();
+ }
+ else
+ {
+ ::rtl::OUString aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
+ GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
+ pImp->m_aSharedFileURL = ::rtl::OUString();
+
+ // now remove the temporary file the document was based on
+ ::utl::UCBContentHelper::Kill( aTempFileURL );
+
+ try
+ {
+ // aOrigURL can not be used since it contains an old value
+ ::svt::ShareControlFile aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
+ aControlFile.RemoveFile();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ else
+ {
+ // the saving has failed!
+ if ( bRemoveEntryOnError )
+ {
+ try
+ {
+ ::svt::ShareControlFile aControlFile( aOrigURL );
+ aControlFile.RemoveEntry();
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ SetSharedXMLFlag( bOldValue );
+ }
+ }
+ else
+ bResult = sal_False; // the second switch to the same mode
+
+ if ( bResult )
+ SetTitle( String() );
+
+ return bResult;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::DisconnectFromShared()
+{
+ if ( IsDocShared() )
+ {
+ if ( pMedium && pMedium->GetStorage().is() )
+ {
+ // set medium to noname
+ pMedium->SetName( String(), sal_True );
+ pMedium->Init_Impl();
+
+ // drop resource
+ SetNoName();
+ InvalidateName();
+
+ // untitled document must be based on temporary storage
+ // the medium should not dispose the storage in this case
+ if ( pMedium->GetStorage() == GetStorage() )
+ ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium );
+
+ pMedium->Close();
+ FreeSharedFile();
+
+ SfxMedium* pTmpMedium = pMedium;
+ ForgetMedium();
+ if( !DoSaveCompleted( pTmpMedium ) )
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ else
+ {
+ // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
+ pMedium->CanDisposeStorage_Impl( sal_False );
+ }
+
+ pMedium->GetItemSet()->ClearItem( SID_DOC_READONLY );
+ pMedium->SetOpenMode( SFX_STREAM_READWRITE, sal_True, sal_True );
+
+ SetTitle( String() );
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::FreeSharedFile()
+{
+ if ( pMedium )
+ FreeSharedFile( pMedium->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
+}
+
+//--------------------------------------------------------------------
+void SfxObjectShell::FreeSharedFile( const ::rtl::OUString& aTempFileURL )
+{
+ SetSharedXMLFlag( sal_False );
+
+ if ( IsDocShared() && aTempFileURL.getLength()
+ && !SfxMedium::EqualURLs( aTempFileURL, GetSharedFileURL() ) )
+ {
+ if ( pImp->m_bAllowShareControlFileClean )
+ {
+ try
+ {
+ ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
+ aControlFile.RemoveEntry();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+
+ // the cleaning is forbidden only once
+ pImp->m_bAllowShareControlFileClean = sal_True;
+
+ // now remove the temporary file the document is based currently on
+ ::utl::UCBContentHelper::Kill( aTempFileURL );
+
+ pImp->m_aSharedFileURL = ::rtl::OUString();
+ }
+}
+
+//--------------------------------------------------------------------
+void SfxObjectShell::DoNotCleanShareControlFile()
+{
+ pImp->m_bAllowShareControlFileClean = sal_False;
+}
+
+//--------------------------------------------------------------------
+void SfxObjectShell::SetSharedXMLFlag( sal_Bool bFlag ) const
+{
+ pImp->m_bSharedXMLFlag = bFlag;
+}
+
+//--------------------------------------------------------------------
+sal_Bool SfxObjectShell::HasSharedXMLFlagSet() const
+{
+ return pImp->m_bSharedXMLFlag;
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsDocShared() const
+{
+ return ( pImp->m_aSharedFileURL.getLength() > 0 );
+}
+
+//--------------------------------------------------------------------
+
+::rtl::OUString SfxObjectShell::GetSharedFileURL() const
+{
+ return pImp->m_aSharedFileURL;
+}
+
+//--------------------------------------------------------------------
+
+Size SfxObjectShell::GetFirstPageSize()
+{
+ return GetVisArea(ASPECT_THUMBNAIL).GetSize();
+}
+
+
+//--------------------------------------------------------------------
+
+IndexBitSet& SfxObjectShell::GetNoSet_Impl()
+{
+ return pImp->aBitSet;
+}
+
+//--------------------------------------------------------------------
+// changes the title of the document
+
+void SfxObjectShell::SetTitle
+(
+ const String& rTitle // der neue Titel des Dokuments
+)
+
+/* [Beschreibung]
+
+ Mit dieser Methode kann der Titel des Dokuments gesetzt werden.
+ Dieser entspricht initial dem kompletten Dateinamen. Ein Setzen
+ des Titels wirkt jedoch nicht zu"uck auf den Dateinamen; er wird
+ jedoch in den Caption-Bars der MDI-Fenster angezeigt.
+*/
+
+{
+ DBG_CHKTHIS(SfxObjectShell, 0);
+
+ // nix zu tun?
+ if ( ( ( HasName() && pImp->aTitle == rTitle )
+ || ( !HasName() && GetTitle() == rTitle ) )
+ && !IsDocShared() )
+ return;
+
+ SfxApplication *pSfxApp = SFX_APP();
+#if 0
+ // wird 'unbenannt#' als Titel gesetzt
+ String aNoName(SfxResId(STR_NONAME));
+ if ( rTitle.Match(aNoName) <= aNoName.Len() )
+ {
+ // er ist es selbst => ignorieren
+ pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
+ pImp->bIsNamedVisible=0;
+ }
+#endif
+
+ // ggf. die unbenannt-Nummer freigeben
+ if ( pImp->bIsNamedVisible && USHRT_MAX != pImp->nVisualDocumentNumber )
+ {
+ pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
+ pImp->bIsNamedVisible = 0;
+ }
+
+ // Title setzen
+ pImp->aTitle = rTitle;
+// Wieso denn in der DocInfo?
+// GetDocInfo().SetTitle( rTitle );
+// FlushDocInfo();
+
+ // Benachrichtigungen
+ if ( GetMedium() )
+ {
+ SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
+ Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
+ }
+}
+
+//--------------------------------------------------------------------
+
+#if OSL_DEBUG_LEVEL > 1
+String X(const String &rRet)
+{
+ if ( !rRet.Len() )
+ return DEFINE_CONST_UNICODE( "-empty-" );
+ return rRet;
+}
+#else
+#define X(ret) ret
+#endif
+
+//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+String SfxObjectShell::GetTitle
+(
+ sal_uInt16 nMaxLength /* 0 (default)
+ der Titel selbst, so wie er ist
+
+ 1 (==SFX_TITLE_FILENAME)
+ liefert den logischen Dateinamen ohne Pfad
+ (unter WNT je nach Systemeinstellung ohne
+ Extension)
+
+ 2 (==SFX_TITLE_FULLNAME)
+ liefert den mit komplettem logischen Dateinamen
+ mit Pfad (remote => ::com::sun::star::util::URL)
+
+ 3 (==SFX_TITLE_APINAME)
+ liefert den logischen Dateinamen ohne Pfad
+ und Extension
+
+ 4 (==SFX_TITLE_DETECT)
+ liefert den kompletten Titel, falls noch
+ nicht gesetzt wird aber aus DocInfo oder
+ dem Namen des Medium erzeugt
+
+ 5 (==SFX_TITLE_CAPTION)
+ liefert den Titel so, wie MB ihn heute in
+ der CaptionBar anzeigen m"ochte
+
+ 6 (==SFX_TITLE_PICKLIST)
+ liefert den Titel so, wie MB ihn heute in
+ der PickList anzeigen m"ochte
+
+ 7 (==SFX_TITLE_HISTORY)
+ liefert den Titel so, wie MB ihn heute in
+ der History anzeigen m"ochte
+
+ 10 bis USHRT_MAX
+ liefert maximal 'nMaxLength' Zeichen vom logischen
+ Dateinamen inkl. Pfad (remote => ::com::sun::star::util::URL)
+ */
+) const
+
+/* [Beschreibung]
+
+ Liefert den Titel bzw. logischen Dateinamen des Dokuments, je nach
+ 'nMaxLength'.
+
+ Falls der Dateiname mit Pfad verwendet wird, wird die Namensk"urzung durch
+ Ersetzung eines oder mehrerer Directory-Namen durch "..." durchgef"uhrt,
+ URLs werden z.Zt. immer komplett geliefert.
+*/
+
+{
+// if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+// return String();
+ SfxMedium *pMed = GetMedium();
+ if ( IsLoading() )
+ return String();
+
+/* if ( !nMaxLength && pImp->pDocInfo )
+ {
+ String aTitle = pImp->pDocInfo->GetTitle();
+ if ( aTitle.Len() )
+ return aTitle;
+ } */
+
+ // Titel erzeugen?
+ if ( SFX_TITLE_DETECT == nMaxLength && !pImp->aTitle.Len() )
+ {
+ static sal_Bool bRecur = sal_False;
+ if ( bRecur )
+ return DEFINE_CONST_UNICODE( "-not available-" );
+ bRecur = sal_True;
+
+ String aTitle;
+ SfxObjectShell *pThis = (SfxObjectShell*) this;
+
+ if ( pMed )
+ {
+ SFX_ITEMSET_ARG( pMed->GetItemSet(), pNameItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
+ if ( pNameItem )
+ aTitle = pNameItem->GetValue();
+ }
+
+ if ( !aTitle.Len() )
+ aTitle = GetTitle( SFX_TITLE_FILENAME );
+
+ if ( IsTemplate() )
+ pThis->SetTitle( aTitle );
+ bRecur = sal_False;
+ return X(aTitle);
+ }
+ else if (SFX_TITLE_APINAME == nMaxLength )
+ return X(GetAPIName());
+
+ // Sonderfall Vorlagen:
+ if( IsTemplate() && pImp->aTitle.Len() &&
+ ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
+ return X(pImp->aTitle);
+
+ // Picklist/Caption wird gemappt
+ if ( pMed && ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
+ {
+ // Wenn ein spezieller Titel beim "Offnen mitgegeben wurde;
+ // wichtig bei URLs, die INET_PROT_FILE verwenden, denn bei denen
+ // wird der gesetzte Titel nicht beachtet.
+ // (s.u., Auswertung von aTitleMap_Impl)
+ SFX_ITEMSET_ARG( pMed->GetItemSet(), pNameItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
+ if ( pNameItem )
+ return X( pNameItem->GetValue() );
+ }
+
+ // noch unbenannt?
+ DBG_ASSERT( !HasName() || pMed, "HasName() aber kein Medium?!?" );
+ if ( !HasName() || !pMed )
+ {
+ // schon Titel gesezt?
+ if ( pImp->aTitle.Len() )
+ return X(pImp->aTitle);
+
+ // mu\s es durchnumeriert werden?
+ String aNoName( SfxResId( STR_NONAME ) );
+ if ( pImp->bIsNamedVisible )
+ // Nummer hintenanh"angen
+ aNoName += String::CreateFromInt32( pImp->nVisualDocumentNumber );
+
+ // Dokument hei\st vorerst 'unbenannt#'
+ return X(aNoName);
+ }
+
+ const INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : ::rtl::OUString( GetMedium()->GetName() ) );
+ if ( nMaxLength > SFX_TITLE_CAPTION && nMaxLength <= SFX_TITLE_HISTORY )
+ {
+ sal_uInt16 nRemote;
+ if( !pMed || aURL.GetProtocol() == INET_PROT_FILE )
+ nRemote = 0;
+ else
+ nRemote = 1;
+ nMaxLength = aTitleMap_Impl[nMaxLength-SFX_TITLE_CAPTION][nRemote];
+ }
+
+ // lokale Datei?
+ if ( aURL.GetProtocol() == INET_PROT_FILE )
+ {
+ String aName( aURL.HasMark() ? INetURLObject( aURL.GetURLNoMark() ).PathToFileName() : aURL.PathToFileName() );
+ if ( nMaxLength == SFX_TITLE_FULLNAME )
+ return X( aName );
+ else if ( nMaxLength == SFX_TITLE_FILENAME )
+ return X( aURL.getName( INetURLObject::LAST_SEGMENT,
+ true, INetURLObject::DECODE_WITH_CHARSET ) );
+ else if ( !pImp->aTitle.Len() )
+ pImp->aTitle = aURL.getBase( INetURLObject::LAST_SEGMENT,
+ true, INetURLObject::DECODE_WITH_CHARSET );
+ }
+ else
+ {
+ // ::com::sun::star::util::URL-Versionen
+ if ( nMaxLength >= SFX_TITLE_MAXLEN )
+ {
+ String aComplete( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
+ if( aComplete.Len() > nMaxLength )
+ {
+ String aRet( DEFINE_CONST_UNICODE( "..." ) );
+ aRet += aComplete.Copy( aComplete.Len() - nMaxLength + 3, nMaxLength - 3 );
+ return X( aRet );
+ }
+ else
+ return X( aComplete );
+ }
+ else if ( nMaxLength == SFX_TITLE_FILENAME )
+ {
+ String aName( aURL.GetBase() );
+ aName = INetURLObject::decode( aName, INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET );
+ if( !aName.Len() )
+ aName = aURL.GetURLNoPass();
+ return X(aName);
+ }
+ else if ( nMaxLength == SFX_TITLE_FULLNAME )
+ return X(aURL.GetMainURL( INetURLObject::DECODE_TO_IURI ));
+
+ // ggf. Titel aus Dateiname generieren
+ if ( !pImp->aTitle.Len() )
+ pImp->aTitle = aURL.GetBase();
+
+ // workaround for the case when the name can not be retrieved from URL by INetURLObject
+ if ( !pImp->aTitle.Len() )
+ pImp->aTitle = aURL.GetMainURL( INetURLObject::DECODE_WITH_CHARSET );
+ }
+
+ // ganzer Titel
+ return X(pImp->aTitle);
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::InvalidateName()
+
+/* [Beschreibung]
+
+ Ermittelt den Titel des Dokuments neu aus 'unbenannt', DocInfo-Titel
+ bzw. Dateinamen. Wird nach Laden aus Template oder SaveAs ben"otigt.
+*/
+
+{
+ // Title neu erzeugen
+ pImp->aTitle.Erase();
+// pImp->nVisualDocumentNumber = USHRT_MAX;
+ //GetTitle( SFX_TITLE_DETECT );
+ SetName( GetTitle( SFX_TITLE_APINAME ) );
+
+ // Benachrichtigungen
+ Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::SetNamedVisibility_Impl()
+{
+ if ( !pImp->bIsNamedVisible )
+ {
+ // Nummer verpassen
+ pImp->bIsNamedVisible = sal_True;
+ // ggf. neue Nummer verpassen
+ if ( !HasName() && USHRT_MAX == pImp->nVisualDocumentNumber && !pImp->aTitle.Len() )
+ {
+ pImp->nVisualDocumentNumber = SFX_APP()->GetFreeIndex();
+ Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
+ }
+ }
+
+ SetName( GetTitle(SFX_TITLE_APINAME) );
+}
+
+void SfxObjectShell::SetNoName()
+{
+ bHasName = 0;
+ bIsTmp = sal_True;
+ GetModel()->attachResource( ::rtl::OUString(), GetModel()->getArgs() );
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::MemoryError()
+{
+}
+
+//--------------------------------------------------------------------
+
+SfxProgress* SfxObjectShell::GetProgress() const
+{
+ return pImp->pProgress;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::SetProgress_Impl
+(
+ SfxProgress *pProgress /* zu startender <SfxProgress> oder 0, falls
+ der Progress zur"uckgesetzt werden soll */
+)
+
+/* [Beschreibung]
+
+ Interne Methode zum setzen oder zur"ucksetzen des Progress-Modes
+ f"ur diese SfxObjectShell.
+*/
+
+{
+ DBG_ASSERT( ( !pImp->pProgress && pProgress ) ||
+ ( pImp->pProgress && !pProgress ),
+ "Progress activation/deacitivation mismatch" );
+ pImp->pProgress = pProgress;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame* pFrame )
+{
+ SfxApplication* pSfxApp = SFX_APP();
+ if ( !pSfxApp->IsDowning() && !IsLoading() && pFrame && !pFrame->GetFrame().IsClosing_Impl() )
+ {
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False );
+ if ( !pHiddenItem || !pHiddenItem->GetValue() )
+ {
+ sal_uInt16 nId = pImp->nEventId;
+ pImp->nEventId = 0;
+ if ( nId == SFX_EVENT_OPENDOC )
+ pSfxApp->NotifyEvent(SfxEventHint( nId, GlobalEventConfig::GetEventName(STR_EVENT_OPENDOC), this ), sal_False);
+ else if (nId == SFX_EVENT_CREATEDOC )
+ pSfxApp->NotifyEvent(SfxEventHint( nId, GlobalEventConfig::GetEventName(STR_EVENT_CREATEDOC), this ), sal_False);
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::SetActivateEvent_Impl(sal_uInt16 nId )
+{
+ if ( GetFactory().GetFlags() & SFXOBJECTSHELL_HASOPENDOC )
+ pImp->nEventId = nId;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::RegisterTransfer( SfxMedium& rMedium )
+/* [Beschreibung ]
+ Alle Medien, die aufgesetzt werden, um Teile eines Dokumentes zu
+ laden, muessen an der zugehoerigen SfxObjectShell angemeldet
+ werden. So kann dokumentweise abgebrochen werden. */
+{
+ rMedium.SetReferer( GetMedium()->GetName() );
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::PrepareReload( )
+/* [Beschreibung ]
+ Wird vor dem Reload gerufen und gibt die Moeglichkeit,
+ etwaige Caches zu leeren. */
+{
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::LockAutoLoad( sal_Bool bLock )
+
+/* Verhindert ein evtl. eintreffendes AutoLoad. Wird auch vor AutoLoad
+ eines umgebenden FrameSet beruecksichtigt.
+*/
+
+{
+ if ( bLock )
+ ++pImp->nAutoLoadLocks;
+ else
+ --pImp->nAutoLoadLocks;
+}
+
+//-------------------------------------------------------------------------
+
+// kann nach frame.cxx gemoved werden, wenn 358+36x-Stand gemerged sind
+
+sal_Bool SfxFrame::IsAutoLoadLocked_Impl() const
+{
+ // sein einges Doc gelockt?
+ const SfxObjectShell* pObjSh = GetCurrentDocument();
+ if ( !pObjSh || !pObjSh->IsAutoLoadLocked() )
+ return sal_False;
+
+ // seine Childs gelockt?
+ for ( sal_uInt16 n = GetChildFrameCount(); n--; )
+ if ( !GetChildFrame(n)->IsAutoLoadLocked_Impl() )
+ return sal_False;
+
+ // sonst ist AutoLoad erlaubt
+ return sal_True;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsAutoLoadLocked() const
+
+/* Liefert, ob ein eintreffendes AutoLoad ausgefuehrt werden darf. Wird auch
+ vor AutoLoad eines umgebenden FrameSet beruecksichtigt.
+*/
+
+{
+ return !IsReadOnly() || pImp->nAutoLoadLocks > 0;
+}
+
+//-------------------------------------------------------------------------
+void SfxObjectShell::BreakMacroSign_Impl( sal_Bool bBreakMacroSign )
+{
+ pImp->m_bMacroSignBroken = bBreakMacroSign;
+}
+
+//-------------------------------------------------------------------------
+void SfxObjectShell::CheckSecurityOnLoading_Impl()
+{
+ uno::Reference< task::XInteractionHandler > xInteraction;
+ if ( GetMedium() )
+ xInteraction = GetMedium()->GetInteractionHandler();
+
+ // check if there is a broken signature...
+ CheckForBrokenDocSignatures_Impl( xInteraction );
+
+ CheckEncryption_Impl( xInteraction );
+
+ // check macro security
+ pImp->aMacroMode.checkMacrosOnLoading( xInteraction );
+}
+
+//-------------------------------------------------------------------------
+void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
+{
+ ::rtl::OUString aVersion;
+ sal_Bool bIsEncrypted = sal_False;
+ sal_Bool bHasNonEncrypted = sal_False;
+
+ try
+ {
+ uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion;
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasEncryptedEntries" ) ) ) >>= bIsEncrypted;
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasNonEncryptedEntries" ) ) ) >>= bHasNonEncrypted;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ if ( aVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
+ {
+ // this is ODF1.2 or later
+ if ( bIsEncrypted && bHasNonEncrypted )
+ {
+ if ( !pImp->m_bIncomplEncrWarnShown )
+ {
+ // this is an encrypted document with nonencrypted streams inside, show the warning
+ ::com::sun::star::task::ErrorCodeRequest aErrorCode;
+ aErrorCode.ErrCode = ERRCODE_SFX_INCOMPLETE_ENCRYPTION;
+
+ SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False );
+ pImp->m_bIncomplEncrWarnShown = sal_True;
+ }
+
+ // broken signatures imply no macro execution at all
+ pImp->aMacroMode.disallowMacroExecution();
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+void SfxObjectShell::CheckForBrokenDocSignatures_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
+{
+ sal_Int16 nSignatureState = GetDocumentSignatureState();
+ bool bSignatureBroken = ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN );
+ if ( !bSignatureBroken )
+ return;
+
+ pImp->showBrokenSignatureWarning( xHandler );
+
+ // broken signatures imply no macro execution at all
+ pImp->aMacroMode.disallowMacroExecution();
+}
+
+//-------------------------------------------------------------------------
+void SfxObjectShell::SetAutoLoad(
+ const INetURLObject& rUrl, sal_uInt32 nTime, sal_Bool bReload )
+{
+ if ( pImp->pReloadTimer )
+ DELETEZ(pImp->pReloadTimer);
+ if ( bReload )
+ {
+ pImp->pReloadTimer = new AutoReloadTimer_Impl(
+ rUrl.GetMainURL( INetURLObject::DECODE_TO_IURI ),
+ nTime, bReload, this );
+ pImp->pReloadTimer->Start();
+ }
+}
+
+sal_Bool SfxObjectShell::IsLoadingFinished() const
+{
+ return ( pImp->nLoadedFlags == SFX_LOADED_ALL );
+}
+
+void impl_addToModelCollection(const com::sun::star::uno::Reference< com::sun::star::frame::XModel >& xModel);
+void SfxObjectShell::InitOwnModel_Impl()
+{
+ if ( !pImp->bModelInitialized )
+ {
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
+ if ( pSalvageItem )
+ {
+ pImp->aTempName = pMedium->GetPhysicalName();
+ pMedium->GetItemSet()->ClearItem( SID_DOC_SALVAGE );
+ pMedium->GetItemSet()->ClearItem( SID_FILE_NAME );
+ pMedium->GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, pMedium->GetOrigURL() ) );
+ }
+ else
+ {
+ pMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
+ pMedium->GetItemSet()->ClearItem( SID_DOCUMENT );
+ }
+
+ pMedium->GetItemSet()->ClearItem( SID_REFERER );
+ uno::Reference< frame::XModel > xModel ( GetModel(), uno::UNO_QUERY );
+ if ( xModel.is() )
+ {
+ ::rtl::OUString aURL = GetMedium()->GetOrigURL();
+ SfxItemSet *pSet = GetMedium()->GetItemSet();
+ if ( !GetMedium()->IsReadOnly() )
+ pSet->ClearItem( SID_INPUTSTREAM );
+ uno::Sequence< beans::PropertyValue > aArgs;
+ TransformItems( SID_OPENDOC, *pSet, aArgs );
+ xModel->attachResource( aURL, aArgs );
+ impl_addToModelCollection(xModel);
+ }
+
+ pImp->bModelInitialized = sal_True;
+ }
+}
+
+void SfxObjectShell::FinishedLoading( sal_uInt16 nFlags )
+{
+ sal_Bool bSetModifiedTRUE = sal_False;
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
+ if( ( nFlags & SFX_LOADED_MAINDOCUMENT ) && !(pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT )
+ && !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ))
+ {
+ pImp->nFlagsInProgress |= SFX_LOADED_MAINDOCUMENT;
+ ((SfxHeaderAttributes_Impl*)GetHeaderAttributes())->SetAttributes();
+ pImp->bImportDone = sal_True;
+ if( !IsAbortingImport() )
+ PositionView_Impl();
+
+ if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().getLength() ) && !IsModifyPasswordEntered() )
+ SetReadOnly();
+
+ // Salvage
+ if ( pSalvageItem )
+ bSetModifiedTRUE = sal_True;
+
+ if ( !IsEnableSetModified() )
+ EnableSetModified( sal_True );
+
+ if( !bSetModifiedTRUE && IsEnableSetModified() )
+ SetModified( sal_False );
+
+ CheckSecurityOnLoading_Impl();
+
+ bHasName = sal_True; // the document is loaded, so the name should already available
+ GetTitle( SFX_TITLE_DETECT );
+ InitOwnModel_Impl();
+ pImp->nFlagsInProgress &= ~SFX_LOADED_MAINDOCUMENT;
+ }
+
+ if( ( nFlags & SFX_LOADED_IMAGES ) && !(pImp->nLoadedFlags & SFX_LOADED_IMAGES )
+ && !(pImp->nFlagsInProgress & SFX_LOADED_IMAGES ))
+ {
+ pImp->nFlagsInProgress |= SFX_LOADED_IMAGES;
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ getDocProperties());
+ ::rtl::OUString url(xDocProps->getAutoloadURL());
+ sal_Int32 delay(xDocProps->getAutoloadSecs());
+ SetAutoLoad( INetURLObject(url), delay * 1000,
+ (delay > 0) || url.getLength() );
+ if( !bSetModifiedTRUE && IsEnableSetModified() )
+ SetModified( sal_False );
+ Invalidate( SID_SAVEASDOC );
+ pImp->nFlagsInProgress &= ~SFX_LOADED_IMAGES;
+ }
+
+ pImp->nLoadedFlags |= nFlags;
+
+ if ( !pImp->nFlagsInProgress )
+ {
+ // in case of reentrance calls the first called FinishedLoading() call on the stack
+ // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
+
+ if ( bSetModifiedTRUE )
+ SetModified( sal_True );
+ else
+ SetModified( sal_False );
+
+ if ( (pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) && (pImp->nLoadedFlags & SFX_LOADED_IMAGES ) )
+ {
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
+ sal_Bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
+
+ // closing the streams on loading should be under control of SFX!
+ DBG_ASSERT( pMedium->IsOpen(), "Don't close the medium when loading documents!" );
+
+ if ( bTemplate )
+ {
+ TemplateDisconnectionAfterLoad();
+ }
+ else
+ {
+ // if a readonly medium has storage then it's stream is already based on temporary file
+ if( !(pMedium->GetOpenMode() & STREAM_WRITE) && !pMedium->HasStorage_Impl() )
+ // don't lock file opened read only
+ pMedium->CloseInStream();
+ }
+ }
+
+ SetInitialized_Impl( false );
+
+ // Title is not available until loading has finished
+ Broadcast( SfxSimpleHint( SFX_HINT_TITLECHANGED ) );
+ if ( pImp->nEventId )
+ PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
+ }
+}
+
+//-------------------------------------------------------------------------
+extern void SetTemplate_Impl( const String&, const String&, SfxObjectShell* );
+
+void SfxObjectShell::TemplateDisconnectionAfterLoad()
+{
+ // document is created from a template
+ //TODO/LATER: should the templates always be XML docs!
+
+ SfxMedium* pTmpMedium = pMedium;
+ if ( pTmpMedium )
+ {
+ String aName( pTmpMedium->GetName() );
+ SFX_ITEMSET_ARG( pTmpMedium->GetItemSet(), pTemplNamItem, SfxStringItem, SID_TEMPLATE_NAME, sal_False);
+ String aTemplateName;
+ if ( pTemplNamItem )
+ aTemplateName = pTemplNamItem->GetValue();
+ else
+ {
+ // !TODO/LATER: what's this?!
+ // Interaktiv ( DClick, Contextmenu ) kommt kein Langname mit
+ aTemplateName = getDocProperties()->getTitle();
+ if ( !aTemplateName.Len() )
+ {
+ INetURLObject aURL( aName );
+ aURL.CutExtension();
+ aTemplateName = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ }
+ }
+
+ // set medium to noname
+ pTmpMedium->SetName( String(), sal_True );
+ pTmpMedium->Init_Impl();
+
+ // drop resource
+ SetNoName();
+ InvalidateName();
+
+ if( IsPackageStorageFormat_Impl( *pTmpMedium ) )
+ {
+ // untitled document must be based on temporary storage
+ // the medium should not dispose the storage in this case
+ uno::Reference < embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
+ GetStorage()->copyToStorage( xTmpStor );
+
+ // the medium should disconnect from the original location
+ // the storage should not be disposed since the document is still
+ // based on it, but in DoSaveCompleted it will be disposed
+ pTmpMedium->CanDisposeStorage_Impl( sal_False );
+ pTmpMedium->Close();
+
+ // setting the new storage the medium will be based on
+ pTmpMedium->SetStorage_Impl( xTmpStor );
+
+ ForgetMedium();
+ if( !DoSaveCompleted( pTmpMedium ) )
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ else
+ {
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
+ sal_Bool bSalvage = pSalvageItem ? sal_True : sal_False;
+
+ if ( !bSalvage )
+ {
+ // some further initializations for templates
+ SetTemplate_Impl( aName, aTemplateName, this );
+ }
+
+ // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
+ pTmpMedium->CanDisposeStorage_Impl( sal_False );
+ }
+ }
+ else
+ {
+ // some further initializations for templates
+ SetTemplate_Impl( aName, aTemplateName, this );
+ pTmpMedium->CreateTempFile( sal_True );
+ }
+
+ // templates are never readonly
+ pTmpMedium->GetItemSet()->ClearItem( SID_DOC_READONLY );
+ pTmpMedium->SetOpenMode( SFX_STREAM_READWRITE, sal_True, sal_True );
+
+ // notifications about possible changes in readonly state and document info
+ Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
+
+ // created untitled document can't be modified
+ SetModified( sal_False );
+ }
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::PositionView_Impl()
+{
+ MarkData_Impl *pMark = Get_Impl()->pMarkData;
+ if( pMark )
+ {
+ SfxViewShell* pSh = pMark->pFrame->GetViewShell();
+ if( pMark->aUserData.Len() )
+ pSh->ReadUserData( pMark->aUserData, sal_True );
+ else if( pMark->aMark.Len() )
+ pSh->JumpToMark( pMark->aMark );
+ DELETEZ( Get_Impl()->pMarkData );
+ }
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsLoading() const
+/* [Beschreibung ]
+ Has FinishedLoading been called? */
+{
+ return !( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT );
+}
+
+//-------------------------------------------------------------------------
+
+void SfxObjectShell::CancelTransfers()
+/* [Beschreibung ]
+ Hier koennen Transfers gecanceled werden, die nicht mit
+ RegisterTransfer registiert wurden */
+{
+ if( ( pImp->nLoadedFlags & SFX_LOADED_ALL ) != SFX_LOADED_ALL )
+ {
+ AbortImport();
+ if( IsLoading() )
+ FinishedLoading( SFX_LOADED_ALL );
+
+/*
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
+ while( pFrame )
+ {
+ pFrame->CancelTransfers();
+ pFrame = SfxViewFrame::GetNext( *pFrame, this );
+ }*/
+ }
+}
+
+//-------------------------------------------------------------------------
+
+AutoReloadTimer_Impl::AutoReloadTimer_Impl(
+ const String& rURL, sal_uInt32 nTime, sal_Bool bReloadP, SfxObjectShell* pSh )
+ : aUrl( rURL ), bReload( bReloadP ), pObjSh( pSh )
+{
+ SetTimeout( nTime );
+}
+
+//-------------------------------------------------------------------------
+
+void AutoReloadTimer_Impl::Timeout()
+{
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjSh );
+
+ if ( pFrame )
+ {
+ // momentan nicht m"oglich/sinnvoll?
+ if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() )
+ {
+ // erneuten Versuch erlauben
+ Start();
+ return;
+ }
+
+ SfxAllItemSet aSet( SFX_APP()->GetPool() );
+ aSet.Put( SfxBoolItem( SID_AUTOLOAD, sal_True ) );
+ if ( aUrl.Len() )
+ aSet.Put( SfxStringItem( SID_FILE_NAME, aUrl ) );
+ SfxRequest aReq( SID_RELOAD, 0, aSet );
+ pObjSh->Get_Impl()->pReloadTimer = 0;
+ delete this;
+ pFrame->ExecReload_Impl( aReq );
+ return;
+ }
+
+ pObjSh->Get_Impl()->pReloadTimer = 0;
+ delete this;
+}
+
+SfxModule* SfxObjectShell::GetModule() const
+{
+ return GetFactory().GetModule();
+}
+
+sal_Bool SfxObjectShell::IsBasic(
+ const String & rCode, SbxObject * pVCtrl )
+{
+ if( !rCode.Len() ) return sal_False;
+ return SfxMacroConfig::IsBasic( pVCtrl, rCode, GetBasicManager() );
+}
+
+ErrCode SfxObjectShell::CallBasic( const String& rMacro,
+ const String& rBasic, SbxObject* pVCtrl, SbxArray* pArgs,
+ SbxValue* pRet )
+{
+ SfxApplication* pApp = SFX_APP();
+ if( pApp->GetName() != rBasic )
+ {
+ if ( !AdjustMacroMode( String() ) )
+ return ERRCODE_IO_ACCESSDENIED;
+ }
+
+ pApp->EnterBasicCall();
+ BasicManager *pMgr = GetBasicManager();
+ if( pApp->GetName() == rBasic )
+ pMgr = pApp->GetBasicManager();
+ ErrCode nRet = SfxMacroConfig::Call( pVCtrl, rMacro, pMgr, pArgs, pRet );
+ pApp->LeaveBasicCall();
+ return nRet;
+}
+
+ErrCode SfxObjectShell::Call( const String & rCode, sal_Bool bIsBasicReturn, SbxObject * pVCtrl )
+{
+ ErrCode nErr = ERRCODE_NONE;
+ if ( bIsBasicReturn )
+ CallBasic( rCode, String(), pVCtrl );
+ return nErr;
+}
+
+namespace
+{
+ static bool lcl_isScriptAccessAllowed_nothrow( const Reference< XInterface >& _rxScriptContext )
+ {
+ try
+ {
+ Reference< XEmbeddedScripts > xScripts( _rxScriptContext, UNO_QUERY );
+ if ( !xScripts.is() )
+ {
+ Reference< XScriptInvocationContext > xContext( _rxScriptContext, UNO_QUERY_THROW );
+ xScripts.set( xContext->getScriptContainer(), UNO_SET_THROW );
+ }
+
+ return xScripts->getAllowMacroExecution();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return false;
+ }
+}
+
+ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptContext, const ::rtl::OUString& _rScriptURL,
+ const Sequence< Any >& aParams, Any& aRet, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam, bool bRaiseError )
+{
+ OSL_TRACE( "in CallXScript" );
+ ErrCode nErr = ERRCODE_NONE;
+
+ bool bIsDocumentScript = ( _rScriptURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "location=document" ) ) >= 0 );
+ // TODO: we should parse the URL, and check whether there is a parameter with this name.
+ // Otherwise, we might find too much.
+ if ( bIsDocumentScript && !lcl_isScriptAccessAllowed_nothrow( _rxScriptContext ) )
+ return ERRCODE_IO_ACCESSDENIED;
+
+ bool bCaughtException = false;
+ Any aException;
+ try
+ {
+ // obtain/create a script provider
+ Reference< provider::XScriptProvider > xScriptProvider;
+ Reference< provider::XScriptProviderSupplier > xSPS( _rxScriptContext, UNO_QUERY );
+ if ( xSPS.is() )
+ xScriptProvider.set( xSPS->getScriptProvider() );
+
+ if ( !xScriptProvider.is() )
+ {
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ Reference< provider::XScriptProviderFactory > xScriptProviderFactory(
+ aContext.getSingleton( "com.sun.star.script.provider.theMasterScriptProviderFactory" ), UNO_QUERY_THROW );
+ xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( _rxScriptContext ) ), UNO_SET_THROW );
+ }
+
+ // obtain the script, and execute it
+ Reference< provider::XScript > xScript( xScriptProvider->getScript( _rScriptURL ), UNO_QUERY_THROW );
+
+ aRet = xScript->invoke( aParams, aOutParamIndex, aOutParam );
+ }
+ catch ( const uno::Exception& )
+ {
+ aException = ::cppu::getCaughtException();
+ bCaughtException = TRUE;
+ nErr = ERRCODE_BASIC_INTERNAL_ERROR;
+ }
+
+ if ( bCaughtException && bRaiseError )
+ {
+ ::std::auto_ptr< VclAbstractDialog > pScriptErrDlg;
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ if ( pFact )
+ pScriptErrDlg.reset( pFact->CreateScriptErrorDialog( NULL, aException ) );
+ OSL_ENSURE( pScriptErrDlg.get(), "SfxObjectShell::CallXScript: no script error dialog!" );
+
+ if ( pScriptErrDlg.get() )
+ pScriptErrDlg->Execute();
+ }
+
+ OSL_TRACE( "leaving CallXScript" );
+ return nErr;
+}
+
+// perhaps rename to CallScript once we get rid of the existing CallScript
+// and Call, CallBasic, CallStarBasic methods
+ErrCode SfxObjectShell::CallXScript( const String& rScriptURL,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >&
+ aParams,
+ ::com::sun::star::uno::Any& aRet,
+ ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam
+ , bool bRaiseError )
+{
+ return CallXScript( GetModel(), rScriptURL, aParams, aRet, aOutParamIndex, aOutParam, bRaiseError );
+}
+
+//-------------------------------------------------------------------------
+namespace {
+ using namespace ::com::sun::star::uno;
+
+ //.....................................................................
+ static SbxArrayRef lcl_translateUno2Basic( const void* _pAnySequence )
+ {
+ SbxArrayRef xReturn;
+ if ( _pAnySequence )
+ {
+ // in real it's a sequence of Any (by convention)
+ const Sequence< Any >* pArguments = static_cast< const Sequence< Any >* >( _pAnySequence );
+
+ // do we have arguments ?
+ if ( pArguments->getLength() )
+ {
+ // yep
+ xReturn = new SbxArray;
+ String sEmptyName;
+
+ // loop through the sequence
+ const Any* pArg = pArguments->getConstArray();
+ const Any* pArgEnd = pArg + pArguments->getLength();
+
+ for ( sal_uInt16 nArgPos=1; pArg != pArgEnd; ++pArg, ++nArgPos )
+ // and create a Sb object for every Any
+ xReturn->Put( GetSbUnoObject( sEmptyName, *pArg ), nArgPos );
+ }
+ }
+ return xReturn;
+ }
+ //.....................................................................
+ void lcl_translateBasic2Uno( const SbxVariableRef& _rBasicValue, void* _pAny )
+ {
+ if ( _pAny )
+ *static_cast< Any* >( _pAny ) = sbxToUnoValue( _rBasicValue );
+ }
+}
+//-------------------------------------------------------------------------
+ErrCode SfxObjectShell::CallStarBasicScript( const String& _rMacroName, const String& _rLocation,
+ const void* _pArguments, void* _pReturn )
+{
+ OSL_TRACE("in CallSBS");
+ ::vos::OClearableGuard aGuard( Application::GetSolarMutex() );
+
+ // the arguments for the call
+ SbxArrayRef xMacroArguments = lcl_translateUno2Basic( _pArguments );
+
+ // the return value
+ SbxVariableRef xReturn = _pReturn ? new SbxVariable : NULL;
+
+ // the location (document or application)
+ String sMacroLocation;
+ if ( _rLocation.EqualsAscii( "application" ) )
+ sMacroLocation = SFX_APP()->GetName();
+#ifdef DBG_UTIL
+ else
+ DBG_ASSERT( _rLocation.EqualsAscii( "document" ),
+ "SfxObjectShell::CallStarBasicScript: invalid (unknown) location!" );
+#endif
+
+ // call the script
+ ErrCode eError = CallBasic( _rMacroName, sMacroLocation, NULL, xMacroArguments, xReturn );
+
+ // translate the return value
+ lcl_translateBasic2Uno( xReturn, _pReturn );
+
+ // outta here
+ return eError;
+}
+
+//-------------------------------------------------------------------------
+ErrCode SfxObjectShell::CallScript(
+ const String & rScriptType,
+ const String & rCode,
+ const void *pArgs,
+ void *pRet
+)
+{
+ ::vos::OClearableGuard aGuard( Application::GetSolarMutex() );
+ ErrCode nErr = ERRCODE_NONE;
+ if( rScriptType.EqualsAscii( "StarBasic" ) )
+ {
+ // the arguments for the call
+ SbxArrayRef xMacroArguments = lcl_translateUno2Basic( pArgs );
+
+ // the return value
+ SbxVariableRef xReturn = pRet ? new SbxVariable : NULL;
+
+ // call the script
+ nErr = CallBasic( rCode, String(), NULL, xMacroArguments, xReturn );
+
+ // translate the return value
+ lcl_translateBasic2Uno( xReturn, pRet );
+
+ // did this fail because the method was not found?
+ if ( nErr == ERRCODE_BASIC_PROC_UNDEFINED )
+ { // yep-> look in the application BASIC module
+ nErr = CallBasic( rCode, SFX_APP()->GetName(), NULL, xMacroArguments, xReturn );
+ }
+ }
+ else if( rScriptType.EqualsAscii( "JavaScript" ) )
+ {
+ DBG_ERROR( "JavaScript not allowed" );
+ return 0;
+ }
+ else
+ {
+ DBG_ERROR( "StarScript not allowed" );
+ }
+ return nErr;
+}
+
+SfxFrame* SfxObjectShell::GetSmartSelf( SfxFrame* pSelf, SfxMedium& /*rMedium*/ )
+{
+ return pSelf;
+}
+
+SfxObjectShellFlags SfxObjectShell::GetFlags() const
+{
+ if( pImp->eFlags == SFXOBJECTSHELL_UNDEFINED )
+ pImp->eFlags = GetFactory().GetFlags();
+ return pImp->eFlags;
+}
+
+void SfxObjectShell::SetFlags( SfxObjectShellFlags eFlags )
+{
+ pImp->eFlags = eFlags;
+}
+
+/*
+void SfxObjectShell::SetBaseURL( const String& rURL )
+{
+ pImp->aBaseURL = rURL;
+ pImp->bNoBaseURL = FALSE;
+}
+
+const String& SfxObjectShell::GetBaseURLForSaving() const
+{
+ if ( pImp->bNoBaseURL )
+ return String();
+ return GetBaseURL();
+}
+
+const String& SfxObjectShell::GetBaseURL() const
+{
+ if ( pImp->aBaseURL.Len() )
+ return pImp->aBaseURL;
+ return pMedium->GetBaseURL();
+}
+
+void SfxObjectShell::SetEmptyBaseURL()
+{
+ pImp->bNoBaseURL = TRUE;
+}
+*/
+String SfxObjectShell::QueryTitle( SfxTitleQuery eType ) const
+{
+ String aRet;
+
+ switch( eType )
+ {
+ case SFX_TITLE_QUERY_SAVE_NAME_PROPOSAL:
+ {
+ SfxMedium* pMed = GetMedium();
+ const INetURLObject aObj( pMed->GetName() );
+ aRet = aObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
+ if ( !aRet.Len() )
+ aRet = GetTitle( SFX_TITLE_CAPTION );
+ break;
+ }
+ }
+ return aRet;
+}
+
+void SfxHeaderAttributes_Impl::SetAttributes()
+{
+ bAlert = sal_True;
+ SvKeyValue aPair;
+ for( sal_Bool bCont = xIter->GetFirst( aPair ); bCont;
+ bCont = xIter->GetNext( aPair ) )
+ SetAttribute( aPair );
+}
+
+void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue& rKV )
+{
+ String aValue = rKV.GetValue();
+ if( rKV.GetKey().CompareIgnoreCaseToAscii( "refresh" ) == COMPARE_EQUAL && rKV.GetValue().Len() )
+ {
+ sal_uInt32 nTime = aValue.GetToken( 0, ';' ).ToInt32() ;
+ String aURL = aValue.GetToken( 1, ';' );
+ aURL.EraseTrailingChars().EraseLeadingChars();
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ pDoc->getDocProperties());
+ if( aURL.Copy(0, 4).CompareIgnoreCaseToAscii( "url=" ) == COMPARE_EQUAL )
+ {
+ INetURLObject aObj;
+ INetURLObject( pDoc->GetMedium()->GetName() ).GetNewAbsURL( aURL.Copy( 4 ), &aObj );
+ xDocProps->setAutoloadURL(
+ aObj.GetMainURL( INetURLObject::NO_DECODE ) );
+ }
+ try
+ {
+ xDocProps->setAutoloadSecs( nTime );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ // ignore
+ }
+ }
+ else if( rKV.GetKey().CompareIgnoreCaseToAscii( "expires" ) == COMPARE_EQUAL )
+ {
+ DateTime aDateTime;
+ if( INetRFC822Message::ParseDateField( rKV.GetValue(), aDateTime ) )
+ {
+ aDateTime.ConvertToLocalTime();
+ pDoc->GetMedium()->SetExpired_Impl( aDateTime );
+ }
+ else
+ {
+// DBG_ERROR( "Schlechtes ::com::sun::star::util::DateTime fuer Expired" );
+ pDoc->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
+ }
+ }
+ else if( rKV.GetKey().CompareIgnoreCaseToAscii( "content-type" ) == COMPARE_EQUAL )
+ {
+ ::rtl::OString sContent = ::rtl::OUStringToOString( aValue, RTL_TEXTENCODING_ASCII_US );
+ ByteString sType, sSubType;
+ INetContentTypeParameterList aParameters;
+
+ if( INetContentTypes::parse( sContent, sType, sSubType, &aParameters ) )
+ {
+ const INetContentTypeParameter * pCharset = aParameters.find("charset");
+ if (pCharset != 0)
+ pDoc->GetMedium()->SetCharset( pCharset->m_sValue );
+ }
+ }
+}
+
+void SfxHeaderAttributes_Impl::Append( const SvKeyValue& rKV )
+{
+ xIter->Append( rKV );
+ if( bAlert ) SetAttribute( rKV );
+}
+
+SvKeyValueIterator* SfxObjectShell::GetHeaderAttributes()
+{
+ if( !pImp->xHeaderAttributes.Is() )
+ {
+ DBG_ASSERT( pMedium, "Kein Medium" );
+ pImp->xHeaderAttributes = new SfxHeaderAttributes_Impl( this );
+ }
+ return ( SvKeyValueIterator*) &pImp->xHeaderAttributes;
+}
+
+void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
+{
+ ((SfxHeaderAttributes_Impl*)GetHeaderAttributes())
+ ->ClearForSourceView();
+}
+
+
+void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
+{
+ ((SfxHeaderAttributes_Impl*)GetHeaderAttributes())
+ ->SetAttributes();
+}
+
+sal_Bool SfxObjectShell::IsPreview() const
+{
+ if ( !pMedium )
+ return sal_False;
+
+ sal_Bool bPreview = sal_False;
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, sal_False);
+ if ( pFlags )
+ {
+ // Werte auf einzelne Items verteilen
+ String aFileFlags = pFlags->GetValue();
+ aFileFlags.ToUpperAscii();
+ if ( STRING_NOTFOUND != aFileFlags.Search( 'B' ) )
+ bPreview = sal_True;
+ }
+
+ if ( !bPreview )
+ {
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pItem, SfxBoolItem, SID_PREVIEW, sal_False);
+ if ( pItem )
+ bPreview = pItem->GetValue();
+ }
+
+ return bPreview;
+}
+
+sal_Bool SfxObjectShell::IsSecure()
+{
+ // Wenn globale Warnung an ist, nach Secure-Referer-Liste gehen
+ String aReferer = GetMedium()->GetName();
+ if ( !aReferer.Len() )
+ {
+ // bei neuen Dokumenten das Template als Referer nehmen
+ ::rtl::OUString aTempl( getDocProperties()->getTemplateURL() );
+ if ( aTempl.getLength() )
+ aReferer = INetURLObject( aTempl ).GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ INetURLObject aURL( "macro:" );
+ if ( !aReferer.Len() )
+ // empty new or embedded document
+ return sal_True;
+
+ SvtSecurityOptions aOpt;
+
+ if( aOpt.GetBasicMode() == eALWAYS_EXECUTE )
+ return sal_True;
+
+ if( aOpt.GetBasicMode() == eNEVER_EXECUTE )
+ return sal_False;
+
+ if ( aOpt.IsSecureURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aReferer ) )
+ //if ( SvtSecurityOptions().IsSecureURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aReferer ) )
+ {
+ if ( GetMedium()->GetContent().is() )
+ {
+ Any aAny( ::utl::UCBContentHelper::GetProperty( aURL.GetMainURL( INetURLObject::NO_DECODE ), String( RTL_CONSTASCII_USTRINGPARAM("IsProtected")) ) );
+ sal_Bool bIsProtected = FALSE;
+ if ( ( aAny >>= bIsProtected ) && bIsProtected )
+ return sal_False;
+ else
+ return sal_True;
+ }
+ else
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+void SfxObjectShell::SetWaitCursor( BOOL bSet ) const
+{
+ for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
+ {
+ if ( bSet )
+ pFrame->GetFrame().GetWindow().EnterWait();
+ else
+ pFrame->GetFrame().GetWindow().LeaveWait();
+ }
+}
+
+String SfxObjectShell::GetAPIName() const
+{
+ INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : ::rtl::OUString( GetMedium()->GetName() ) );
+ String aName( aURL.GetBase() );
+ if( !aName.Len() )
+ aName = aURL.GetURLNoPass();
+ if ( !aName.Len() )
+ aName = GetTitle( SFX_TITLE_DETECT );
+ return aName;
+}
+
+void SfxObjectShell::Invalidate( USHORT nId )
+{
+ for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
+ Invalidate_Impl( pFrame->GetBindings(), nId );
+}
+
+bool SfxObjectShell::AdjustMacroMode( const String& /*rScriptType*/, bool bSuppressUI )
+{
+ uno::Reference< task::XInteractionHandler > xInteraction;
+ if ( pMedium && !bSuppressUI )
+ xInteraction = pMedium->GetInteractionHandler();
+
+ CheckForBrokenDocSignatures_Impl( xInteraction );
+
+ CheckEncryption_Impl( xInteraction );
+
+ return pImp->aMacroMode.adjustMacroMode( xInteraction );
+}
+
+Window* SfxObjectShell::GetDialogParent( SfxMedium* pLoadingMedium )
+{
+ Window* pWindow = 0;
+ SfxItemSet* pSet = pLoadingMedium ? pLoadingMedium->GetItemSet() : GetMedium()->GetItemSet();
+ SFX_ITEMSET_ARG( pSet, pUnoItem, SfxUnoFrameItem, SID_FILLFRAME, FALSE );
+ if ( pUnoItem )
+ {
+ uno::Reference < frame::XFrame > xFrame( pUnoItem->GetFrame() );
+ pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ }
+
+ if ( !pWindow )
+ {
+ SfxFrame* pFrame = 0;
+ SFX_ITEMSET_ARG( pSet, pFrameItem, SfxFrameItem, SID_DOCFRAME, FALSE );
+ if( pFrameItem && pFrameItem->GetFrame() )
+ // get target frame from ItemSet
+ pFrame = pFrameItem->GetFrame();
+ else
+ {
+ // try the current frame
+ SfxViewFrame* pView = SfxViewFrame::Current();
+ if ( !pView || pView->GetObjectShell() != this )
+ // get any visible frame
+ pView = SfxViewFrame::GetFirst(this);
+ if ( pView )
+ pFrame = &pView->GetFrame();
+ }
+
+ if ( pFrame )
+ // get topmost window
+ pWindow = VCLUnoHelper::GetWindow( pFrame->GetFrameInterface()->getContainerWindow() );
+ }
+
+ if ( pWindow )
+ {
+ // this frame may be invisible, show it if it is allowed
+ SFX_ITEMSET_ARG( pSet, pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False );
+ if ( !pHiddenItem || !pHiddenItem->GetValue() )
+ {
+ pWindow->Show();
+ pWindow->ToTop();
+ }
+ }
+
+ return pWindow;
+}
+
+String SfxObjectShell::UpdateTitle( SfxMedium* pMed, USHORT nDocViewNumber )
+{
+ // Titel des Fensters
+ String aTitle;
+ if ( pMed )
+ {
+ INetURLObject aTmp( pMed->GetName() );
+ aTitle = aTmp.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ }
+ else
+ {
+ pMed = GetMedium();
+ aTitle = GetTitle(SFX_TITLE_CAPTION);
+ String aName(aTitle);
+ if ( nDocViewNumber )
+ {
+ aName += ':';
+ aName += String::CreateFromInt32( nDocViewNumber );
+ }
+ }
+
+ if ( pMed )
+ {
+ SFX_ITEMSET_ARG( pMed->GetItemSet(), pRepairedDocItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False );
+ if ( pRepairedDocItem && pRepairedDocItem->GetValue() )
+ aTitle += String( SfxResId(STR_REPAIREDDOCUMENT) );
+ }
+
+ if ( IsReadOnlyUI() || (pMed && pMed->IsReadOnly()) )
+ aTitle += String( SfxResId(STR_READONLY) );
+ else if ( IsDocShared() )
+ aTitle += String( SfxResId(STR_SHARED) );
+
+ return aTitle;
+}
+
+void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode )
+{
+ eCreateMode = nMode;
+}
+
+BOOL SfxObjectShell::IsInPlaceActive()
+{
+ if ( eCreateMode != SFX_CREATE_MODE_EMBEDDED )
+ return FALSE;
+
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
+ return pFrame && pFrame->GetFrame().IsInPlace();
+}
+
+BOOL SfxObjectShell::IsUIActive()
+{
+ if ( eCreateMode != SFX_CREATE_MODE_EMBEDDED )
+ return FALSE;
+
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
+ return pFrame && pFrame->GetFrame().IsInPlace() && pFrame->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
+}
+
+void SfxObjectShell::UIActivate( BOOL )
+{
+}
+
+void SfxObjectShell::InPlaceActivate( BOOL )
+{
+}
+
+sal_Bool SfxObjectShell::UseInteractionToHandleError(
+ const uno::Reference< task::XInteractionHandler >& xHandler,
+ sal_uInt32 nError )
+{
+ sal_Bool bResult = sal_False;
+
+ if ( xHandler.is() )
+ {
+ try
+ {
+ uno::Any aInteraction;
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > lContinuations(2);
+ ::framework::ContinuationAbort* pAbort = new ::framework::ContinuationAbort();
+ ::framework::ContinuationApprove* pApprove = new ::framework::ContinuationApprove();
+ lContinuations[0] = uno::Reference< task::XInteractionContinuation >(
+ static_cast< task::XInteractionContinuation* >( pAbort ), uno::UNO_QUERY );
+ lContinuations[1] = uno::Reference< task::XInteractionContinuation >(
+ static_cast< task::XInteractionContinuation* >( pApprove ), uno::UNO_QUERY );
+
+ task::ErrorCodeRequest aErrorCode;
+ aErrorCode.ErrCode = nError;
+ aInteraction <<= aErrorCode;
+
+ ::framework::InteractionRequest* pRequest = new ::framework::InteractionRequest(aInteraction,lContinuations);
+ uno::Reference< task::XInteractionRequest > xRequest(
+ static_cast< task::XInteractionRequest* >( pRequest ),
+ uno::UNO_QUERY);
+
+ xHandler->handle(xRequest);
+ bResult = pAbort->isSelected();
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ return bResult;
+}
+
+sal_Bool SfxObjectShell_Impl::NeedsOfficeUpdateDialog()
+{
+ // if the configuration is not available for any reason, the default behavior is to show the message
+ sal_Bool bResult = sal_True;
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager( ::comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
+ uno::Reference< uno::XInterface > xCommonConfig(
+ ::comphelper::ConfigurationHelper::openConfig(
+ xServiceManager,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
+ ::comphelper::ConfigurationHelper::E_STANDARD ),
+ uno::UNO_SET_THROW );
+
+ ::comphelper::ConfigurationHelper::readRelativeKey(
+ xCommonConfig,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Load/" ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ShowOfficeUpdateDialog" ) ) ) >>= bResult;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return bResult;
+}
+
+sal_Int16 SfxObjectShell_Impl::getCurrentMacroExecMode() const
+{
+ sal_Int16 nImposedExecMode( MacroExecMode::NEVER_EXECUTE );
+
+ const SfxMedium* pMedium( rDocShell.GetMedium() );
+ OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
+ if ( pMedium )
+ {
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pMacroModeItem, SfxUInt16Item, SID_MACROEXECMODE, sal_False);
+ if ( pMacroModeItem )
+ nImposedExecMode = pMacroModeItem->GetValue();
+ }
+ return nImposedExecMode;
+}
+
+sal_Bool SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
+{
+ const SfxMedium* pMedium( rDocShell.GetMedium() );
+ OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
+ if ( pMedium )
+ {
+ pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, nMacroMode ) );
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+::rtl::OUString SfxObjectShell_Impl::getDocumentLocation() const
+{
+ ::rtl::OUString sLocation;
+
+ const SfxMedium* pMedium( rDocShell.GetMedium() );
+ OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
+ if ( pMedium )
+ {
+ sLocation = pMedium->GetName();
+ if ( !sLocation.getLength() )
+ {
+ // for documents made from a template: get the name of the template
+ sLocation = rDocShell.getDocProperties()->getTemplateURL();
+ }
+ }
+ return sLocation;
+}
+
+uno::Reference< embed::XStorage > SfxObjectShell_Impl::getZipStorageToSign()
+{
+ Reference < embed::XStorage > xStore;
+
+ SfxMedium* pMedium( rDocShell.GetMedium() );
+ OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getLastCommitDocumentStorage: no medium!" );
+ if ( pMedium )
+ xStore = pMedium->GetZipStorageToSign_Impl();
+
+ return xStore;
+}
+
+sal_Bool SfxObjectShell_Impl::documentStorageHasMacros() const
+{
+ return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage );
+}
+
+Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
+{
+ return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY );
+}
+
+sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState()
+{
+ sal_Int16 nSignatureState( rDocShell.GetScriptingSignatureState() );
+
+ if ( nSignatureState != SIGNATURESTATE_NOSIGNATURES && m_bMacroSignBroken )
+ {
+ // if there is a macro signature it must be handled as broken
+ nSignatureState = SIGNATURESTATE_SIGNATURES_BROKEN;
+ }
+
+ return nSignatureState;
+}
+
+sal_Bool SfxObjectShell_Impl::hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor )
+{
+ sal_Bool bResult = sal_False;
+
+ try
+ {
+ ::rtl::OUString aVersion;
+ try
+ {
+ uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[0] <<= aVersion;
+
+ uno::Reference< security::XDocumentDigitalSignatures > xSigner( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW );
+
+ if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN
+ || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK
+ || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
+ {
+ uno::Sequence< security::DocumentSignatureInformation > aInfo = rDocShell.ImplAnalyzeSignature( sal_True, xSigner );
+
+ if ( aInfo.getLength() )
+ {
+ if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN )
+ nScriptingSignatureState = rDocShell.ImplCheckSignaturesInformation( aInfo );
+
+ if ( nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK
+ || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
+ {
+ for ( sal_Int32 nInd = 0; !bResult && nInd < aInfo.getLength(); nInd++ )
+ {
+ bResult = xSigner->isAuthorTrusted( aInfo[nInd].Signer );
+ }
+
+ if ( !bResult && bAllowUIToAddAuthor )
+ {
+ uno::Reference< task::XInteractionHandler > xInteraction;
+ if ( rDocShell.GetMedium() )
+ xInteraction = rDocShell.GetMedium()->GetInteractionHandler();
+
+ if ( xInteraction.is() )
+ {
+ task::DocumentMacroConfirmationRequest aRequest;
+ aRequest.DocumentURL = getDocumentLocation();
+ aRequest.DocumentStorage = rDocShell.GetMedium()->GetZipStorageToSign_Impl();
+ aRequest.DocumentSignatureInformation = aInfo;
+ aRequest.DocumentVersion = aVersion;
+ aRequest.Classification = task::InteractionClassification_QUERY;
+ bResult = SfxMedium::CallApproveHandler( xInteraction, uno::makeAny( aRequest ), sal_True );
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+
+ return bResult;
+}
+
+void SfxObjectShell_Impl::showBrokenSignatureWarning( const uno::Reference< task::XInteractionHandler >& _rxInteraction ) const
+{
+ if ( !bSignatureErrorIsShown )
+ {
+ SfxObjectShell::UseInteractionToHandleError( _rxInteraction, ERRCODE_SFX_BROKENSIGNATURE );
+ const_cast< SfxObjectShell_Impl* >( this )->bSignatureErrorIsShown = sal_True;
+ }
+}
+
+void SfxObjectShell::AddLog( const ::rtl::OUString& aMessage )
+{
+ if ( !pImp->m_xLogRing.is() )
+ {
+ try
+ {
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ if ( aContext.is() )
+ pImp->m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if ( pImp->m_xLogRing.is() )
+ pImp->m_xLogRing->logString( aMessage );
+}
+
+namespace {
+
+void WriteStringInStream( const uno::Reference< io::XOutputStream >& xOutStream, const ::rtl::OUString& aString )
+{
+ if ( xOutStream.is() )
+ {
+ ::rtl::OString aStrLog = ::rtl::OUStringToOString( aString, RTL_TEXTENCODING_UTF8 );
+ uno::Sequence< sal_Int8 > aLogData( (const sal_Int8*)aStrLog.getStr(), aStrLog.getLength() );
+ xOutStream->writeBytes( aLogData );
+
+ aLogData.realloc( 1 );
+ aLogData[0] = '\n';
+ xOutStream->writeBytes( aLogData );
+ }
+}
+
+}
+
+void SfxObjectShell::StoreLog()
+{
+ if ( !pImp->m_xLogRing.is() )
+ {
+ try
+ {
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ if ( aContext.is() )
+ pImp->m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if ( pImp->m_xLogRing.is() )
+ {
+#ifdef WNT
+ ::rtl::OUString aFileURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$BRAND_BASE_DIR/program/bootstrap.ini:UserInstallation}" ) );
+#else
+ ::rtl::OUString aFileURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}" ) );
+#endif
+
+ ::rtl::Bootstrap::expandMacros( aFileURL );
+
+#ifdef WNT
+ ::rtl::OUString aBuildID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$BRAND_BASE_DIR/program/setup.ini:buildid}" ) );
+#else
+ ::rtl::OUString aBuildID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$BRAND_BASE_DIR/program/setuprc:buildid}" ) );
+#endif
+
+ ::rtl::Bootstrap::expandMacros( aBuildID );
+
+ if ( aFileURL.getLength() )
+ {
+ aFileURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/temp/document_io_logring.txt" ) );
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
+ uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( xFactory->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.ucb.SimpleFileAccess" ) ), uno::UNO_QUERY_THROW );
+ uno::Reference< io::XStream > xStream( xSimpleFileAccess->openFileReadWrite( aFileURL ), uno::UNO_SET_THROW );
+ uno::Reference< io::XOutputStream > xOutStream( xStream->getOutputStream(), uno::UNO_SET_THROW );
+ uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY_THROW );
+ xTruncate->truncate();
+
+ if ( aBuildID.getLength() )
+ WriteStringInStream( xOutStream, aBuildID );
+
+ uno::Sequence< ::rtl::OUString > aLogSeq = pImp->m_xLogRing->getCollectedLog();
+ for ( sal_Int32 nInd = 0; nInd < aLogSeq.getLength(); nInd++ )
+ WriteStringInStream( xOutStream, aLogSeq[nInd] );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ }
+}
+
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx
new file mode 100644
index 000000000000..c063546da1c7
--- /dev/null
+++ b/sfx2/source/doc/objserv.cxx
@@ -0,0 +1,1502 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <sot/storage.hxx>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/XControlAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/frame/XDocumentTemplates.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/security/CertificateValidity.hpp>
+
+#include <com/sun/star/security/DocumentSignatureInformation.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+#include <tools/urlobj.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include <vcl/wrkwin.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+
+#include <comphelper/string.hxx>
+#include <basic/sbx.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/useroptions.hxx>
+#include <svtools/asynclink.hxx>
+#include <unotools/saveopt.hxx>
+#include <comphelper/documentconstants.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/signaturestate.hxx>
+#include "sfxresid.hxx"
+#include <sfx2/event.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/doctdlg.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/dinfdlg.hxx>
+#include <sfx2/objitem.hxx>
+#include <sfx2/objsh.hxx>
+#include "objshimp.hxx"
+#include "sfxtypes.hxx"
+//#include "interno.hxx"
+#include <sfx2/module.hxx>
+#include <sfx2/viewfrm.hxx>
+#include "versdlg.hxx"
+#include "doc.hrc"
+#include <sfx2/docfac.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include "sfxhelp.hxx"
+#include <sfx2/msgpool.hxx>
+#include <sfx2/objface.hxx>
+
+#include "../appl/app.hrc"
+#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+#include "helpid.hrc"
+
+#include "guisaveas.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::task;
+
+//====================================================================
+
+class SfxSaveAsContext_Impl
+{
+ String& _rNewNameVar;
+ String _aNewName;
+
+public:
+ SfxSaveAsContext_Impl( String &rNewNameVar,
+ const String &rNewName )
+ : _rNewNameVar( rNewNameVar ),
+ _aNewName( rNewName )
+ { rNewNameVar = rNewName; }
+ ~SfxSaveAsContext_Impl()
+ { _rNewNameVar.Erase(); }
+};
+
+//====================================================================
+
+#define SfxObjectShell
+#include "sfxslots.hxx"
+
+//=========================================================================
+
+
+
+SFX_IMPL_INTERFACE(SfxObjectShell,SfxShell,SfxResId(0))
+{
+}
+
+//=========================================================================
+
+class SfxClosePreventer_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
+{
+ sal_Bool m_bGotOwnership;
+ sal_Bool m_bPreventClose;
+
+public:
+ SfxClosePreventer_Impl();
+
+ sal_Bool HasOwnership() { return m_bGotOwnership; }
+
+ void SetPreventClose( sal_Bool bPrevent ) { m_bPreventClose = bPrevent; }
+
+ virtual void SAL_CALL queryClosing( const lang::EventObject& aEvent, sal_Bool bDeliverOwnership )
+ throw ( uno::RuntimeException, util::CloseVetoException );
+
+ virtual void SAL_CALL notifyClosing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException ) ;
+
+ virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException ) ;
+
+} ;
+
+SfxClosePreventer_Impl::SfxClosePreventer_Impl()
+: m_bGotOwnership( sal_False )
+, m_bPreventClose( sal_True )
+{
+}
+
+void SAL_CALL SfxClosePreventer_Impl::queryClosing( const lang::EventObject&, sal_Bool bDeliverOwnership )
+ throw ( uno::RuntimeException, util::CloseVetoException )
+{
+ if ( m_bPreventClose )
+ {
+ if ( !m_bGotOwnership )
+ m_bGotOwnership = bDeliverOwnership;
+
+ throw util::CloseVetoException();
+ }
+}
+
+void SAL_CALL SfxClosePreventer_Impl::notifyClosing( const lang::EventObject& ) throw ( uno::RuntimeException )
+{}
+
+void SAL_CALL SfxClosePreventer_Impl::disposing( const lang::EventObject& ) throw ( uno::RuntimeException )
+{}
+
+//=========================================================================
+class SfxInstanceCloseGuard_Impl
+{
+ SfxClosePreventer_Impl* m_pPreventer;
+ uno::Reference< util::XCloseListener > m_xPreventer;
+ uno::Reference< util::XCloseable > m_xCloseable;
+
+public:
+ SfxInstanceCloseGuard_Impl()
+ : m_pPreventer( NULL )
+ {}
+
+ ~SfxInstanceCloseGuard_Impl();
+
+ sal_Bool Init_Impl( const uno::Reference< util::XCloseable >& xCloseable );
+};
+
+sal_Bool SfxInstanceCloseGuard_Impl::Init_Impl( const uno::Reference< util::XCloseable >& xCloseable )
+{
+ sal_Bool bResult = sal_False;
+
+ // do not allow reinit after the successful init
+ if ( xCloseable.is() && !m_xCloseable.is() )
+ {
+ try
+ {
+ m_pPreventer = new SfxClosePreventer_Impl();
+ m_xPreventer = uno::Reference< util::XCloseListener >( m_pPreventer );
+ xCloseable->addCloseListener( m_xPreventer );
+ m_xCloseable = xCloseable;
+ bResult = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Could not register close listener!\n" );
+ }
+ }
+
+ return bResult;
+}
+
+SfxInstanceCloseGuard_Impl::~SfxInstanceCloseGuard_Impl()
+{
+ if ( m_xCloseable.is() && m_xPreventer.is() )
+ {
+ try
+ {
+ m_xCloseable->removeCloseListener( m_xPreventer );
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ try
+ {
+ if ( m_pPreventer )
+ {
+ m_pPreventer->SetPreventClose( sal_False );
+
+ if ( m_pPreventer->HasOwnership() )
+ m_xCloseable->close( sal_True ); // TODO: do it asynchronously
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+}
+
+//=========================================================================
+
+void SfxObjectShell::PrintExec_Impl(SfxRequest &rReq)
+{
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this);
+ if ( pFrame )
+ {
+ rReq.SetSlot( SID_PRINTDOC );
+ pFrame->GetViewShell()->ExecuteSlot(rReq);
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::PrintState_Impl(SfxItemSet &rSet)
+{
+ bool bPrinting = false;
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
+ if ( pFrame )
+ {
+ SfxPrinter *pPrinter = pFrame->GetViewShell()->GetPrinter();
+ bPrinting = pPrinter && pPrinter->IsPrinting();
+ }
+ rSet.Put( SfxBoolItem( SID_PRINTOUT, bPrinting ) );
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::APISaveAs_Impl
+(
+ const String& aFileName,
+ SfxItemSet* aParams
+)
+{
+ BOOL bOk = sal_False;
+
+ {DBG_CHKTHIS(SfxObjectShell, 0);}
+
+ if ( GetMedium() )
+ {
+ String aFilterName;
+ SFX_ITEMSET_ARG( aParams, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if( pFilterNameItem )
+ {
+ aFilterName = pFilterNameItem->GetValue();
+ }
+ else
+ {
+ SFX_ITEMSET_ARG( aParams, pContentTypeItem, SfxStringItem, SID_CONTENTTYPE, sal_False );
+ if ( pContentTypeItem )
+ {
+ const SfxFilter* pFilter = SfxFilterMatcher( String::CreateFromAscii(GetFactory().GetShortName()) ).GetFilter4Mime( pContentTypeItem->GetValue(), SFX_FILTER_EXPORT );
+ if ( pFilter )
+ aFilterName = pFilter->GetName();
+ }
+ }
+
+ // in case no filter defined use default one
+ if( !aFilterName.Len() )
+ {
+ const SfxFilter* pFilt = SfxFilter::GetDefaultFilterFromFactory(GetFactory().GetFactoryName());
+
+ DBG_ASSERT( pFilt, "No default filter!\n" );
+ if( pFilt )
+ aFilterName = pFilt->GetFilterName();
+
+ aParams->Put(SfxStringItem( SID_FILTER_NAME, aFilterName));
+ }
+
+
+ {
+ SfxObjectShellRef xLock( this ); // ???
+
+ // use the title that is provided in the media descriptor
+ SFX_ITEMSET_ARG( aParams, pDocTitleItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
+ if ( pDocTitleItem )
+ getDocProperties()->setTitle( pDocTitleItem->GetValue() );
+
+ bOk = CommonSaveAs_Impl( INetURLObject(aFileName), aFilterName,
+ aParams );
+
+ }
+
+ // prevent picklist-entry
+ GetMedium()->SetUpdatePickList( FALSE );
+ }
+
+ return bOk;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
+{
+ {DBG_CHKTHIS(SfxObjectShell, 0);}
+
+ USHORT nId = rReq.GetSlot();
+
+ if( SID_SIGNATURE == nId || SID_MACRO_SIGNATURE == nId )
+ {
+ if ( QueryHiddenInformation( WhenSigning, NULL ) == RET_YES )
+ ( SID_SIGNATURE == nId ) ? SignDocumentContent() : SignScriptingContent();
+ return;
+ }
+
+ if ( !GetMedium() && nId != SID_CLOSEDOC )
+ {
+ rReq.Ignore();
+ return;
+ }
+
+ // this guard is created here to have it destruction at the end of the method
+ SfxInstanceCloseGuard_Impl aModelGuard;
+
+ sal_Bool bIsPDFExport = sal_False;
+ switch(nId)
+ {
+ case SID_VERSION:
+ {
+ SfxViewFrame* pFrame = GetFrame();
+ if ( !pFrame )
+ pFrame = SfxViewFrame::GetFirst( this );
+ if ( !pFrame )
+ return;
+
+ if ( pFrame->GetFrame().GetParentFrame() )
+ {
+ pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq );
+ return;
+ }
+
+ if ( !IsOwnStorageFormat_Impl( *GetMedium() ) )
+ return;
+
+ SfxVersionDialog *pDlg = new SfxVersionDialog( pFrame, IsSaveVersionOnClose() );
+ pDlg->Execute();
+ SetSaveVersionOnClose( pDlg->IsSaveVersionOnClose() );
+ delete pDlg;
+ rReq.Done();
+ return;
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ case SID_DOCINFO:
+ {
+ SFX_REQUEST_ARG(rReq, pDocInfItem, SfxDocumentInfoItem, SID_DOCINFO, FALSE);
+ if ( pDocInfItem )
+ {
+ // parameter, e.g. from replayed macro
+ pDocInfItem->UpdateDocumentInfo(getDocProperties(), true);
+ SetUseUserData( pDocInfItem->IsUseUserData() );
+ }
+ else
+ {
+ // no argument containing DocInfo; check optional arguments
+ BOOL bReadOnly = IsReadOnly();
+ SFX_REQUEST_ARG(rReq, pROItem, SfxBoolItem, SID_DOC_READONLY, FALSE);
+ if ( pROItem )
+ // override readonly attribute of document
+ // e.g. if a readonly document is saved elsewhere and user asks for editing DocInfo before
+ bReadOnly = pROItem->GetValue();
+
+ // collect data for dialog
+ String aURL, aTitle;
+ if ( HasName() )
+ {
+ aURL = GetMedium()->GetName();
+ aTitle = GetTitle();
+ }
+ else
+ {
+ aURL = DEFINE_CONST_UNICODE( "private:factory/" );
+ aURL += String::CreateFromAscii( GetFactory().GetShortName() );
+
+ aTitle = GetTitle();
+ }
+
+ SfxDocumentInfoItem aDocInfoItem( aURL, getDocProperties(),
+ IsUseUserData() );
+ if ( !GetSlotState( SID_DOCTEMPLATE ) )
+ // templates not supported
+ aDocInfoItem.SetTemplate(FALSE);
+
+ SfxItemSet aSet(GetPool(), SID_DOCINFO, SID_DOCINFO, SID_DOC_READONLY, SID_DOC_READONLY,
+ SID_EXPLORER_PROPS_START, SID_EXPLORER_PROPS_START, SID_BASEURL, SID_BASEURL,
+ 0L );
+ aSet.Put( aDocInfoItem );
+ aSet.Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
+ aSet.Put( SfxStringItem( SID_EXPLORER_PROPS_START, aTitle ) );
+ aSet.Put( SfxStringItem( SID_BASEURL, GetMedium()->GetBaseURL() ) );
+
+ // creating dialog is done via virtual method; application will add its own statistics page
+ SfxDocumentInfoDialog *pDlg = CreateDocumentInfoDialog(0, aSet);
+ if ( RET_OK == pDlg->Execute() )
+ {
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pDocInfoItem, SfxDocumentInfoItem, SID_DOCINFO, FALSE);
+ if ( pDocInfoItem )
+ {
+ // user has done some changes to DocumentInfo
+ pDocInfoItem->UpdateDocumentInfo(getDocProperties());
+ SetUseUserData( ((const SfxDocumentInfoItem *)pDocInfoItem)->IsUseUserData() );
+
+ // add data from dialog for possible recording purposes
+ rReq.AppendItem( SfxDocumentInfoItem( GetTitle(),
+ getDocProperties(), IsUseUserData() ) );
+ }
+
+ rReq.Done();
+ }
+ else
+ // nothing done; no recording
+ rReq.Ignore();
+
+ delete pDlg;
+ }
+
+ return;
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ case SID_EXPORTDOCASPDF:
+ case SID_DIRECTEXPORTDOCASPDF:
+ bIsPDFExport = sal_True;
+ case SID_EXPORTDOC:
+ case SID_SAVEASDOC:
+ case SID_SAVEDOC:
+ {
+ //!! detaillierte Auswertung eines Fehlercodes
+ SfxObjectShellRef xLock( this );
+
+ // the model can not be closed till the end of this method
+ // if somebody tries to close it during this time the model will be closed
+ // at the end of the method
+ aModelGuard.Init_Impl( uno::Reference< util::XCloseable >( GetModel(), uno::UNO_QUERY ) );
+
+ sal_Bool bDialogUsed = sal_False;
+ sal_uInt32 nErrorCode = ERRCODE_NONE;
+
+ // by default versions should be preserved always except in case of an explicit
+ // SaveAs via GUI, so the flag must be set accordingly
+ pImp->bPreserveVersions = (nId == SID_SAVEDOC);
+ try
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, GetTitle() ); // ???
+
+ if ( nId == SID_SAVEASDOC )
+ {
+ // in case of plugin mode the SaveAs operation means SaveTo
+ SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pViewOnlyItem, SfxBoolItem, SID_VIEWONLY, FALSE );
+ if ( pViewOnlyItem && pViewOnlyItem->GetValue() )
+ rReq.AppendItem( SfxBoolItem( SID_SAVETO, sal_True ) );
+ }
+
+ // TODO/LATER: do the following GUI related actions in standalown method
+ // ========================================================================================================
+ // Introduce a status indicator for GUI operation
+ SFX_REQUEST_ARG( rReq, pStatusIndicatorItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, FALSE );
+ if ( !pStatusIndicatorItem )
+ {
+ // get statusindicator
+ uno::Reference< task::XStatusIndicator > xStatusIndicator;
+ SfxViewFrame *pFrame = GetFrame();
+ if ( pFrame )
+ {
+ uno::Reference< task::XStatusIndicatorFactory > xStatFactory(
+ pFrame->GetFrame().GetFrameInterface(),
+ uno::UNO_QUERY );
+ if( xStatFactory.is() )
+ xStatusIndicator = xStatFactory->createStatusIndicator();
+ }
+
+
+ OSL_ENSURE( xStatusIndicator.is(), "Can not retrieve default status indicator!\n" );
+ if ( xStatusIndicator.is() )
+ {
+ SfxUnoAnyItem aStatIndItem( SID_PROGRESS_STATUSBAR_CONTROL, uno::makeAny( xStatusIndicator ) );
+
+ if ( nId == SID_SAVEDOC )
+ {
+ // in case of saving it is not possible to transport the parameters from here
+ // but it is not clear here whether the saving will be done or saveAs operation
+ GetMedium()->GetItemSet()->Put( aStatIndItem );
+ }
+
+ rReq.AppendItem( aStatIndItem );
+ }
+ }
+ else if ( nId == SID_SAVEDOC )
+ {
+ // in case of saving it is not possible to transport the parameters from here
+ // but it is not clear here whether the saving will be done or saveAs operation
+ GetMedium()->GetItemSet()->Put( *pStatusIndicatorItem );
+ }
+
+ // Introduce an interaction handler for GUI operation
+ SFX_REQUEST_ARG( rReq, pInteractionHandlerItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, FALSE );
+ if ( !pInteractionHandlerItem )
+ {
+ uno::Reference< task::XInteractionHandler > xInteract;
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+ if( xServiceManager.is() )
+ {
+ xInteract = Reference< XInteractionHandler >(
+ xServiceManager->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ),
+ UNO_QUERY );
+ }
+
+ OSL_ENSURE( xInteract.is(), "Can not retrieve default status indicator!\n" );
+ if ( xInteract.is() )
+ {
+ SfxUnoAnyItem aInteractionItem( SID_INTERACTIONHANDLER, uno::makeAny( xInteract ) );
+ if ( nId == SID_SAVEDOC )
+ {
+ // in case of saving it is not possible to transport the parameters from here
+ // but it is not clear here whether the saving will be done or saveAs operation
+ GetMedium()->GetItemSet()->Put( aInteractionItem );
+ }
+
+ rReq.AppendItem( aInteractionItem );
+ }
+ }
+ else if ( nId == SID_SAVEDOC )
+ {
+ // in case of saving it is not possible to transport the parameters from here
+ // but it is not clear here whether the saving will be done or saveAs operation
+ GetMedium()->GetItemSet()->Put( *pInteractionHandlerItem );
+ }
+ // ========================================================================================================
+
+ sal_Bool bPreselectPassword = sal_False;
+ SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pOldPasswordItem, SfxStringItem, SID_PASSWORD, FALSE );
+ if ( pOldPasswordItem )
+ bPreselectPassword = sal_True;
+
+ uno::Sequence< beans::PropertyValue > aDispatchArgs;
+ if ( rReq.GetArgs() )
+ TransformItems( nId,
+ *rReq.GetArgs(),
+ aDispatchArgs,
+ NULL );
+
+ const SfxSlot* pSlot = GetModule()->GetSlotPool()->GetSlot( nId );
+ if ( !pSlot )
+ throw uno::Exception();
+
+ uno::Reference< lang::XMultiServiceFactory > xEmptyFactory;
+ SfxStoringHelper aHelper( xEmptyFactory );
+
+ if ( QueryHiddenInformation( bIsPDFExport ? WhenCreatingPDF : WhenSaving, NULL ) == RET_YES )
+ {
+ bDialogUsed = aHelper.GUIStoreModel( GetModel(),
+ ::rtl::OUString::createFromAscii( pSlot->GetUnoName() ),
+ aDispatchArgs,
+ bPreselectPassword,
+ GetSharedFileURL(),
+ GetDocumentSignatureState() );
+ }
+ else
+ {
+ // the user has decided not to store the document
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ ERRCODE_IO_ABORT );
+ }
+
+ // merge aDispatchArgs to the request
+ SfxAllItemSet aResultParams( GetPool() );
+ TransformParameters( nId,
+ aDispatchArgs,
+ aResultParams,
+ NULL );
+ rReq.SetArgs( aResultParams );
+
+ SFX_REQUEST_ARG( rReq, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, FALSE );
+ ::rtl::OUString aFilterName = pFilterNameItem ? ::rtl::OUString( pFilterNameItem->GetValue() )
+ : ::rtl::OUString();
+ const SfxFilter* pFilt = GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
+
+ OSL_ENSURE( nId == SID_SAVEDOC || pFilt, "The filter can not be zero since it was used for storing!\n" );
+ if ( bDialogUsed && pFilt
+ && pFilt->IsOwnFormat()
+ && pFilt->UsesStorage()
+ && pFilt->GetVersion() >= SOFFICE_FILEFORMAT_60 )
+ {
+ SfxViewFrame* pDocViewFrame = SfxViewFrame::GetFirst( this );
+ if ( pDocViewFrame )
+ SfxHelp::OpenHelpAgent( &pDocViewFrame->GetFrame(), HID_DID_SAVE_PACKED_XML );
+ }
+
+ // the StoreAsURL/StoreToURL method have called this method with false
+ // so it has to be restored to true here since it is a call from GUI
+ GetMedium()->SetUpdatePickList( sal_True );
+
+ // TODO: in future it must be done in followind way
+ // if document is opened from GUI it is immediatelly appeares in the picklist
+ // if the document is a new one then it appeares in the picklist immediatelly
+ // after SaveAs operation triggered from GUI
+ }
+ catch( task::ErrorCodeIOException& aErrorEx )
+ {
+ nErrorCode = (sal_uInt32)aErrorEx.ErrCode;
+ }
+ catch( Exception& )
+ {
+ nErrorCode = ERRCODE_IO_GENERAL;
+ }
+
+ // by default versions should be preserved always except in case of an explicit
+ // SaveAs via GUI, so the flag must be reset to guarantee this
+ pImp->bPreserveVersions = sal_True;
+ ULONG lErr=GetErrorCode();
+
+ if ( !lErr && nErrorCode )
+ lErr = nErrorCode;
+
+ if ( lErr && nErrorCode == ERRCODE_NONE )
+ {
+ SFX_REQUEST_ARG( rReq, pWarnItem, SfxBoolItem, SID_FAIL_ON_WARNING, FALSE );
+ if ( pWarnItem && pWarnItem->GetValue() )
+ nErrorCode = lErr;
+ }
+
+ // may be nErrorCode should be shown in future
+ if ( lErr != ERRCODE_IO_ABORT )
+ {
+ SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC,GetTitle());
+ ErrorHandler::HandleError( lErr );
+ }
+
+ if ( nId == SID_EXPORTDOCASPDF )
+ {
+ // This function is used by the SendMail function that needs information if a export
+ // file was written or not. This could be due to cancellation of the export
+ // or due to an error. So IO abort must be handled like an error!
+ nErrorCode = ( lErr != ERRCODE_IO_ABORT ) && ( nErrorCode == ERRCODE_NONE ) ? nErrorCode : lErr;
+ }
+
+ rReq.SetReturnValue( SfxBoolItem(0, nErrorCode == ERRCODE_NONE ) );
+
+ ResetError();
+
+ Invalidate();
+ break;
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ case SID_CLOSEDOC:
+ {
+ SfxViewFrame *pFrame = GetFrame();
+ if ( pFrame && pFrame->GetFrame().GetParentFrame() )
+ {
+ // Wenn SID_CLOSEDOC "uber Menue etc. ausgef"uhrt wird, das
+ // aktuelle Dokument aber in einem Frame liegt, soll eigentlich
+ // das FrameSetDocument geclosed werden
+ pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq );
+ rReq.Done();
+ return;
+ }
+
+ BOOL bInFrameSet = FALSE;
+ USHORT nFrames=0;
+ pFrame = SfxViewFrame::GetFirst( this );
+ while ( pFrame )
+ {
+ if ( pFrame->GetFrame().GetParentFrame() )
+ {
+ // Auf dieses Dokument existiert noch eine Sicht, die
+ // in einem FrameSet liegt; diese darf nat"urlich nicht
+ // geclosed werden
+ bInFrameSet = TRUE;
+ }
+ else
+ nFrames++;
+
+ pFrame = SfxViewFrame::GetNext( *pFrame, this );
+ }
+
+ if ( bInFrameSet )
+ {
+ // Alle Sichten, die nicht in einem FrameSet liegen, closen
+ pFrame = SfxViewFrame::GetFirst( this );
+ while ( pFrame )
+ {
+ if ( !pFrame->GetFrame().GetParentFrame() )
+ pFrame->GetFrame().DoClose();
+ pFrame = SfxViewFrame::GetNext( *pFrame, this );
+ }
+ }
+
+ // Parameter auswerten
+ SFX_REQUEST_ARG(rReq, pSaveItem, SfxBoolItem, SID_CLOSEDOC_SAVE, FALSE);
+ SFX_REQUEST_ARG(rReq, pNameItem, SfxStringItem, SID_CLOSEDOC_FILENAME, FALSE);
+ if ( pSaveItem )
+ {
+ if ( pSaveItem->GetValue() )
+ {
+ if ( !pNameItem )
+ {
+ SbxBase::SetError( SbxERR_WRONG_ARGS );
+ rReq.Ignore();
+ return;
+ }
+ SfxAllItemSet aArgs( GetPool() );
+ SfxStringItem aTmpItem( SID_FILE_NAME, pNameItem->GetValue() );
+ aArgs.Put( aTmpItem, aTmpItem.Which() );
+ SfxRequest aSaveAsReq( SID_SAVEASDOC, SFX_CALLMODE_API, aArgs );
+ ExecFile_Impl( aSaveAsReq );
+ if ( !aSaveAsReq.IsDone() )
+ {
+ rReq.Ignore();
+ return;
+ }
+ }
+ else
+ SetModified(FALSE);
+ }
+
+ // Benutzer bricht ab?
+ if ( !PrepareClose( 2 ) )
+ {
+ rReq.SetReturnValue( SfxBoolItem(0, FALSE) );
+ rReq.Done();
+ return;
+ }
+
+ SetModified( FALSE );
+ ULONG lErr = GetErrorCode();
+ ErrorHandler::HandleError(lErr);
+
+ rReq.SetReturnValue( SfxBoolItem(0, TRUE) );
+ rReq.Done();
+ rReq.ReleaseArgs(); // da der Pool in Close zerst"ort wird
+ DoClose();
+ return;
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ case SID_DOCTEMPLATE:
+ {
+ // speichern als Dokumentvorlagen
+ SfxDocumentTemplateDlg *pDlg = 0;
+ SfxErrorContext aEc(ERRCTX_SFX_DOCTEMPLATE,GetTitle());
+ SfxDocumentTemplates *pTemplates = new SfxDocumentTemplates;
+
+ if ( !rReq.GetArgs() )
+ {
+ pDlg = new SfxDocumentTemplateDlg(0, pTemplates);
+ if ( RET_OK == pDlg->Execute() && pDlg->GetTemplateName().Len())
+ {
+ rReq.AppendItem(SfxStringItem(
+ SID_TEMPLATE_NAME, pDlg->GetTemplateName()));
+ rReq.AppendItem(SfxStringItem(
+ SID_TEMPLATE_REGIONNAME, pDlg->GetRegionName()));
+ }
+ else
+ {
+ delete pDlg;
+ rReq.Ignore();
+ return;
+ }
+ }
+
+ SFX_REQUEST_ARG(rReq, pRegionItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, FALSE);
+ SFX_REQUEST_ARG(rReq, pNameItem, SfxStringItem, SID_TEMPLATE_NAME, FALSE);
+ SFX_REQUEST_ARG(rReq, pRegionNrItem, SfxUInt16Item, SID_TEMPLATE_REGION, FALSE);
+ if ( (!pRegionItem && !pRegionNrItem ) || !pNameItem )
+ {
+ DBG_ASSERT( rReq.IsAPI(), "non-API call without Arguments" );
+ SbxBase::SetError( SbxERR_WRONG_ARGS );
+ rReq.Ignore();
+ return;
+ }
+
+ ::rtl::OUString aTemplateName = pNameItem->GetValue();
+ ::rtl::OUString aTemplateGroup;
+ if ( pRegionItem )
+ aTemplateGroup = pRegionItem->GetValue();
+ else
+ // pRegionNrItem must not be NULL, it was just checked
+ aTemplateGroup = pTemplates->GetFullRegionName( pRegionNrItem->GetValue() );
+ // check Group and Name
+ delete pTemplates;
+
+ sal_Bool bOk = sal_False;
+ try
+ {
+ uno::Reference< frame::XStorable > xStorable( GetModel(), uno::UNO_QUERY_THROW );
+ ::rtl::OUString aService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.DocumentTemplates" ) );
+ uno::Reference< frame::XDocumentTemplates > xTemplates(
+ comphelper::getProcessServiceFactory()->createInstance( aService ),
+ uno::UNO_QUERY_THROW );
+
+ bOk = xTemplates->storeTemplate( aTemplateGroup, aTemplateName, xStorable );
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ DELETEX(pDlg);
+
+ rReq.SetReturnValue( SfxBoolItem( 0, bOk ) );
+ if ( bOk )
+ {
+ // update the Organizer runtime cache from the template component if the cache has already been created
+ // TODO/LATER: get rid of this cache duplication
+ SfxDocumentTemplates aTemplates;
+ aTemplates.ReInitFromComponent();
+ }
+ else
+ {
+ ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
+ return;
+ }
+
+ break;
+ }
+ }
+
+ // Picklisten-Eintrag verhindern
+ if ( rReq.IsAPI() )
+ GetMedium()->SetUpdatePickList( FALSE );
+ else if ( rReq.GetArgs() )
+ {
+ SFX_ITEMSET_GET( *rReq.GetArgs(), pPicklistItem, SfxBoolItem, SID_PICKLIST, FALSE );
+ if ( pPicklistItem )
+ GetMedium()->SetUpdatePickList( pPicklistItem->GetValue() );
+ }
+
+ // Ignore()-Zweige haben schon returnt
+ rReq.Done();
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::GetState_Impl(SfxItemSet &rSet)
+{
+ DBG_CHKTHIS(SfxObjectShell, 0);
+ SfxWhichIter aIter( rSet );
+
+ for ( USHORT nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich() )
+ {
+ switch ( nWhich )
+ {
+ case SID_DOCTEMPLATE :
+ {
+ if ( !GetFactory().GetTemplateFilter() )
+ rSet.DisableItem( nWhich );
+ break;
+ }
+
+ case SID_VERSION:
+ {
+ SfxObjectShell *pDoc = this;
+ SfxViewFrame* pFrame = GetFrame();
+ if ( !pFrame )
+ pFrame = SfxViewFrame::GetFirst( this );
+ if ( pFrame )
+ {
+ if ( pFrame->GetFrame().GetParentFrame() )
+ {
+ pFrame = pFrame->GetTopViewFrame();
+ pDoc = pFrame->GetObjectShell();
+ }
+ }
+
+ if ( !pFrame || !pDoc->HasName() ||
+ !IsOwnStorageFormat_Impl( *pDoc->GetMedium() ) )
+//REMOVE || pDoc->GetMedium()->GetStorage()->GetVersion() < SOFFICE_FILEFORMAT_50 )
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ case SID_SAVEDOC:
+ {
+ BOOL bMediumRO = IsReadOnlyMedium();
+ if ( !bMediumRO && GetMedium() && IsModified() )
+ rSet.Put(SfxStringItem(
+ nWhich, String(SfxResId(STR_SAVEDOC))));
+ else
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
+ case SID_DOCINFO:
+ if ( 0 != ( pImp->eFlags & SFXOBJECTSHELL_NODOCINFO ) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_CLOSEDOC:
+ {
+ SfxObjectShell *pDoc = this;
+ SfxViewFrame *pFrame = GetFrame();
+ if ( pFrame && pFrame->GetFrame().GetParentFrame() )
+ {
+ // Wenn SID_CLOSEDOC "uber Menue etc. ausgef"uhrt wird, das
+ // aktuelle Dokument aber in einem Frame liegt, soll eigentlich
+ // das FrameSetDocument geclosed werden
+ pDoc = pFrame->GetTopViewFrame()->GetObjectShell();
+ }
+
+ if ( pDoc->GetFlags() & SFXOBJECTSHELL_DONTCLOSE )
+ rSet.DisableItem(nWhich);
+ else
+ rSet.Put(SfxStringItem(nWhich, String(SfxResId(STR_CLOSEDOC))));
+ break;
+ }
+
+ case SID_SAVEASDOC:
+ {
+ if( ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) != SFX_LOADED_MAINDOCUMENT )
+ {
+ rSet.DisableItem( nWhich );
+ break;
+ }
+/*
+ const SfxFilter* pCombinedFilters = NULL;
+ SfxFilterContainer* pFilterContainer = GetFactory().GetFilterContainer();
+
+ if ( pFilterContainer )
+ {
+ SfxFilterFlags nMust = SFX_FILTER_IMPORT | SFX_FILTER_EXPORT;
+ SfxFilterFlags nDont = SFX_FILTER_NOTINSTALLED | SFX_FILTER_INTERNAL;
+
+ pCombinedFilters = pFilterContainer->GetAnyFilter( nMust, nDont );
+ }
+*/
+ if ( /*!pCombinedFilters ||*/ !GetMedium() )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxStringItem( nWhich, String( SfxResId( STR_SAVEASDOC ) ) ) );
+ break;
+ }
+
+ case SID_EXPORTDOCASPDF:
+ case SID_DIRECTEXPORTDOCASPDF:
+ {
+ /*
+
+ search for filter cant work correctly ...
+ Because it's not clear, which export filter for which office module
+ must be searched. On the other side it can be very expensive doing so.
+ The best solution would be: on installation time we should know if pdf feature
+ was installed or not!!! (e.g. by writing a bool inside cfg)
+
+ SfxFilterContainer* pFilterContainer = GetFactory().GetFilterContainer();
+ if ( pFilterContainer )
+ {
+ String aPDFExtension = String::CreateFromAscii( "pdf" );
+ const SfxFilter* pFilter = pFilterContainer->GetFilter4Extension( aPDFExtension, SFX_FILTER_EXPORT );
+ if ( pFilter != NULL )
+ break;
+ }
+
+ rSet.DisableItem( nWhich );
+ */
+ break;
+ }
+
+ case SID_DOC_MODIFIED:
+ {
+ rSet.Put( SfxStringItem( SID_DOC_MODIFIED, IsModified() ? '*' : ' ' ) );
+ break;
+ }
+
+ case SID_MODIFIED:
+ {
+ rSet.Put( SfxBoolItem( SID_MODIFIED, IsModified() ) );
+ break;
+ }
+
+ case SID_DOCINFO_TITLE:
+ {
+ rSet.Put( SfxStringItem(
+ SID_DOCINFO_TITLE, getDocProperties()->getTitle() ) );
+ break;
+ }
+ case SID_FILE_NAME:
+ {
+ if( GetMedium() && HasName() )
+ rSet.Put( SfxStringItem(
+ SID_FILE_NAME, GetMedium()->GetName() ) );
+ break;
+ }
+ case SID_SIGNATURE:
+ {
+ rSet.Put( SfxUInt16Item( SID_SIGNATURE, GetDocumentSignatureState() ) );
+ break;
+ }
+ case SID_MACRO_SIGNATURE:
+ {
+ // the slot makes sense only if there is a macro in the document
+ if ( pImp->documentStorageHasMacros() || pImp->aMacroMode.hasMacroLibrary() )
+ rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, GetScriptingSignatureState() ) );
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::ExecProps_Impl(SfxRequest &rReq)
+{
+ switch ( rReq.GetSlot() )
+ {
+ case SID_MODIFIED:
+ {
+ SetModified( ( (SfxBoolItem&) rReq.GetArgs()->Get(SID_MODIFIED)).GetValue() );
+ rReq.Done();
+ break;
+ }
+
+ case SID_DOCTITLE:
+ SetTitle( ( (SfxStringItem&) rReq.GetArgs()->Get(SID_DOCTITLE)).GetValue() );
+ rReq.Done();
+ break;
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ case SID_PLAYMACRO:
+ {
+ SFX_APP()->PlayMacro_Impl( rReq, GetBasic() );
+ break;
+ }
+
+ case SID_DOCINFO_AUTHOR :
+ {
+ ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
+ getDocProperties()->setAuthor( aStr );
+ break;
+ }
+
+ case SID_DOCINFO_COMMENTS :
+ {
+ ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
+ getDocProperties()->setDescription( aStr );
+ break;
+ }
+
+ case SID_DOCINFO_KEYWORDS :
+ {
+ ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
+ getDocProperties()->setKeywords(
+ ::comphelper::string::convertCommaSeparated(aStr) );
+ break;
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::StateProps_Impl(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter(rSet);
+ for ( USHORT nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
+ {
+ switch ( nSID )
+ {
+ case SID_DOCINFO_AUTHOR :
+ {
+ rSet.Put( SfxStringItem( nSID,
+ getDocProperties()->getAuthor() ) );
+ break;
+ }
+
+ case SID_DOCINFO_COMMENTS :
+ {
+ rSet.Put( SfxStringItem( nSID,
+ getDocProperties()->getDescription()) );
+ break;
+ }
+
+ case SID_DOCINFO_KEYWORDS :
+ {
+ rSet.Put( SfxStringItem( nSID, ::comphelper::string::
+ convertCommaSeparated(getDocProperties()->getKeywords())) );
+ break;
+ }
+
+ case SID_DOCPATH:
+ {
+ DBG_ERROR( "Not supported anymore!" );
+ break;
+ }
+
+ case SID_DOCFULLNAME:
+ {
+ rSet.Put( SfxStringItem( SID_DOCFULLNAME, GetTitle(SFX_TITLE_FULLNAME) ) );
+ break;
+ }
+
+ case SID_DOCTITLE:
+ {
+ rSet.Put( SfxStringItem( SID_DOCTITLE, GetTitle() ) );
+ break;
+ }
+
+ case SID_DOC_READONLY:
+ {
+ rSet.Put( SfxBoolItem( SID_DOC_READONLY, IsReadOnly() ) );
+ break;
+ }
+
+ case SID_DOC_SAVED:
+ {
+ rSet.Put( SfxBoolItem( SID_DOC_SAVED, !IsModified() ) );
+ break;
+ }
+
+ case SID_CLOSING:
+ {
+ rSet.Put( SfxBoolItem( SID_CLOSING, false ) );
+ break;
+ }
+
+ case SID_DOC_LOADING:
+ rSet.Put( SfxBoolItem( nSID, SFX_LOADED_MAINDOCUMENT !=
+ ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) ) );
+ break;
+
+ case SID_IMG_LOADING:
+ rSet.Put( SfxBoolItem( nSID, SFX_LOADED_IMAGES !=
+ ( pImp->nLoadedFlags & SFX_LOADED_IMAGES ) ) );
+ break;
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::ExecView_Impl(SfxRequest &rReq)
+{
+ switch ( rReq.GetSlot() )
+ {
+ case SID_ACTIVATE:
+ {
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this, TRUE );
+ if ( pFrame )
+ pFrame->GetFrame().Appear();
+ rReq.SetReturnValue( SfxObjectItem( 0, pFrame ) );
+ rReq.Done();
+ break;
+ }
+ case SID_NEWWINDOWFOREDIT:
+ {
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+ if( pFrame->GetObjectShell() == this &&
+ ( pFrame->GetFrameType() & SFXFRAME_HASTITLE ) )
+ pFrame->ExecuteSlot( rReq );
+ else
+ {
+ String aFileName( GetObjectShell()->GetMedium()->GetName() );
+ if ( aFileName.Len() )
+ {
+ SfxStringItem aName( SID_FILE_NAME, aFileName );
+ SfxBoolItem aCreateView( SID_OPEN_NEW_VIEW, TRUE );
+ SFX_APP()->GetAppDispatcher_Impl()->Execute(
+ SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, &aName,
+ &aCreateView, 0L);
+ }
+ }
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::StateView_Impl(SfxItemSet& /*rSet*/)
+{
+}
+
+sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< security::DocumentSignatureInformation >& aInfos )
+{
+ sal_Bool bCertValid = sal_True;
+ sal_uInt16 nResult = SIGNATURESTATE_NOSIGNATURES;
+ int nInfos = aInfos.getLength();
+ bool bCompleteSignature = true;
+ if( nInfos )
+ {
+ nResult = SIGNATURESTATE_SIGNATURES_OK;
+ for ( int n = 0; n < nInfos; n++ )
+ {
+ if ( bCertValid )
+ {
+ sal_Int32 nCertStat = aInfos[n].CertificateStatus;
+ bCertValid = nCertStat == security::CertificateValidity::VALID ? sal_True : sal_False;
+ }
+
+ if ( !aInfos[n].SignatureIsValid )
+ {
+ nResult = SIGNATURESTATE_SIGNATURES_BROKEN;
+ break; // we know enough
+ }
+ bCompleteSignature &= !aInfos[n].PartialDocumentSignature;
+ }
+ }
+
+ if ( nResult == SIGNATURESTATE_SIGNATURES_OK && !bCertValid )
+ nResult = SIGNATURESTATE_SIGNATURES_NOTVALIDATED;
+ else if ( nResult == SIGNATURESTATE_SIGNATURES_OK && bCertValid && !bCompleteSignature)
+ nResult = SIGNATURESTATE_SIGNATURES_PARTIAL_OK;
+
+ // this code must not check whether the document is modified
+ // it should only check the provided info
+
+ return nResult;
+}
+
+uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnalyzeSignature( sal_Bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner )
+{
+ uno::Sequence< security::DocumentSignatureInformation > aResult;
+ uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner;
+
+ if ( GetMedium() && GetMedium()->GetName().Len() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() )
+ {
+ try
+ {
+ if ( !xLocSigner.is() )
+ {
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[0] <<= ::rtl::OUString();
+ try
+ {
+ uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
+ aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ xLocSigner.set( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW );
+
+ }
+
+ if ( bScriptingContent )
+ aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
+ uno::Reference< io::XInputStream >() );
+ else
+ aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
+ uno::Reference< io::XInputStream >() );
+ }
+ catch( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ return aResult;
+}
+
+sal_uInt16 SfxObjectShell::ImplGetSignatureState( sal_Bool bScriptingContent )
+{
+ sal_Int16* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState;
+
+ if ( *pState == SIGNATURESTATE_UNKNOWN )
+ {
+ *pState = SIGNATURESTATE_NOSIGNATURES;
+
+ uno::Sequence< security::DocumentSignatureInformation > aInfos = ImplAnalyzeSignature( bScriptingContent );
+ *pState = ImplCheckSignaturesInformation( aInfos );
+ }
+
+ if ( *pState == SIGNATURESTATE_SIGNATURES_OK || *pState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED
+ || *pState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK)
+ {
+ if ( IsModified() )
+ *pState = SIGNATURESTATE_SIGNATURES_INVALID;
+ }
+
+ return (sal_uInt16)*pState;
+}
+
+void SfxObjectShell::ImplSign( sal_Bool bScriptingContent )
+{
+ // Check if it is stored in OASIS format...
+ if ( GetMedium() && GetMedium()->GetFilter()
+ && ( !GetMedium()->GetFilter()->IsOwnFormat() || !GetMedium()->HasStorage_Impl() ) )
+ {
+ // Only OASIS and OOo6.x formats will be handled further
+ InfoBox( NULL, SfxResId( RID_XMLSEC_INFO_WRONGDOCFORMAT ) ).Execute();
+ return;
+ }
+
+ // check whether the document is signed
+ ImplGetSignatureState( sal_False ); // document signature
+ ImplGetSignatureState( sal_True ); // script signature
+ sal_Bool bHasSign = ( pImp->nScriptingSignatureState != SIGNATURESTATE_NOSIGNATURES || pImp->nDocumentSignatureState != SIGNATURESTATE_NOSIGNATURES );
+
+ // the target ODF version on saving
+ SvtSaveOptions aSaveOpt;
+ SvtSaveOptions::ODFDefaultVersion nVersion = aSaveOpt.GetODFDefaultVersion();
+
+ // the document is not new and is not modified
+ ::rtl::OUString aODFVersion;
+ try
+ {
+ // check the version of the document
+ uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aODFVersion;
+ }
+ catch( uno::Exception& )
+ {}
+
+ bool bNoSig = false;
+
+ if ( IsModified() || !GetMedium() || !GetMedium()->GetName().Len()
+ || (!aODFVersion.equals( ODFVER_012_TEXT ) && !bHasSign) )
+ {
+ // the document might need saving ( new, modified or in ODF1.1 format without signature )
+
+ if ( nVersion >= SvtSaveOptions::ODFVER_012 )
+ {
+
+ if ( (bHasSign && QueryBox( NULL, SfxResId( MSG_XMLSEC_QUERY_SAVESIGNEDBEFORESIGN ) ).Execute() == RET_YES)
+ || (!bHasSign && QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_SAVEBEFORESIGN ) ).Execute() == RET_YES) )
+ {
+ USHORT nId = SID_SAVEDOC;
+ if ( !GetMedium() || !GetMedium()->GetName().Len() )
+ nId = SID_SAVEASDOC;
+ SfxRequest aSaveRequest( nId, 0, GetPool() );
+ //ToDo: Review. We needed to call SetModified, otherwise the document would not be saved.
+ SetModified(sal_True);
+ ExecFile_Impl( aSaveRequest );
+
+ // Check if it is stored in OASIS format...
+ if ( GetMedium() && GetMedium()->GetFilter()
+ && ( !GetMedium()->GetFilter()->IsOwnFormat() || !GetMedium()->HasStorage_Impl()
+ || SotStorage::GetVersion( GetMedium()->GetStorage() ) <= SOFFICE_FILEFORMAT_60 ) )
+ {
+ // Only OASIS format will be handled further
+ InfoBox( NULL, SfxResId( RID_XMLSEC_INFO_WRONGDOCFORMAT ) ).Execute();
+ return;
+ }
+ }
+ else
+ {
+ //When the document is modified then we must not show the digital signatures dialog
+ //If we have come here then the user denied to save.
+ if (!bHasSign)
+ bNoSig = true;
+ }
+ }
+ else
+ {
+ ErrorBox( NULL, WB_OK, SfxResId( STR_XMLSEC_ODF12_EXPECTED ) ).Execute();
+ return;
+ }
+
+ if ( IsModified() || !GetMedium() || !GetMedium()->GetName().Len() )
+ return;
+ }
+
+ // the document is not modified currently, so it can not become modified after signing
+ sal_Bool bAllowModifiedBack = sal_False;
+ if ( IsEnableSetModified() )
+ {
+ EnableSetModified( sal_False );
+ bAllowModifiedBack = sal_True;
+ }
+
+ // we have to store to the original document, the original medium should be closed for this time
+ if ( !bNoSig
+ && ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
+ {
+ GetMedium()->CloseAndRelease();
+
+ // We sign only ODF1.2, that means that if this point has been reached,
+ // the ODF1.2 signing process should be used.
+ // This code still might be called to show the signature of ODF1.1 document.
+ sal_Bool bSigned = GetMedium()->SignContents_Impl(
+ bScriptingContent,
+ aODFVersion,
+ pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_OK
+ || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED
+ || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK);
+
+ DoSaveCompleted( GetMedium() );
+
+ if ( bSigned )
+ {
+ if ( bScriptingContent )
+ {
+ pImp->nScriptingSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
+
+ // adding of scripting signature removes existing document signature
+ pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
+ }
+ else
+ pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
+
+ pImp->bSignatureErrorIsShown = sal_False;
+
+ Invalidate( SID_SIGNATURE );
+ Invalidate( SID_MACRO_SIGNATURE );
+ Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
+ }
+ }
+
+ if ( bAllowModifiedBack )
+ EnableSetModified( sal_True );
+}
+
+sal_uInt16 SfxObjectShell::GetDocumentSignatureState()
+{
+ return ImplGetSignatureState( FALSE );
+}
+
+void SfxObjectShell::SignDocumentContent()
+{
+ ImplSign( FALSE );
+}
+
+sal_uInt16 SfxObjectShell::GetScriptingSignatureState()
+{
+ return ImplGetSignatureState( TRUE );
+}
+
+void SfxObjectShell::SignScriptingContent()
+{
+ ImplSign( TRUE );
+}
+
+// static
+const uno::Sequence<sal_Int8>& SfxObjectShell::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
new file mode 100644
index 000000000000..49188defc4f1
--- /dev/null
+++ b/sfx2/source/doc/objstor.cxx
@@ -0,0 +1,3702 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <tools/zcodec.hxx>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/document/FilterOptionsRequest.hpp>
+#include <com/sun/star/document/XInteractionFilterOptions.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/XInteractionAskLater.hpp>
+#include <com/sun/star/task/FutureDocumentVersionProductUpdateRequest.hpp>
+#include <com/sun/star/task/InteractionClassification.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/embed/XLinkageSupport.hpp>
+#include <com/sun/star/embed/EntryInitModes.hpp>
+#include <com/sun/star/embed/XOptimizedStorage.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/configurationhelper.hxx>
+#include <comphelper/interaction.hxx>
+#include <svtools/sfxecode.hxx>
+#include <unotools/securityoptions.hxx>
+#include <cppuhelper/weak.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/cachestr.hxx>
+#include <unotools/streamwrap.hxx>
+
+#include <unotools/saveopt.hxx>
+#include <unotools/useroptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/docinfohelper.hxx>
+#include <ucbhelper/content.hxx>
+#include <sot/storinfo.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/seqstream.hxx>
+#include <comphelper/documentconstants.hxx>
+#include <comphelper/string.hxx>
+#include <vcl/bitmapex.hxx>
+#include <svtools/embedhlp.hxx>
+#include <rtl/logfile.hxx>
+#include <basic/modsizeexceeded.hxx>
+#include <osl/file.hxx>
+
+#include <sfx2/signaturestate.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/request.hxx>
+#include "sfxresid.hxx"
+#include <sfx2/docfile.hxx>
+#include "fltfnc.hxx"
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfac.hxx>
+#include "objshimp.hxx"
+#include "sfxtypes.hxx"
+#include "doc.hrc"
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/module.hxx>
+#include <sfx2/dispatch.hxx>
+#include "openflag.hxx"
+#include "helper.hxx"
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/event.hxx>
+#include "fltoptint.hxx"
+#include <sfx2/viewfrm.hxx>
+#include "graphhelp.hxx"
+#include "appbaslib.hxx"
+#include "appdata.hxx"
+
+#ifdef OS2
+#include <osl/file.hxx>
+#include <stdio.h>
+#include <sys/ea.h>
+#endif
+
+#include "../appl/app.hrc"
+
+extern sal_uInt32 CheckPasswd_Impl( SfxObjectShell*, SfxItemPool&, SfxMedium* );
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::document;
+using namespace ::rtl;
+using namespace ::cppu;
+
+namespace css = ::com::sun::star;
+
+//=========================================================================
+void impl_addToModelCollection(const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ if (!xModel.is())
+ return;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+ css::uno::Reference< css::container::XSet > xModelCollection(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.GlobalEventBroadcaster")),
+ css::uno::UNO_QUERY);
+ if (xModelCollection.is())
+ {
+ try
+ {
+ xModelCollection->insert(css::uno::makeAny(xModel));
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "The document seems to be in the collection already!\n" );
+ }
+ }
+}
+
+//=========================================================================
+
+sal_Bool SfxObjectShell::Save()
+{
+ return SaveChildren();
+}
+
+//--------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::SaveAs( SfxMedium& rMedium )
+{
+ return SaveAsChildren( rMedium );
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool GetPasswd_Impl( const SfxItemSet* pSet, ::rtl::OUString& rPasswd )
+{
+ const SfxPoolItem* pItem = NULL;
+ if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_PASSWORD, sal_True, &pItem ) )
+ {
+ DBG_ASSERT( pItem->IsA( TYPE(SfxStringItem) ), "wrong item type" );
+ rPasswd = ( (const SfxStringItem*)pItem )->GetValue();
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SfxObjectShell::PutURLContentsToVersionStream_Impl(
+ ::rtl::OUString aURL,
+ const uno::Reference< embed::XStorage >& xDocStorage,
+ ::rtl::OUString aStreamName )
+{
+ sal_Bool bResult = sal_False;
+ try
+ {
+ uno::Reference< embed::XStorage > xVersion = xDocStorage->openStorageElement(
+ ::rtl::OUString::createFromAscii( "Versions" ),
+ embed::ElementModes::READWRITE );
+
+ DBG_ASSERT( xVersion.is(),
+ "The method must throw an exception if the storage can not be opened!\n" );
+ if ( !xVersion.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< io::XStream > xVerStream = xVersion->openStreamElement(
+ aStreamName,
+ embed::ElementModes::READWRITE );
+ DBG_ASSERT( xVerStream.is(), "The method must throw an exception if the storage can not be opened!\n" );
+ if ( !xVerStream.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< io::XOutputStream > xOutStream = xVerStream->getOutputStream();
+ uno::Reference< io::XTruncate > xTrunc( xOutStream, uno::UNO_QUERY );
+
+ DBG_ASSERT( xTrunc.is(), "The output stream must exist and implement XTruncate interface!\n" );
+ if ( !xTrunc.is() )
+ throw RuntimeException();
+
+ uno::Reference< io::XInputStream > xTmpInStream =
+ ::comphelper::OStorageHelper::GetInputStreamFromURL( aURL );
+ DBG_ASSERT( xTmpInStream.is(), "The method must create the stream or throw an exception!\n" );
+ if ( !xTmpInStream.is() )
+ throw uno::RuntimeException();
+
+ xTrunc->truncate();
+ ::comphelper::OStorageHelper::CopyInputToOutput( xTmpInStream, xOutStream );
+ xOutStream->closeOutput();
+
+ uno::Reference< embed::XTransactedObject > xTransact( xVersion, uno::UNO_QUERY );
+ DBG_ASSERT( xTransact.is(), "The storage must implement XTransacted interface!\n" );
+ if ( xTransact.is() )
+ xTransact->commit();
+
+ bResult = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ // TODO/LATER: handle the error depending on exception
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ return bResult;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SfxObjectShell::CreateTempCopyOfStorage_Impl( const uno::Reference< embed::XStorage >& xStorage )
+{
+ ::rtl::OUString aTempURL = ::utl::TempFile().GetURL();
+
+ DBG_ASSERT( aTempURL.getLength(), "Can't create a temporary file!\n" );
+ if ( aTempURL.getLength() )
+ {
+ try
+ {
+ uno::Reference< embed::XStorage > xTempStorage =
+ ::comphelper::OStorageHelper::GetStorageFromURL( aTempURL, embed::ElementModes::READWRITE );
+
+ // the password will be transfered from the xStorage to xTempStorage by storage implemetation
+ xStorage->copyToStorage( xTempStorage );
+
+ // the temporary storage was commited by the previous method and it will die by refcount
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR( "Creation of a storage copy is failed!" );
+ ::utl::UCBContentHelper::Kill( aTempURL );
+
+ aTempURL = ::rtl::OUString();
+
+ // TODO/LATER: may need error code setting based on exception
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+
+ return aTempURL;
+}
+
+//-------------------------------------------------------------------------
+SvGlobalName SfxObjectShell::GetClassName() const
+{
+ return GetFactory().GetClassId();
+}
+
+//-------------------------------------------------------------------------
+void SfxObjectShell::SetupStorage( const uno::Reference< embed::XStorage >& xStorage,
+ sal_Int32 nVersion,
+ sal_Bool bTemplate ) const
+{
+ uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
+
+ if ( xProps.is() )
+ {
+ SvGlobalName aName;
+ String aFullTypeName, aShortTypeName, aAppName;
+ sal_uInt32 nClipFormat=0;
+
+ FillClass( &aName, &nClipFormat, &aAppName, &aFullTypeName, &aShortTypeName, nVersion, bTemplate );
+ if ( nClipFormat )
+ {
+ // basic doesn't have a ClipFormat
+ // without MediaType the storage is not really usable, but currently the BasicIDE still
+ // is an SfxObjectShell and so we can't take this as an error
+ datatransfer::DataFlavor aDataFlavor;
+ SotExchange::GetFormatDataFlavor( nClipFormat, aDataFlavor );
+ if ( aDataFlavor.MimeType.getLength() )
+ {
+ try
+ {
+ xProps->setPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ), uno::makeAny( aDataFlavor.MimeType ) );
+ }
+ catch( uno::Exception& )
+ {
+ const_cast<SfxObjectShell*>( this )->SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ ::rtl::OUString aVersion;
+ SvtSaveOptions aSaveOpt;
+ SvtSaveOptions::ODFDefaultVersion nDefVersion = aSaveOpt.GetODFDefaultVersion();
+
+ // older versions can not have this property set, it exists only starting from ODF1.2
+ if ( nDefVersion >= SvtSaveOptions::ODFVER_012 )
+ aVersion = ODFVER_012_TEXT;
+
+ if ( aVersion.getLength() )
+ {
+ try
+ {
+ xProps->setPropertyValue( ::rtl::OUString::createFromAscii( "Version" ), uno::makeAny( aVersion ) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+void SfxObjectShell::PrepareSecondTryLoad_Impl()
+{
+ // only for internal use
+ pImp->m_xDocStorage = uno::Reference< embed::XStorage >();
+ pImp->m_bIsInit = sal_False;
+ ResetError();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SfxObjectShell::GeneralInit_Impl( const uno::Reference< embed::XStorage >& xStorage,
+ sal_Bool bTypeMustBeSetAlready )
+{
+ if ( pImp->m_bIsInit )
+ return sal_False;
+
+ pImp->m_bIsInit = sal_True;
+ if ( xStorage.is() )
+ {
+ // no notification is required the storage is set the first time
+ pImp->m_xDocStorage = xStorage;
+
+ try {
+ uno::Reference < beans::XPropertySet > xPropSet( xStorage, uno::UNO_QUERY_THROW );
+ Any a = xPropSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) );
+ ::rtl::OUString aMediaType;
+ if ( !(a>>=aMediaType) || !aMediaType.getLength() )
+ {
+ if ( bTypeMustBeSetAlready )
+ {
+ SetError( ERRCODE_IO_BROKENPACKAGE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return sal_False;
+ }
+
+ SetupStorage( xStorage, SOFFICE_FILEFORMAT_CURRENT, sal_False );
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Can't check storage's mediatype!\n" );
+ }
+ }
+ else
+ pImp->m_bCreateTempStor = sal_True;
+
+ return sal_True;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SfxObjectShell::InitNew( const uno::Reference< embed::XStorage >& xStorage )
+{
+ return GeneralInit_Impl( xStorage, sal_False );
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SfxObjectShell::Load( SfxMedium& rMedium )
+{
+ return GeneralInit_Impl( rMedium.GetStorage(), sal_True );
+}
+
+sal_Bool SfxObjectShell::DoInitNew( SfxMedium* pMed )
+/* [Beschreibung]
+
+ Diese von SvPersist geerbte virtuelle Methode wird gerufen, um
+ die SfxObjectShell-Instanz aus einem Storage (pStor != 0) bzw.
+ (pStor == 0) ganz neu zu initialisieren.
+
+ Wie alle Do...-Methoden liegt hier eine Steuerung vor, die eigentliche
+ Implementierung erfolgt, indem die ebenfalls virtuellen Methode
+ InitNew(SvStorate*) von der SfxObjectShell-Subclass implementiert wird.
+
+ F"ur pStor == 0 wird ein die SfxObjectShell-Instanz mit einem leeren
+ SfxMedium verbunden, sonst mit einem SfxMedium, welches auf den
+ als Parameter "ubergeben SvStorage verweist.
+
+ Erst nach InitNew() oder Load() ist das Objekt korrekt initialisiert.
+
+ [R"uckgabewert]
+ sal_True Das Objekt wurde initialisiert.
+ sal_False Das Objekt konnte nicht initialisiert werden
+*/
+
+{
+ ModifyBlocker_Impl aBlock( this );
+ pMedium = pMed;
+ if ( !pMedium )
+ {
+ bIsTmp = sal_True;
+ pMedium = new SfxMedium;
+ }
+
+ pMedium->CanDisposeStorage_Impl( sal_True );
+
+ if ( InitNew( pMed ? pMed->GetStorage() : uno::Reference < embed::XStorage >() ) )
+ {
+ // empty documents always get their macros from the user, so there is no reason to restrict access
+ pImp->aMacroMode.allowMacroExecution();
+ if ( SFX_CREATE_MODE_EMBEDDED == eCreateMode )
+ SetTitle( String( SfxResId( STR_NONAME ) ));
+
+ uno::Reference< frame::XModel > xModel ( GetModel(), uno::UNO_QUERY );
+ if ( xModel.is() )
+ {
+ SfxItemSet *pSet = GetMedium()->GetItemSet();
+ uno::Sequence< beans::PropertyValue > aArgs;
+ TransformItems( SID_OPENDOC, *pSet, aArgs );
+ sal_Int32 nLength = aArgs.getLength();
+ aArgs.realloc( nLength + 1 );
+ aArgs[nLength].Name = DEFINE_CONST_UNICODE("Title");
+ aArgs[nLength].Value <<= ::rtl::OUString( GetTitle( SFX_TITLE_DETECT ) );
+ xModel->attachResource( ::rtl::OUString(), aArgs );
+ impl_addToModelCollection(xModel);
+ }
+
+ SetInitialized_Impl( true );
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::ImportFromGeneratedStream_Impl(
+ const uno::Reference< io::XStream >& xStream,
+ const uno::Sequence< beans::PropertyValue >& aMediaDescr )
+{
+ if ( !xStream.is() )
+ return sal_False;
+
+ if ( pMedium && pMedium->HasStorage_Impl() )
+ pMedium->CloseStorage();
+
+ sal_Bool bResult = sal_False;
+
+ try
+ {
+ uno::Reference< embed::XStorage > xStorage =
+ ::comphelper::OStorageHelper::GetStorageFromStream( xStream, embed::ElementModes::READWRITE );
+
+ if ( !xStorage.is() )
+ throw uno::RuntimeException();
+
+ if ( !pMedium )
+ pMedium = new SfxMedium( xStorage, String() );
+ else
+ pMedium->SetStorage_Impl( xStorage );
+
+ SfxAllItemSet aSet( SFX_APP()->GetPool() );
+ TransformParameters( SID_OPENDOC, aMediaDescr, aSet );
+ pMedium->GetItemSet()->Put( aSet );
+ pMedium->CanDisposeStorage_Impl( sal_False );
+
+ // allow the subfilter to reinit the model
+ if ( pImp->m_bIsInit )
+ pImp->m_bIsInit = sal_False;
+
+ if ( LoadOwnFormat( *pMedium ) )
+ {
+ bHasName = sal_True;
+ if ( !IsReadOnly() && IsLoadReadonly() )
+ SetReadOnlyUI();
+
+ bResult = sal_True;
+ OSL_ENSURE( pImp->m_xDocStorage == xStorage, "Wrong storage is used!\n" );
+ }
+
+ // now the medium can be disconnected from the storage
+ // the medium is not allowed to dispose the storage so CloseStorage() can be used
+ pMedium->CloseStorage();
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return bResult;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed )
+{
+ ModifyBlocker_Impl aBlock( this );
+
+ if ( SFX_CREATE_MODE_EMBEDDED != eCreateMode )
+ GetpApp()->ShowStatusText( SfxResId(STR_DOC_LOADING) );
+
+ pMedium = pMed;
+ pMedium->CanDisposeStorage_Impl( sal_True );
+
+ sal_Bool bOk = sal_False;
+ const SfxFilter* pFilter = pMed->GetFilter();
+ SfxItemSet* pSet = pMedium->GetItemSet();
+ if( !pImp->nEventId )
+ {
+ SFX_ITEMSET_ARG(
+ pSet, pTemplateItem, SfxBoolItem,
+ SID_TEMPLATE, sal_False);
+ SetActivateEvent_Impl(
+ ( pTemplateItem && pTemplateItem->GetValue() )
+ ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC );
+ }
+
+
+ SFX_ITEMSET_ARG( pSet, pBaseItem, SfxStringItem,
+ SID_BASEURL, sal_False);
+ String aBaseURL;
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
+ if( pBaseItem )
+ aBaseURL = pBaseItem->GetValue();
+ else
+ {
+ if ( pSalvageItem )
+ {
+ String aName( pMed->GetPhysicalName() );
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aBaseURL );
+ }
+ else
+ aBaseURL = pMed->GetBaseURL();
+ }
+ pMed->GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL, aBaseURL ) );
+
+ pImp->nLoadedFlags = 0;
+ pImp->bModelInitialized = sal_False;
+
+ //TODO/LATER: make a clear strategy how to handle "UsesStorage" etc.
+ sal_Bool bOwnStorageFormat = IsOwnStorageFormat_Impl( *pMedium );
+ sal_Bool bHasStorage = IsPackageStorageFormat_Impl( *pMedium );
+ if ( pMedium->GetFilter() )
+ {
+ sal_uInt32 nError = HandleFilter( pMedium, this );
+ if ( nError != ERRCODE_NONE )
+ SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ EnableSetModified( sal_False );
+
+ pMedium->LockOrigFileOnDemand( sal_True, sal_False );
+ if ( GetError() == ERRCODE_NONE && bOwnStorageFormat && ( !pFilter || !( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) ) )
+ {
+ uno::Reference< embed::XStorage > xStorage;
+ if ( pMedium->GetError() == ERRCODE_NONE )
+ xStorage = pMedium->GetStorage();
+
+ if( xStorage.is() && pMedium->GetLastStorageCreationState() == ERRCODE_NONE )
+ {
+ DBG_ASSERT( pFilter, "No filter for storage found!" );
+
+ try
+ {
+ sal_Bool bWarnMediaTypeFallback = sal_False;
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pRepairPackageItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False);
+
+ // treat the package as broken if the mediatype was retrieved as a fallback
+ uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW );
+ xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaTypeFallbackUsed" ) ) )
+ >>= bWarnMediaTypeFallback;
+
+ if ( pRepairPackageItem && pRepairPackageItem->GetValue() )
+ {
+ // the macros in repaired documents should be disabled
+ pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, document::MacroExecMode::NEVER_EXECUTE ) );
+
+ // the mediatype was retrieved by using fallback solution but this is a repairing mode
+ // so it is acceptable to open the document if there is no contents that required manifest.xml
+ bWarnMediaTypeFallback = sal_False;
+ }
+
+ if ( bWarnMediaTypeFallback || !xStorage->getElementNames().getLength() )
+ SetError( ERRCODE_IO_BROKENPACKAGE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ catch( uno::Exception& )
+ {
+ // TODO/LATER: may need error code setting based on exception
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ // Load
+ if ( !GetError() )
+ {
+ pImp->nLoadedFlags = 0;
+ pImp->bModelInitialized = sal_False;
+ bOk = xStorage.is() && LoadOwnFormat( *pMed );
+ if ( bOk )
+ {
+ // the document loaded from template has no name
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
+ if ( !pTemplateItem || !pTemplateItem->GetValue() )
+ bHasName = sal_True;
+
+ if ( !IsReadOnly() && IsLoadReadonly() )
+ SetReadOnlyUI();
+ }
+ else
+ SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ else
+ SetError( pMed->GetLastStorageCreationState(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ else if ( GetError() == ERRCODE_NONE && InitNew(0) )
+ {
+ // Name vor ConvertFrom setzen, damit GetSbxObject() schon funktioniert
+ bHasName = sal_True;
+ SetName( SfxResId( STR_NONAME ) );
+
+ if( !bHasStorage )
+ pMedium->GetInStream();
+ else
+ pMedium->GetStorage();
+
+ if ( GetError() == ERRCODE_NONE )
+ {
+ pImp->nLoadedFlags = 0;
+ pImp->bModelInitialized = sal_False;
+ if ( pMedium->GetFilter() && ( pMedium->GetFilter()->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) )
+ {
+ uno::Reference < beans::XPropertySet > xSet( GetModel(), uno::UNO_QUERY );
+ ::rtl::OUString sLockUpdates(::rtl::OUString::createFromAscii("LockUpdates"));
+ bool bSetProperty = true;
+ try
+ {
+ xSet->setPropertyValue( sLockUpdates, makeAny( (sal_Bool) sal_True ) );
+ }
+ catch(const beans::UnknownPropertyException& )
+ {
+ bSetProperty = false;
+ }
+ bOk = ImportFrom(*pMedium);
+ if(bSetProperty)
+ {
+ try
+ {
+ xSet->setPropertyValue( sLockUpdates, makeAny( (sal_Bool) sal_False ) );
+ }
+ catch(const beans::UnknownPropertyException& )
+ {}
+ }
+ UpdateLinks();
+ FinishedLoading( SFX_LOADED_ALL );
+ }
+ else
+ {
+ bOk = ConvertFrom(*pMedium);
+ InitOwnModel_Impl();
+ }
+ }
+ }
+
+ if ( bOk )
+ {
+ try
+ {
+ ::ucbhelper::Content aContent( pMedium->GetName(), com::sun::star::uno::Reference < XCommandEnvironment >() );
+ com::sun::star::uno::Reference < XPropertySetInfo > xProps = aContent.getProperties();
+ if ( xProps.is() )
+ {
+ ::rtl::OUString aAuthor( RTL_CONSTASCII_USTRINGPARAM("Author") );
+ ::rtl::OUString aKeywords( RTL_CONSTASCII_USTRINGPARAM("Keywords") );
+ ::rtl::OUString aSubject( RTL_CONSTASCII_USTRINGPARAM("Subject") );
+ Any aAny;
+ ::rtl::OUString aValue;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ if ( xProps->hasPropertyByName( aAuthor ) )
+ {
+ aAny = aContent.getPropertyValue( aAuthor );
+ if ( ( aAny >>= aValue ) )
+ xDocProps->setAuthor(aValue);
+ }
+ if ( xProps->hasPropertyByName( aKeywords ) )
+ {
+ aAny = aContent.getPropertyValue( aKeywords );
+ if ( ( aAny >>= aValue ) )
+ xDocProps->setKeywords(
+ ::comphelper::string::convertCommaSeparated(aValue));
+;
+ }
+ if ( xProps->hasPropertyByName( aSubject ) )
+ {
+ aAny = aContent.getPropertyValue( aSubject );
+ if ( ( aAny >>= aValue ) ) {
+ xDocProps->setSubject(aValue);
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ // Falls nicht asynchron geladen wird selbst FinishedLoading aufrufen
+ if ( !( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) &&
+ ( !pMedium->GetFilter() || pMedium->GetFilter()->UsesStorage() )
+ )
+ FinishedLoading( SFX_LOADED_MAINDOCUMENT );
+
+ if( IsOwnStorageFormat_Impl(*pMed) && pMed->GetFilter() )
+ {
+//???? dv DirEntry aDirEntry( pMed->GetPhysicalName() );
+//???? dv SetFileName( aDirEntry.GetFull() );
+ }
+ Broadcast( SfxSimpleHint(SFX_HINT_NAMECHANGED) );
+
+ if ( SFX_CREATE_MODE_EMBEDDED != eCreateMode )
+ {
+ GetpApp()->HideStatusText();
+
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pAsTempItem, SfxBoolItem, SID_TEMPLATE, sal_False);
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False);
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False);
+ if( bOk && pMedium->GetOrigURL().Len()
+ && !( pAsTempItem && pAsTempItem->GetValue() )
+ && !( pPreviewItem && pPreviewItem->GetValue() )
+ && !( pHiddenItem && pHiddenItem->GetValue() ) )
+ {
+ INetURLObject aUrl( pMedium->GetOrigURL() );
+
+ if ( aUrl.GetProtocol() == INET_PROT_FILE )
+ {
+ const SfxFilter* pOrgFilter = pMedium->GetOrigFilter();
+ Application::AddToRecentDocumentList(
+ aUrl.GetURLNoPass( INetURLObject::NO_DECODE ),
+ (pOrgFilter) ? pOrgFilter->GetMimeType() : String() );
+ }
+ }
+ }
+
+ if ( pMedium->HasStorage_Impl() )
+ {
+ uno::Reference< XInteractionHandler > xHandler( pMedium->GetInteractionHandler() );
+ if ( xHandler.is() && !SFX_APP()->Get_Impl()->bODFVersionWarningLater )
+ {
+ uno::Reference<beans::XPropertySet> xStorageProps( pMedium->GetStorage(), uno::UNO_QUERY_THROW );
+ ::rtl::OUString sVersion;
+ try
+ {
+ xStorageProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= sVersion;
+ }
+ catch( const uno::Exception& )
+ {
+ // Custom Property "ODFVersion" does not exist
+ }
+
+ if ( sVersion.getLength() )
+ {
+ double nVersion = sVersion.toDouble();
+ if ( nVersion > 1.20001 && SfxObjectShell_Impl::NeedsOfficeUpdateDialog() )
+ // ODF version greater than 1.2 - added some decimal places to be safe against floating point conversion errors (hack)
+ {
+ ::rtl::OUString sDocumentURL( pMedium->GetOrigURL() );
+ ::rtl::OUString aSystemFileURL;
+ if ( osl::FileBase::getSystemPathFromFileURL( sDocumentURL, aSystemFileURL ) == osl::FileBase::E_None )
+ sDocumentURL = aSystemFileURL;
+
+ FutureDocumentVersionProductUpdateRequest aUpdateRequest;
+ aUpdateRequest.Classification = InteractionClassification_QUERY;
+ aUpdateRequest.DocumentURL = sDocumentURL;
+
+ ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest = new ::comphelper::OInteractionRequest( makeAny( aUpdateRequest ) );
+ pRequest->addContinuation( new ::comphelper::OInteractionApprove );
+ pRequest->addContinuation( new ::comphelper::OInteractionAbort );
+
+ typedef ::comphelper::OInteraction< XInteractionAskLater > OInteractionAskLater;
+ OInteractionAskLater* pLater = new OInteractionAskLater;
+ pRequest->addContinuation( pLater );
+
+ try
+ {
+ xHandler->handle( pRequest.get() );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ if ( pLater->wasSelected() )
+ SFX_APP()->Get_Impl()->bODFVersionWarningLater = true;
+ }
+ }
+ }
+ }
+ }
+ else
+ GetpApp()->HideStatusText();
+
+ return bOk;
+}
+
+sal_uInt32 SfxObjectShell::HandleFilter( SfxMedium* pMedium, SfxObjectShell* pDoc )
+{
+ sal_uInt32 nError = ERRCODE_NONE;
+ SfxItemSet* pSet = pMedium->GetItemSet();
+ SFX_ITEMSET_ARG( pSet, pOptions, SfxStringItem, SID_FILE_FILTEROPTIONS, sal_False );
+ SFX_ITEMSET_ARG( pSet, pData, SfxUnoAnyItem, SID_FILTER_DATA, sal_False );
+ if ( !pData && !pOptions )
+ {
+ com::sun::star::uno::Reference< XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+ com::sun::star::uno::Reference< XNameAccess > xFilterCFG;
+ if( xServiceManager.is() )
+ {
+ xFilterCFG = com::sun::star::uno::Reference< XNameAccess >(
+ xServiceManager->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
+ UNO_QUERY );
+ }
+
+ if( xFilterCFG.is() )
+ {
+ BOOL bAbort = FALSE;
+ try {
+ const SfxFilter* pFilter = pMedium->GetFilter();
+ Sequence < PropertyValue > aProps;
+ Any aAny = xFilterCFG->getByName( pFilter->GetName() );
+ if ( aAny >>= aProps )
+ {
+ sal_Int32 nPropertyCount = aProps.getLength();
+ for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty )
+ if( aProps[nProperty].Name.equals( ::rtl::OUString::createFromAscii("UIComponent")) )
+ {
+ ::rtl::OUString aServiceName;
+ aProps[nProperty].Value >>= aServiceName;
+ if( aServiceName.getLength() )
+ {
+ com::sun::star::uno::Reference< XInteractionHandler > rHandler = pMedium->GetInteractionHandler();
+ if( rHandler.is() )
+ {
+ // we need some properties in the media descriptor, so we have to make sure that they are in
+ Any aStreamAny;
+ aStreamAny <<= pMedium->GetInputStream();
+ if ( pSet->GetItemState( SID_INPUTSTREAM ) < SFX_ITEM_SET )
+ pSet->Put( SfxUnoAnyItem( SID_INPUTSTREAM, aStreamAny ) );
+ if ( pSet->GetItemState( SID_FILE_NAME ) < SFX_ITEM_SET )
+ pSet->Put( SfxStringItem( SID_FILE_NAME, pMedium->GetName() ) );
+ if ( pSet->GetItemState( SID_FILTER_NAME ) < SFX_ITEM_SET )
+ pSet->Put( SfxStringItem( SID_FILTER_NAME, pFilter->GetName() ) );
+
+ Sequence< PropertyValue > rProperties;
+ TransformItems( SID_OPENDOC, *pSet, rProperties, NULL );
+ RequestFilterOptions* pFORequest = new RequestFilterOptions( pDoc->GetModel(), rProperties );
+
+ com::sun::star::uno::Reference< XInteractionRequest > rRequest( pFORequest );
+ rHandler->handle( rRequest );
+
+ if ( !pFORequest->isAbort() )
+ {
+ SfxAllItemSet aNewParams( pDoc->GetPool() );
+ TransformParameters( SID_OPENDOC,
+ pFORequest->getFilterOptions(),
+ aNewParams,
+ NULL );
+
+ SFX_ITEMSET_ARG( &aNewParams,
+ pFilterOptions,
+ SfxStringItem,
+ SID_FILE_FILTEROPTIONS,
+ sal_False );
+ if ( pFilterOptions )
+ pSet->Put( *pFilterOptions );
+
+ SFX_ITEMSET_ARG( &aNewParams,
+ pFilterData,
+ SfxUnoAnyItem,
+ SID_FILTER_DATA,
+ sal_False );
+ if ( pFilterData )
+ pSet->Put( *pFilterData );
+ }
+ else
+ bAbort = TRUE;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if( bAbort )
+ {
+ // filter options were not entered
+ nError = ERRCODE_ABORT;
+ }
+ }
+ catch( NoSuchElementException& )
+ {
+ // the filter name is unknown
+ nError = ERRCODE_IO_INVALIDPARAMETER;
+ }
+ catch( Exception& )
+ {
+ nError = ERRCODE_ABORT;
+ }
+ }
+ }
+
+ return nError;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsOwnStorageFormat_Impl(const SfxMedium &rMedium) const
+{
+ return !rMedium.GetFilter() || // Embedded
+ ( rMedium.GetFilter()->IsOwnFormat() &&
+ rMedium.GetFilter()->UsesStorage() &&
+ rMedium.GetFilter()->GetVersion() >= SOFFICE_FILEFORMAT_60 );
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::IsPackageStorageFormat_Impl(const SfxMedium &rMedium) const
+{
+ return !rMedium.GetFilter() || // Embedded
+ ( rMedium.GetFilter()->UsesStorage() &&
+ rMedium.GetFilter()->GetVersion() >= SOFFICE_FILEFORMAT_60 );
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::DoSave()
+// DoSave wird nur noch ueber OLE aufgerufen. Sichern eigener Dokumente im SFX
+// laeuft uber DoSave_Impl, um das Anlegen von Backups zu ermoeglichen.
+// Save in eigenes Format jetzt auch wieder Hierueber
+{
+ sal_Bool bOk = sal_False ;
+ {
+ ModifyBlocker_Impl aBlock( this );
+
+ pImp->bIsSaving = sal_True;
+
+ ::rtl::OUString aPasswd;
+ if ( IsPackageStorageFormat_Impl( *GetMedium() ) )
+ {
+ if ( GetPasswd_Impl( GetMedium()->GetItemSet(), aPasswd ) )
+ {
+ try
+ {
+ //TODO/MBA: GetOutputStorage?! Special mode, because it's "Save"?!
+ ::comphelper::OStorageHelper::SetCommonStoragePassword( GetMedium()->GetStorage(), aPasswd );
+ bOk = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+
+ DBG_ASSERT( bOk, "The root storage must allow to set common password!\n" );
+ }
+ else
+ bOk = sal_True;
+
+ if ( HasBasic() )
+ {
+ try
+ {
+ // The basic and dialogs related contents are still not able to proceed with save operation ( saveTo only )
+ // so since the document storage is locked a workaround has to be used
+
+ uno::Reference< embed::XStorage > xTmpStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
+ DBG_ASSERT( xTmpStorage.is(), "If a storage can not be created an exception must be thrown!\n" );
+ if ( !xTmpStorage.is() )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aBasicStorageName( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) );
+ ::rtl::OUString aDialogsStorageName( RTL_CONSTASCII_USTRINGPARAM( "Dialogs" ) );
+ if ( GetMedium()->GetStorage()->hasByName( aBasicStorageName ) )
+ GetMedium()->GetStorage()->copyElementTo( aBasicStorageName, xTmpStorage, aBasicStorageName );
+ if ( GetMedium()->GetStorage()->hasByName( aDialogsStorageName ) )
+ GetMedium()->GetStorage()->copyElementTo( aDialogsStorageName, xTmpStorage, aDialogsStorageName );
+
+ GetBasicManager();
+
+ // disconnect from the current storage
+ pImp->pBasicManager->setStorage( xTmpStorage );
+
+ // store to the current storage
+ pImp->pBasicManager->storeLibrariesToStorage( GetMedium()->GetStorage() );
+
+ // connect to the current storage back
+ pImp->pBasicManager->setStorage( GetMedium()->GetStorage() );
+ }
+ catch( uno::Exception& )
+ {
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ bOk = sal_False;
+ }
+ }
+ }
+
+ if ( bOk )
+ bOk = Save();
+
+ bOk = pMedium->Commit();
+ }
+
+//#88046
+// if ( bOk )
+// SetModified( sal_False );
+ return bOk;
+}
+
+void Lock_Impl( SfxObjectShell* pDoc, BOOL bLock )
+{
+ SfxViewFrame *pFrame= SfxViewFrame::GetFirst( pDoc );
+ while ( pFrame )
+ {
+ pFrame->GetDispatcher()->Lock( bLock );
+ pFrame->Enable( !bLock );
+ pFrame = SfxViewFrame::GetNext( *pFrame, pDoc );
+ }
+
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::SaveTo_Impl
+(
+ SfxMedium &rMedium, // Medium, in das gespeichert werden soll
+ const SfxItemSet* pSet
+)
+
+/* [Beschreibung]
+
+ Schreibt den aktuellen Inhalt in das Medium rMedium.
+ Ist das Zielmedium kein Storage, so wird ueber ein temporaeres
+ Medium gespeichert, sonst direkt, da das Medium transacted
+ geschaltet ist, wenn wir es selbst geoeffnet haben und falls wir
+ Server sind entweder der Container einen transacted Storage zur
+ Verfuegung stellt oder selbst einen temporaeren Storage erzeugt hat.
+*/
+
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE SfxObjectShell::SaveTo_Impl" );
+ if( RTL_LOGFILE_HASLOGFILE() )
+ {
+ ByteString aString( rMedium.GetName(), RTL_TEXTENCODING_ASCII_US );
+ RTL_LOGFILE_PRODUCT_CONTEXT_TRACE1( aLog, "saving \"%s\"", aString.GetBuffer() );
+ }
+
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Begin" ) ) );
+
+ ModifyBlocker_Impl aMod(this);
+
+ const SfxFilter *pFilter = rMedium.GetFilter();
+ if ( !pFilter )
+ {
+ // if no filter was set, use the default filter
+ // this should be changed in the feature, it should be an error!
+ DBG_ERROR("No filter set!");
+ pFilter = GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_IMPORT | SFX_FILTER_EXPORT );
+ rMedium.SetFilter(pFilter);
+ }
+
+ sal_Bool bStorageBasedSource = IsPackageStorageFormat_Impl( *pMedium );
+ sal_Bool bStorageBasedTarget = IsPackageStorageFormat_Impl( rMedium );
+ sal_Bool bOwnSource = IsOwnStorageFormat_Impl( *pMedium );
+ sal_Bool bOwnTarget = IsOwnStorageFormat_Impl( rMedium );
+
+ // Examine target format to determine whether to query if any password
+ // protected libraries exceed the size we can handler
+ if ( bOwnTarget && !QuerySaveSizeExceededModules_Impl( rMedium.GetInteractionHandler() ) )
+ {
+ SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return sal_False;
+ }
+
+ sal_Bool bNeedsDisconnectionOnFail = sal_False;
+
+ sal_Bool bStoreToSameLocation = sal_False;
+
+ // the detection whether the script is changed should be done before saving
+ sal_Bool bTryToPreserveScriptSignature = sal_False;
+ // no way to detect whether a filter is oasis format, have to wait for saving process
+ sal_Bool bNoPreserveForOasis = sal_False;
+ if ( bOwnSource && bOwnTarget
+ && ( pImp->nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK
+ || pImp->nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED
+ || pImp->nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_INVALID ) )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "MacroSignaturePreserving" ) ) );
+
+ // the checking of the library modified state iterates over the libraries, should be done only when required
+ // currently the check is commented out since it is broken, we have to check the signature every time we save
+ // TODO/LATER: let isAnyContainerModified() work!
+ bTryToPreserveScriptSignature = sal_True; // !pImp->pBasicManager->isAnyContainerModified();
+ if ( bTryToPreserveScriptSignature )
+ {
+ // check that the storage format stays the same
+ SvtSaveOptions aSaveOpt;
+ SvtSaveOptions::ODFDefaultVersion nVersion = aSaveOpt.GetODFDefaultVersion();
+
+ ::rtl::OUString aODFVersion;
+ try
+ {
+ uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aODFVersion;
+ }
+ catch( uno::Exception& )
+ {}
+
+ // preserve only if the same filter has been used
+ bTryToPreserveScriptSignature = pMedium->GetFilter() && pFilter && pMedium->GetFilter()->GetFilterName() == pFilter->GetFilterName();
+
+ bNoPreserveForOasis = (
+ (aODFVersion.equals( ODFVER_012_TEXT ) && nVersion == SvtSaveOptions::ODFVER_011) ||
+ (!aODFVersion.getLength() && nVersion >= SvtSaveOptions::ODFVER_012)
+ );
+ }
+ }
+
+ sal_Bool bCopyTo = sal_False;
+ SfxItemSet *pMedSet = rMedium.GetItemSet();
+ if( pMedSet )
+ {
+ SFX_ITEMSET_ARG( pMedSet, pSaveToItem, SfxBoolItem, SID_SAVETO, sal_False );
+ bCopyTo = GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ||
+ (pSaveToItem && pSaveToItem->GetValue());
+ }
+
+ // use UCB for case sensitive/insensitive file name comparison
+ if ( pMedium
+ && pMedium->GetName().CompareIgnoreCaseToAscii( "private:stream", 14 ) != COMPARE_EQUAL
+ && rMedium.GetName().CompareIgnoreCaseToAscii( "private:stream", 14 ) != COMPARE_EQUAL
+ && SfxMedium::EqualURLs( pMedium->GetName(), rMedium.GetName() ) )
+ {
+ bStoreToSameLocation = sal_True;
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save" ) ) );
+
+ if ( pMedium->DocNeedsFileDateCheck() )
+ rMedium.CheckFileDate( pMedium->GetInitFileDate( sal_False ) );
+
+ if ( bCopyTo && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
+ {
+ // export to the same location is vorbidden
+ SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ else
+ {
+ // before we overwrite the original file, we will make a backup if there is a demand for that
+ // if the backup is not created here it will be created internally and will be removed in case of successful saving
+ const sal_Bool bDoBackup = SvtSaveOptions().IsBackup();
+ if ( bDoBackup )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "DoBackup" ) ) );
+ rMedium.DoBackup_Impl();
+ if ( rMedium.GetError() )
+ {
+ SetError( rMedium.GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ rMedium.ResetError();
+ }
+ }
+
+ if ( bStorageBasedSource && bStorageBasedTarget )
+ {
+ // The active storage must be switched. The simple saving is not enough.
+ // The problem is that the target medium contains target MediaDescriptor.
+
+ // In future the switch of the persistance could be done on stream level:
+ // a new wrapper service will be implemented that allows to exchange
+ // persistance on the fly. So the real persistance will be set
+ // to that stream only after successful commit of the storage.
+ // TODO/LATER:
+ // create wrapper stream based on the URL
+ // create a new storage based on this stream
+ // store to this new storage
+ // commit the new storage
+ // call saveCompleted based with this new storage ( get rid of old storage and "frees" URL )
+ // commit the wrapper stream ( the stream will connect the URL only on commit, after that it will hold it )
+ // if the last step is failed the stream should stay to be transacted and should be commited on any flush
+ // so we can forget the stream in any way and the next storage commit will flush it
+
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save: Own to Own" ) ) );
+
+ bNeedsDisconnectionOnFail = DisconnectStorage_Impl(
+ *pMedium, rMedium );
+ if ( bNeedsDisconnectionOnFail
+ || ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
+ {
+ pMedium->CloseAndRelease();
+
+ // TODO/LATER: for now the medium must be closed since it can already contain streams from old medium
+ // in future those streams should not be copied in case a valid target url is provided,
+ // if the url is not provided ( means the document is based on a stream ) this code is not
+ // reachable.
+ rMedium.CloseAndRelease();
+ rMedium.GetOutputStorage();
+ }
+ }
+ else if ( !bStorageBasedSource && !bStorageBasedTarget )
+ {
+ // the source and the target formats are alien
+ // just disconnect the stream from the source format
+ // so that the target medium can use it
+
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save: Alien to Alien" ) ) );
+
+ pMedium->CloseAndRelease();
+ rMedium.CloseAndRelease();
+ rMedium.CreateTempFileNoCopy();
+ rMedium.GetOutStream();
+ }
+ else if ( !bStorageBasedSource && bStorageBasedTarget )
+ {
+ // the source format is an alien one but the target
+ // format is an own one so just disconnect the source
+ // medium
+
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save: Alien to Own" ) ) );
+
+ pMedium->CloseAndRelease();
+ rMedium.CloseAndRelease();
+ rMedium.GetOutputStorage();
+ }
+ else // means if ( bStorageBasedSource && !bStorageBasedTarget )
+ {
+ // the source format is an own one but the target is
+ // an alien format, just connect the source to temporary
+ // storage
+
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save: Own to Alien" ) ) );
+
+ bNeedsDisconnectionOnFail = DisconnectStorage_Impl(
+ *pMedium, rMedium );
+ if ( bNeedsDisconnectionOnFail
+ || ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
+ {
+ pMedium->CloseAndRelease();
+ rMedium.CloseAndRelease();
+ rMedium.CreateTempFileNoCopy();
+ rMedium.GetOutStream();
+ }
+ }
+ }
+ }
+ else
+ {
+ // This is SaveAs or export action, prepare the target medium
+ // the alien filters still might write directly to the file, that is of course a bug,
+ // but for now the framework has to be ready for it
+ // TODO/LATER: let the medium be prepared for alien formats as well
+
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "SaveAs/Export" ) ) );
+
+ rMedium.CloseAndRelease();
+ if ( bStorageBasedTarget )
+ {
+ rMedium.GetOutputStorage();
+ }
+ }
+
+ // TODO/LATER: error handling
+ if( rMedium.GetErrorCode() || pMedium->GetErrorCode() || GetErrorCode() )
+ return sal_False;
+
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Locking" ) ) );
+
+ rMedium.LockOrigFileOnDemand( sal_False, sal_False );
+
+ if ( bStorageBasedTarget )
+ {
+ if ( rMedium.GetErrorCode() )
+ return sal_False;
+
+ // If the filter is a "cross export" filter ( f.e. a filter for exporting an impress document from
+ // a draw document ), the ClassId of the destination storage is different from the ClassId of this
+ // document. It can be retrieved from the default filter for the desired target format
+ long nFormat = rMedium.GetFilter()->GetFormat();
+ SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher();
+ const SfxFilter *pFilt = rMatcher.GetFilter4ClipBoardId( nFormat );
+ if ( pFilt )
+ {
+ if ( pFilt->GetServiceName() != rMedium.GetFilter()->GetServiceName() )
+ {
+ datatransfer::DataFlavor aDataFlavor;
+ SotExchange::GetFormatDataFlavor( nFormat, aDataFlavor );
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps( rMedium.GetStorage(), uno::UNO_QUERY );
+ DBG_ASSERT( xProps.is(), "The storage implementation must implement XPropertySet!" );
+ if ( !xProps.is() )
+ throw uno::RuntimeException();
+
+ xProps->setPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ),
+ uno::makeAny( aDataFlavor.MimeType ) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+
+ // TODO/LATER: error handling
+ if( rMedium.GetErrorCode() || pMedium->GetErrorCode() || GetErrorCode() )
+ return sal_False;
+
+ sal_Bool bOldStat = pImp->bForbidReload;
+ pImp->bForbidReload = sal_True;
+
+ // lock user interface while saving the document
+ Lock_Impl( this, sal_True );
+
+ sal_Bool bOk = sal_False;
+ // TODO/LATER: get rid of bOk
+
+ if( bOwnTarget && !( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing in own format." ) ) );
+ uno::Reference< embed::XStorage > xMedStorage = rMedium.GetStorage();
+ if ( !xMedStorage.is() )
+ {
+ // no saving without storage, unlock UI and return
+ Lock_Impl( this, sal_False );
+ pImp->bForbidReload = bOldStat;
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing failed, still no error set." ) ) );
+ return sal_False;
+ }
+
+ // transfer password from the parameters to the storage
+ ::rtl::OUString aPasswd;
+ sal_Bool bPasswdProvided = sal_False;
+ if ( GetPasswd_Impl( rMedium.GetItemSet(), aPasswd ) )
+ {
+ bPasswdProvided = sal_True;
+ try {
+ ::comphelper::OStorageHelper::SetCommonStoragePassword( xMedStorage, aPasswd );
+ bOk = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ DBG_ERROR( "Setting of common encryption key failed!" );
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+ else
+ bOk = sal_True;
+
+ pFilter = rMedium.GetFilter();
+
+ const SfxStringItem *pVersionItem = pSet ? (const SfxStringItem*)
+ SfxRequest::GetItem( pSet, SID_DOCINFO_COMMENTS, sal_False, TYPE(SfxStringItem) ) : NULL;
+ ::rtl::OUString aTmpVersionURL;
+
+ if ( bOk )
+ {
+ bOk = sal_False;
+ // currently the case that the storage is the same should be impossible
+ if ( xMedStorage == GetStorage() )
+ {
+ OSL_ENSURE( !pVersionItem, "This scenario is impossible currently!\n" );
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Should be impossible." ) ) );
+ // usual save procedure
+ bOk = Save();
+ }
+ else
+ {
+ // save to target
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save as own format." ) ) );
+ bOk = SaveAsOwnFormat( rMedium );
+ if ( bOk && pVersionItem )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "pVersionItem != NULL" ) ) );
+ aTmpVersionURL = CreateTempCopyOfStorage_Impl( xMedStorage );
+ bOk = ( aTmpVersionURL.getLength() > 0 );
+ }
+ }
+ }
+
+
+ if ( bOk && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED && !bPasswdProvided )
+ {
+ // store the thumbnail representation image
+ // the thumbnail is not stored in case of encrypted document
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Thumbnail creation." ) ) );
+ if ( !GenerateAndStoreThumbnail( bPasswdProvided,
+ sal_False,
+ pFilter->IsOwnTemplateFormat(),
+ xMedStorage ) )
+ {
+ // TODO: error handling
+ OSL_ENSURE( sal_False, "Couldn't store thumbnail representation!" );
+ }
+ }
+
+ if ( bOk )
+ {
+ if ( pImp->bIsSaving || pImp->bPreserveVersions )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Preserve versions." ) ) );
+ try
+ {
+ Sequence < util::RevisionTag > aVersions = rMedium.GetVersionList();
+ if ( aVersions.getLength() )
+ {
+ // copy the version streams
+ ::rtl::OUString aVersionsName( RTL_CONSTASCII_USTRINGPARAM( "Versions" ) );
+ uno::Reference< embed::XStorage > xNewVerStor = xMedStorage->openStorageElement(
+ aVersionsName,
+ embed::ElementModes::READWRITE );
+ uno::Reference< embed::XStorage > xOldVerStor = GetStorage()->openStorageElement(
+ aVersionsName,
+ embed::ElementModes::READ );
+ if ( !xNewVerStor.is() || !xOldVerStor.is() )
+ throw uno::RuntimeException();
+
+ for ( sal_Int32 n=0; n<aVersions.getLength(); n++ )
+ {
+ if ( xOldVerStor->hasByName( aVersions[n].Identifier ) )
+ xOldVerStor->copyElementTo( aVersions[n].Identifier, xNewVerStor, aVersions[n].Identifier );
+ }
+
+ uno::Reference< embed::XTransactedObject > xTransact( xNewVerStor, uno::UNO_QUERY );
+ if ( xTransact.is() )
+ xTransact->commit();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Preserve versions has failed." ) ) );
+ DBG_ERROR( "Couldn't copy versions!\n" );
+ bOk = sal_False;
+ // TODO/LATER: a specific error could be set
+ }
+ }
+
+ if ( bOk && pVersionItem )
+ {
+ // store a version also
+ const SfxStringItem *pAuthorItem = pSet ? (const SfxStringItem*)
+ SfxRequest::GetItem( pSet, SID_DOCINFO_AUTHOR, sal_False, TYPE(SfxStringItem) ) : NULL;
+
+ // version comment
+ util::RevisionTag aInfo;
+ aInfo.Comment = pVersionItem->GetValue();
+
+ // version author
+ String aAuthor;
+ if ( pAuthorItem )
+ aInfo.Author = pAuthorItem->GetValue();
+ else
+ // if not transferred as a parameter, get it from user settings
+ aInfo.Author = SvtUserOptions().GetFullName();
+
+ DateTime aTime;
+ aInfo.TimeStamp.Day = aTime.GetDay();
+ aInfo.TimeStamp.Month = aTime.GetMonth();
+ aInfo.TimeStamp.Year = aTime.GetYear();
+ aInfo.TimeStamp.Hours = aTime.GetHour();
+ aInfo.TimeStamp.Minutes = aTime.GetMin();
+ aInfo.TimeStamp.Seconds = aTime.GetSec();
+
+ if ( bOk )
+ {
+ // add new version information into the versionlist and save the versionlist
+ // the version list must have been transferred from the "old" medium before
+ rMedium.AddVersion_Impl( aInfo );
+ rMedium.SaveVersionList_Impl( sal_True );
+ bOk = PutURLContentsToVersionStream_Impl( aTmpVersionURL, xMedStorage, aInfo.Identifier );
+ }
+ }
+ else if ( bOk && ( pImp->bIsSaving || pImp->bPreserveVersions ) )
+ {
+ rMedium.SaveVersionList_Impl( sal_True );
+ }
+ }
+
+ if ( aTmpVersionURL.getLength() )
+ ::utl::UCBContentHelper::Kill( aTmpVersionURL );
+ }
+ else
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing in alien format." ) ) );
+ // it's a "SaveAs" in an alien format
+ if ( rMedium.GetFilter() && ( rMedium.GetFilter()->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) )
+ bOk = ExportTo( rMedium );
+ else
+ bOk = ConvertTo( rMedium );
+
+ // after saving the document, the temporary object storage must be updated
+ // if the old object storage was not a temporary one, it will be updated also, because it will be used
+ // as a source for copying the objects into the new temporary storage that will be created below
+ // updating means: all child objects must be stored into it
+ // ( same as on loading, where these objects are copied to the temporary storage )
+ // but don't commit these changes, because in the case when the old object storage is not a temporary one,
+ // all changes will be written into the original file !
+
+ if( bOk && !bCopyTo )
+ // we also don't touch any graphical replacements here
+ bOk = SaveChildren( TRUE );
+ }
+
+ if ( bOk )
+ {
+ // if ODF version of oasis format changes on saving the signature should not be preserved
+ if ( bOk && bTryToPreserveScriptSignature && bNoPreserveForOasis )
+ bTryToPreserveScriptSignature = ( SotStorage::GetVersion( rMedium.GetStorage() ) == SOFFICE_FILEFORMAT_60 );
+
+ uno::Reference< security::XDocumentDigitalSignatures > xDDSigns;
+ if ( bOk && bTryToPreserveScriptSignature )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Copying scripting signature." ) ) );
+
+ // if the scripting code was not changed and it is signed the signature should be preserved
+ // unfortunately at this point we have only information whether the basic code has changed or not
+ // so the only way is to check the signature if the basic was not changed
+ try
+ {
+ // get the ODF version of the new medium
+ uno::Sequence< uno::Any > aArgs( 1 );
+ aArgs[0] <<= ::rtl::OUString();
+ try
+ {
+ uno::Reference < beans::XPropertySet > xPropSet( rMedium.GetStorage(), uno::UNO_QUERY_THROW );
+ aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ xDDSigns = uno::Reference< security::XDocumentDigitalSignatures >(
+ comphelper::getProcessServiceFactory()->createInstanceWithArguments(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ),
+ aArgs ),
+ uno::UNO_QUERY_THROW );
+
+ ::rtl::OUString aScriptSignName = xDDSigns->getScriptingContentSignatureDefaultStreamName();
+
+ if ( aScriptSignName.getLength() )
+ {
+ pMedium->Close();
+
+ // target medium is still not commited, it should not be closed
+ // commit the package storage and close it, but leave the streams open
+ rMedium.StorageCommit_Impl();
+ rMedium.CloseStorage();
+
+ uno::Reference< embed::XStorage > xReadOrig = pMedium->GetZipStorageToSign_Impl();
+ if ( !xReadOrig.is() )
+ throw uno::RuntimeException();
+ uno::Reference< embed::XStorage > xMetaInf = xReadOrig->openStorageElement(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ),
+ embed::ElementModes::READ );
+
+ uno::Reference< embed::XStorage > xTarget = rMedium.GetZipStorageToSign_Impl( sal_False );
+ if ( !xTarget.is() )
+ throw uno::RuntimeException();
+ uno::Reference< embed::XStorage > xTargetMetaInf = xTarget->openStorageElement(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ),
+ embed::ElementModes::READWRITE );
+
+ if ( xMetaInf.is() && xTargetMetaInf.is() )
+ {
+ xMetaInf->copyElementTo( aScriptSignName, xTargetMetaInf, aScriptSignName );
+
+ uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY );
+ if ( xTransact.is() )
+ xTransact->commit();
+
+ xTargetMetaInf->dispose();
+
+ // now check the copied signature
+ uno::Sequence< security::DocumentSignatureInformation > aInfos =
+ xDDSigns->verifyScriptingContentSignatures( xTarget,
+ uno::Reference< io::XInputStream >() );
+ sal_uInt16 nState = ImplCheckSignaturesInformation( aInfos );
+ if ( nState == SIGNATURESTATE_SIGNATURES_OK || nState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED
+ || nState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK)
+ {
+ rMedium.SetCachedSignatureState_Impl( nState );
+
+ // commit the ZipStorage from target medium
+ xTransact.set( xTarget, uno::UNO_QUERY );
+ if ( xTransact.is() )
+ xTransact->commit();
+ }
+ else
+ {
+ // it should not happen, the copies signature is invalid!
+ // throw the changes away
+ OSL_ASSERT( "An invalid signature was copied!" );
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ pMedium->Close();
+ rMedium.CloseZipStorage_Impl();
+ }
+
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Medium commit." ) ) );
+
+ // transfer data to its destinated location
+ // the medium commits the storage or the stream it is based on
+ RegisterTransfer( rMedium );
+ bOk = rMedium.Commit();
+
+ if ( bOk )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing is successful." ) ) );
+
+ // if the target medium is an alien format and the "old" medium was an own format and the "old" medium
+ // has a name, the object storage must be exchanged, because now we need a new temporary storage
+ // as object storage
+ if ( !bCopyTo && bStorageBasedSource && !bStorageBasedTarget )
+ {
+ if ( bStoreToSameLocation )
+ {
+ // if the old medium already disconnected from document storage, the storage still must
+ // be switched if backup file is used
+ if ( bNeedsDisconnectionOnFail )
+ ConnectTmpStorage_Impl( pImp->m_xDocStorage, NULL );
+ }
+ else if ( pMedium->GetName().Len()
+ || ( pMedium->HasStorage_Impl() && pMedium->WillDisposeStorageOnClose_Impl() ) )
+ {
+ OSL_ENSURE( pMedium->GetName().Len(), "Fallback is used, the medium without name should not dispose the storage!\n" );
+ // copy storage of old medium to new temporary storage and take this over
+ if( !ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Process after storing has failed." ) ) );
+ bOk = sal_False;
+ }
+ }
+ }
+ }
+ else
+ {
+ AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing has failed." ) ) );
+
+ // in case the document storage was connected to backup temporarely it must be disconnected now
+ if ( bNeedsDisconnectionOnFail )
+ ConnectTmpStorage_Impl( pImp->m_xDocStorage, NULL );
+ }
+ }
+
+ // unlock user interface
+ Lock_Impl( this, sal_False );
+ pImp->bForbidReload = bOldStat;
+
+ if ( bOk )
+ {
+ try
+ {
+ ::ucbhelper::Content aContent( rMedium.GetName(), com::sun::star::uno::Reference < XCommandEnvironment >() );
+ com::sun::star::uno::Reference < XPropertySetInfo > xProps = aContent.getProperties();
+ if ( xProps.is() )
+ {
+ ::rtl::OUString aAuthor( RTL_CONSTASCII_USTRINGPARAM("Author") );
+ ::rtl::OUString aKeywords( RTL_CONSTASCII_USTRINGPARAM("Keywords") );
+ ::rtl::OUString aSubject( RTL_CONSTASCII_USTRINGPARAM("Subject") );
+ Any aAny;
+
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+
+ if ( xProps->hasPropertyByName( aAuthor ) )
+ {
+ aAny <<= xDocProps->getAuthor();
+ aContent.setPropertyValue( aAuthor, aAny );
+ }
+ if ( xProps->hasPropertyByName( aKeywords ) )
+ {
+ aAny <<= ::comphelper::string::convertCommaSeparated(
+ xDocProps->getKeywords());
+ aContent.setPropertyValue( aKeywords, aAny );
+ }
+ if ( xProps->hasPropertyByName( aSubject ) )
+ {
+ aAny <<= xDocProps->getSubject();
+ aContent.setPropertyValue( aSubject, aAny );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+#ifdef OS2
+ {
+#define CHAR_POINTER(THE_OUSTRING) ::rtl::OUStringToOString (THE_OUSTRING, RTL_TEXTENCODING_UTF8).pData->buffer
+ // Header for a single-valued ASCII EA data item
+ typedef struct _EA_ASCII_header {
+ USHORT usAttr; /* value: EAT_ASCII */
+ USHORT usLen; /* length of data */
+ CHAR szType[_MAX_PATH]; /* ASCII data fits in here ... */
+ } EA_ASCII_HEADER;
+ char filePath[_MAX_PATH];
+ char fileExt[_MAX_PATH];
+ char docType[_MAX_PATH];
+ int rc;
+ oslFileError eRet;
+ ::rtl::OUString aSystemFileURL;
+ const ::rtl::OUString aFileURL = rMedium.GetName();
+ // close medium
+ rMedium.Close();
+
+ // convert file URL to system path
+ if (osl::FileBase::getSystemPathFromFileURL( aFileURL, aSystemFileURL) == osl::FileBase::E_None) {
+ EA_ASCII_HEADER eaAscii;
+ struct _ea eaType;
+ strcpy( filePath, CHAR_POINTER( aSystemFileURL));
+ strcpy( docType, CHAR_POINTER( rMedium.GetFilter()->GetServiceName()));
+#if OSL_DEBUG_LEVEL>1
+ printf( "file name: %s\n", filePath);
+ printf( "filter name: %s\n", CHAR_POINTER(rMedium.GetFilter()->GetFilterName()));
+ printf( "service name: %s\n", docType);
+#endif
+ // initialize OS/2 EA data structure
+ eaAscii.usAttr = EAT_ASCII;
+ _splitpath ( filePath, NULL, NULL, NULL, fileExt);
+ if (!stricmp( fileExt, ".pdf"))
+ strcpy( eaAscii.szType, "Acrobat Document");
+ else if (!strcmp( docType, "com.sun.star.text.TextDocument"))
+ strcpy( eaAscii.szType, "OpenOfficeOrg Writer Document");
+ else if (!strcmp( docType, "com.sun.star.sheet.SpreadsheetDocument"))
+ strcpy( eaAscii.szType, "OpenOfficeOrg Calc Document");
+ else if (!strcmp( docType, "com.sun.star.presentation.PresentationDocument"))
+ strcpy( eaAscii.szType, "OpenOfficeOrg Impress Document");
+ else if (!strcmp( docType, "com.sun.star.drawing.DrawingDocument"))
+ strcpy( eaAscii.szType, "OpenOfficeOrg Draw Document");
+ else
+ strcpy( eaAscii.szType, "OpenOfficeOrg Document");
+ eaAscii.usLen = strlen( eaAscii.szType);
+ // fill libc EA data structure
+ eaType.flags = 0;
+ eaType.size = sizeof(USHORT)*2 + eaAscii.usLen;
+ eaType.value = &eaAscii;
+ // put EA to file
+ rc = _ea_put( &eaType, filePath, 0, ".TYPE");
+#if OSL_DEBUG_LEVEL>1
+ printf( "ea name: %s, rc %d, errno %d\n", eaAscii.szType, rc, errno);
+#endif
+ }
+ }
+#endif
+
+ }
+
+ return bOk;
+}
+
+//------------------------------------------------------------------------
+sal_Bool SfxObjectShell::DisconnectStorage_Impl( SfxMedium& rSrcMedium, SfxMedium& rTargetMedium )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::DisconnectStorage_Impl" );
+
+ // this method disconnects the storage from source medium, and attaches it to the backup created by the target medium
+
+ uno::Reference< embed::XStorage > xStorage = rSrcMedium.GetStorage();
+
+ sal_Bool bResult = sal_False;
+ if ( xStorage == pImp->m_xDocStorage )
+ {
+ try
+ {
+ uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY_THROW );
+ ::rtl::OUString aBackupURL = rTargetMedium.GetBackup_Impl();
+ if ( !aBackupURL.getLength() )
+ {
+ // the backup could not be created, try to disconnect the storage and close the source SfxMedium
+ // in this case the optimization is not possible, connect storage to a temporary file
+ rTargetMedium.ResetError();
+ xOptStorage->writeAndAttachToStream( uno::Reference< io::XStream >() );
+ rSrcMedium.CanDisposeStorage_Impl( sal_False );
+ rSrcMedium.Close();
+
+ // now try to create the backup
+ rTargetMedium.GetBackup_Impl();
+ }
+ else
+ {
+ // the following call will only compare stream sizes
+ // TODO/LATER: this is a very risky part, since if the URL contents are different from the storage
+ // contents, the storag will be broken
+ xOptStorage->attachToURL( aBackupURL, sal_True );
+
+ // the storage is successfuly attached to backup, thus it it owned by the document not by the medium
+ rSrcMedium.CanDisposeStorage_Impl( sal_False );
+ bResult = sal_True;
+ }
+ }
+ catch ( uno::Exception& )
+ {}
+ }
+
+ OSL_ENSURE( bResult, "Storage disconnecting has failed - affects performance!" );
+
+ return bResult;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::ConnectTmpStorage_Impl(
+ const uno::Reference< embed::XStorage >& xStorage,
+ SfxMedium* pMediumArg )
+
+/* [Beschreibung]
+
+ Arbeitet die Applikation auf einem temporaeren Storage,
+ so darf der temporaere Storage nicht aus dem SaveCompleted
+ genommen werden. Daher wird in diesem Fall schon hier an
+ den neuen Storage connected. SaveCompleted tut dann nichts.
+
+ */
+
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::ConnectTmpStorage_Impl" );
+
+ sal_Bool bResult = sal_False;
+
+ if ( xStorage.is() )
+ {
+ try
+ {
+ // the empty argument means that the storage will create temporary stream itself
+ uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY_THROW );
+ xOptStorage->writeAndAttachToStream( uno::Reference< io::XStream >() );
+
+ // the storage is successfuly disconnected from the original sources, thus the medium must not dispose it
+ if ( pMediumArg )
+ pMediumArg->CanDisposeStorage_Impl( sal_False );
+
+ bResult = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ // if switching of the storage does not work for any reason ( nonroot storage for example ) use the old method
+ if ( !bResult ) try
+ {
+ uno::Reference< embed::XStorage > xTmpStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
+
+ DBG_ASSERT( xTmpStorage.is(), "If a storage can not be created an exception must be thrown!\n" );
+ if ( !xTmpStorage.is() )
+ throw uno::RuntimeException();
+
+ // TODO/LATER: may be it should be done in SwitchPersistence also
+ // TODO/LATER: find faster way to copy storage; perhaps sharing with backup?!
+ xStorage->copyToStorage( xTmpStorage );
+ //CopyStoragesOfUnknownMediaType( xStorage, xTmpStorage );
+ bResult = SaveCompleted( xTmpStorage );
+
+ if ( bResult )
+ pImp->pBasicManager->setStorage( xTmpStorage );
+ }
+ catch( uno::Exception& )
+ {}
+
+ if ( !bResult )
+ {
+ // TODO/LATER: may need error code setting based on exception
+ SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+
+ return bResult;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::DoSaveObjectAs( SfxMedium& rMedium, BOOL bCommit )
+{
+ sal_Bool bOk = sal_False;
+ {
+ ModifyBlocker_Impl aBlock( this );
+
+ uno::Reference < embed::XStorage > xNewStor = rMedium.GetStorage();
+ if ( !xNewStor.is() )
+ return sal_False;
+
+ uno::Reference < beans::XPropertySet > xPropSet( xNewStor, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ Any a = xPropSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) );
+ ::rtl::OUString aMediaType;
+ if ( !(a>>=aMediaType) || !aMediaType.getLength() )
+ {
+ OSL_ENSURE( sal_False, "The mediatype must be set already!\n" );
+ SetupStorage( xNewStor, SOFFICE_FILEFORMAT_CURRENT, sal_False );
+ }
+
+ pImp->bIsSaving = sal_False;
+ bOk = SaveAsOwnFormat( rMedium );
+
+ if ( bCommit )
+ {
+ try {
+ uno::Reference< embed::XTransactedObject > xTransact( xNewStor, uno::UNO_QUERY_THROW );
+ xTransact->commit();
+ }
+ catch( uno::Exception& )
+ {
+ DBG_ERROR( "The strotage was not commited on DoSaveAs!\n" );
+ }
+ }
+ }
+ }
+
+ return bOk;
+}
+
+//-------------------------------------------------------------------------
+// TODO/LATER: may be the call must be removed completelly
+sal_Bool SfxObjectShell::DoSaveAs( SfxMedium& rMedium )
+{
+ // hier kommen nur Root-Storages rein, die via Temp-File gespeichert werden
+ rMedium.CreateTempFileNoCopy();
+ SetError(rMedium.GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ if ( GetError() )
+ return sal_False;
+
+ // copy version list from "old" medium to target medium, so it can be used on saving
+ if ( pImp->bPreserveVersions )
+ rMedium.TransferVersionList_Impl( *pMedium );
+
+ sal_Bool bRet = SaveTo_Impl( rMedium, NULL );
+ if ( !bRet )
+ SetError(rMedium.GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return bRet;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::DoSaveCompleted" );
+
+ sal_Bool bOk = sal_True;
+ sal_Bool bMedChanged = pNewMed && pNewMed!=pMedium;
+/* sal_Bool bCreatedTempStor = pNewMed && pMedium &&
+ IsPackageStorageFormat_Impl(*pMedium) &&
+ !IsPackageStorageFormat_Impl(*pNewMed) &&
+ pMedium->GetName().Len();
+*/
+ DBG_ASSERT( !pNewMed || pNewMed->GetError() == ERRCODE_NONE, "DoSaveCompleted: Medium has error!" );
+
+ // delete Medium (and Storage!) after all notifications
+ SfxMedium* pOld = pMedium;
+ if ( bMedChanged )
+ {
+ pMedium = pNewMed;
+ pMedium->CanDisposeStorage_Impl( sal_True );
+ }
+
+ const SfxFilter *pFilter = pMedium ? pMedium->GetFilter() : 0;
+ if ( pNewMed )
+ {
+ if( bMedChanged )
+ {
+ if( pNewMed->GetName().Len() )
+ bHasName = sal_True;
+ Broadcast( SfxSimpleHint(SFX_HINT_NAMECHANGED) );
+ getDocProperties()->setGenerator(
+ ::utl::DocInfoHelper::GetGeneratorString() );
+ }
+
+ uno::Reference< embed::XStorage > xStorage;
+ if ( !pFilter || IsPackageStorageFormat_Impl( *pMedium ) )
+ {
+ uno::Reference < embed::XStorage > xOld = GetStorage();
+
+ // when the package based medium is broken and has no storage or if the storage
+ // is the same as the document storage the current document storage should be preserved
+ xStorage = pMedium->GetStorage();
+ bOk = SaveCompleted( xStorage );
+ if ( bOk && xStorage.is() && xOld != xStorage
+ && (!pOld || !pOld->HasStorage_Impl() || xOld != pOld->GetStorage() ) )
+ {
+ // old own storage was not controlled by old Medium -> dispose it
+ try {
+ xOld->dispose();
+ } catch( uno::Exception& )
+ {
+ // the storage is disposed already
+ // can happen during reload scenario when the medium has disposed it during the closing
+ // will be fixed in one of the next milestones
+ }
+ }
+ }
+ else
+ {
+ if( pMedium->GetOpenMode() & STREAM_WRITE )
+ pMedium->GetInStream();
+ xStorage = GetStorage();
+ }
+
+ // TODO/LATER: may be this code will be replaced, but not sure
+ // Set storage in document library containers
+ pImp->pBasicManager->setStorage( xStorage );
+ }
+ else
+ {
+ if( pMedium )
+ {
+ if( pFilter && !IsPackageStorageFormat_Impl( *pMedium ) && (pMedium->GetOpenMode() & STREAM_WRITE ))
+ {
+ pMedium->ReOpen();
+ bOk = SaveCompletedChildren( sal_False );
+ }
+ else
+ bOk = SaveCompleted( NULL );
+ }
+ // entweder Save oder ConvertTo
+ else
+ bOk = SaveCompleted( NULL );
+ }
+
+ if ( bOk && pNewMed )
+ {
+ if( bMedChanged )
+ {
+ delete pOld;
+
+ uno::Reference< frame::XModel > xModel = GetModel();
+ if ( xModel.is() )
+ {
+ ::rtl::OUString aURL = pNewMed->GetOrigURL();
+ uno::Sequence< beans::PropertyValue > aMediaDescr;
+ TransformItems( SID_OPENDOC, *pNewMed->GetItemSet(), aMediaDescr );
+ try
+ {
+ xModel->attachResource( aURL, aMediaDescr );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ // before the title regenerated the document must loose the signatures
+ pImp->nDocumentSignatureState = SIGNATURESTATE_NOSIGNATURES;
+ pImp->nScriptingSignatureState = pNewMed->GetCachedSignatureState_Impl();
+ OSL_ENSURE( pImp->nScriptingSignatureState != SIGNATURESTATE_SIGNATURES_BROKEN, "The signature must not be broken at this place" );
+ pImp->bSignatureErrorIsShown = sal_False;
+
+ // TODO/LATER: in future the medium must control own signature state, not the document
+ pNewMed->SetCachedSignatureState_Impl( SIGNATURESTATE_NOSIGNATURES ); // set the default value back
+
+ // Titel neu setzen
+ if ( pNewMed->GetName().Len() && SFX_CREATE_MODE_EMBEDDED != eCreateMode )
+ InvalidateName();
+ SetModified(sal_False); // nur bei gesetztem Medium zur"ucksetzen
+ Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
+
+ // this is the end of the saving process, it is possible that the file was changed
+ // between medium commit and this step ( attributes change and so on )
+ // so get the file date again
+ if ( pNewMed->DocNeedsFileDateCheck() )
+ pNewMed->GetInitFileDate( sal_True );
+ }
+ }
+
+ pMedium->ClearBackup_Impl();
+ pMedium->LockOrigFileOnDemand( sal_True, sal_False );
+
+ return bOk;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::ConvertFrom
+(
+ SfxMedium& /*rMedium*/ /* <SfxMedium>, welches die Quell-Datei beschreibt
+ (z.B. Dateiname, <SfxFilter>, Open-Modi etc.) */
+)
+
+/* [Beschreibung]
+
+ Diese Methode wird zum Laden von Dokumenten "uber alle Filter gerufen,
+ die nicht SFX_FILTER_OWN sind oder f"ur die kein Clipboard-Format
+ registriert wurde (also kein Storage-Format benutzen). Mit anderen Worten:
+ mit dieser Methode wird importiert.
+
+ Das hier zu "offende File sollte "uber 'rMedium' ge"offnet werden,
+ um die richtigen Open-Modi zu gew"ahrleisten. Insbesondere wenn das
+ Format beibehalten wird (nur m"oglich bei SFX_FILTER_SIMULATE oder
+ SFX_FILTER_ONW) mu\s die Datei STREAM_SHARE_DENYWRITE ge"offnet werden.
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Das Dokument konnte geladen werden.
+
+ sal_False
+ Das Dokument konnte nicht geladen werden, ein
+ Fehlercode ist mit <SvMedium::GetError()const> zu
+ erhalten.
+
+
+ [Beispiel]
+
+ sal_Bool DocSh::ConvertFrom( SfxMedium &rMedium )
+ {
+ SvStreamRef xStream = rMedium.GetInStream();
+ if( xStream.is() )
+ {
+ xStream->SetBufferSize(4096);
+ *xStream >> ...;
+
+ // NICHT 'rMedium.CloseInStream()' rufen! File gelockt halten!
+ return SVSTREAM_OK == rMedium.GetError();
+ }
+
+ return sal_False;
+ }
+
+
+ [Querverweise]
+
+ <SfxObjectShell::ConvertTo(SfxMedium&)>
+ <SFX_FILTER_REGISTRATION>
+*/
+{
+ return sal_False;
+}
+
+sal_Bool SfxObjectShell::InsertFrom( SfxMedium& rMedium )
+{
+ ::rtl::OUString aTypeName( rMedium.GetFilter()->GetTypeName() );
+ ::rtl::OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
+
+ uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory();
+ uno::Reference < lang::XMultiServiceFactory > xFilterFact (
+ xMan->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), uno::UNO_QUERY );
+
+ uno::Sequence < beans::PropertyValue > aProps;
+ uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY );
+ if ( xFilters->hasByName( aFilterName ) )
+ {
+ xFilters->getByName( aFilterName ) >>= aProps;
+ rMedium.GetItemSet()->Put( SfxStringItem( SID_FILTER_NAME, aFilterName ) );
+ }
+
+ ::rtl::OUString aFilterImplName;
+ sal_Int32 nFilterProps = aProps.getLength();
+ for ( sal_Int32 nFilterProp = 0; nFilterProp<nFilterProps; nFilterProp++ )
+ {
+ const beans::PropertyValue& rFilterProp = aProps[nFilterProp];
+ if ( rFilterProp.Name.compareToAscii("FilterService") == COMPARE_EQUAL )
+ {
+ rFilterProp.Value >>= aFilterImplName;
+ break;
+ }
+ }
+
+ uno::Reference< document::XFilter > xLoader;
+ if ( aFilterImplName.getLength() )
+ {
+ try{
+ xLoader = uno::Reference< document::XFilter >
+ ( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY );
+ }catch(const uno::Exception&)
+ { xLoader.clear(); }
+ }
+ if ( xLoader.is() )
+ {
+ // #131744#: it happens that xLoader does not support xImporter!
+ try{
+ uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< document::XImporter > xImporter( xLoader, uno::UNO_QUERY_THROW );
+ xImporter->setTargetDocument( xComp );
+
+ uno::Sequence < beans::PropertyValue > lDescriptor;
+ rMedium.GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, rMedium.GetName() ) );
+ TransformItems( SID_OPENDOC, *rMedium.GetItemSet(), lDescriptor );
+
+ com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aArgs ( lDescriptor.getLength() );
+ com::sun::star::beans::PropertyValue * pNewValue = aArgs.getArray();
+ const com::sun::star::beans::PropertyValue * pOldValue = lDescriptor.getConstArray();
+ const OUString sInputStream ( RTL_CONSTASCII_USTRINGPARAM ( "InputStream" ) );
+
+ sal_Bool bHasInputStream = sal_False;
+ BOOL bHasBaseURL = FALSE;
+ sal_Int32 i;
+ sal_Int32 nEnd = lDescriptor.getLength();
+
+ for ( i = 0; i < nEnd; i++ )
+ {
+ pNewValue[i] = pOldValue[i];
+ if ( pOldValue [i].Name == sInputStream )
+ bHasInputStream = sal_True;
+ else if ( pOldValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "DocumentBaseURL" ) ) )
+ bHasBaseURL = sal_True;
+ }
+
+ if ( !bHasInputStream )
+ {
+ aArgs.realloc ( ++nEnd );
+ aArgs[nEnd-1].Name = sInputStream;
+ aArgs[nEnd-1].Value <<= com::sun::star::uno::Reference < com::sun::star::io::XInputStream > ( new utl::OSeekableInputStreamWrapper ( *rMedium.GetInStream() ) );
+ }
+
+ if ( !bHasBaseURL )
+ {
+ aArgs.realloc ( ++nEnd );
+ aArgs[nEnd-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DocumentBaseURL" ) );
+ aArgs[nEnd-1].Value <<= rMedium.GetBaseURL();
+ }
+
+ aArgs.realloc( ++nEnd );
+ aArgs[nEnd-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "InsertMode" ) );
+ aArgs[nEnd-1].Value <<= (sal_Bool) sal_True;
+
+ return xLoader->filter( aArgs );
+ }catch(const uno::Exception&)
+ {}
+ }
+
+ return sal_False;
+}
+
+sal_Bool SfxObjectShell::ImportFrom( SfxMedium& rMedium )
+{
+ ::rtl::OUString aTypeName( rMedium.GetFilter()->GetTypeName() );
+ ::rtl::OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
+
+ uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory();
+ uno::Reference < lang::XMultiServiceFactory > xFilterFact (
+ xMan->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), uno::UNO_QUERY );
+
+ uno::Sequence < beans::PropertyValue > aProps;
+ uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY );
+ if ( xFilters->hasByName( aFilterName ) )
+ {
+ xFilters->getByName( aFilterName ) >>= aProps;
+ rMedium.GetItemSet()->Put( SfxStringItem( SID_FILTER_NAME, aFilterName ) );
+ }
+
+ ::rtl::OUString aFilterImplName;
+ sal_Int32 nFilterProps = aProps.getLength();
+ for ( sal_Int32 nFilterProp = 0; nFilterProp<nFilterProps; nFilterProp++ )
+ {
+ const beans::PropertyValue& rFilterProp = aProps[nFilterProp];
+ if ( rFilterProp.Name.compareToAscii("FilterService") == COMPARE_EQUAL )
+ {
+ rFilterProp.Value >>= aFilterImplName;
+ break;
+ }
+ }
+
+ uno::Reference< document::XFilter > xLoader;
+ if ( aFilterImplName.getLength() )
+ {
+ try{
+ xLoader = uno::Reference< document::XFilter >
+ ( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY );
+ }catch(const uno::Exception&)
+ { xLoader.clear(); }
+ }
+ if ( xLoader.is() )
+ {
+ // #131744#: it happens that xLoader does not support xImporter!
+ try{
+ uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< document::XImporter > xImporter( xLoader, uno::UNO_QUERY_THROW );
+ xImporter->setTargetDocument( xComp );
+
+ uno::Sequence < beans::PropertyValue > lDescriptor;
+ rMedium.GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, rMedium.GetName() ) );
+ TransformItems( SID_OPENDOC, *rMedium.GetItemSet(), lDescriptor );
+
+ com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aArgs ( lDescriptor.getLength() );
+ com::sun::star::beans::PropertyValue * pNewValue = aArgs.getArray();
+ const com::sun::star::beans::PropertyValue * pOldValue = lDescriptor.getConstArray();
+ const OUString sInputStream ( RTL_CONSTASCII_USTRINGPARAM ( "InputStream" ) );
+
+ sal_Bool bHasInputStream = sal_False;
+ BOOL bHasBaseURL = FALSE;
+ sal_Int32 i;
+ sal_Int32 nEnd = lDescriptor.getLength();
+
+ for ( i = 0; i < nEnd; i++ )
+ {
+ pNewValue[i] = pOldValue[i];
+ if ( pOldValue [i].Name == sInputStream )
+ bHasInputStream = sal_True;
+ else if ( pOldValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "DocumentBaseURL" ) ) )
+ bHasBaseURL = sal_True;
+ }
+
+ if ( !bHasInputStream )
+ {
+ aArgs.realloc ( ++nEnd );
+ aArgs[nEnd-1].Name = sInputStream;
+ aArgs[nEnd-1].Value <<= com::sun::star::uno::Reference < com::sun::star::io::XInputStream > ( new utl::OSeekableInputStreamWrapper ( *rMedium.GetInStream() ) );
+ }
+
+ if ( !bHasBaseURL )
+ {
+ aArgs.realloc ( ++nEnd );
+ aArgs[nEnd-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DocumentBaseURL" ) );
+ aArgs[nEnd-1].Value <<= rMedium.GetBaseURL();
+ }
+
+ return xLoader->filter( aArgs );
+ }catch(const uno::Exception&)
+ {}
+ }
+
+ return sal_False;
+}
+
+sal_Bool SfxObjectShell::ExportTo( SfxMedium& rMedium )
+{
+ ::rtl::OUString aTypeName( rMedium.GetFilter()->GetTypeName() );
+ ::rtl::OUString aFilterName( rMedium.GetFilter()->GetFilterName() );
+ uno::Reference< document::XExporter > xExporter;
+
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory();
+ uno::Reference < lang::XMultiServiceFactory > xFilterFact (
+ xMan->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), uno::UNO_QUERY );
+
+ uno::Sequence < beans::PropertyValue > aProps;
+ uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY );
+ if ( xFilters->hasByName( aFilterName ) )
+ xFilters->getByName( aFilterName ) >>= aProps;
+
+ ::rtl::OUString aFilterImplName;
+ sal_Int32 nFilterProps = aProps.getLength();
+ for ( sal_Int32 nFilterProp = 0; nFilterProp<nFilterProps; nFilterProp++ )
+ {
+ const beans::PropertyValue& rFilterProp = aProps[nFilterProp];
+ if ( rFilterProp.Name.compareToAscii("FilterService") == COMPARE_EQUAL )
+ {
+ rFilterProp.Value >>= aFilterImplName;
+ break;
+ }
+ }
+
+ if ( aFilterImplName.getLength() )
+ {
+ try{
+ xExporter = uno::Reference< document::XExporter >
+ ( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY );
+ }catch(const uno::Exception&)
+ { xExporter.clear(); }
+ }
+ }
+
+ if ( xExporter.is() )
+ {
+ try{
+ uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY_THROW );
+ xExporter->setSourceDocument( xComp );
+
+ com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aOldArgs;
+ SfxItemSet* pItems = rMedium.GetItemSet();
+ TransformItems( SID_SAVEASDOC, *pItems, aOldArgs );
+
+ const com::sun::star::beans::PropertyValue * pOldValue = aOldArgs.getConstArray();
+ com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aArgs ( aOldArgs.getLength() );
+ com::sun::star::beans::PropertyValue * pNewValue = aArgs.getArray();
+
+ // put in the REAL file name, and copy all PropertyValues
+ const OUString sOutputStream ( RTL_CONSTASCII_USTRINGPARAM ( "OutputStream" ) );
+ const OUString sStream ( RTL_CONSTASCII_USTRINGPARAM ( "StreamForOutput" ) );
+ BOOL bHasOutputStream = FALSE;
+ BOOL bHasStream = FALSE;
+ BOOL bHasBaseURL = FALSE;
+ sal_Int32 i;
+ sal_Int32 nEnd = aOldArgs.getLength();
+
+ for ( i = 0; i < nEnd; i++ )
+ {
+ pNewValue[i] = pOldValue[i];
+ if ( pOldValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "FileName" ) ) )
+ pNewValue[i].Value <<= OUString ( rMedium.GetName() );
+ else if ( pOldValue[i].Name == sOutputStream )
+ bHasOutputStream = sal_True;
+ else if ( pOldValue[i].Name == sStream )
+ bHasStream = sal_True;
+ else if ( pOldValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "DocumentBaseURL" ) ) )
+ bHasBaseURL = sal_True;
+ }
+
+ if ( !bHasOutputStream )
+ {
+ aArgs.realloc ( ++nEnd );
+ aArgs[nEnd-1].Name = sOutputStream;
+ aArgs[nEnd-1].Value <<= com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > ( new utl::OOutputStreamWrapper ( *rMedium.GetOutStream() ) );
+ }
+
+ // add stream as well, for OOX export and maybe others
+ if ( !bHasStream )
+ {
+ aArgs.realloc ( ++nEnd );
+ aArgs[nEnd-1].Name = sStream;
+ aArgs[nEnd-1].Value <<= com::sun::star::uno::Reference < com::sun::star::io::XStream > ( new utl::OStreamWrapper ( *rMedium.GetOutStream() ) );
+ }
+
+ if ( !bHasBaseURL )
+ {
+ aArgs.realloc ( ++nEnd );
+ aArgs[nEnd-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DocumentBaseURL" ) );
+ aArgs[nEnd-1].Value <<= rMedium.GetBaseURL( sal_True );
+ }
+
+ return xFilter->filter( aArgs );
+ }catch(const uno::Exception&)
+ {}
+ }
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::ConvertTo
+(
+ SfxMedium& /*rMedium*/ /* <SfxMedium>, welches die Ziel-Datei beschreibt
+ (z.B. Dateiname, <SfxFilter>, Open-Modi etc.) */
+)
+
+/* [Beschreibung]
+
+ Diese Methode wird zum Speichern von Dokumenten "uber alle Filter gerufen,
+ die nicht SFX_FILTER_OWN sind oder f"ur die kein Clipboard-Format
+ registriert wurde (also kein Storage-Format benutzen). Mit anderen Worten:
+ mit dieser Methode wird exportiert.
+
+ Das hier zu "offende File sollte "uber 'rMedium' ge"offnet werden,
+ um die richtigen Open-Modi zu gew"ahrleisten. Insbesondere wenn das
+ Format beibehalten wird (nur m"oglich bei SFX_FILTER_SIMULATE oder
+ SFX_FILTER_ONW) mu\s die Datei auch nach dem Speichern im Modus
+ STREAM_SHARE_DENYWRITE ge"offnet bleiben.
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Das Dokument konnte gespeichert werden.
+
+ sal_False
+ Das Dokument konnte nicht gespeichert werden, ein
+ Fehlercode ist mit <SvMedium::GetError()const> zu
+ erhalten.
+
+
+ [Beispiel]
+
+ sal_Bool DocSh::ConvertTo( SfxMedium &rMedium )
+ {
+ SvStreamRef xStream = rMedium.GetOutStream();
+ if ( xStream.is() )
+ {
+ xStream->SetBufferSize(4096);
+ *xStream << ...;
+
+ rMedium.CloseOutStream(); // "offnet automatisch wieder den InStream
+ return SVSTREAM_OK == rMedium.GetError();
+ }
+ return sal_False ;
+ }
+
+
+ [Querverweise]
+
+ <SfxObjectShell::ConvertFrom(SfxMedium&)>
+ <SFX_FILTER_REGISTRATION>
+*/
+
+{
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::DoSave_Impl( const SfxItemSet* pArgs )
+{
+ SfxMedium* pRetrMedium = GetMedium();
+ const SfxFilter* pFilter = pRetrMedium->GetFilter();
+
+ // copy the original itemset, but remove the "version" item, because pMediumTmp
+ // is a new medium "from scratch", so no version should be stored into it
+ SfxItemSet* pSet = new SfxAllItemSet(*pRetrMedium->GetItemSet());
+ pSet->ClearItem( SID_VERSION );
+ pSet->ClearItem( SID_DOC_BASEURL );
+
+ // create a medium as a copy; this medium is only for writingm, because it uses the same name as the original one
+ // writing is done through a copy, that will be transferred to the target ( of course after calling HandsOff )
+ SfxMedium* pMediumTmp = new SfxMedium( pRetrMedium->GetName(), pRetrMedium->GetOpenMode(), pRetrMedium->IsDirect(), pFilter, pSet );
+ pMediumTmp->SetLongName( pRetrMedium->GetLongName() );
+// pMediumTmp->CreateTempFileNoCopy();
+ if ( pMediumTmp->GetErrorCode() != ERRCODE_NONE )
+ {
+ SetError( pMediumTmp->GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ delete pMediumTmp;
+ return sal_False;
+ }
+
+ // copy version list from "old" medium to target medium, so it can be used on saving
+ pMediumTmp->TransferVersionList_Impl( *pRetrMedium );
+/*
+ if ( pFilter && ( pFilter->GetFilterFlags() & SFX_FILTER_PACKED ) )
+ SetError( GetMedium()->Unpack_Impl( pRetrMedium->GetPhysicalName() ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+*/
+
+ // an interaction handler here can aquire only in case of GUI Saving
+ // and should be removed after the saving is done
+ com::sun::star::uno::Reference< XInteractionHandler > xInteract;
+ SFX_ITEMSET_ARG( pArgs, pxInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False );
+ if ( pxInteractionItem && ( pxInteractionItem->GetValue() >>= xInteract ) && xInteract.is() )
+ pMediumTmp->GetItemSet()->Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER, makeAny( xInteract ) ) );
+
+ sal_Bool bSaved = sal_False;
+ if( !GetError() && SaveTo_Impl( *pMediumTmp, pArgs ) )
+ {
+ bSaved = sal_True;
+
+ if( pMediumTmp->GetItemSet() )
+ {
+ pMediumTmp->GetItemSet()->ClearItem( SID_INTERACTIONHANDLER );
+ pMediumTmp->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
+ }
+
+ SetError(pMediumTmp->GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ sal_Bool bOpen( sal_False );
+ bOpen = DoSaveCompleted( pMediumTmp );
+ DBG_ASSERT(bOpen,"Fehlerbehandlung fuer DoSaveCompleted nicht implementiert");
+ }
+ else
+ {
+ // transfer error code from medium to objectshell
+ SetError( pMediumTmp->GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ // reconnect to object storage
+ DoSaveCompleted( 0 );
+
+ if( pRetrMedium->GetItemSet() )
+ {
+ pRetrMedium->GetItemSet()->ClearItem( SID_INTERACTIONHANDLER );
+ pRetrMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
+ }
+
+ delete pMediumTmp;
+ }
+
+ SetModified( !bSaved );
+ return bSaved;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::Save_Impl( const SfxItemSet* pSet )
+{
+ if ( IsReadOnly() )
+ {
+ SetError( ERRCODE_SFX_DOCUMENTREADONLY, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return sal_False;
+ }
+
+ DBG_CHKTHIS(SfxObjectShell, 0);
+
+ pImp->bIsSaving = sal_True;
+ sal_Bool bSaved = FALSE;
+ SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
+ if ( pSalvageItem )
+ {
+ SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False);
+ String aFilterName;
+ const SfxFilter *pFilter = NULL;
+ if ( pFilterItem )
+ pFilter = SfxFilterMatcher( String::CreateFromAscii( GetFactory().GetShortName()) ).GetFilter4FilterName( aFilterName );
+
+ SfxMedium *pMed = new SfxMedium(
+ pSalvageItem->GetValue(), STREAM_READWRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC, sal_False, pFilter );
+
+ SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False );
+ if ( pPasswordItem )
+ pMed->GetItemSet()->Put( *pPasswordItem );
+
+ bSaved = DoSaveAs( *pMed );
+ if ( bSaved )
+ bSaved = DoSaveCompleted( pMed );
+ else
+ delete pMed;
+ }
+ else
+ bSaved = DoSave_Impl( pSet );
+ return bSaved;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::CommonSaveAs_Impl
+(
+ const INetURLObject& aURL,
+ const String& aFilterName,
+ SfxItemSet* aParams
+)
+{
+ if( aURL.HasError() )
+ {
+ SetError( ERRCODE_IO_INVALIDPARAMETER, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return sal_False;
+ }
+
+ if ( aURL != INetURLObject( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ) ) )
+ {
+ // gibt es schon ein Doc mit dem Namen?
+ SfxObjectShell* pDoc = 0;
+ for ( SfxObjectShell* pTmp = SfxObjectShell::GetFirst();
+ pTmp && !pDoc;
+ pTmp = SfxObjectShell::GetNext(*pTmp) )
+ {
+ if( ( pTmp != this ) && pTmp->GetMedium() )
+ {
+ INetURLObject aCompare( pTmp->GetMedium()->GetName() );
+ if ( aCompare == aURL )
+ pDoc = pTmp;
+ }
+ }
+ if ( pDoc )
+ {
+ // dann Fehlermeldeung: "schon offen"
+ SetError(ERRCODE_SFX_ALREADYOPEN, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ return sal_False;
+ }
+ }
+
+ DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" );
+ DBG_ASSERT( aParams->Count() != 0, "fehlerhafte Parameter");
+
+ SFX_ITEMSET_ARG( aParams, pSaveToItem, SfxBoolItem, SID_SAVETO, sal_False );
+ sal_Bool bSaveTo = pSaveToItem ? pSaveToItem->GetValue() : sal_False;
+
+ const SfxFilter* pFilter = GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
+ if ( !pFilter
+ || !pFilter->CanExport()
+ || (!bSaveTo && !pFilter->CanImport()) )
+ {
+ SetError( ERRCODE_IO_INVALIDPARAMETER, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ return sal_False;
+ }
+
+ SFX_ITEMSET_ARG( aParams, pCopyStreamItem, SfxBoolItem, SID_COPY_STREAM_IF_POSSIBLE, sal_False );
+ if ( bSaveTo && pCopyStreamItem && pCopyStreamItem->GetValue() && !IsModified() )
+ {
+ if ( pMedium->TryDirectTransfer( aURL.GetMainURL( INetURLObject::NO_DECODE ), *aParams ) )
+ return sal_True;
+ }
+ aParams->ClearItem( SID_COPY_STREAM_IF_POSSIBLE );
+
+ pImp->bPasswd = aParams && SFX_ITEM_SET == aParams->GetItemState(SID_PASSWORD);
+
+ SfxMedium *pActMed = GetMedium();
+ const INetURLObject aActName(pActMed->GetName());
+
+ BOOL bWasReadonly = IsReadOnly();
+
+ if ( aURL == aActName && aURL != INetURLObject( OUString::createFromAscii( "private:stream" ) )
+ && IsReadOnly() )
+ {
+ SetError(ERRCODE_SFX_DOCUMENTREADONLY, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
+ return sal_False;
+ }
+
+ // this notification should be already sent by caller in sfxbasemodel
+ // SFX_APP()->NotifyEvent(SfxEventHint( bSaveTo? SFX_EVENT_SAVETODOC : SFX_EVENT_SAVEASDOC,this));
+
+ if( SFX_ITEM_SET != aParams->GetItemState(SID_UNPACK) && SvtSaveOptions().IsSaveUnpacked() )
+ aParams->Put( SfxBoolItem( SID_UNPACK, sal_False ) );
+
+ ::rtl::OUString aTempFileURL;
+ if ( IsDocShared() )
+ aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
+
+ if ( PreDoSaveAs_Impl(aURL.GetMainURL( INetURLObject::NO_DECODE ),aFilterName,aParams))
+ {
+ pImp->bWaitingForPicklist = sal_True;
+
+ // Daten am Medium updaten
+ SfxItemSet *pSet = GetMedium()->GetItemSet();
+ pSet->ClearItem( SID_INTERACTIONHANDLER );
+ pSet->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
+ pSet->ClearItem( SID_STANDARD_DIR );
+ pSet->ClearItem( SID_PATH );
+
+ if ( !bSaveTo )
+ {
+ pSet->ClearItem( SID_REFERER );
+ pSet->ClearItem( SID_POSTDATA );
+ pSet->ClearItem( SID_TEMPLATE );
+ pSet->ClearItem( SID_DOC_READONLY );
+ pSet->ClearItem( SID_CONTENTTYPE );
+ pSet->ClearItem( SID_CHARSET );
+ pSet->ClearItem( SID_FILTER_NAME );
+ pSet->ClearItem( SID_OPTIONS );
+ //pSet->ClearItem( SID_FILE_FILTEROPTIONS );
+ pSet->ClearItem( SID_VERSION );
+ pSet->ClearItem( SID_EDITDOC );
+ pSet->ClearItem( SID_OVERWRITE );
+ pSet->ClearItem( SID_DEFAULTFILEPATH );
+ pSet->ClearItem( SID_DEFAULTFILENAME );
+
+ SFX_ITEMSET_GET( (*aParams), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if ( pFilterItem )
+ pSet->Put( *pFilterItem );
+
+ SFX_ITEMSET_GET( (*aParams), pOptionsItem, SfxStringItem, SID_OPTIONS, sal_False );
+ if ( pOptionsItem )
+ pSet->Put( *pOptionsItem );
+
+ SFX_ITEMSET_GET( (*aParams), pFilterOptItem, SfxStringItem, SID_FILE_FILTEROPTIONS, sal_False );
+ if ( pFilterOptItem )
+ pSet->Put( *pFilterOptItem );
+
+ if ( IsDocShared() && aTempFileURL.getLength() )
+ {
+ // this is a shared document that has to be disconnected from the old location
+ FreeSharedFile( aTempFileURL );
+
+ if ( pFilter->IsOwnFormat()
+ && pFilter->UsesStorage()
+ && pFilter->GetVersion() >= SOFFICE_FILEFORMAT_60 )
+ {
+ // the target format is the own format
+ // the target document must be shared
+ SwitchToShared( sal_True, sal_False );
+ }
+ }
+ }
+
+ if ( bWasReadonly && !bSaveTo )
+ Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
+
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::PreDoSaveAs_Impl
+(
+ const String& rFileName,
+ const String& aFilterName,
+ SfxItemSet* pParams
+)
+{
+ // copy all items stored in the itemset of the current medium
+ SfxAllItemSet* pMergedParams = new SfxAllItemSet( *pMedium->GetItemSet() );
+
+ // in "SaveAs" title and password will be cleared ( maybe the new itemset contains new values, otherwise they will be empty )
+ pMergedParams->ClearItem( SID_PASSWORD );
+ pMergedParams->ClearItem( SID_DOCINFO_TITLE );
+
+ pMergedParams->ClearItem( SID_INPUTSTREAM );
+ pMergedParams->ClearItem( SID_STREAM );
+ pMergedParams->ClearItem( SID_CONTENT );
+ pMergedParams->ClearItem( SID_DOC_READONLY );
+ pMergedParams->ClearItem( SID_DOC_BASEURL );
+
+ pMergedParams->ClearItem( SID_REPAIRPACKAGE );
+
+ // "SaveAs" will never store any version information - it's a complete new file !
+ pMergedParams->ClearItem( SID_VERSION );
+
+ // merge the new parameters into the copy
+ // all values present in both itemsets will be overwritten by the new parameters
+ if( pParams )
+ pMergedParams->Put( *pParams );
+ //DELETEZ( pParams );
+
+#ifdef DBG_UTIL
+ if ( pMergedParams->GetItemState( SID_DOC_SALVAGE) >= SFX_ITEM_SET )
+ DBG_ERROR("Salvage item present in Itemset, check the parameters!");
+#endif
+
+ // should be unneccessary - too hot to handle!
+ pMergedParams->ClearItem( SID_DOC_SALVAGE );
+
+ // take over the new merged itemset
+ pParams = pMergedParams;
+
+ // create a medium for the target URL
+ SfxMedium *pNewFile = new SfxMedium( rFileName, STREAM_READWRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC, sal_False, 0, pParams );
+
+ // set filter; if no filter is given, take the default filter of the factory
+ if ( aFilterName.Len() )
+ pNewFile->SetFilter( GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ) );
+ else
+ pNewFile->SetFilter( GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_IMPORT | SFX_FILTER_EXPORT ) );
+
+ if ( pNewFile->GetErrorCode() != ERRCODE_NONE )
+ {
+ // creating temporary file failed ( f.e. floppy disk not inserted! )
+ SetError( pNewFile->GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ delete pNewFile;
+ return sal_False;
+ }
+
+ // check if a "SaveTo" is wanted, no "SaveAs"
+ SFX_ITEMSET_ARG( pParams, pSaveToItem, SfxBoolItem, SID_SAVETO, sal_False );
+ sal_Bool bCopyTo = GetCreateMode() == SFX_CREATE_MODE_EMBEDDED || (pSaveToItem && pSaveToItem->GetValue());
+
+ // distinguish between "Save" and "SaveAs"
+ pImp->bIsSaving = sal_False;
+
+ // copy version list from "old" medium to target medium, so it can be used on saving
+ if ( pImp->bPreserveVersions )
+ pNewFile->TransferVersionList_Impl( *pMedium );
+
+/*
+ if ( GetMedium()->GetFilter() && ( GetMedium()->GetFilter()->GetFilterFlags() & SFX_FILTER_PACKED ) )
+ {
+ SfxMedium *pMed = bCopyTo ? pMedium : pNewFile;
+ pNewFile->SetError( GetMedium()->Unpack_Impl( pMed->GetPhysicalName() ) , ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+*/
+ // Save the document ( first as temporary file, then transfer to the target URL by committing the medium )
+ sal_Bool bOk = sal_False;
+ if ( !pNewFile->GetErrorCode() && SaveTo_Impl( *pNewFile, NULL ) )
+ {
+ bOk = sal_True;
+
+ // transfer a possible error from the medium to the document
+ SetError( pNewFile->GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ // notify the document that saving was done successfully
+ if ( !bCopyTo )
+ {
+ bOk = DoSaveCompleted( pNewFile );
+ }
+ else
+ bOk = DoSaveCompleted(0);
+
+ if( bOk )
+ {
+ if( !bCopyTo )
+ SetModified( sal_False );
+ }
+ else
+ {
+ // TODO/LATER: the code below must be dead since the storage commit makes all the stuff
+ // and the DoSaveCompleted call should not be able to fail in general
+
+ DBG_ASSERT( !bCopyTo, "Error while reconnecting to medium, can't be handled!");
+ SetError( pNewFile->GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ if ( !bCopyTo )
+ {
+ // reconnect to the old medium
+ BOOL bRet( FALSE );
+ bRet = DoSaveCompleted( pMedium );
+ DBG_ASSERT( bRet, "Error in DoSaveCompleted, can't be handled!");
+ }
+
+ // TODO/LATER: disconnect the new file from the storage for the case when pure saving is done
+ // if storing has corrupted the file, probably it must be restored either here or
+ // by the storage
+ DELETEZ( pNewFile );
+ }
+ }
+ else
+ {
+ SetError( pNewFile->GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+
+ // reconnect to the old storage
+ DoSaveCompleted( 0 );
+
+ DELETEZ( pNewFile );
+ }
+
+ if ( bCopyTo )
+ DELETEZ( pNewFile );
+ else if( !bOk )
+ SetModified( sal_True );
+
+ return bOk;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::LoadFrom( SfxMedium& /*rMedium*/ )
+{
+ DBG_ERROR( "Base implementation, must not be called in general!" );
+ return sal_True;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SfxObjectShell::IsInformationLost()
+{
+ Sequence< PropertyValue > aProps = GetModel()->getArgs();
+ ::rtl::OUString aFilterName;
+ ::rtl::OUString aPreusedFilterName;
+ for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ )
+ {
+ if ( aProps[nInd].Name.equalsAscii( "FilterName" ) )
+ aProps[nInd].Value >>= aFilterName;
+ else if ( aProps[nInd].Name.equalsAscii( "PreusedFilterName" ) )
+ aProps[nInd].Value >>= aPreusedFilterName;
+ }
+
+ // if current filter can lead to information loss and it was used
+ // for the latest store then the user should be asked to store in own format
+ if ( aFilterName.getLength() && aFilterName.equals( aPreusedFilterName ) )
+ {
+ const SfxFilter *pFilt = GetMedium()->GetFilter();
+ DBG_ASSERT( pFilt && aFilterName.equals( pFilt->GetName() ), "MediaDescriptor contains wrong filter!\n" );
+ return ( pFilt && pFilt->IsAlienFormat() && !(pFilt->GetFilterFlags() & SFX_FILTER_SILENTEXPORT ) );
+ }
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SfxObjectShell::CanReload_Impl()
+
+/* [Beschreibung]
+
+ Interne Methode zum Feststellen, ob eine erneutes Laden des
+ Dokuments (auch als RevertToSaved oder LastVersion bekannt)
+ m"oglich ist.
+*/
+
+{
+ return pMedium && HasName() && !IsInModalMode() && !pImp->bForbidReload;
+}
+
+//-------------------------------------------------------------------------
+
+sal_uInt16 SfxObjectShell::GetHiddenInformationState( sal_uInt16 nStates )
+{
+ sal_uInt16 nState = 0;
+ if ( nStates & HIDDENINFORMATION_DOCUMENTVERSIONS )
+ {
+ if ( GetMedium()->GetVersionList().getLength() )
+ nState |= HIDDENINFORMATION_DOCUMENTVERSIONS;
+ }
+
+ return nState;
+}
+
+sal_Int16 SfxObjectShell::QueryHiddenInformation( HiddenWarningFact eFact, Window* pParent )
+{
+ sal_Int16 nRet = RET_YES;
+ USHORT nResId = 0;
+ SvtSecurityOptions::EOption eOption = static_cast< SvtSecurityOptions::EOption >( -1 );
+
+ switch ( eFact )
+ {
+ case WhenSaving :
+ {
+ nResId = STR_HIDDENINFO_CONTINUE_SAVING;
+ eOption = SvtSecurityOptions::E_DOCWARN_SAVEORSEND;
+ break;
+ }
+ case WhenPrinting :
+ {
+ nResId = STR_HIDDENINFO_CONTINUE_PRINTING;
+ eOption = SvtSecurityOptions::E_DOCWARN_PRINT;
+ break;
+ }
+ case WhenSigning :
+ {
+ nResId = STR_HIDDENINFO_CONTINUE_SIGNING;
+ eOption = SvtSecurityOptions::E_DOCWARN_SIGNING;
+ break;
+ }
+ case WhenCreatingPDF :
+ {
+ nResId = STR_HIDDENINFO_CONTINUE_CREATEPDF;
+ eOption = SvtSecurityOptions::E_DOCWARN_CREATEPDF;
+ break;
+ }
+ default:
+ {
+ DBG_ERRORFILE( "SfxObjectShell::DetectHiddenInformation(): what fact?" );
+ }
+ }
+
+ if ( eOption != -1 && SvtSecurityOptions().IsOptionSet( eOption ) )
+ {
+ String sMessage( SfxResId( STR_HIDDENINFO_CONTAINS ) );
+ sal_uInt16 nWantedStates = HIDDENINFORMATION_RECORDEDCHANGES | HIDDENINFORMATION_NOTES;
+ if ( eFact != WhenPrinting )
+ nWantedStates |= HIDDENINFORMATION_DOCUMENTVERSIONS;
+ sal_uInt16 nStates = GetHiddenInformationState( nWantedStates );
+ bool bWarning = false;
+
+ if ( ( nStates & HIDDENINFORMATION_RECORDEDCHANGES ) == HIDDENINFORMATION_RECORDEDCHANGES )
+ {
+ sMessage += String( SfxResId( STR_HIDDENINFO_RECORDCHANGES ) );
+ sMessage += '\n';
+ bWarning = true;
+ }
+ if ( ( nStates & HIDDENINFORMATION_NOTES ) == HIDDENINFORMATION_NOTES )
+ {
+ sMessage += String( SfxResId( STR_HIDDENINFO_NOTES ) );
+ sMessage += '\n';
+ bWarning = true;
+ }
+ if ( ( nStates & HIDDENINFORMATION_DOCUMENTVERSIONS ) == HIDDENINFORMATION_DOCUMENTVERSIONS )
+ {
+ sMessage += String( SfxResId( STR_HIDDENINFO_DOCVERSIONS ) );
+ sMessage += '\n';
+ bWarning = true;
+ }
+
+ if ( bWarning )
+ {
+ sMessage += '\n';
+ sMessage += String( SfxResId( nResId ) );
+ WarningBox aWBox( pParent, WB_YES_NO | WB_DEF_NO, sMessage );
+ nRet = aWBox.Execute();
+ }
+ }
+
+ return nRet;
+}
+
+sal_Bool SfxObjectShell::HasSecurityOptOpenReadOnly() const
+{
+ return sal_True;
+}
+
+sal_Bool SfxObjectShell::IsSecurityOptOpenReadOnly() const
+{
+ return IsLoadReadonly();
+}
+
+void SfxObjectShell::SetSecurityOptOpenReadOnly( sal_Bool _b )
+{
+ SetLoadReadonly( _b );
+}
+
+sal_Bool SfxObjectShell::LoadOwnFormat( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE SfxObjectShell::LoadOwnFormat" );
+ if( RTL_LOGFILE_HASLOGFILE() )
+ {
+ ByteString aString( rMedium.GetName(), RTL_TEXTENCODING_ASCII_US );
+ RTL_LOGFILE_PRODUCT_CONTEXT_TRACE1( aLog, "loading \"%s\"", aString.GetBuffer() );
+ }
+
+ uno::Reference< embed::XStorage > xStorage = rMedium.GetStorage();
+ if ( xStorage.is() )
+ {
+ // Password
+ SFX_ITEMSET_ARG( rMedium.GetItemSet(), pPasswdItem, SfxStringItem, SID_PASSWORD, sal_False );
+ if ( pPasswdItem || ERRCODE_IO_ABORT != CheckPasswd_Impl( this, SFX_APP()->GetPool(), pMedium ) )
+ {
+ ::rtl::OUString aPasswd;
+ if ( GetPasswd_Impl(pMedium->GetItemSet(), aPasswd) )
+ {
+ try
+ {
+ // the following code must throw an exception in case of failure
+ ::comphelper::OStorageHelper::SetCommonStoragePassword( xStorage, aPasswd );
+ }
+ catch( uno::Exception& )
+ {
+ // TODO/LATER: handle the error code
+ }
+ }
+
+ // load document
+ return Load( rMedium );
+ }
+ return sal_False;
+ }
+ else
+ return sal_False;
+}
+
+sal_Bool SfxObjectShell::SaveAsOwnFormat( SfxMedium& rMedium )
+{
+ uno::Reference< embed::XStorage > xStorage = rMedium.GetStorage();
+ if( xStorage.is() )
+ {
+ sal_Int32 nVersion = rMedium.GetFilter()->GetVersion();
+
+ // OASIS templates have own mediatypes ( SO7 also actually, but it is to late to use them here )
+ sal_Bool bTemplate = ( rMedium.GetFilter()->IsOwnTemplateFormat() && nVersion > SOFFICE_FILEFORMAT_60 );
+
+ SetupStorage( xStorage, nVersion, bTemplate );
+
+ if ( HasBasic() )
+ {
+ // Initialize Basic
+ GetBasicManager();
+
+ // Save dialog/script container
+ pImp->pBasicManager->storeLibrariesToStorage( xStorage );
+ }
+
+ return SaveAs( rMedium );
+ }
+ else return sal_False;
+}
+
+uno::Reference< embed::XStorage > SfxObjectShell::GetStorage()
+{
+ if ( !pImp->m_xDocStorage.is() )
+ {
+ OSL_ENSURE( pImp->m_bCreateTempStor, "The storage must exist already!\n" );
+ try {
+ // no notification is required the storage is set the first time
+ pImp->m_xDocStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
+ OSL_ENSURE( pImp->m_xDocStorage.is(), "The method must either return storage or throw an exception!" );
+
+ SetupStorage( pImp->m_xDocStorage, SOFFICE_FILEFORMAT_CURRENT, sal_False );
+ pImp->m_bCreateTempStor = sal_False;
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_STORAGECHANGED, GlobalEventConfig::GetEventName(STR_EVENT_STORAGECHANGED), this ) );
+ }
+ catch( uno::Exception& )
+ {
+ // TODO/LATER: error handling?
+ }
+ }
+
+ OSL_ENSURE( pImp->m_xDocStorage.is(), "The document storage must be created!" );
+ return pImp->m_xDocStorage;
+}
+
+
+sal_Bool SfxObjectShell::SaveChildren( BOOL bObjectsOnly )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SaveChildren" );
+
+ sal_Bool bResult = sal_True;
+ if ( pImp->mpObjectContainer )
+ {
+ sal_Bool bOasis = ( SotStorage::GetVersion( GetStorage() ) > SOFFICE_FILEFORMAT_60 );
+ GetEmbeddedObjectContainer().StoreChildren(bOasis,bObjectsOnly);
+ }
+
+ return bResult;
+}
+
+sal_Bool SfxObjectShell::SaveAsChildren( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SaveAsChildren" );
+
+ sal_Bool bResult = sal_True;
+
+ uno::Reference < embed::XStorage > xStorage = rMedium.GetStorage();
+ if ( !xStorage.is() )
+ return sal_False;
+
+ if ( xStorage == GetStorage() )
+ return SaveChildren();
+
+ sal_Bool bOasis = sal_True;
+ if ( pImp->mpObjectContainer )
+ {
+ bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 );
+ GetEmbeddedObjectContainer().StoreAsChildren(bOasis,SFX_CREATE_MODE_EMBEDDED == eCreateMode,xStorage);
+ }
+
+ if ( bResult )
+ bResult = CopyStoragesOfUnknownMediaType( GetStorage(), xStorage );
+
+ return bResult;
+}
+
+sal_Bool SfxObjectShell::SaveCompletedChildren( sal_Bool bSuccess )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SaveCompletedChildren" );
+
+ sal_Bool bResult = sal_True;
+
+ if ( pImp->mpObjectContainer )
+ {
+ uno::Sequence < ::rtl::OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
+ for ( sal_Int32 n=0; n<aNames.getLength(); n++ )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( aNames[n] );
+ 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->saveCompleted( bSuccess );
+ }
+ catch( uno::Exception& )
+ {
+ // TODO/LATER: error handling
+ bResult = sal_False;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+sal_Bool SfxObjectShell::SwitchChildrenPersistance( const uno::Reference< embed::XStorage >& xStorage,
+ sal_Bool bForceNonModified )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SwitchChildrenPersistence" );
+
+ if ( !xStorage.is() )
+ {
+ // TODO/LATER: error handling
+ return sal_False;
+ }
+
+ sal_Bool bResult = sal_True;
+
+ if ( pImp->mpObjectContainer )
+ pImp->mpObjectContainer->SetPersistentEntries(xStorage,bForceNonModified);
+
+ return bResult;
+}
+
+// Never call this method directly, always use the DoSaveCompleted call
+sal_Bool SfxObjectShell::SaveCompleted( const uno::Reference< embed::XStorage >& xStorage )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SaveCompleted" );
+
+ sal_Bool bResult = sal_False;
+ sal_Bool bSendNotification = sal_False;
+ uno::Reference< embed::XStorage > xOldStorageHolder;
+
+#ifdef DBG_UTIL
+ // check for wrong creation of object container
+ BOOL bHasContainer = ( pImp->mpObjectContainer != 0 );
+#endif
+
+ if ( !xStorage.is() || xStorage == GetStorage() )
+ {
+ // no persistence change
+ bResult = SaveCompletedChildren( sal_False );
+ }
+ else
+ {
+ if ( pImp->mpObjectContainer )
+ GetEmbeddedObjectContainer().SwitchPersistence( xStorage );
+
+ bResult = SwitchChildrenPersistance( xStorage, sal_True );
+ }
+
+ if ( bResult )
+ {
+ if ( xStorage.is() && pImp->m_xDocStorage != xStorage )
+ {
+ // make sure that until the storage is assigned the object container is not created by accident!
+ DBG_ASSERT( bHasContainer == (pImp->mpObjectContainer != 0), "Wrong storage in object container!" );
+ xOldStorageHolder = pImp->m_xDocStorage;
+ pImp->m_xDocStorage = xStorage;
+ bSendNotification = sal_True;
+
+ if ( IsEnableSetModified() )
+ SetModified( sal_False );
+ }
+ }
+ else
+ {
+ if ( pImp->mpObjectContainer )
+ GetEmbeddedObjectContainer().SwitchPersistence( pImp->m_xDocStorage );
+
+ // let already successfully connected objects be switched back
+ SwitchChildrenPersistance( pImp->m_xDocStorage, sal_True );
+ }
+
+ if ( bSendNotification )
+ {
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_STORAGECHANGED, GlobalEventConfig::GetEventName(STR_EVENT_STORAGECHANGED), this ) );
+ }
+
+ return bResult;
+}
+
+
+sal_Bool StoragesOfUnknownMediaTypeAreCopied_Impl( const uno::Reference< embed::XStorage >& xSource,
+ const uno::Reference< embed::XStorage >& xTarget )
+{
+ OSL_ENSURE( xSource.is() && xTarget.is(), "Source and/or target storages are not available!\n" );
+ if ( !xSource.is() || !xTarget.is() || xSource == xTarget )
+ return sal_True;
+
+ try
+ {
+ uno::Sequence< ::rtl::OUString > aSubElements = xSource->getElementNames();
+ for ( sal_Int32 nInd = 0; nInd < aSubElements.getLength(); nInd++ )
+ {
+ if ( xSource->isStorageElement( aSubElements[nInd] ) )
+ {
+ ::rtl::OUString aMediaType;
+ ::rtl::OUString aMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
+ sal_Bool bGotMediaType = sal_False;
+
+ try
+ {
+ uno::Reference< embed::XOptimizedStorage > xOptStorage( xSource, uno::UNO_QUERY_THROW );
+ bGotMediaType =
+ ( xOptStorage->getElementPropertyValue( aSubElements[nInd], aMediaTypePropName ) >>= aMediaType );
+ }
+ catch( uno::Exception& )
+ {}
+
+ if ( !bGotMediaType )
+ {
+ uno::Reference< embed::XStorage > xSubStorage;
+ try {
+ xSubStorage = xSource->openStorageElement( aSubElements[nInd], embed::ElementModes::READ );
+ } catch( uno::Exception& )
+ {}
+
+ if ( !xSubStorage.is() )
+ {
+ xSubStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
+ xSource->copyStorageElementLastCommitTo( aSubElements[nInd], xSubStorage );
+ }
+
+ uno::Reference< beans::XPropertySet > xProps( xSubStorage, uno::UNO_QUERY_THROW );
+ bGotMediaType = ( xProps->getPropertyValue( aMediaTypePropName ) >>= aMediaType );
+ }
+
+ // TODO/LATER: there should be a way to detect whether an object with such a MediaType can exist
+ // probably it should be placed in the MimeType-ClassID table or in standalone table
+ if ( aMediaType.getLength()
+ && aMediaType.compareToAscii( "application/vnd.sun.star.oleobject" ) != COMPARE_EQUAL )
+ {
+ ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
+ aDataFlavor.MimeType = aMediaType;
+ sal_uInt32 nFormat = SotExchange::GetFormat( aDataFlavor );
+
+ switch ( nFormat )
+ {
+ case SOT_FORMATSTR_ID_STARWRITER_60 :
+ case SOT_FORMATSTR_ID_STARWRITERWEB_60 :
+ case SOT_FORMATSTR_ID_STARWRITERGLOB_60 :
+ case SOT_FORMATSTR_ID_STARDRAW_60 :
+ case SOT_FORMATSTR_ID_STARIMPRESS_60 :
+ case SOT_FORMATSTR_ID_STARCALC_60 :
+ case SOT_FORMATSTR_ID_STARCHART_60 :
+ case SOT_FORMATSTR_ID_STARMATH_60 :
+ case SOT_FORMATSTR_ID_STARWRITER_8:
+ case SOT_FORMATSTR_ID_STARWRITERWEB_8:
+ case SOT_FORMATSTR_ID_STARWRITERGLOB_8:
+ case SOT_FORMATSTR_ID_STARDRAW_8:
+ case SOT_FORMATSTR_ID_STARIMPRESS_8:
+ case SOT_FORMATSTR_ID_STARCALC_8:
+ case SOT_FORMATSTR_ID_STARCHART_8:
+ case SOT_FORMATSTR_ID_STARMATH_8:
+ break;
+
+ default:
+ {
+ if ( !xTarget->hasByName( aSubElements[nInd] ) )
+ return sal_False;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Cant check storage consistency!\n" );
+ }
+
+ return sal_True;
+}
+
+
+sal_Bool SfxObjectShell::SwitchPersistance( const uno::Reference< embed::XStorage >& xStorage )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SwitchPersistance" );
+
+ sal_Bool bResult = sal_False;
+#ifdef DBG_UTIL
+ // check for wrong creation of object container
+ BOOL bHasContainer = ( pImp->mpObjectContainer != 0 );
+#endif
+ if ( xStorage.is() )
+ {
+ if ( pImp->mpObjectContainer )
+ GetEmbeddedObjectContainer().SwitchPersistence( xStorage );
+ bResult = SwitchChildrenPersistance( xStorage );
+
+ // TODO/LATER: substorages that have unknown mimetypes probably should be copied to the target storage here
+ OSL_ENSURE( StoragesOfUnknownMediaTypeAreCopied_Impl( pImp->m_xDocStorage, xStorage ),
+ "Some of substorages with unknown mimetypes is lost!" );
+ }
+
+ if ( bResult )
+ {
+ // make sure that until the storage is assigned the object container is not created by accident!
+ DBG_ASSERT( bHasContainer == (pImp->mpObjectContainer != 0), "Wrong storage in object container!" );
+ if ( pImp->m_xDocStorage != xStorage )
+ DoSaveCompleted( new SfxMedium( xStorage, GetMedium()->GetBaseURL() ) );
+
+ if ( IsEnableSetModified() )
+ SetModified( sal_True ); // ???
+ }
+
+ return bResult;
+}
+
+sal_Bool SfxObjectShell::CopyStoragesOfUnknownMediaType( const uno::Reference< embed::XStorage >& xSource,
+ const uno::Reference< embed::XStorage >& xTarget )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::CopyStoragesOfUnknownMediaType" );
+
+ // This method does not commit the target storage and should not do it
+ sal_Bool bResult = sal_True;
+
+ try
+ {
+ uno::Sequence< ::rtl::OUString > aSubElements = xSource->getElementNames();
+ for ( sal_Int32 nInd = 0; nInd < aSubElements.getLength(); nInd++ )
+ {
+ if ( aSubElements[nInd].equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Configurations" ) ) ) )
+ {
+ // The workaround for compatibility with SO7, "Configurations" substorage must be preserved
+ if ( xSource->isStorageElement( aSubElements[nInd] ) )
+ {
+ OSL_ENSURE( !xTarget->hasByName( aSubElements[nInd] ),
+ "The target storage is an output storage, the element should not exist in the target!\n" );
+
+ xSource->copyElementTo( aSubElements[nInd], xTarget, aSubElements[nInd] );
+ }
+ }
+ else if ( xSource->isStorageElement( aSubElements[nInd] ) )
+ {
+ ::rtl::OUString aMediaType;
+ ::rtl::OUString aMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
+ sal_Bool bGotMediaType = sal_False;
+
+ try
+ {
+ uno::Reference< embed::XOptimizedStorage > xOptStorage( xSource, uno::UNO_QUERY_THROW );
+ bGotMediaType =
+ ( xOptStorage->getElementPropertyValue( aSubElements[nInd], aMediaTypePropName ) >>= aMediaType );
+ }
+ catch( uno::Exception& )
+ {}
+
+ if ( !bGotMediaType )
+ {
+ uno::Reference< embed::XStorage > xSubStorage;
+ try {
+ xSubStorage = xSource->openStorageElement( aSubElements[nInd], embed::ElementModes::READ );
+ } catch( uno::Exception& )
+ {}
+
+ if ( !xSubStorage.is() )
+ {
+ // TODO/LATER: as optimization in future a substorage of target storage could be used
+ // instead of the temporary storage; this substorage should be removed later
+ // if the MimeType is wrong
+ xSubStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
+ xSource->copyStorageElementLastCommitTo( aSubElements[nInd], xSubStorage );
+ }
+
+ uno::Reference< beans::XPropertySet > xProps( xSubStorage, uno::UNO_QUERY_THROW );
+ bGotMediaType = ( xProps->getPropertyValue( aMediaTypePropName ) >>= aMediaType );
+ }
+
+ // TODO/LATER: there should be a way to detect whether an object with such a MediaType can exist
+ // probably it should be placed in the MimeType-ClassID table or in standalone table
+ if ( aMediaType.getLength()
+ && aMediaType.compareToAscii( "application/vnd.sun.star.oleobject" ) != COMPARE_EQUAL )
+ {
+ ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
+ aDataFlavor.MimeType = aMediaType;
+ sal_uInt32 nFormat = SotExchange::GetFormat( aDataFlavor );
+
+ switch ( nFormat )
+ {
+ case SOT_FORMATSTR_ID_STARWRITER_60 :
+ case SOT_FORMATSTR_ID_STARWRITERWEB_60 :
+ case SOT_FORMATSTR_ID_STARWRITERGLOB_60 :
+ case SOT_FORMATSTR_ID_STARDRAW_60 :
+ case SOT_FORMATSTR_ID_STARIMPRESS_60 :
+ case SOT_FORMATSTR_ID_STARCALC_60 :
+ case SOT_FORMATSTR_ID_STARCHART_60 :
+ case SOT_FORMATSTR_ID_STARMATH_60 :
+ case SOT_FORMATSTR_ID_STARWRITER_8:
+ case SOT_FORMATSTR_ID_STARWRITERWEB_8:
+ case SOT_FORMATSTR_ID_STARWRITERGLOB_8:
+ case SOT_FORMATSTR_ID_STARDRAW_8:
+ case SOT_FORMATSTR_ID_STARIMPRESS_8:
+ case SOT_FORMATSTR_ID_STARCALC_8:
+ case SOT_FORMATSTR_ID_STARCHART_8:
+ case SOT_FORMATSTR_ID_STARMATH_8:
+ break;
+
+ default:
+ {
+ OSL_ENSURE(
+ aSubElements[nInd].equalsAscii( "Configurations2" ) || !xTarget->hasByName( aSubElements[nInd] ),
+ "The target storage is an output storage, the element should not exist in the target!\n" );
+
+ if ( !xTarget->hasByName( aSubElements[nInd] ) )
+ {
+ xSource->copyElementTo( aSubElements[nInd], xTarget, aSubElements[nInd] );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ bResult = sal_False;
+ // TODO/LATER: a specific error could be provided
+ }
+
+ return bResult;
+}
+
+sal_Bool SfxObjectShell::GenerateAndStoreThumbnail( sal_Bool bEncrypted,
+ sal_Bool bSigned,
+ sal_Bool bIsTemplate,
+ const uno::Reference< embed::XStorage >& xStor )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::GenerateAndStoreThumbnail" );
+
+ sal_Bool bResult = sal_False;
+
+ try {
+ uno::Reference< embed::XStorage > xThumbnailStor =
+ xStor->openStorageElement( ::rtl::OUString::createFromAscii( "Thumbnails" ),
+ embed::ElementModes::READWRITE );
+ if ( xThumbnailStor.is() )
+ {
+ uno::Reference< io::XStream > xStream = xThumbnailStor->openStreamElement(
+ ::rtl::OUString::createFromAscii( "thumbnail.png" ),
+ embed::ElementModes::READWRITE );
+
+ if ( xStream.is() && WriteThumbnail( bEncrypted, bSigned, bIsTemplate, xStream ) )
+ {
+ uno::Reference< embed::XTransactedObject > xTransact( xThumbnailStor, uno::UNO_QUERY_THROW );
+ xTransact->commit();
+ bResult = sal_True;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return bResult;
+}
+
+sal_Bool SfxObjectShell::WriteThumbnail( sal_Bool bEncrypted,
+ sal_Bool bSigned,
+ sal_Bool bIsTemplate,
+ const uno::Reference< io::XStream >& xStream )
+{
+ sal_Bool bResult = sal_False;
+
+ if ( xStream.is() )
+ {
+ try {
+ uno::Reference< io::XTruncate > xTruncate( xStream->getOutputStream(), uno::UNO_QUERY_THROW );
+ xTruncate->truncate();
+
+ if ( bEncrypted )
+ {
+ sal_uInt16 nResID = GraphicHelper::getThumbnailReplacementIDByFactoryName_Impl(
+ ::rtl::OUString::createFromAscii( GetFactory().GetShortName() ),
+ bIsTemplate );
+ if ( nResID )
+ {
+ if ( !bSigned )
+ {
+ bResult = GraphicHelper::getThumbnailReplacement_Impl( nResID, xStream );
+ }
+ else
+ {
+ // retrieve the bitmap and write a signature bitmap over it
+ SfxResId aResId( nResID );
+ BitmapEx aThumbBitmap( aResId );
+ bResult = GraphicHelper::getSignedThumbnailFormatFromBitmap_Impl( aThumbBitmap, xStream );
+ }
+ }
+ }
+ else
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ GetPreviewMetaFile( sal_False );
+ if ( pMetaFile )
+ {
+ bResult = GraphicHelper::getThumbnailFormatFromGDI_Impl(
+ pMetaFile.get(), bSigned, xStream );
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ return bResult;
+}
+
+void SfxObjectShell::UpdateLinks()
+{
+}
+
+sal_Bool SfxObjectShell::QuerySaveSizeExceededModules_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
+{
+ if ( !HasBasic() )
+ return sal_True;
+
+ if ( !pImp->pBasicManager->isValid() )
+ GetBasicManager();
+ uno::Sequence< rtl::OUString > sModules;
+ if ( xHandler.is() )
+ {
+ if( pImp->pBasicManager->LegacyPsswdBinaryLimitExceeded( sModules ) )
+ {
+ ModuleSizeExceeded* pReq = new ModuleSizeExceeded( sModules );
+ uno::Reference< task::XInteractionRequest > xReq( pReq );
+ xHandler->handle( xReq );
+ return pReq->isApprove();
+ }
+ }
+ // No interaction handler, default is to continue to save
+ return sal_True;
+}
+// -----------------------------------------------------------------------------
+uno::Reference< task::XInteractionHandler > SfxObjectShell::getInteractionHandler() const
+{
+ uno::Reference< task::XInteractionHandler > xRet;
+ if ( GetMedium() )
+ xRet = GetMedium()->GetInteractionHandler();
+ return xRet;
+}
diff --git a/sfx2/source/doc/objuno.cxx b/sfx2/source/doc/objuno.cxx
new file mode 100644
index 000000000000..466f8dd43104
--- /dev/null
+++ b/sfx2/source/doc/objuno.cxx
@@ -0,0 +1,1350 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+#include <unotools/configmgr.hxx>
+#include <tools/inetdef.hxx>
+#include <unotools/bootstrap.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+
+#include <tools/errcode.hxx>
+#include <svl/cntwids.hrc>
+#include <comphelper/string.hxx>
+#include <comphelper/sequenceasvector.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <sot/storage.hxx>
+
+#include <sfx2/objuno.hxx>
+#include <sfx2/sfx.hrc>
+
+#include <vector>
+#include <algorithm>
+
+#include "sfxresid.hxx"
+#include "doc.hrc"
+
+using namespace ::com::sun::star;
+
+// TODO/REFACTOR: provide service for MS formats
+// TODO/REFACTOR: IsEncrypted is never set nor read
+// Generator is not saved ATM; which value?!
+// Generator handling must be implemented
+// Deprecate "Theme", rework IDL
+// AutoLoadEnabled is deprecated?!
+// Reasonable defaults for DateTime
+// MIMEType readonly?!
+// Announce changes about Theme, Language, Generator, removed entries etc.
+// IsEncrypted is necessary for binary formats!
+// Open: When to call PrepareDocInfoForSave? Currently only called for own formats and HTML/Writer
+// Open: How to load and save EditingTime to MS formats
+// PPT-Export should use SavePropertySet
+
+//=============================================================================
+
+// The number of user defined fields handled by the evil XDocumentInfo
+// interface. There are exactly 4. No more, no less.
+#define FOUR 4
+
+#define PROPERTY_UNBOUND 0
+#define PROPERTY_MAYBEVOID ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
+
+const SfxItemPropertyMapEntry* lcl_GetDocInfoPropertyMap()
+{
+ static SfxItemPropertyMapEntry aDocInfoPropertyMap_Impl[] =
+ {
+ { "Author" , 6 , WID_FROM, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "AutoloadEnabled" , 15, MID_DOCINFO_AUTOLOADENABLED, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 },
+ { "AutoloadSecs" , 12, MID_DOCINFO_AUTOLOADSECS, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 },
+ { "AutoloadURL" , 11, MID_DOCINFO_AUTOLOADURL, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "CreationDate" , 12, WID_DATE_CREATED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
+ { "DefaultTarget" , 13, MID_DOCINFO_DEFAULTTARGET, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "Description" , 11, MID_DOCINFO_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "DocumentStatistic", 17 , MID_DOCINFO_STATISTIC, &::getCppuType((const uno::Sequence< beans::NamedValue >*)0), PROPERTY_UNBOUND, 0 },
+ { "EditingCycles" , 13, MID_DOCINFO_REVISION, &::getCppuType((const sal_Int16*)0), PROPERTY_UNBOUND, 0 },
+ { "EditingDuration" , 15, MID_DOCINFO_EDITTIME, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 },
+ { "Generator" , 9, SID_APPLICATION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "Keywords" , 8 , WID_KEYWORDS, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "Language" , 8, MID_DOCINFO_CHARLOCALE, &::getCppuType((const lang::Locale*)0), PROPERTY_UNBOUND, 0 },
+ { "MIMEType" , 8 , WID_CONTENT_TYPE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND | ::com::sun::star::beans::PropertyAttribute::READONLY, 0 },
+ { "ModifiedBy" , 10, MID_DOCINFO_MODIFICATIONAUTHOR, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "ModifyDate" , 10, WID_DATE_MODIFIED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
+ { "PrintDate" , 9 , MID_DOCINFO_PRINTDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
+ { "PrintedBy" , 9 , MID_DOCINFO_PRINTEDBY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "Subject" , 7 , MID_DOCINFO_SUBJECT, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "Template" , 8 , MID_DOCINFO_TEMPLATE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "TemplateFileName", 16, SID_TEMPLATE_NAME, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "TemplateDate" , 12, MID_DOCINFO_TEMPLATEDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
+ { "Title" , 5 , WID_TITLE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aDocInfoPropertyMap_Impl;
+}
+
+static USHORT aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31 };
+
+inline USHORT DaysInMonth( USHORT nMonth, USHORT nYear )
+{
+ if ( nMonth != 2 )
+ return aDaysInMonth[nMonth-1];
+ else
+ {
+ if ( (((nYear % 4) == 0) && ((nYear % 100) != 0)) ||
+ ((nYear % 400) == 0) )
+ return aDaysInMonth[nMonth-1] + 1;
+ else
+ return aDaysInMonth[nMonth-1];
+ }
+}
+
+bool IsValidDateTime( const util::DateTime& rDT )
+{
+ if ( !rDT.Month || (rDT.Month > 12) )
+ return false;
+ if ( !rDT.Day || (rDT.Day > DaysInMonth( rDT.Month, rDT.Year )) )
+ return false;
+ else if ( rDT.Year <= 1582 )
+ {
+ if ( rDT.Year < 1582 )
+ return false;
+ else if ( rDT.Month < 10 )
+ return false;
+ else if ( (rDT.Month == 10) && (rDT.Day < 15) )
+ return false;
+ }
+
+ return true;
+}
+
+struct OUStringHashCode
+{
+ size_t operator()( const ::rtl::OUString& sString ) const
+ {
+ return sString.hashCode();
+ }
+};
+
+struct SfxExtendedItemPropertyMap : public SfxItemPropertyMapEntry
+{
+ ::com::sun::star::uno::Any aValue;
+};
+
+void Copy( const uno::Reference < document::XStandaloneDocumentInfo >& rSource, const uno::Reference < document::XStandaloneDocumentInfo >& rTarget )
+{
+ try
+ {
+ uno::Reference< beans::XPropertySet > xSet( rSource, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySet > xTarget( rTarget, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
+ uno::Reference< beans::XPropertyContainer > xContainer( rTarget, uno::UNO_QUERY );
+ uno::Sequence< beans::Property > lProps = xSetInfo->getProperties();
+ const beans::Property* pProps = lProps.getConstArray();
+ sal_Int32 c = lProps.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ uno::Any aValue = xSet->getPropertyValue( pProps[i].Name );
+ if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE )
+ // QUESTION: DefaultValue?!
+ xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue );
+ try
+ {
+ // it is possible that the propertysets from XML and binary files differ; we shouldn't break then
+ xTarget->setPropertyValue( pProps[i].Name, aValue );
+ }
+ catch ( uno::Exception& ) {}
+ }
+
+ sal_Int16 nCount = rSource->getUserFieldCount();
+ sal_Int16 nSupportedCount = rTarget->getUserFieldCount();
+ for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ )
+ {
+ ::rtl::OUString aPropName = rSource->getUserFieldName( nInd );
+ rTarget->setUserFieldName( nInd, aPropName );
+ ::rtl::OUString aPropVal = rSource->getUserFieldValue( nInd );
+ rTarget->setUserFieldValue( nInd, aPropVal );
+ }
+ }
+ catch ( uno::Exception& ) {}
+}
+
+class MixedPropertySetInfo : public ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo >
+{
+ private:
+
+ SfxItemPropertyMap _aPropertyMap;
+ ::rtl::OUString* _pUserKeys;
+ uno::Reference<beans::XPropertySet> _xUDProps;
+
+ public:
+
+ MixedPropertySetInfo( const SfxItemPropertyMapEntry* pFixProps,
+ ::rtl::OUString* pUserKeys,
+ uno::Reference<beans::XPropertySet> xUDProps);
+
+ virtual ~MixedPropertySetInfo();
+
+ 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);
+};
+
+//-----------------------------------------------------------------------------
+
+MixedPropertySetInfo::MixedPropertySetInfo(const SfxItemPropertyMapEntry* pFixProps,
+ ::rtl::OUString* pUserKeys,
+ uno::Reference<beans::XPropertySet> xUDProps)
+ : _aPropertyMap( pFixProps )
+ , _pUserKeys(pUserKeys)
+ , _xUDProps(xUDProps)
+{
+}
+
+//-----------------------------------------------------------------------------
+
+MixedPropertySetInfo::~MixedPropertySetInfo()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL MixedPropertySetInfo::getProperties()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ::comphelper::SequenceAsVector< ::com::sun::star::beans::Property > lProps;
+
+ // copy "fix" props
+ //todo: os: this ugly thing should be replaced
+ const SfxItemPropertyMapEntry* pFixProp = lcl_GetDocInfoPropertyMap();
+
+ while(pFixProp && pFixProp->pName)
+ {
+ ::com::sun::star::beans::Property aProp;
+
+ aProp.Name = ::rtl::OUString::createFromAscii(pFixProp->pName);
+ aProp.Handle = pFixProp->nWID;
+ aProp.Type = *(pFixProp->pType);
+ aProp.Attributes = (sal_Int16)(pFixProp->nFlags);
+
+ lProps.push_back(aProp);
+ ++pFixProp;
+ }
+
+ // copy "dynamic" props
+
+ // NB: this is really ugly:
+ // The returned properties must _not_ include the 4 user-defined fields!
+ // These are _not_ properties of the XDocumentInfo interface.
+ // Some things rely on this, e.g. Copy would break otherwise.
+ // This will have interesting consequences if someone expects to insert
+ // a property with the same name as an user-defined key, but nobody
+ // sane does that.
+ uno::Sequence<beans::Property> udProps =
+ _xUDProps->getPropertySetInfo()->getProperties();
+ for (sal_Int32 i = 0; i < udProps.getLength(); ++i) {
+ if (std::find(_pUserKeys, _pUserKeys+FOUR, udProps[i].Name)
+ == _pUserKeys+FOUR) {
+ // #i100027#: handles from udProps are not valid here
+ udProps[i].Handle = -1;
+ lProps.push_back(udProps[i]);
+ }
+ }
+
+ return lProps.getAsConstList();
+}
+
+//-----------------------------------------------------------------------------
+
+::com::sun::star::beans::Property SAL_CALL MixedPropertySetInfo::getPropertyByName(
+ const ::rtl::OUString& sName )
+ throw(::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ ::com::sun::star::beans::Property aProp;
+
+ // search it as "fix" prop
+ if( _aPropertyMap.hasPropertyByName( sName ) )
+ return _aPropertyMap.getPropertyByName( sName );
+ else
+ // search it as "dynamic" prop
+ return _xUDProps->getPropertySetInfo()->getPropertyByName(sName);
+}
+
+//-----------------------------------------------------------------------------
+
+::sal_Bool SAL_CALL MixedPropertySetInfo::hasPropertyByName(const ::rtl::OUString& sName)
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aPropertyMap.hasPropertyByName( sName ) ? // "fix" prop?
+ sal_True :
+ _xUDProps->getPropertySetInfo()->hasPropertyByName(sName); // "dynamic" prop?
+}
+
+//-----------------------------------------------------------------------------
+
+struct SfxDocumentInfoObject_Impl
+{
+ ::osl::Mutex _aMutex;
+ ::cppu::OInterfaceContainerHelper _aDisposeContainer;
+
+ sal_Bool bDisposed;
+
+ // this contains the names of the 4 user defined properties
+ // which are accessible via the evil XDocumentInfo interface
+ ::rtl::OUString m_UserDefined[FOUR];
+
+ // the actual contents
+ uno::Reference<document::XDocumentProperties> m_xDocProps;
+ SfxItemPropertyMap m_aPropertyMap;
+
+ SfxDocumentInfoObject_Impl()
+ : _aDisposeContainer( _aMutex )
+ , bDisposed(sal_False)
+ , m_xDocProps()
+ , m_aPropertyMap( lcl_GetDocInfoPropertyMap() )
+ {
+ // the number of user fields is not changeable from the outside
+ // we can't set it too high because every name/value pair will be written to the file (even if empty)
+ // currently our dialog has only 4 user keys so 4 is still a reasonable number
+ }
+
+ /// the initialization function
+ void Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined = 0);
+};
+
+void SfxDocumentInfoObject_Impl::Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined)
+{
+ if (pUserDefined == 0) {
+ // NB: this is an ugly hack; the "Properties" ui dialog displays
+ // exactly 4 user-defined fields and expects these to be available
+ // (should be redesigned), but I do not want to do this in
+ // DocumentProperties; do it here instead
+ uno::Reference<beans::XPropertyAccess> xPropAccess(
+ xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertyContainer> xPropContainer(
+ xPropAccess, uno::UNO_QUERY_THROW);
+ uno::Sequence< beans::PropertyValue >
+ props = xPropAccess->getPropertyValues();
+ sal_Int32 oldLength = props.getLength();
+ if (oldLength < FOUR) {
+ std::vector< ::rtl::OUString > names;
+ for (sal_Int32 i = 0; i < oldLength; ++i) {
+ names.push_back(props[i].Name);
+ }
+ const ::rtl::OUString sInfo(
+ String( SfxResId( STR_DOCINFO_INFOFIELD ) ));
+ for (sal_Int32 i = oldLength; i < FOUR; ++i) {
+ ::rtl::OUString sName(sInfo);
+ sal_Int32 idx = sName.indexOfAsciiL("%1", 2);
+ ::rtl::OUString name = (idx > 0)
+ ? sName.replaceAt(idx, 2, ::rtl::OUString::valueOf(i+1))
+ : sName + ::rtl::OUString::valueOf(i+1);
+ while (std::find(names.begin(), names.end(), name)
+ != names.end()) {
+ name += ::rtl::OUString::createFromAscii("'");
+ }
+ // FIXME there is a race condition here
+ try {
+ xPropContainer->addProperty(name,
+ beans::PropertyAttribute::REMOVEABLE,
+ uno::makeAny(::rtl::OUString::createFromAscii("")));
+ } catch (uno::RuntimeException) {
+ throw;
+ } catch (uno::Exception) {
+ // ignore
+ }
+ }
+ }
+ props = xPropAccess->getPropertyValues();
+ for (sal_Int32 i = 0; i < FOUR; ++i) {
+ m_UserDefined[i] = props[i].Name;
+ }
+ } else {
+ std::copy(pUserDefined, pUserDefined+FOUR, m_UserDefined);
+ }
+ m_xDocProps = xDocProps;
+}
+
+//-----------------------------------------------------------------------------
+
+SfxDocumentInfoObject::SfxDocumentInfoObject()
+ : _pImp( new SfxDocumentInfoObject_Impl() )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+SfxDocumentInfoObject::~SfxDocumentInfoObject()
+{
+ delete _pImp;
+}
+
+//-----------------------------------------------------------------------------
+
+// ::com::sun::star::lang::XInitialization:
+void SAL_CALL
+SfxDocumentInfoObject::initialize(const uno::Sequence< uno::Any > & aArguments)
+ throw (uno::RuntimeException, uno::Exception)
+{
+ if (aArguments.getLength() >= 1) {
+ uno::Any any = aArguments[0];
+ uno::Reference<document::XDocumentProperties> xDoc;
+ if (!(any >>= xDoc) || !xDoc.is()) throw lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentInfoObject::initialize: no XDocumentProperties given"),
+ *this, 0);
+ _pImp->Reset(xDoc);
+ } else {
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii(
+ "SfxDocumentInfoObject::initialize: no argument given"),
+ *this, 0);
+ }
+}
+
+// ::com::sun::star::util::XCloneable:
+uno::Reference<util::XCloneable> SAL_CALL
+SfxDocumentInfoObject::createClone() throw (uno::RuntimeException)
+{
+ SfxDocumentInfoObject *pNew = new SfxDocumentInfoObject;
+ uno::Reference< util::XCloneable >
+ xCloneable(_pImp->m_xDocProps, uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xCloneable->createClone(), uno::UNO_QUERY_THROW);
+ pNew->_pImp->Reset(xDocProps, _pImp->m_UserDefined);
+ return pNew;
+}
+
+// ::com::sun::star::document::XDocumentProperties:
+uno::Reference< document::XDocumentProperties > SAL_CALL
+SfxDocumentInfoObject::getDocumentProperties()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _pImp->m_xDocProps;
+}
+
+//-----------------------------------------------------------------------------
+
+const SfxDocumentInfoObject& SfxDocumentInfoObject::operator=( const SfxDocumentInfoObject & rOther)
+{
+ uno::Reference< util::XCloneable >
+ xCloneable(rOther._pImp->m_xDocProps, uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xCloneable->createClone(), uno::UNO_QUERY_THROW);
+ _pImp->Reset(xDocProps, rOther._pImp->m_UserDefined);
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::dispose() throw( ::com::sun::star::uno::RuntimeException )
+{
+ ::com::sun::star::lang::EventObject aEvent( (::cppu::OWeakObject *)this );
+ _pImp->_aDisposeContainer.disposeAndClear( aEvent );
+ ::osl::MutexGuard aGuard( _pImp->_aMutex );
+ _pImp->m_xDocProps = 0;
+ // NB: do not call m_xDocProps->dispose(), there could be other refs
+ _pImp->bDisposed = sal_True;
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException )
+{
+ _pImp->_aDisposeContainer.addInterface( aListener );
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException )
+{
+ _pImp->_aDisposeContainer.removeInterface( aListener );
+}
+//-----------------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SfxDocumentInfoObject::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( _pImp->_aMutex );
+
+ uno::Reference<beans::XPropertySet> xPropSet(
+ _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ MixedPropertySetInfo* pInfo = new MixedPropertySetInfo( lcl_GetDocInfoPropertyMap(), _pImp->m_UserDefined, xPropSet);
+ uno::Reference< beans::XPropertySetInfo > xInfo(
+ static_cast< beans::XPropertySetInfo* >(pInfo), uno::UNO_QUERY_THROW);
+ return xInfo;
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aValue) throw (
+ uno::RuntimeException, beans::UnknownPropertyException,
+ beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName );
+ // fix prop!
+ if ( pEntry )
+ setFastPropertyValue( pEntry->nWID, aValue );
+ else
+ // dynamic prop!
+ {
+ uno::Reference<beans::XPropertySet> xPropSet(
+ _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ return xPropSet->setPropertyValue(aPropertyName, aValue);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+uno::Any SAL_CALL SfxDocumentInfoObject::getPropertyValue(const ::rtl::OUString& aPropertyName) throw(
+ uno::RuntimeException, beans::UnknownPropertyException,
+ lang::WrappedTargetException)
+{
+ const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName );
+ // fix prop!
+ if ( pEntry )
+ return getFastPropertyValue( pEntry->nWID );
+ else
+ // dynamic prop!
+ {
+ uno::Reference<beans::XPropertySet> xPropSet(
+ _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ return xPropSet->getPropertyValue(aPropertyName);
+ }
+}
+
+sal_Bool SAL_CALL SfxDocumentInfoObject::isModified() throw(::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference<util::XModifiable> xModif(
+ _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
+ return xModif->isModified();
+}
+
+void SAL_CALL SfxDocumentInfoObject::setModified( sal_Bool bModified )
+ throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference<util::XModifiable> xModif(
+ _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
+ return xModif->setModified(bModified);
+}
+
+void SAL_CALL SfxDocumentInfoObject::addModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException )
+{
+ uno::Reference<util::XModifiable> xModif(
+ _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
+ return xModif->addModifyListener(xListener);
+}
+
+void SAL_CALL SfxDocumentInfoObject::removeModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException )
+{
+ uno::Reference<util::XModifiable> xModif(
+ _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
+ return xModif->removeModifyListener(xListener);
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::addPropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw(
+ uno::RuntimeException, beans::UnknownPropertyException,
+ lang::WrappedTargetException)
+{}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::removePropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw(
+ uno::RuntimeException, beans::UnknownPropertyException,
+ lang::WrappedTargetException)
+{}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::addVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw(
+ uno::RuntimeException, beans::UnknownPropertyException,
+ lang::WrappedTargetException)
+{}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::removeVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw(
+ uno::RuntimeException, beans::UnknownPropertyException,
+ lang::WrappedTargetException)
+{}
+
+uno::Sequence< beans::PropertyValue > SAL_CALL SfxDocumentInfoObject::getPropertyValues( void ) throw( uno::RuntimeException )
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = getPropertySetInfo();
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps = xInfo->getProperties();
+
+ const ::com::sun::star::beans::Property* pProps = aProps.getConstArray();
+ sal_uInt32 nCount = aProps.getLength();
+
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >aSeq( nCount );
+ ::com::sun::star::beans::PropertyValue* pValues = aSeq.getArray();
+
+ for ( sal_uInt32 n = 0; n < nCount; ++n )
+ {
+ ::com::sun::star::beans::PropertyValue& rCurrValue = pValues[n];
+ const ::com::sun::star::beans::Property& rCurrProp = pProps[n];
+
+ rCurrValue.Name = rCurrProp.Name;
+ rCurrValue.Handle = rCurrProp.Handle;
+ rCurrValue.Value = getPropertyValue( rCurrProp.Name );
+ }
+
+ return aSeq;
+}
+
+void SAL_CALL SfxDocumentInfoObject::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 )
+{
+ const ::com::sun::star::beans::PropertyValue* pProps = aProps.getConstArray();
+ sal_uInt32 nCount = aProps.getLength();
+
+ for ( sal_uInt32 n = 0; n < nCount; ++n )
+ {
+ const ::com::sun::star::beans::PropertyValue& rProp = pProps[n];
+ setPropertyValue( rProp.Name, rProp.Value );
+ }
+}
+
+void SAL_CALL SfxDocumentInfoObject::addProperty(const ::rtl::OUString& sName ,
+ sal_Int16 nAttributes ,
+ const ::com::sun::star::uno::Any& aDefaultValue)
+ throw(::com::sun::star::beans::PropertyExistException ,
+ ::com::sun::star::beans::IllegalTypeException ,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ // clash with "fix" properties ?
+ sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0;
+ if ( bFixProp )
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("The property \"" );
+ sMsg.append (sName );
+ sMsg.appendAscii("\" " );
+ if ( bFixProp )
+ sMsg.appendAscii(" already exists as a fix property. Please have a look into the IDL documentation of the DocumentInfo service.");
+
+ throw ::com::sun::star::beans::PropertyExistException(
+ sMsg.makeStringAndClear(),
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ uno::Reference<beans::XPropertyContainer> xPropSet(
+ _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ return xPropSet->addProperty(sName, nAttributes, aDefaultValue);
+}
+
+void SAL_CALL SfxDocumentInfoObject::removeProperty(const ::rtl::OUString& sName)
+ throw(::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::beans::NotRemoveableException ,
+ ::com::sun::star::uno::RuntimeException )
+{
+ // clash with "fix" properties ?
+ sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0;
+ if ( bFixProp )
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("The property \"" );
+ sMsg.append (sName );
+ sMsg.appendAscii("\" cant be removed. Its a fix property of the DocumentInfo service.");
+
+ throw ::com::sun::star::beans::NotRemoveableException(
+ sMsg.makeStringAndClear(),
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ uno::Reference<beans::XPropertyContainer> xPropSet(
+ _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ return xPropSet->removeProperty(sName);
+}
+
+BOOL equalsDateTime( const util::DateTime& D1, const util::DateTime& D2 )
+{
+ return D1.HundredthSeconds == D2.HundredthSeconds &&
+ D1.Seconds == D2.Seconds &&
+ D1.Minutes == D2.Minutes &&
+ D1.Hours == D2.Hours &&
+ D1.Day == D2.Day &&
+ D1.Month == D2.Month &&
+ D1.Year == D2.Year;
+}
+
+void SAL_CALL SfxDocumentInfoObject::setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) throw(
+ uno::RuntimeException, beans::UnknownPropertyException,
+ beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ // Attention: Only fix properties should be provided by this method.
+ // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-)
+
+ ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
+
+ if ( aValue.getValueType() == ::getCppuType((const ::rtl::OUString*)0) )
+ {
+ ::rtl::OUString sTemp ;
+ aValue >>= sTemp ;
+ switch ( nHandle )
+ {
+ case SID_APPLICATION :
+ _pImp->m_xDocProps->setGenerator(sTemp);
+ break;
+ case WID_FROM :
+ {
+ // QUESTION: do we still need this?
+ /*
+ // String aStrVal( sTemp );
+ if ( aStrVal.Len() > TIMESTAMP_MAXLENGTH )
+ {
+ SvAddressParser aParser( aStrVal );
+ if ( aParser.Count() > 0 )
+ {
+ String aEmail = aParser.GetEmailAddress(0);
+ String aRealname = aParser.GetRealName(0);
+
+ if ( aRealname.Len() <= TIMESTAMP_MAXLENGTH )
+ aStrVal = aRealname;
+ else if ( aEmail.Len() <= TIMESTAMP_MAXLENGTH )
+ aStrVal = aEmail;
+ }
+ } */
+
+ if ( _pImp->m_xDocProps->getAuthor() != sTemp )
+ _pImp->m_xDocProps->setAuthor(sTemp);
+ break;
+ }
+ case MID_DOCINFO_PRINTEDBY:
+ if ( _pImp->m_xDocProps->getPrintedBy() != sTemp )
+ _pImp->m_xDocProps->setPrintedBy(sTemp);
+ break;
+ case MID_DOCINFO_MODIFICATIONAUTHOR:
+ if ( _pImp->m_xDocProps->getModifiedBy() != sTemp )
+ _pImp->m_xDocProps->setModifiedBy(sTemp);
+ break;
+ case WID_TITLE :
+ {
+ if ( _pImp->m_xDocProps->getTitle() != sTemp )
+ _pImp->m_xDocProps->setTitle(sTemp);
+ break;
+ }
+ case MID_DOCINFO_SUBJECT :
+ if ( _pImp->m_xDocProps->getSubject() != sTemp )
+ _pImp->m_xDocProps->setSubject(sTemp);
+ break;
+ case WID_KEYWORDS :
+ {
+ _pImp->m_xDocProps->setKeywords(
+ ::comphelper::string::convertCommaSeparated(sTemp));
+ }
+ break;
+ case MID_DOCINFO_TEMPLATE:
+ if ( _pImp->m_xDocProps->getTemplateName() != sTemp )
+ _pImp->m_xDocProps->setTemplateName(sTemp);
+ break;
+ case SID_TEMPLATE_NAME:
+ if ( _pImp->m_xDocProps->getTemplateURL() != sTemp )
+ _pImp->m_xDocProps->setTemplateURL(sTemp);
+ break;
+ case MID_DOCINFO_DESCRIPTION:
+ if ( _pImp->m_xDocProps->getDescription() != sTemp )
+ _pImp->m_xDocProps->setDescription(sTemp);
+ break;
+ case MID_DOCINFO_AUTOLOADURL:
+ if ( _pImp->m_xDocProps->getAutoloadURL() != sTemp )
+ _pImp->m_xDocProps->setAutoloadURL(sTemp);
+ break;
+ case MID_DOCINFO_DEFAULTTARGET:
+ if ( _pImp->m_xDocProps->getDefaultTarget() != sTemp )
+ _pImp->m_xDocProps->setDefaultTarget(sTemp);
+ break;
+// case WID_CONTENT_TYPE : // this is readonly!
+ default:
+ break;
+ }
+ }
+ else if ( aValue.getValueType() == ::getCppuType((const ::com::sun::star::util::DateTime*)0) )
+ {
+ com::sun::star::util::DateTime aTemp;
+ aValue >>= aTemp ;
+ switch ( nHandle )
+ {
+ case WID_DATE_CREATED :
+ {
+ if ( !equalsDateTime(_pImp->m_xDocProps->getCreationDate(), aTemp ) )
+ {
+ _pImp->m_xDocProps->setCreationDate(aTemp);
+ }
+ break;
+ }
+ case WID_DATE_MODIFIED :
+ {
+ if ( !equalsDateTime(_pImp->m_xDocProps->getModificationDate(), aTemp ) )
+ {
+ _pImp->m_xDocProps->setModificationDate(aTemp);
+ }
+ break;
+ }
+ case MID_DOCINFO_PRINTDATE :
+ {
+ if ( !equalsDateTime(_pImp->m_xDocProps->getPrintDate(), aTemp ) )
+ {
+ _pImp->m_xDocProps->setPrintDate(aTemp);
+ }
+ break;
+ }
+ case MID_DOCINFO_TEMPLATEDATE :
+ {
+ if ( !equalsDateTime(_pImp->m_xDocProps->getTemplateDate(), aTemp ) )
+ {
+ _pImp->m_xDocProps->setTemplateDate(aTemp);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ else if ( aValue.getValueType() == ::getBooleanCppuType() )
+ {
+ sal_Bool bBoolVal = false;
+ aValue >>= bBoolVal ;
+ switch ( nHandle )
+ {
+ case MID_DOCINFO_AUTOLOADENABLED:
+ // NB: this property does not exist any more
+ // it is emulated as enabled iff delay > 0
+ if ( bBoolVal && (0 == _pImp->m_xDocProps->getAutoloadSecs()) ) {
+ _pImp->m_xDocProps->setAutoloadSecs(60); // default
+ } else if ( !bBoolVal && (0 != _pImp->m_xDocProps->getAutoloadSecs()) ) {
+ _pImp->m_xDocProps->setAutoloadSecs(0);
+ _pImp->m_xDocProps->setAutoloadURL(::rtl::OUString::createFromAscii(""));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else if ( aValue.getValueType() == ::getCppuType((const sal_Int32*)0) )
+ {
+ sal_Int32 nIntVal = 0;
+ aValue >>= nIntVal ;
+ switch ( nHandle )
+ {
+ case MID_DOCINFO_AUTOLOADSECS:
+ if ( nIntVal != _pImp->m_xDocProps->getAutoloadSecs())
+ _pImp->m_xDocProps->setAutoloadSecs(nIntVal);
+ break;
+ case MID_DOCINFO_EDITTIME:
+ if ( nIntVal != _pImp->m_xDocProps->getEditingDuration())
+ _pImp->m_xDocProps->setEditingDuration(nIntVal);
+ break;
+ default:
+ break;
+ }
+ }
+ else if ( aValue.getValueType() == ::getCppuType((const sal_Int16*)0) )
+ {
+ short nIntVal = 0;
+ aValue >>= nIntVal ;
+ switch ( nHandle )
+ {
+ case MID_DOCINFO_REVISION:
+ if ( nIntVal != _pImp->m_xDocProps->getEditingCycles())
+ _pImp->m_xDocProps->setEditingCycles(nIntVal);
+ break;
+ default:
+ break;
+ }
+ }
+ else if ( aValue.getValueType() == ::getCppuType((const uno::Sequence< beans::NamedValue >*)0) )
+ {
+ if ( nHandle == MID_DOCINFO_STATISTIC )
+ {
+ uno::Sequence < beans::NamedValue > aData;
+ aValue >>= aData;
+ {
+ _pImp->m_xDocProps->setDocumentStatistics(aData);
+ }
+ }
+ }
+ else if ( aValue.getValueType() == ::getCppuType((const lang::Locale*)0) )
+ {
+ if ( nHandle == MID_DOCINFO_CHARLOCALE )
+ {
+ lang::Locale aLocale;
+ aValue >>= aLocale;
+ lang::Locale oldLocale = _pImp->m_xDocProps->getLanguage();
+ if ( aLocale.Language != oldLocale.Language ||
+ aLocale.Country != oldLocale.Country ||
+ aLocale.Variant != oldLocale.Variant )
+ {
+ _pImp->m_xDocProps->setLanguage(aLocale);
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+::com::sun::star::uno::Any SAL_CALL SfxDocumentInfoObject::getFastPropertyValue(sal_Int32 nHandle) throw(
+ uno::RuntimeException, beans::UnknownPropertyException,
+ lang::WrappedTargetException)
+{
+ // Attention: Only fix properties should be provided by this method.
+ // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-)
+
+ ::osl::MutexGuard aGuard( _pImp->_aMutex );
+ ::com::sun::star::uno::Any aValue;
+ switch ( nHandle )
+ {
+ case SID_APPLICATION :
+ aValue <<= _pImp->m_xDocProps->getGenerator();
+ break;
+ case WID_CONTENT_TYPE :
+// FIXME this is not available anymore
+ aValue <<= ::rtl::OUString();
+ break;
+ case MID_DOCINFO_REVISION :
+ aValue <<= _pImp->m_xDocProps->getEditingCycles();
+ break;
+ case MID_DOCINFO_EDITTIME :
+ aValue <<= _pImp->m_xDocProps->getEditingDuration();
+ break;
+ case WID_FROM :
+ aValue <<= _pImp->m_xDocProps->getAuthor();
+ break;
+ case WID_DATE_CREATED :
+ if ( IsValidDateTime( _pImp->m_xDocProps->getCreationDate() ) )
+ aValue <<= _pImp->m_xDocProps->getCreationDate();
+ break;
+ case WID_TITLE :
+ aValue <<= _pImp->m_xDocProps->getTitle();
+ break;
+ case MID_DOCINFO_SUBJECT:
+ aValue <<= _pImp->m_xDocProps->getSubject();
+ break;
+ case MID_DOCINFO_MODIFICATIONAUTHOR:
+ aValue <<= _pImp->m_xDocProps->getModifiedBy();
+ break;
+ case WID_DATE_MODIFIED :
+ if ( IsValidDateTime( _pImp->m_xDocProps->getModificationDate() ) )
+ aValue <<= _pImp->m_xDocProps->getModificationDate();
+ break;
+ case MID_DOCINFO_PRINTEDBY:
+ aValue <<= _pImp->m_xDocProps->getPrintedBy();
+ break;
+ case MID_DOCINFO_PRINTDATE:
+ if ( IsValidDateTime( _pImp->m_xDocProps->getPrintDate() ) )
+ aValue <<= _pImp->m_xDocProps->getPrintDate();
+ break;
+ case WID_KEYWORDS :
+ aValue <<= ::comphelper::string::convertCommaSeparated(
+ _pImp->m_xDocProps->getKeywords());
+ break;
+ case MID_DOCINFO_DESCRIPTION:
+ aValue <<= _pImp->m_xDocProps->getDescription();
+ break;
+ case MID_DOCINFO_TEMPLATE:
+ aValue <<= _pImp->m_xDocProps->getTemplateName();
+ break;
+ case SID_TEMPLATE_NAME:
+ aValue <<= _pImp->m_xDocProps->getTemplateURL();
+ break;
+ case MID_DOCINFO_TEMPLATEDATE:
+ if ( IsValidDateTime( _pImp->m_xDocProps->getTemplateDate() ) )
+ aValue <<= _pImp->m_xDocProps->getTemplateDate();
+ break;
+ case MID_DOCINFO_AUTOLOADENABLED:
+ aValue <<= static_cast<sal_Bool>
+ ( (_pImp->m_xDocProps->getAutoloadSecs() != 0)
+ || !(_pImp->m_xDocProps->getAutoloadURL().equalsAscii("")));
+ break;
+ case MID_DOCINFO_AUTOLOADURL:
+ aValue <<= _pImp->m_xDocProps->getAutoloadURL();
+ break;
+ case MID_DOCINFO_AUTOLOADSECS:
+ aValue <<= _pImp->m_xDocProps->getAutoloadSecs();
+ break;
+ case MID_DOCINFO_DEFAULTTARGET:
+ aValue <<= _pImp->m_xDocProps->getDefaultTarget();
+ break;
+ case MID_DOCINFO_STATISTIC:
+ aValue <<= _pImp->m_xDocProps->getDocumentStatistics();
+ break;
+ case MID_DOCINFO_CHARLOCALE:
+ aValue <<= _pImp->m_xDocProps->getLanguage();
+ break;
+ default:
+ aValue <<= ::rtl::OUString();
+ break;
+ }
+
+ return aValue;
+}
+
+//-----------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL SfxDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException )
+{
+// uno::Reference<beans::XPropertyAccess> xPropSet(
+// _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+// return xPropSet->getPropertyValues().getLength();
+ return FOUR;
+}
+
+//-----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( _pImp->_aMutex );
+ if (nIndex < FOUR)
+ return _pImp->m_UserDefined[nIndex];
+ else
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( _pImp->_aMutex );
+ if (nIndex < FOUR) {
+ ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
+ uno::Reference<beans::XPropertySet> xPropSet(
+ _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ ::rtl::OUString val;
+ try {
+ xPropSet->getPropertyValue(name) >>= val;
+ return val;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception &) {
+ return ::rtl::OUString(); // ignore
+ }
+ } else
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException )
+{
+ ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
+ if (nIndex < FOUR) // yes, four!
+ {
+ // FIXME this is full of race conditions because the PropertyBag
+ // can be accessed from clients of the DocumentProperties!
+ ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
+ if (name != aName) {
+ uno::Reference<beans::XPropertySet> xPropSet(
+ _pImp->m_xDocProps->getUserDefinedProperties(),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertyContainer> xPropContainer(
+ _pImp->m_xDocProps->getUserDefinedProperties(),
+ uno::UNO_QUERY_THROW);
+ uno::Any value;
+ try {
+ value = xPropSet->getPropertyValue(name);
+ xPropContainer->removeProperty(name);
+ xPropContainer->addProperty(aName,
+ beans::PropertyAttribute::REMOVEABLE, value);
+ _pImp->m_UserDefined[nIndex] = aName;
+ } catch (beans::UnknownPropertyException) {
+ try {
+ xPropContainer->addProperty(aName,
+ beans::PropertyAttribute::REMOVEABLE,
+ uno::makeAny(::rtl::OUString::createFromAscii("")));
+ _pImp->m_UserDefined[nIndex] = aName;
+ } catch (beans::PropertyExistException) {
+ _pImp->m_UserDefined[nIndex] = aName;
+ // ignore
+ }
+ } catch (beans::PropertyExistException) {
+ try {
+ xPropContainer->addProperty(name,
+ beans::PropertyAttribute::REMOVEABLE, value);
+ } catch (beans::PropertyExistException) {
+ // bugger...
+ }
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception &) {
+ // ignore everything else; xPropSet _may_ be corrupted
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException )
+{
+ ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
+ if (nIndex < FOUR) // yes, four!
+ {
+ ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
+ uno::Reference<beans::XPropertySet> xPropSet(
+ _pImp->m_xDocProps->getUserDefinedProperties(),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertyContainer> xPropContainer(
+ _pImp->m_xDocProps->getUserDefinedProperties(),
+ uno::UNO_QUERY_THROW);
+ uno::Any aAny;
+ aAny <<= aValue;
+ try {
+ uno::Any value = xPropSet->getPropertyValue(name);
+ if (value != aAny) {
+ xPropSet->setPropertyValue(name, aAny);
+ }
+ } catch (beans::UnknownPropertyException) {
+ try {
+ // someone removed it, add it back again
+ xPropContainer->addProperty(name,
+ beans::PropertyAttribute::REMOVEABLE, aAny);
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception &) {
+ // ignore everything else
+ }
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception &) {
+ // ignore everything else
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+SFX_IMPL_XINTERFACE_2( SfxStandaloneDocumentInfoObject, SfxDocumentInfoObject, ::com::sun::star::lang::XServiceInfo, ::com::sun::star::document::XStandaloneDocumentInfo )
+SFX_IMPL_XTYPEPROVIDER_10( SfxStandaloneDocumentInfoObject, ::com::sun::star::document::XDocumentInfo, ::com::sun::star::lang::XComponent,
+ ::com::sun::star::beans::XPropertySet, ::com::sun::star::beans::XFastPropertySet, ::com::sun::star::beans::XPropertyAccess,
+ ::com::sun::star::beans::XPropertyContainer, ::com::sun::star::util::XModifiable, ::com::sun::star::util::XModifyBroadcaster,
+ ::com::sun::star::document::XStandaloneDocumentInfo, ::com::sun::star::lang::XServiceInfo )
+
+SFX_IMPL_XSERVICEINFO( SfxStandaloneDocumentInfoObject, "com.sun.star.document.StandaloneDocumentInfo", "com.sun.star.comp.sfx2.StandaloneDocumentInfo" )
+SFX_IMPL_SINGLEFACTORY( SfxStandaloneDocumentInfoObject )
+
+SfxStandaloneDocumentInfoObject::SfxStandaloneDocumentInfoObject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory )
+ : SfxDocumentInfoObject()
+ , _xFactory( xFactory )
+{
+ uno::Reference< lang::XInitialization > xDocProps(
+ _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW);
+// xDocProps->initialize(uno::Sequence<uno::Any>());
+ uno::Any a;
+ a <<= xDocProps;
+ uno::Sequence<uno::Any> args(1);
+ args[0] = a;
+ initialize(args);
+}
+
+//-----------------------------------------------------------------------------
+
+SfxStandaloneDocumentInfoObject::~SfxStandaloneDocumentInfoObject()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+uno::Reference< embed::XStorage > GetStorage_Impl( const ::rtl::OUString& rName, sal_Bool bWrite, uno::Reference < lang::XMultiServiceFactory >& xFactory )
+{
+ // catch unexpected exceptions under solaris
+ // Client code checks the returned reference but is not interested on error details.
+ try
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ return ::comphelper::OStorageHelper::GetStorageFromURL(
+ rName,
+ bWrite ? embed::ElementModes::READWRITE : embed::ElementModes::READ,
+ xFactory );
+ }
+ catch(const uno::Exception&)
+ {}
+
+ return uno::Reference< embed::XStorage >();
+}
+
+//-----------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException )
+{
+ return SfxDocumentInfoObject::getUserFieldCount();
+}
+
+//-----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
+{
+ return SfxDocumentInfoObject::getUserFieldName(nIndex);
+}
+
+//-----------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
+{
+ return SfxDocumentInfoObject::getUserFieldValue(nIndex);
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException )
+{
+ SfxDocumentInfoObject::setUserFieldName( nIndex, aName );
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException )
+{
+ SfxDocumentInfoObject::setUserFieldValue( nIndex, aValue );
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxStandaloneDocumentInfoObject::loadFromURL(const ::rtl::OUString& aURL)
+ throw( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException )
+{
+ sal_Bool bOK = sal_False;
+
+ ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
+ uno::Reference< document::XDocumentProperties > xDocProps(
+ _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW);
+// uno::Reference< lang::XInitialization > xInit(xDocProps, uno::UNO_QUERY_THROW);
+// xInit->initialize(uno::Sequence<uno::Any>());
+ _pImp->Reset(xDocProps);
+ aGuard.clear();
+
+ uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_False, _xFactory );
+ if ( xStorage.is() )
+ {
+ try
+ {
+ uno::Sequence<beans::PropertyValue> medium(2);
+ medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL");
+ medium[0].Value <<= aURL;
+ medium[1].Name = ::rtl::OUString::createFromAscii("URL");
+ medium[1].Value <<= aURL;
+ _pImp->m_xDocProps->loadFromStorage(xStorage, medium);
+ _pImp->Reset(_pImp->m_xDocProps);
+ bOK = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ else
+ {
+ uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY );
+ if ( xBinary.is() )
+ {
+ xBinary->loadFromURL( aURL );
+ bOK = sal_True;
+ uno::Reference < document::XStandaloneDocumentInfo > xTarget( static_cast < document::XStandaloneDocumentInfo*> (this), uno::UNO_QUERY );
+ Copy( xBinary, xTarget );
+ }
+ }
+
+ if ( !bOK )
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTREAD );
+}
+
+//-----------------------------------------------------------------------------
+
+void SAL_CALL SfxStandaloneDocumentInfoObject::storeIntoURL(const ::rtl::OUString& aURL) throw( ::com::sun::star::io::IOException )
+{
+ sal_Bool bOK = sal_False;
+ uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_True, _xFactory );
+ if ( xStorage.is() )
+ {
+ try
+ {
+ uno::Sequence<beans::PropertyValue> medium(2);
+ medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL");
+ medium[0].Value <<= aURL;
+ medium[1].Name = ::rtl::OUString::createFromAscii("URL");
+ medium[1].Value <<= aURL;
+
+ _pImp->m_xDocProps->storeToStorage(xStorage, medium);
+ bOK = sal_True;
+ }
+ catch( io::IOException & )
+ {
+ throw;
+ }
+ catch( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ else
+ {
+ uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY );
+ if ( xBinary.is() )
+ {
+ Copy( this, xBinary );
+ xBinary->storeIntoURL( aURL );
+ bOK = sal_True;
+ }
+ }
+
+ if ( !bOK )
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTWRITE );
+}
+
diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx
new file mode 100755
index 000000000000..f202266dd74e
--- /dev/null
+++ b/sfx2/source/doc/objxtor.cxx
@@ -0,0 +1,1118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "arrdecl.hxx"
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/util/XCloseBroadcaster.hpp>
+#include <com/sun/star/util/XCloseListener.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <vos/mutex.hxx>
+
+#ifndef _SV_RESARY_HXX
+#include <tools/resary.hxx>
+#endif
+#ifndef _MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#ifndef _WRKWIN_HXX //autogen
+#include <vcl/wrkwin.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <svl/eitem.hxx>
+#include <tools/rtti.hxx>
+#include <svl/lstner.hxx>
+#include <sfxhelp.hxx>
+#include <basic/sbstar.hxx>
+#include <svl/stritem.hxx>
+#include <basic/sbx.hxx>
+#include <unotools/eventcfg.hxx>
+
+#include <sfx2/objsh.hxx>
+#include <sfx2/signaturestate.hxx>
+#include <sfx2/sfxmodelfactory.hxx>
+
+#ifndef _BASIC_SBUNO_HXX
+#include <basic/sbuno.hxx>
+#endif
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <unotools/printwarningoptions.hxx>
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
+#include <comphelper/processfactory.hxx>
+#endif
+
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
+#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
+#include <com/sun/star/document/XEmbeddedScripts.hpp>
+#include <com/sun/star/document/XScriptInvocationContext.hpp>
+
+#include <svl/urihelper.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/sharecontrolfile.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <svtools/asynclink.hxx>
+#include <tools/diagnose_ex.h>
+#include <sot/clsids.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/event.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include "sfxresid.hxx"
+#include "objshimp.hxx"
+#include "appbas.hxx"
+#include "sfxtypes.hxx"
+#include <sfx2/evntconf.hxx>
+#include <sfx2/request.hxx>
+#include "doc.hrc"
+#include "sfxlocal.hrc"
+#include "appdata.hxx"
+#include <sfx2/appuno.hxx>
+#include <sfx2/sfxsids.hrc>
+#include "basmgr.hxx"
+#include "QuerySaveDocument.hxx"
+#include "helpid.hrc"
+#include <sfx2/msg.hxx>
+#include "appbaslib.hxx"
+#include <sfx2/sfxbasemodel.hxx>
+
+#include <basic/basicmanagerrepository.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::document;
+
+using ::basic::BasicManagerRepository;
+#include <uno/mapping.hxx>
+
+//====================================================================
+
+DBG_NAME(SfxObjectShell)
+
+#define DocumentInfo
+#include "sfxslots.hxx"
+
+static WeakReference< XInterface > s_xCurrentComponent;
+
+//=========================================================================
+
+
+//=========================================================================
+
+class SfxModelListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
+{
+ SfxObjectShell* mpDoc;
+public:
+ SfxModelListener_Impl( SfxObjectShell* pDoc ) : mpDoc(pDoc) {};
+ virtual void SAL_CALL queryClosing( const com::sun::star::lang::EventObject& aEvent, sal_Bool bDeliverOwnership )
+ throw ( com::sun::star::uno::RuntimeException, com::sun::star::util::CloseVetoException) ;
+ virtual void SAL_CALL notifyClosing( const com::sun::star::lang::EventObject& aEvent ) throw ( com::sun::star::uno::RuntimeException ) ;
+ virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& aEvent ) throw ( com::sun::star::uno::RuntimeException ) ;
+
+};
+
+void SAL_CALL SfxModelListener_Impl::queryClosing( const com::sun::star::lang::EventObject& , sal_Bool )
+ throw ( com::sun::star::uno::RuntimeException, com::sun::star::util::CloseVetoException)
+{
+}
+
+void SAL_CALL SfxModelListener_Impl::notifyClosing( const com::sun::star::lang::EventObject& ) throw ( com::sun::star::uno::RuntimeException )
+{
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ mpDoc->Broadcast( SfxSimpleHint(SFX_HINT_DEINITIALIZING) );
+}
+
+void SAL_CALL SfxModelListener_Impl::disposing( const com::sun::star::lang::EventObject& _rEvent ) throw ( com::sun::star::uno::RuntimeException )
+{
+ // am I ThisComponent in AppBasic?
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ if ( SfxObjectShell::GetCurrentComponent() == _rEvent.Source )
+ {
+ // remove ThisComponent reference from AppBasic
+ SfxObjectShell::SetCurrentComponent( Reference< XInterface >() );
+ }
+
+ if ( mpDoc->Get_Impl()->bHiddenLockedByAPI )
+ {
+ mpDoc->Get_Impl()->bHiddenLockedByAPI = FALSE;
+ mpDoc->OwnerLock(FALSE);
+ }
+ else if ( !mpDoc->Get_Impl()->bClosing )
+ // GCC stuerzt ab, wenn schon im dtor, also vorher Flag abfragen
+ mpDoc->DoClose();
+}
+
+TYPEINIT1(SfxObjectShell, SfxShell);
+
+//--------------------------------------------------------------------
+SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell )
+ :mpObjectContainer(0)
+ ,pBasicManager( new SfxBasicManagerHolder )
+ ,rDocShell( _rDocShell )
+ ,aMacroMode( *this )
+ ,pProgress( 0)
+ ,nTime()
+ ,nVisualDocumentNumber( USHRT_MAX)
+ ,nDocumentSignatureState( SIGNATURESTATE_UNKNOWN )
+ ,nScriptingSignatureState( SIGNATURESTATE_UNKNOWN )
+ ,bInList( sal_False)
+ ,bClosing( sal_False)
+ ,bIsSaving( sal_False)
+ ,bPasswd( sal_False)
+ ,bIsTmp( sal_False)
+ ,bIsNamedVisible( sal_False)
+ ,bIsTemplate(sal_False)
+ ,bIsAbortingImport ( sal_False)
+ ,bImportDone ( sal_False)
+ ,bInPrepareClose( sal_False )
+ ,bPreparedForClose( sal_False )
+ ,bWaitingForPicklist( sal_True )
+ ,bForbidReload( sal_False )
+ ,bBasicInitialized( sal_False )
+ ,bIsPrintJobCancelable( sal_True )
+ ,bOwnsStorage( sal_True )
+ ,bNoBaseURL( sal_False )
+ ,bInitialized( sal_False )
+ ,bSignatureErrorIsShown( sal_False )
+ ,bModelInitialized( sal_False )
+ ,bPreserveVersions( sal_True )
+ ,m_bMacroSignBroken( sal_False )
+ ,m_bNoBasicCapabilities( sal_False )
+ ,m_bDocRecoverySupport( sal_True )
+ ,bQueryLoadTemplate( sal_True )
+ ,bLoadReadonly( sal_False )
+ ,bUseUserData( sal_True )
+ ,bSaveVersionOnClose( sal_False )
+ ,m_bSharedXMLFlag( sal_False )
+ ,m_bAllowShareControlFileClean( sal_True )
+ ,lErr(ERRCODE_NONE)
+ ,nEventId ( 0)
+ ,pReloadTimer ( 0)
+ ,pMarkData( 0 )
+ ,nLoadedFlags ( SFX_LOADED_ALL )
+ ,nFlagsInProgress( 0 )
+ ,bModalMode( sal_False )
+ ,bRunningMacro( sal_False )
+ ,bReloadAvailable( sal_False )
+ ,nAutoLoadLocks( 0 )
+ ,pModule( 0 )
+ ,eFlags( SFXOBJECTSHELL_UNDEFINED )
+ ,bReadOnlyUI( sal_False )
+ ,bHiddenLockedByAPI( sal_False )
+ ,nStyleFilter( 0 )
+ ,bDisposing( sal_False )
+ ,m_bEnableSetModified( sal_True )
+ ,m_bIsModified( sal_False )
+ ,m_nMapUnit( MAP_100TH_MM )
+ ,m_bCreateTempStor( sal_False )
+ ,m_bIsInit( sal_False )
+ ,m_bIncomplEncrWarnShown( sal_False )
+ ,m_nModifyPasswordHash( 0 )
+ ,m_bModifyPasswordEntered( sal_False )
+{
+ SfxObjectShell* pDoc = &_rDocShell;
+ SfxObjectShellArr_Impl &rArr = SFX_APP()->GetObjectShells_Impl();
+ rArr.C40_INSERT( SfxObjectShell, pDoc, rArr.Count() );
+ bInList = sal_True;
+}
+
+//--------------------------------------------------------------------
+
+SfxObjectShell_Impl::~SfxObjectShell_Impl()
+{
+ delete pBasicManager;
+}
+
+//--------------------------------------------------------------------
+
+SfxObjectShell::SfxObjectShell( const sal_uInt64 i_nCreationFlags )
+ : pImp( new SfxObjectShell_Impl( *this ) )
+ , pMedium(0)
+ , pStyleSheetPool(0)
+ , eCreateMode( ( i_nCreationFlags & SFXMODEL_EMBEDDED_OBJECT ) ? SFX_CREATE_MODE_EMBEDDED : SFX_CREATE_MODE_STANDARD )
+ , bHasName( sal_False )
+{
+ DBG_CTOR(SfxObjectShell, 0);
+
+ const bool bScriptSupport = ( i_nCreationFlags & SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) == 0;
+ if ( !bScriptSupport )
+ SetHasNoBasic();
+
+ const bool bDocRecovery = ( i_nCreationFlags & SFXMODEL_DISABLE_DOCUMENT_RECOVERY ) == 0;
+ if ( !bDocRecovery )
+ pImp->m_bDocRecoverySupport = sal_False;
+}
+
+//--------------------------------------------------------------------
+
+// initializes a document from a file-description
+
+SfxObjectShell::SfxObjectShell
+(
+ SfxObjectCreateMode eMode /* Zweck, zu dem die SfxObjectShell
+ erzeugt wird:
+
+ SFX_CREATE_MODE_EMBEDDED (default)
+ als SO-Server aus einem anderen
+ Dokument heraus
+
+ SFX_CREATE_MODE_STANDARD,
+ als normales, selbst"aendig ge"offnetes
+ Dokument
+
+ SFX_CREATE_MODE_PREVIEW
+ um ein Preview durchzuf"uhren,
+ ggf. werden weniger Daten ben"otigt
+
+ SFX_CREATE_MODE_ORGANIZER
+ um im Organizer dargestellt zu
+ werden, hier werden keine Inhalte
+ ben"otigt */
+)
+
+/* [Beschreibung]
+
+ Konstruktor der Klasse SfxObjectShell.
+*/
+
+: pImp( new SfxObjectShell_Impl( *this ) ),
+ pMedium(0),
+ pStyleSheetPool(0),
+ eCreateMode(eMode),
+ bHasName( sal_False )
+{
+ DBG_CTOR(SfxObjectShell, 0);
+}
+
+//--------------------------------------------------------------------
+
+// virtual dtor of typical base-class SfxObjectShell
+
+SfxObjectShell::~SfxObjectShell()
+{
+ DBG_DTOR(SfxObjectShell, 0);
+
+ if ( IsEnableSetModified() )
+ EnableSetModified( sal_False );
+
+ // Niemals GetInPlaceObject() aufrufen, der Zugriff auf den
+ // Ableitungszweig SfxInternObject ist wegen eines Compiler Bugs nicht
+ // erlaubt
+ SfxObjectShell::Close();
+ pImp->pBaseModel.set( NULL );
+
+ DELETEX(pImp->pReloadTimer );
+
+ SfxApplication *pSfxApp = SFX_APP();
+ if ( USHRT_MAX != pImp->nVisualDocumentNumber )
+ pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
+
+ // Basic-Manager zerst"oren
+ pImp->pBasicManager->reset( NULL );
+
+ if ( pSfxApp->GetDdeService() )
+ pSfxApp->RemoveDdeTopic( this );
+
+ pImp->pBaseModel.set( NULL );
+
+ // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned!
+ if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( sal_False ) == pImp->m_xDocStorage )
+ pMedium->CanDisposeStorage_Impl( sal_False );
+
+ if ( pImp->mpObjectContainer )
+ {
+ pImp->mpObjectContainer->CloseEmbeddedObjects();
+ delete pImp->mpObjectContainer;
+ }
+
+ if ( pImp->bOwnsStorage && pImp->m_xDocStorage.is() )
+ pImp->m_xDocStorage->dispose();
+
+ if ( pMedium )
+ {
+ pMedium->CloseAndReleaseStreams_Impl();
+
+ if ( IsDocShared() )
+ FreeSharedFile();
+
+ DELETEX( pMedium );
+ }
+
+ // The removing of the temporary file must be done as the latest step in the document destruction
+ if ( pImp->aTempName.Len() )
+ {
+ String aTmp;
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->aTempName, aTmp );
+ ::utl::UCBContentHelper::Kill( aTmp );
+ }
+
+ delete pImp;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::Stamp_SetPrintCancelState(sal_Bool bState)
+{
+ pImp->bIsPrintJobCancelable = bState;
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::Stamp_GetPrintCancelState() const
+{
+ return pImp->bIsPrintJobCancelable;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::ViewAssigned()
+
+/* [Beschreibung]
+
+ Diese Methode wird gerufen, wenn eine View zugewiesen wird.
+*/
+
+{
+}
+
+//--------------------------------------------------------------------
+// closes the Object and all its views
+
+sal_Bool SfxObjectShell::Close()
+{
+ {DBG_CHKTHIS(SfxObjectShell, 0);}
+ SfxObjectShellRef aRef(this);
+ if ( !pImp->bClosing )
+ {
+ // falls noch ein Progress l"auft, nicht schlie\sen
+ if ( !pImp->bDisposing && GetProgress() )
+ return sal_False;
+
+ pImp->bClosing = sal_True;
+ Reference< util::XCloseable > xCloseable( GetBaseModel(), UNO_QUERY );
+
+ if ( xCloseable.is() )
+ {
+ try
+ {
+ xCloseable->close( sal_True );
+ }
+ catch( Exception& )
+ {
+ pImp->bClosing = sal_False;
+ }
+ }
+
+ if ( pImp->bClosing )
+ {
+ // aus Document-Liste austragen
+ SfxApplication *pSfxApp = SFX_APP();
+ SfxObjectShellArr_Impl &rDocs = pSfxApp->GetObjectShells_Impl();
+ const SfxObjectShell *pThis = this;
+ sal_uInt16 nPos = rDocs.GetPos(pThis);
+ if ( nPos < rDocs.Count() )
+ rDocs.Remove( nPos );
+ pImp->bInList = sal_False;
+ }
+ }
+
+ return sal_True;
+}
+
+//--------------------------------------------------------------------
+
+// returns a pointer the first SfxDocument of specified type
+
+SfxObjectShell* SfxObjectShell::GetFirst
+(
+ const TypeId* pType ,
+ sal_Bool bOnlyVisible
+)
+{
+ SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl();
+
+ // seach for a SfxDocument of the specified type
+ for ( sal_uInt16 nPos = 0; nPos < rDocs.Count(); ++nPos )
+ {
+ SfxObjectShell* pSh = rDocs.GetObject( nPos );
+ if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() )
+ continue;
+
+ if ( ( !pType || pSh->IsA(*pType) ) &&
+ ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True )))
+ return pSh;
+ }
+
+ return 0;
+}
+//--------------------------------------------------------------------
+
+// returns a pointer to the next SfxDocument of specified type behind *pDoc
+
+SfxObjectShell* SfxObjectShell::GetNext
+(
+ const SfxObjectShell& rPrev,
+ const TypeId* pType,
+ sal_Bool bOnlyVisible
+)
+{
+ SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl();
+
+ // refind the specified predecessor
+ sal_uInt16 nPos;
+ for ( nPos = 0; nPos < rDocs.Count(); ++nPos )
+ if ( rDocs.GetObject(nPos) == &rPrev )
+ break;
+
+ // search for the next SfxDocument of the specified type
+ for ( ++nPos; nPos < rDocs.Count(); ++nPos )
+ {
+ SfxObjectShell* pSh = rDocs.GetObject( nPos );
+ if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() )
+ continue;
+
+ if ( ( !pType || pSh->IsA(*pType) ) &&
+ ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True )))
+ return pSh;
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------
+
+SfxObjectShell* SfxObjectShell::Current()
+{
+ SfxViewFrame *pFrame = SfxViewFrame::Current();
+ return pFrame ? pFrame->GetObjectShell() : 0;
+}
+
+//------------------------------------------------------------------------
+
+struct BoolEnv_Impl
+{
+ SfxObjectShell_Impl* pImp;
+ BoolEnv_Impl( SfxObjectShell_Impl* pImpP) : pImp( pImpP )
+ { pImpP->bInPrepareClose = sal_True; }
+ ~BoolEnv_Impl() { pImp->bInPrepareClose = sal_False; }
+};
+
+
+sal_uInt16 SfxObjectShell::PrepareClose
+(
+ sal_Bool bUI, // sal_True: Dialoge etc. erlaubt, sal_False: silent-mode
+ sal_Bool bForBrowsing
+)
+{
+ if( pImp->bInPrepareClose || pImp->bPreparedForClose )
+ return sal_True;
+ BoolEnv_Impl aBoolEnv( pImp );
+
+ // DocModalDialog?
+ if ( IsInModalMode() )
+ return sal_False;
+
+ SfxViewFrame* pFirst = SfxViewFrame::GetFirst( this );
+ if( pFirst && !pFirst->GetFrame().PrepareClose_Impl( bUI, bForBrowsing ) )
+ return sal_False;
+
+ // prepare views for closing
+ for ( SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
+ pFrm; pFrm = SfxViewFrame::GetNext( *pFrm, this ) )
+ {
+ DBG_ASSERT(pFrm->GetViewShell(),"KeineShell");
+ if ( pFrm->GetViewShell() )
+ {
+ sal_uInt16 nRet = pFrm->GetViewShell()->PrepareClose( bUI, bForBrowsing );
+ if ( nRet != sal_True )
+ return nRet;
+ }
+ }
+
+ SfxApplication *pSfxApp = SFX_APP();
+ pSfxApp->NotifyEvent( SfxEventHint(SFX_EVENT_PREPARECLOSEDOC, GlobalEventConfig::GetEventName(STR_EVENT_PREPARECLOSEDOC), this) );
+
+ if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ pImp->bPreparedForClose = sal_True;
+ return sal_True;
+ }
+
+ // ggf. nachfragen, ob gespeichert werden soll
+ // nur fuer in sichtbaren Fenstern dargestellte Dokumente fragen
+ SfxViewFrame *pFrame = SfxObjectShell::Current() == this
+ ? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this );
+
+ sal_Bool bClose = sal_False;
+ if ( bUI && IsModified() && pFrame )
+ {
+ // minimierte restoren
+ SfxFrame& rTop = pFrame->GetTopFrame();
+ SfxViewFrame::SetViewFrame( rTop.GetCurrentViewFrame() );
+ pFrame->GetFrame().Appear();
+
+ // fragen, ob gespeichert werden soll
+ short nRet = RET_YES;
+ //TODO/CLEANUP
+ //brauchen wir UI=2 noch?
+ //if( SfxApplication::IsPlugin() == sal_False || bUI == 2 )
+ {
+ //initiate help agent to inform about "print modifies the document"
+ SvtPrintWarningOptions aPrintOptions;
+ if (aPrintOptions.IsModifyDocumentOnPrintingAllowed() &&
+ HasName() && getDocProperties()->getPrintDate().Month > 0)
+ {
+ SfxHelp::OpenHelpAgent( &pFirst->GetFrame(), HID_CLOSE_WARNING );
+ }
+ const Reference< XTitle > xTitle( *pImp->pBaseModel.get(), UNO_QUERY_THROW );
+ const ::rtl::OUString sTitle = xTitle->getTitle ();
+ nRet = ExecuteQuerySaveDocument(&pFrame->GetWindow(),sTitle);
+ }
+ /*HACK for plugin::destroy()*/
+
+ if ( RET_YES == nRet )
+ {
+ // per Dispatcher speichern
+ const SfxPoolItem *pPoolItem;
+ if ( IsSaveVersionOnClose() )
+ {
+ SfxStringItem aItem( SID_DOCINFO_COMMENTS, String( SfxResId( STR_AUTOMATICVERSION ) ) );
+ SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
+ const SfxPoolItem* ppArgs[] = { &aItem, &aWarnItem, 0 };
+ pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs );
+ }
+ else
+ {
+ SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
+ const SfxPoolItem* ppArgs[] = { &aWarnItem, 0 };
+ pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs );
+ }
+
+ if ( !pPoolItem || pPoolItem->ISA(SfxVoidItem) || ( pPoolItem->ISA(SfxBoolItem) && !( (const SfxBoolItem*) pPoolItem )->GetValue() ) )
+ return sal_False;
+ else
+ bClose = sal_True;
+ }
+ else if ( RET_CANCEL == nRet )
+ // abgebrochen
+ return sal_False;
+ else if ( RET_NEWTASK == nRet )
+ {
+ return RET_NEWTASK;
+ }
+ else
+ {
+ // Bei Nein nicht noch Informationlost
+ bClose = sal_True;
+ }
+ }
+
+ pImp->bPreparedForClose = sal_True;
+ return sal_True;
+}
+
+//--------------------------------------------------------------------
+namespace
+{
+ static BasicManager* lcl_getBasicManagerForDocument( const SfxObjectShell& _rDocument )
+ {
+ if ( !_rDocument.Get_Impl()->m_bNoBasicCapabilities )
+ {
+ if ( !_rDocument.Get_Impl()->bBasicInitialized )
+ const_cast< SfxObjectShell& >( _rDocument ).InitBasicManager_Impl();
+ return _rDocument.Get_Impl()->pBasicManager->get();
+ }
+
+ // assume we do not have Basic ourself, but we can refer to another
+ // document which does (by our model's XScriptInvocationContext::getScriptContainer).
+ // In this case, we return the BasicManager of this other document.
+
+ OSL_ENSURE( !Reference< XEmbeddedScripts >( _rDocument.GetModel(), UNO_QUERY ).is(),
+ "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" );
+ Reference< XModel > xForeignDocument;
+ Reference< XScriptInvocationContext > xContext( _rDocument.GetModel(), UNO_QUERY );
+ if ( xContext.is() )
+ {
+ xForeignDocument.set( xContext->getScriptContainer(), UNO_QUERY );
+ OSL_ENSURE( xForeignDocument.is() && xForeignDocument != _rDocument.GetModel(),
+ "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" );
+ }
+
+ BasicManager* pBasMgr = NULL;
+ if ( xForeignDocument.is() )
+ pBasMgr = ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument );
+
+ return pBasMgr;
+ }
+}
+
+//--------------------------------------------------------------------
+
+BasicManager* SfxObjectShell::GetBasicManager() const
+{
+ BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
+ if ( !pBasMgr )
+ pBasMgr = SFX_APP()->GetBasicManager();
+ return pBasMgr;
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::SetHasNoBasic()
+{
+ pImp->m_bNoBasicCapabilities = sal_True;
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::HasBasic() const
+{
+ if ( pImp->m_bNoBasicCapabilities )
+ return sal_False;
+
+ if ( !pImp->bBasicInitialized )
+ const_cast< SfxObjectShell* >( this )->InitBasicManager_Impl();
+
+ return pImp->pBasicManager->isValid();
+}
+
+//--------------------------------------------------------------------
+namespace
+{
+ const Reference< XLibraryContainer >&
+ lcl_getOrCreateLibraryContainer( bool _bScript, Reference< XLibraryContainer >& _rxContainer,
+ const Reference< XModel >& _rxDocument )
+ {
+ if ( !_rxContainer.is() )
+ {
+ try
+ {
+ Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY );
+ const Reference< XComponentContext > xContext(
+ ::comphelper::getProcessComponentContext() );
+ _rxContainer.set ( _bScript
+ ? DocumentScriptLibraryContainer::create(
+ xContext, xStorageDoc )
+ : DocumentDialogLibraryContainer::create(
+ xContext, xStorageDoc )
+ , UNO_QUERY_THROW );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ return _rxContainer;
+ }
+}
+
+//--------------------------------------------------------------------
+
+Reference< XLibraryContainer > SfxObjectShell::GetDialogContainer()
+{
+ if ( !pImp->m_bNoBasicCapabilities )
+ return lcl_getOrCreateLibraryContainer( false, pImp->xDialogLibraries, GetModel() );
+
+ BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
+ if ( pBasMgr )
+ return pBasMgr->GetDialogLibraryContainer().get();
+
+ OSL_ENSURE( false, "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?" );
+ return SFX_APP()->GetDialogContainer();
+}
+
+//--------------------------------------------------------------------
+
+Reference< XLibraryContainer > SfxObjectShell::GetBasicContainer()
+{
+ if ( !pImp->m_bNoBasicCapabilities )
+ return lcl_getOrCreateLibraryContainer( true, pImp->xBasicLibraries, GetModel() );
+
+ BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
+ if ( pBasMgr )
+ return pBasMgr->GetScriptLibraryContainer().get();
+
+ OSL_ENSURE( false, "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?" );
+ return SFX_APP()->GetBasicContainer();
+}
+
+//--------------------------------------------------------------------
+
+StarBASIC* SfxObjectShell::GetBasic() const
+{
+ return GetBasicManager()->GetLib(0);
+}
+
+//--------------------------------------------------------------------
+
+void SfxObjectShell::InitBasicManager_Impl()
+/* [Beschreibung]
+
+ creates a document's BasicManager and loads it, if we are already based on
+ a storage.
+
+ [Anmerkung]
+
+ Diese Methode mu"s aus den "Uberladungen von <SvPersist::Load()> (mit
+ dem pStor aus dem Parameter von Load()) sowie aus der "Uberladung
+ von <SvPersist::InitNew()> (mit pStor = 0) gerufen werden.
+*/
+
+{
+ DBG_ASSERT( !pImp->bBasicInitialized && !pImp->pBasicManager->isValid(), "Lokaler BasicManager bereits vorhanden");
+ pImp->bBasicInitialized = TRUE;
+
+ pImp->pBasicManager->reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) );
+ DBG_ASSERT( pImp->pBasicManager->isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" );
+}
+
+//--------------------------------------------------------------------
+#if 0 //(mba)
+SotObjectRef SfxObjectShell::CreateAggObj( const SotFactory* pFact )
+{
+ // SvDispatch?
+ SotFactory* pDispFact = SvDispatch::ClassFactory();
+ if( pFact == pDispFact )
+ return( (SfxShellObject*)GetSbxObject() );
+
+ // sonst unbekannte Aggregation
+ DBG_ERROR("unkekannte Factory");
+ SotObjectRef aSvObjectRef;
+ return aSvObjectRef;
+}
+#endif
+
+//--------------------------------------------------------------------
+
+sal_uInt16 SfxObjectShell::Count()
+{
+ return SFX_APP()->GetObjectShells_Impl().Count();
+}
+
+//--------------------------------------------------------------------
+
+sal_Bool SfxObjectShell::DoClose()
+{
+ return Close();
+}
+
+//--------------------------------------------------------------------
+
+SfxObjectShell* SfxObjectShell::GetObjectShell()
+{
+ return this;
+}
+
+//--------------------------------------------------------------------
+
+SEQUENCE< OUSTRING > SfxObjectShell::GetEventNames()
+{
+ static uno::Sequence< ::rtl::OUString >* pEventNameContainer = NULL;
+
+ if ( !pEventNameContainer )
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( !pEventNameContainer )
+ {
+ static uno::Sequence< ::rtl::OUString > aEventNameContainer = GlobalEventConfig().getElementNames();
+ pEventNameContainer = &aEventNameContainer;
+ }
+ }
+
+ return *pEventNameContainer;
+}
+
+//--------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetModel() const
+{
+ return GetBaseModel();
+}
+
+void SfxObjectShell::SetBaseModel( SfxBaseModel* pModel )
+{
+ OSL_ENSURE( !pImp->pBaseModel.is() || pModel == NULL, "Model already set!" );
+ pImp->pBaseModel.set( pModel );
+ if ( pImp->pBaseModel.is() )
+ {
+ pImp->pBaseModel->addCloseListener( new SfxModelListener_Impl(this) );
+ }
+}
+
+//--------------------------------------------------------------------
+
+::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetBaseModel() const
+{
+ return pImp->pBaseModel.get();
+}
+/* -----------------------------10.09.2001 15:56------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet)
+{
+ pImp->nStyleFilter = nSet;
+}
+
+sal_uInt16 SfxObjectShell::GetAutoStyleFilterIndex()
+{
+ return pImp->nStyleFilter;
+}
+
+
+void SfxObjectShell::SetCurrentComponent( const Reference< XInterface >& _rxComponent )
+{
+ Reference< XInterface > xTest(s_xCurrentComponent);
+ if ( _rxComponent == xTest )
+ // nothing to do
+ return;
+ // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not
+ // /required/ for "_rxComponent == s_xCurrentComponent.get()".
+ // In other words, it's still possible that we here do something which is not necessary,
+ // but we should have filtered quite some unnecessary calls already.
+
+ BasicManager* pAppMgr = SFX_APP()->GetBasicManager();
+ s_xCurrentComponent = _rxComponent;
+ if ( pAppMgr )
+ pAppMgr->SetGlobalUNOConstant( "ThisComponent", makeAny( _rxComponent ) );
+
+#if OSL_DEBUG_LEVEL > 0
+ const char* pComponentImplName = _rxComponent.get() ? typeid( *_rxComponent.get() ).name() : "void";
+ OSL_TRACE( "current component is a %s\n", pComponentImplName );
+#endif
+}
+
+Reference< XInterface > SfxObjectShell::GetCurrentComponent()
+{
+ return s_xCurrentComponent;
+}
+
+
+String SfxObjectShell::GetServiceNameFromFactory( const String& rFact )
+{
+ //! Remove everything behind name!
+ String aFact( rFact );
+ String aPrefix = String::CreateFromAscii( "private:factory/" );
+ if ( aPrefix.Len() == aFact.Match( aPrefix ) )
+ aFact.Erase( 0, aPrefix.Len() );
+ USHORT nPos = aFact.Search( '?' );
+ String aParam;
+ if ( nPos != STRING_NOTFOUND )
+ {
+ aParam = aFact.Copy( nPos, aFact.Len() );
+ aFact.Erase( nPos, aFact.Len() );
+ aParam.Erase(0,1);
+ }
+ aFact.EraseAllChars('4').ToLowerAscii();
+
+ // HACK: sometimes a real document service name is given here instead of
+ // a factory short name. Set return value directly to this service name as fallback
+ // in case next lines of code does nothing ...
+ // use rFact instead of normed aFact value !
+ ::rtl::OUString aServiceName = rFact;
+
+ if ( aFact.EqualsAscii("swriter") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument");
+ }
+ else if ( aFact.EqualsAscii("sweb") || aFact.EqualsAscii("swriter/web") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument");
+ }
+ else if ( aFact.EqualsAscii("sglobal") || aFact.EqualsAscii("swriter/globaldocument") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument");
+ }
+ else if ( aFact.EqualsAscii("scalc") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument");
+ }
+ else if ( aFact.EqualsAscii("sdraw") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument");
+ }
+ else if ( aFact.EqualsAscii("simpress") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument");
+ }
+ else if ( aFact.EqualsAscii("schart") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.chart.ChartDocument");
+ }
+ else if ( aFact.EqualsAscii("smath") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties");
+ }
+ else if ( aFact.EqualsAscii("sbasic") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.script.BasicIDE");
+ }
+ else if ( aFact.EqualsAscii("sdatabase") )
+ {
+ aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sdb.OfficeDatabaseDocument");
+ }
+
+ return aServiceName;
+}
+
+SfxObjectShell* SfxObjectShell::CreateObjectByFactoryName( const String& rFact, SfxObjectCreateMode eMode )
+{
+ return CreateObject( GetServiceNameFromFactory( rFact ), eMode );
+}
+
+
+SfxObjectShell* SfxObjectShell::CreateObject( const String& rServiceName, SfxObjectCreateMode eCreateMode )
+{
+ if ( rServiceName.Len() )
+ {
+ ::com::sun::star::uno::Reference < ::com::sun::star::frame::XModel > xDoc(
+ ::comphelper::getProcessServiceFactory()->createInstance( rServiceName ), UNO_QUERY );
+ if ( xDoc.is() )
+ {
+ ::com::sun::star::uno::Reference < ::com::sun::star::lang::XUnoTunnel > xObj( xDoc, UNO_QUERY );
+ ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
+ sal_Int64 nHandle = xObj->getSomething( aSeq );
+ if ( nHandle )
+ {
+ SfxObjectShell* pRet = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
+ pRet->SetCreateMode_Impl( eCreateMode );
+ return pRet;
+ }
+ }
+ }
+
+ return 0;
+}
+
+SfxObjectShell* SfxObjectShell::CreateAndLoadObject( const SfxItemSet& rSet, SfxFrame* pFrame )
+{
+ uno::Sequence < beans::PropertyValue > aProps;
+ TransformItems( SID_OPENDOC, rSet, aProps );
+ SFX_ITEMSET_ARG(&rSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, FALSE);
+ SFX_ITEMSET_ARG(&rSet, pTargetItem, SfxStringItem, SID_TARGETNAME, FALSE);
+ ::rtl::OUString aURL;
+ ::rtl::OUString aTarget = rtl::OUString::createFromAscii("_blank");
+ if ( pFileNameItem )
+ aURL = pFileNameItem->GetValue();
+ if ( pTargetItem )
+ aTarget = pTargetItem->GetValue();
+
+ uno::Reference < frame::XComponentLoader > xLoader;
+ if ( pFrame )
+ {
+ xLoader = uno::Reference < frame::XComponentLoader >( pFrame->GetFrameInterface(), uno::UNO_QUERY );
+ }
+ else
+ xLoader = uno::Reference < frame::XComponentLoader >( comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop") ), uno::UNO_QUERY );
+
+ uno::Reference < lang::XUnoTunnel > xObj;
+ try
+ {
+ xObj = uno::Reference< lang::XUnoTunnel >( xLoader->loadComponentFromURL( aURL, aTarget, 0, aProps ), uno::UNO_QUERY );
+ }
+ catch( uno::Exception& )
+ {}
+
+ if ( xObj.is() )
+ {
+ ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
+ sal_Int64 nHandle = xObj->getSomething( aSeq );
+ if ( nHandle )
+ return reinterpret_cast< SfxObjectShell* >(sal::static_int_cast< sal_IntPtr >( nHandle ));
+ }
+
+ return NULL;
+}
+
+void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew )
+{
+ pImp->bInitialized = sal_True;
+ if ( i_fromInitNew )
+ {
+ SetActivateEvent_Impl( SFX_EVENT_CREATEDOC );
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_DOCCREATED, GlobalEventConfig::GetEventName(STR_EVENT_DOCCREATED), this ) );
+ }
+ else
+ {
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_LOADFINISHED, GlobalEventConfig::GetEventName(STR_EVENT_LOADFINISHED), this ) );
+ }
+}
+
+
+bool SfxObjectShell::IsChangeRecording() const
+{
+ // currently this function needs to be overwritten by Writer and Calc only
+ DBG_ASSERT( 0, "function not implemented" );
+ return false;
+}
+
+
+bool SfxObjectShell::HasChangeRecordProtection() const
+{
+ // currently this function needs to be overwritten by Writer and Calc only
+ DBG_ASSERT( 0, "function not implemented" );
+ return false;
+}
+
+
+void SfxObjectShell::SetChangeRecording( bool /*bActivate*/ )
+{
+ // currently this function needs to be overwritten by Writer and Calc only
+ DBG_ASSERT( 0, "function not implemented" );
+}
+
+
+bool SfxObjectShell::SetProtectionPassword( const String & /*rPassword*/ )
+{
+ // currently this function needs to be overwritten by Writer and Calc only
+ DBG_ASSERT( 0, "function not implemented" );
+ return false;
+}
+
+
+bool SfxObjectShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > & /*rPasswordHash*/ )
+{
+ // currently this function needs to be overwritten by Writer and Calc only
+ DBG_ASSERT( 0, "function not implemented" );
+ return false;
+}
+
diff --git a/sfx2/source/doc/oleprops.cxx b/sfx2/source/doc/oleprops.cxx
new file mode 100755
index 000000000000..d6192542d1a1
--- /dev/null
+++ b/sfx2/source/doc/oleprops.cxx
@@ -0,0 +1,1227 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "oleprops.hxx"
+
+#include <comphelper/types.hxx>
+#include <tools/debug.hxx>
+#include <tools/datetime.hxx>
+#include <rtl/tencinfo.h>
+
+// ============================================================================
+
+
+// ============================================================================
+
+#define VERSION 11
+#define STREAM_BUFFER_SIZE 2048
+
+// usings
+using ::rtl::OUString;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::makeAny;
+
+using namespace ::com::sun::star;
+
+#define TIMESTAMP_INVALID_DATETIME ( DateTime ( Date ( 1, 1, 1601 ), Time ( 0, 0, 0 ) ) ) /// Invalid value for date and time to create invalid instance of TimeStamp.
+#define TIMESTAMP_INVALID_UTILDATETIME ( util::DateTime ( 0, 0, 0, 0, 1, 1, 1601 ) ) /// Invalid value for date and time to create invalid instance of TimeStamp.
+
+static
+bool operator==(const util::DateTime &i_rLeft, const util::DateTime &i_rRight)
+{
+ return i_rLeft.Year == i_rRight.Year
+ && i_rLeft.Month == i_rRight.Month
+ && i_rLeft.Day == i_rRight.Day
+ && i_rLeft.Hours == i_rRight.Hours
+ && i_rLeft.Minutes == i_rRight.Minutes
+ && i_rLeft.Seconds == i_rRight.Seconds
+ && i_rLeft.HundredthSeconds == i_rRight.HundredthSeconds;
+}
+
+// ============================================================================
+
+/** Property representing a signed 32-bit integer value. */
+class SfxOleInt32Property : public SfxOlePropertyBase
+{
+public:
+ explicit SfxOleInt32Property( sal_Int32 nPropId, sal_Int32 nValue = 0 );
+
+ inline sal_Int32 GetValue() const { return mnValue; }
+ inline void SetValue( sal_Int32 nValue ) { mnValue = nValue; }
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+private:
+ sal_Int32 mnValue;
+};
+
+// ============================================================================
+
+/** Property representing a floating-point value. */
+class SfxOleDoubleProperty : public SfxOlePropertyBase
+{
+public:
+ explicit SfxOleDoubleProperty( sal_Int32 nPropId, double fValue = 0.0 );
+
+ inline double GetValue() const { return mfValue; }
+ inline void SetValue( double fValue ) { mfValue = fValue; }
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+private:
+ double mfValue;
+};
+
+// ============================================================================
+
+/** Property representing a boolean value. */
+class SfxOleBoolProperty : public SfxOlePropertyBase
+{
+public:
+ explicit SfxOleBoolProperty( sal_Int32 nPropId, bool bValue = false );
+
+ inline bool GetValue() const { return mbValue; }
+ inline void SetValue( bool bValue ) { mbValue = bValue; }
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+private:
+ bool mbValue;
+};
+
+// ============================================================================
+
+/** Base class for properties that contain a single string value. */
+class SfxOleStringPropertyBase : public SfxOlePropertyBase, public SfxOleStringHelper
+{
+public:
+ explicit SfxOleStringPropertyBase(
+ sal_Int32 nPropId, sal_Int32 nPropType,
+ const SfxOleTextEncoding& rTextEnc );
+ explicit SfxOleStringPropertyBase(
+ sal_Int32 nPropId, sal_Int32 nPropType,
+ const SfxOleTextEncoding& rTextEnc, const String& rValue );
+ explicit SfxOleStringPropertyBase(
+ sal_Int32 nPropId, sal_Int32 nPropType,
+ rtl_TextEncoding eTextEnc );
+ explicit SfxOleStringPropertyBase(
+ sal_Int32 nPropId, sal_Int32 nPropType,
+ rtl_TextEncoding eTextEnc, const String& rValue );
+
+ inline const String& GetValue() const { return maValue; }
+ inline void SetValue( const String& rValue ) { maValue = rValue; }
+
+private:
+ String maValue;
+};
+
+// ============================================================================
+
+/** Property representing a bytestring value. */
+class SfxOleString8Property : public SfxOleStringPropertyBase
+{
+public:
+ explicit SfxOleString8Property(
+ sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc );
+ explicit SfxOleString8Property(
+ sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc,
+ const String& rValue );
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+};
+
+// ============================================================================
+
+/** Property representing a Unicode string value. */
+class SfxOleString16Property : public SfxOleStringPropertyBase
+{
+public:
+ explicit SfxOleString16Property( sal_Int32 nPropId );
+ explicit SfxOleString16Property( sal_Int32 nPropId, const String& rValue );
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+};
+
+// ============================================================================
+
+/** Property representing a filetime value as defined by the Windows API. */
+class SfxOleFileTimeProperty : public SfxOlePropertyBase
+{
+public:
+ explicit SfxOleFileTimeProperty( sal_Int32 nPropId );
+ /** @param rDateTime Date and time as LOCAL time. */
+ explicit SfxOleFileTimeProperty( sal_Int32 nPropId, const util::DateTime& rDateTime );
+
+ /** Returns the time value as LOCAL time. */
+ inline const util::DateTime& GetValue() const { return maDateTime; }
+ /** @param rDateTime Date and time as LOCAL time. */
+ inline void SetValue( const util::DateTime& rDateTime ) { maDateTime = rDateTime; }
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+private:
+ util::DateTime maDateTime;
+};
+
+// ============================================================================
+
+/** Property representing a thumbnail picture.
+
+ Currently, only saving this property is implemented.
+ */
+class SfxOleThumbnailProperty : public SfxOlePropertyBase
+{
+public:
+ explicit SfxOleThumbnailProperty( sal_Int32 nPropId,
+ const uno::Sequence<sal_uInt8> & i_rData);
+
+ inline bool IsValid() const { return mData.getLength() > 0; }
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+private:
+ uno::Sequence<sal_uInt8> mData;
+};
+
+// ============================================================================
+
+/** Property representing a BLOB (which presumably stands for binary large
+ object).
+
+ Currently, only saving this property is implemented.
+ */
+class SfxOleBlobProperty : public SfxOlePropertyBase
+{
+public:
+ explicit SfxOleBlobProperty( sal_Int32 nPropId,
+ const uno::Sequence<sal_uInt8> & i_rData);
+ inline bool IsValid() const { return mData.getLength() > 0; }
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+private:
+ uno::Sequence<sal_uInt8> mData;
+};
+
+// ============================================================================
+
+sal_uInt16 SfxOleTextEncoding::GetCodePage() const
+{
+ sal_uInt16 nCodePage = IsUnicode() ? CODEPAGE_UNICODE :
+ static_cast< sal_uInt16 >( rtl_getWindowsCodePageFromTextEncoding( *mxTextEnc ) );
+ return (nCodePage == CODEPAGE_UNKNOWN) ? CODEPAGE_UTF8 : nCodePage;
+}
+
+void SfxOleTextEncoding::SetCodePage( sal_uInt16 nCodePage )
+{
+ if( nCodePage == CODEPAGE_UNICODE )
+ SetUnicode();
+ else
+ {
+ rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
+ if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
+ *mxTextEnc = eTextEnc;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+String SfxOleStringHelper::LoadString8( SvStream& rStrm ) const
+{
+ return IsUnicode() ? ImplLoadString16( rStrm ) : ImplLoadString8( rStrm );
+}
+
+void SfxOleStringHelper::SaveString8( SvStream& rStrm, const String& rValue ) const
+{
+ if( IsUnicode() )
+ ImplSaveString16( rStrm, rValue );
+ else
+ ImplSaveString8( rStrm, rValue );
+}
+
+String SfxOleStringHelper::LoadString16( SvStream& rStrm ) const
+{
+ return ImplLoadString16( rStrm );
+}
+
+void SfxOleStringHelper::SaveString16( SvStream& rStrm, const String& rValue ) const
+{
+ ImplSaveString16( rStrm, rValue );
+}
+
+String SfxOleStringHelper::ImplLoadString8( SvStream& rStrm ) const
+{
+ String aValue;
+ // read size field (signed 32-bit)
+ sal_Int32 nSize;
+ rStrm >> nSize;
+ // size field includes trailing NUL character
+ DBG_ASSERT( (0 < nSize) && (nSize <= 0xFFFF), "SfxOleStringHelper::ImplLoadString8 - invalid string" );
+ if( (0 < nSize) && (nSize <= 0xFFFF) )
+ {
+ // load character buffer
+ ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nSize + 1 ), 0 );
+ rStrm.Read( &aBuffer.front(), static_cast< sal_Size >( nSize ) );
+ // create string from encoded character array
+ aValue = String( &aBuffer.front(), GetTextEncoding() );
+ }
+ return aValue;
+}
+
+String SfxOleStringHelper::ImplLoadString16( SvStream& rStrm ) const
+{
+ String aValue;
+ // read size field (signed 32-bit), may be buffer size or character count
+ sal_Int32 nSize;
+ rStrm >> nSize;
+ DBG_ASSERT( (0 < nSize) && (nSize <= 0xFFFF), "SfxOleStringHelper::ImplLoadString16 - invalid string" );
+ // size field includes trailing NUL character
+ if( (0 < nSize) && (nSize <= 0xFFFF) )
+ {
+ // load character buffer
+ ::std::vector< sal_Unicode > aBuffer;
+ aBuffer.reserve( static_cast< size_t >( nSize + 1 ) );
+ sal_uInt16 cChar;
+ for( sal_Int32 nIdx = 0; nIdx < nSize; ++nIdx )
+ {
+ rStrm >> cChar;
+ aBuffer.push_back( static_cast< sal_Unicode >( cChar ) );
+ }
+ // stream is always padded to 32-bit boundary, skip 2 bytes on odd character count
+ if( (nSize & 1) == 1 )
+ rStrm.SeekRel( 2 );
+ // create string from character array
+ aBuffer.push_back( 0 );
+ aValue = String( &aBuffer.front() );
+ }
+ return aValue;
+}
+
+void SfxOleStringHelper::ImplSaveString8( SvStream& rStrm, const String& rValue ) const
+{
+ // encode to byte string
+ ByteString aEncoded( rValue, GetTextEncoding() );
+ // write size field (including trailing NUL character)
+ sal_Int32 nSize = static_cast< sal_Int32 >( aEncoded.Len() + 1 );
+ rStrm << nSize;
+ // write character array with trailing NUL character
+ rStrm.Write( aEncoded.GetBuffer(), aEncoded.Len() );
+ rStrm << sal_uInt8( 0 );
+}
+
+void SfxOleStringHelper::ImplSaveString16( SvStream& rStrm, const String& rValue ) const
+{
+ // write size field (including trailing NUL character)
+ sal_Int32 nSize = static_cast< sal_Int32 >( rValue.Len() + 1 );
+ rStrm << nSize;
+ // write character array with trailing NUL character
+ for( xub_StrLen nIdx = 0; nIdx < rValue.Len(); ++nIdx )
+ rStrm << static_cast< sal_uInt16 >( rValue.GetChar( nIdx ) );
+ rStrm << sal_uInt16( 0 );
+ // stream is always padded to 32-bit boundary, add 2 bytes on odd character count
+ if( (nSize & 1) == 1 )
+ rStrm << sal_uInt16( 0 );
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleObjectBase::~SfxOleObjectBase()
+{
+}
+
+ErrCode SfxOleObjectBase::Load( SvStream& rStrm )
+{
+ mnErrCode = ERRCODE_NONE;
+ ImplLoad( rStrm );
+ SetError( rStrm.GetErrorCode() );
+ return GetError();
+}
+
+ErrCode SfxOleObjectBase::Save( SvStream& rStrm )
+{
+ mnErrCode = ERRCODE_NONE;
+ ImplSave( rStrm );
+ SetError( rStrm.GetErrorCode() );
+ return GetError();
+}
+
+void SfxOleObjectBase::LoadObject( SvStream& rStrm, SfxOleObjectBase& rObj )
+{
+ SetError( rObj.Load( rStrm ) );
+}
+
+void SfxOleObjectBase::SaveObject( SvStream& rStrm, SfxOleObjectBase& rObj )
+{
+ SetError( rObj.Save( rStrm ) );
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleCodePageProperty::SfxOleCodePageProperty() :
+ SfxOlePropertyBase( PROPID_CODEPAGE, PROPTYPE_INT16 )
+{
+}
+
+void SfxOleCodePageProperty::ImplLoad( SvStream& rStrm )
+{
+ // property type is signed int16, but we use always unsigned int16 for codepages
+ sal_uInt16 nCodePage;
+ rStrm >> nCodePage;
+ SetCodePage( nCodePage );
+}
+
+void SfxOleCodePageProperty::ImplSave( SvStream& rStrm )
+{
+ // property type is signed int16, but we use always unsigned int16 for codepages
+ rStrm << GetCodePage();
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleInt32Property::SfxOleInt32Property( sal_Int32 nPropId, sal_Int32 nValue ) :
+ SfxOlePropertyBase( nPropId, PROPTYPE_INT32 ),
+ mnValue( nValue )
+{
+}
+
+void SfxOleInt32Property::ImplLoad( SvStream& rStrm )
+{
+ rStrm >> mnValue;
+}
+
+void SfxOleInt32Property::ImplSave( SvStream& rStrm )
+{
+ rStrm << mnValue;
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleDoubleProperty::SfxOleDoubleProperty( sal_Int32 nPropId, double fValue ) :
+ SfxOlePropertyBase( nPropId, PROPTYPE_DOUBLE ),
+ mfValue( fValue )
+{
+}
+
+void SfxOleDoubleProperty::ImplLoad( SvStream& rStrm )
+{
+ rStrm >> mfValue;
+}
+
+void SfxOleDoubleProperty::ImplSave( SvStream& rStrm )
+{
+ rStrm << mfValue;
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleBoolProperty::SfxOleBoolProperty( sal_Int32 nPropId, bool bValue ) :
+ SfxOlePropertyBase( nPropId, PROPTYPE_BOOL ),
+ mbValue( bValue )
+{
+}
+
+void SfxOleBoolProperty::ImplLoad( SvStream& rStrm )
+{
+ sal_Int16 nValue;
+ rStrm >> nValue;
+ mbValue = nValue != 0;
+}
+
+void SfxOleBoolProperty::ImplSave( SvStream& rStrm )
+{
+ rStrm << static_cast< sal_Int16 >( mbValue ? -1 : 0 );
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleStringPropertyBase::SfxOleStringPropertyBase(
+ sal_Int32 nPropId, sal_Int32 nPropType, const SfxOleTextEncoding& rTextEnc ) :
+ SfxOlePropertyBase( nPropId, nPropType ),
+ SfxOleStringHelper( rTextEnc )
+{
+}
+
+SfxOleStringPropertyBase::SfxOleStringPropertyBase(
+ sal_Int32 nPropId, sal_Int32 nPropType, const SfxOleTextEncoding& rTextEnc, const String& rValue ) :
+ SfxOlePropertyBase( nPropId, nPropType ),
+ SfxOleStringHelper( rTextEnc ),
+ maValue( rValue )
+{
+}
+
+SfxOleStringPropertyBase::SfxOleStringPropertyBase(
+ sal_Int32 nPropId, sal_Int32 nPropType, rtl_TextEncoding eTextEnc ) :
+ SfxOlePropertyBase( nPropId, nPropType ),
+ SfxOleStringHelper( eTextEnc )
+{
+}
+
+SfxOleStringPropertyBase::SfxOleStringPropertyBase(
+ sal_Int32 nPropId, sal_Int32 nPropType, rtl_TextEncoding eTextEnc, const String& rValue ) :
+ SfxOlePropertyBase( nPropId, nPropType ),
+ SfxOleStringHelper( eTextEnc ),
+ maValue( rValue )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleString8Property::SfxOleString8Property(
+ sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc ) :
+ SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING8, rTextEnc )
+{
+}
+
+SfxOleString8Property::SfxOleString8Property(
+ sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc, const String& rValue ) :
+ SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING8, rTextEnc, rValue )
+{
+}
+
+void SfxOleString8Property::ImplLoad( SvStream& rStrm )
+{
+ SetValue( LoadString8( rStrm ) );
+}
+
+void SfxOleString8Property::ImplSave( SvStream& rStrm )
+{
+ SaveString8( rStrm, GetValue() );
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleString16Property::SfxOleString16Property( sal_Int32 nPropId ) :
+ SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING16, RTL_TEXTENCODING_UCS2 )
+{
+}
+
+SfxOleString16Property::SfxOleString16Property( sal_Int32 nPropId, const String& rValue ) :
+ SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING16, RTL_TEXTENCODING_UCS2, rValue )
+{
+}
+
+void SfxOleString16Property::ImplLoad( SvStream& rStrm )
+{
+ SetValue( LoadString16( rStrm ) );
+}
+
+void SfxOleString16Property::ImplSave( SvStream& rStrm )
+{
+ SaveString16( rStrm, GetValue() );
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleFileTimeProperty::SfxOleFileTimeProperty( sal_Int32 nPropId ) :
+ SfxOlePropertyBase( nPropId, PROPTYPE_FILETIME )
+{
+}
+
+SfxOleFileTimeProperty::SfxOleFileTimeProperty( sal_Int32 nPropId, const util::DateTime& rDateTime ) :
+ SfxOlePropertyBase( nPropId, PROPTYPE_FILETIME ),
+ maDateTime( rDateTime )
+{
+}
+
+void SfxOleFileTimeProperty::ImplLoad( SvStream& rStrm )
+{
+ sal_uInt32 nLower, nUpper;
+ rStrm >> nLower >> nUpper;
+ ::DateTime aDateTime = DateTime::CreateFromWin32FileDateTime( nLower, nUpper );
+ // note: editing duration is stored as offset to TIMESTAMP_INVALID_DATETIME
+ // of course we should not convert the time zone of a duration!
+ // heuristic to detect editing durations (which we assume to be < 1 year):
+ // check only the year, not the entire date
+ if ( aDateTime.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() )
+ aDateTime.ConvertToLocalTime();
+ maDateTime.Year = aDateTime.GetYear();
+ maDateTime.Month = aDateTime.GetMonth();
+ maDateTime.Day = aDateTime.GetDay();
+ maDateTime.Hours = aDateTime.GetHour();
+ maDateTime.Minutes = aDateTime.GetMin();
+ maDateTime.Seconds = aDateTime.GetSec();
+ maDateTime.HundredthSeconds = aDateTime.Get100Sec();
+}
+
+void SfxOleFileTimeProperty::ImplSave( SvStream& rStrm )
+{
+ DateTime aDateTimeUtc(
+ Date(
+ static_cast< USHORT >( maDateTime.Day ),
+ static_cast< USHORT >( maDateTime.Month ),
+ static_cast< USHORT >( maDateTime.Year ) ),
+ Time(
+ static_cast< ULONG >( maDateTime.Hours ),
+ static_cast< ULONG >( maDateTime.Minutes ),
+ static_cast< ULONG >( maDateTime.Seconds ),
+ static_cast< ULONG >( maDateTime.HundredthSeconds ) ) );
+ // invalid time stamp is not converted to UTC
+ // heuristic to detect editing durations (which we assume to be < 1 year):
+ // check only the year, not the entire date
+ if( aDateTimeUtc.IsValid()
+ && aDateTimeUtc.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() ) {
+ aDateTimeUtc.ConvertToUTC();
+ }
+ sal_uInt32 nLower, nUpper;
+ aDateTimeUtc.GetWin32FileDateTime( nLower, nUpper );
+ rStrm << nLower << nUpper;
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleThumbnailProperty::SfxOleThumbnailProperty(
+ sal_Int32 nPropId, const uno::Sequence<sal_uInt8> & i_rData) :
+ SfxOlePropertyBase( nPropId, PROPTYPE_CLIPFMT ),
+ mData(i_rData)
+{
+}
+
+void SfxOleThumbnailProperty::ImplLoad( SvStream& )
+{
+ DBG_ERRORFILE( "SfxOleThumbnailProperty::ImplLoad - not implemented" );
+ SetError( SVSTREAM_INVALID_ACCESS );
+}
+
+void SfxOleThumbnailProperty::ImplSave( SvStream& rStrm )
+{
+ /* Type Contents
+ -----------------------------------------------------------------------
+ int32 size of following data
+ int32 clipboard format tag (see below)
+ byte[] clipboard data (see below)
+
+ Clipboard format tag:
+ -1 = Windows clipboard format
+ -2 = Macintosh clipboard format
+ -3 = GUID that contains a format identifier (FMTID)
+ >0 = custom clipboard format name plus data (see msdn site below)
+ 0 = no data
+
+ References:
+ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stg/stg/propvariant.asp
+ http://jakarta.apache.org/poi/hpsf/thumbnails.html
+ http://linux.com.hk/docs/poi/org/apache/poi/hpsf/Thumbnail.html
+ http://sparks.discreet.com/knowledgebase/public/solutions/ExtractThumbnailImg.htm
+ */
+ if( IsValid() )
+ {
+ // clipboard size: clip_format_tag + data_format_tag + bitmap_len
+ sal_Int32 nClipSize = static_cast< sal_Int32 >( 4 + 4 + mData.getLength() );
+ rStrm << nClipSize << CLIPFMT_WIN << CLIPDATAFMT_DIB;
+ rStrm.Write( mData.getConstArray(), mData.getLength() );
+ }
+ else
+ {
+ DBG_ERRORFILE( "SfxOleThumbnailProperty::ImplSave - invalid thumbnail property" );
+ SetError( SVSTREAM_INVALID_ACCESS );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleBlobProperty::SfxOleBlobProperty( sal_Int32 nPropId,
+ const uno::Sequence<sal_uInt8> & i_rData) :
+ SfxOlePropertyBase( nPropId, PROPTYPE_BLOB ),
+ mData(i_rData)
+{
+}
+
+void SfxOleBlobProperty::ImplLoad( SvStream& )
+{
+ DBG_ERRORFILE( "SfxOleBlobProperty::ImplLoad - not implemented" );
+ SetError( SVSTREAM_INVALID_ACCESS );
+}
+
+void SfxOleBlobProperty::ImplSave( SvStream& rStrm )
+{
+ if (IsValid()) {
+ rStrm.Write( mData.getConstArray(), mData.getLength() );
+ } else {
+ DBG_ERRORFILE( "SfxOleBlobProperty::ImplSave - invalid BLOB property" );
+ SetError( SVSTREAM_INVALID_ACCESS );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleDictionaryProperty::SfxOleDictionaryProperty( const SfxOleTextEncoding& rTextEnc ) :
+ SfxOlePropertyBase( PROPID_DICTIONARY, 0 ),
+ SfxOleStringHelper( rTextEnc )
+{
+}
+
+const String& SfxOleDictionaryProperty::GetPropertyName( sal_Int32 nPropId ) const
+{
+ SfxOlePropNameMap::const_iterator aIt = maPropNameMap.find( nPropId );
+ return (aIt == maPropNameMap.end()) ? String::EmptyString() : aIt->second;
+}
+
+void SfxOleDictionaryProperty::SetPropertyName( sal_Int32 nPropId, const String& rPropName )
+{
+ maPropNameMap[ nPropId ] = rPropName;
+ // dictionary property contains number of pairs in property type field
+ SetPropType( static_cast< sal_Int32 >( maPropNameMap.size() ) );
+}
+
+void SfxOleDictionaryProperty::ImplLoad( SvStream& rStrm )
+{
+ // dictionary property contains number of pairs in property type field
+ sal_Int32 nNameCount = GetPropType();
+ // read property ID/name pairs
+ maPropNameMap.clear();
+ for( sal_Int32 nIdx = 0; (nIdx < nNameCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nIdx )
+ {
+ sal_Int32 nPropId;
+ rStrm >> nPropId;
+ // name always stored as byte string
+ maPropNameMap[ nPropId ] = LoadString8( rStrm );
+ }
+}
+
+void SfxOleDictionaryProperty::ImplSave( SvStream& rStrm )
+{
+ // write property ID/name pairs
+ for( SfxOlePropNameMap::const_iterator aIt = maPropNameMap.begin(), aEnd = maPropNameMap.end(); aIt != aEnd; ++aIt )
+ {
+ rStrm << aIt->first;
+ // name always stored as byte string
+ SaveString8( rStrm, aIt->second );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+SfxOleSection::SfxOleSection( bool bSupportsDict ) :
+ maDictProp( maCodePageProp ),
+ mnStartPos( 0 ),
+ mbSupportsDict( bSupportsDict )
+{
+}
+
+SfxOlePropertyRef SfxOleSection::GetProperty( sal_Int32 nPropId ) const
+{
+ SfxOlePropertyRef xProp;
+ SfxOlePropMap::const_iterator aIt = maPropMap.find( nPropId );
+ if( aIt != maPropMap.end() )
+ xProp = aIt->second;
+ return xProp;
+}
+
+bool SfxOleSection::GetInt32Value( sal_Int32& rnValue, sal_Int32 nPropId ) const
+{
+ SfxOlePropertyRef xProp = GetProperty( nPropId );
+ const SfxOleInt32Property* pProp =
+ dynamic_cast< const SfxOleInt32Property* >( xProp.get() );
+ if( pProp )
+ rnValue = pProp->GetValue();
+ return pProp != 0;
+}
+
+bool SfxOleSection::GetDoubleValue( double& rfValue, sal_Int32 nPropId ) const
+{
+ SfxOlePropertyRef xProp = GetProperty( nPropId );
+ const SfxOleDoubleProperty* pProp =
+ dynamic_cast< const SfxOleDoubleProperty* >( xProp.get() );
+ if( pProp )
+ rfValue = pProp->GetValue();
+ return pProp != 0;
+}
+
+bool SfxOleSection::GetBoolValue( bool& rbValue, sal_Int32 nPropId ) const
+{
+ SfxOlePropertyRef xProp = GetProperty( nPropId );
+ const SfxOleBoolProperty* pProp =
+ dynamic_cast< const SfxOleBoolProperty* >( xProp.get() );
+ if( pProp )
+ rbValue = pProp->GetValue();
+ return pProp != 0;
+}
+
+bool SfxOleSection::GetStringValue( String& rValue, sal_Int32 nPropId ) const
+{
+ SfxOlePropertyRef xProp = GetProperty( nPropId );
+ const SfxOleStringPropertyBase* pProp =
+ dynamic_cast< const SfxOleStringPropertyBase* >( xProp.get() );
+ if( pProp )
+ rValue = pProp->GetValue();
+ return pProp != 0;
+}
+
+bool SfxOleSection::GetFileTimeValue( util::DateTime& rValue, sal_Int32 nPropId ) const
+{
+ SfxOlePropertyRef xProp = GetProperty( nPropId );
+ const SfxOleFileTimeProperty* pProp =
+ dynamic_cast< const SfxOleFileTimeProperty* >( xProp.get() );
+ if( pProp )
+ {
+ if ( pProp->GetValue() == TIMESTAMP_INVALID_UTILDATETIME )
+ rValue = util::DateTime();
+ else
+ rValue = pProp->GetValue();
+ }
+ return pProp != 0;
+}
+
+void SfxOleSection::SetProperty( SfxOlePropertyRef xProp )
+{
+ if( xProp.get() )
+ maPropMap[ xProp->GetPropId() ] = xProp;
+}
+
+void SfxOleSection::SetInt32Value( sal_Int32 nPropId, sal_Int32 nValue )
+{
+ SetProperty( SfxOlePropertyRef( new SfxOleInt32Property( nPropId, nValue ) ) );
+}
+
+void SfxOleSection::SetDoubleValue( sal_Int32 nPropId, double fValue )
+{
+ SetProperty( SfxOlePropertyRef( new SfxOleDoubleProperty( nPropId, fValue ) ) );
+}
+
+void SfxOleSection::SetBoolValue( sal_Int32 nPropId, bool bValue )
+{
+ SetProperty( SfxOlePropertyRef( new SfxOleBoolProperty( nPropId, bValue ) ) );
+}
+
+bool SfxOleSection::SetStringValue( sal_Int32 nPropId, const String& rValue, bool bSkipEmpty )
+{
+ bool bInserted = !bSkipEmpty || (rValue.Len() > 0);
+ if( bInserted )
+ SetProperty( SfxOlePropertyRef( new SfxOleString8Property( nPropId, maCodePageProp, rValue ) ) );
+ return bInserted;
+}
+
+void SfxOleSection::SetFileTimeValue( sal_Int32 nPropId, const util::DateTime& rValue )
+{
+ if ( rValue.Year == 0 || rValue.Month == 0 || rValue.Day == 0 )
+ SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, TIMESTAMP_INVALID_UTILDATETIME ) ) );
+ else
+ SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, rValue ) ) );
+}
+
+void SfxOleSection::SetThumbnailValue( sal_Int32 nPropId,
+ const uno::Sequence<sal_uInt8> & i_rData)
+{
+ SfxOleThumbnailProperty* pThumbnail = new SfxOleThumbnailProperty( nPropId, i_rData );
+ SfxOlePropertyRef xProp( pThumbnail ); // take ownership
+ if( pThumbnail->IsValid() )
+ SetProperty( xProp );
+}
+
+void SfxOleSection::SetBlobValue( sal_Int32 nPropId,
+ const uno::Sequence<sal_uInt8> & i_rData)
+{
+ SfxOleBlobProperty* pBlob( new SfxOleBlobProperty( nPropId, i_rData ) );
+ SfxOlePropertyRef xProp( pBlob );
+ if( pBlob->IsValid() ) {
+ SetProperty( xProp );
+ }
+}
+
+Any SfxOleSection::GetAnyValue( sal_Int32 nPropId ) const
+{
+ Any aValue;
+ sal_Int32 nInt32 = 0;
+ double fDouble = 0.0;
+ bool bBool = false;
+ String aString;
+ ::com::sun::star::util::DateTime aApiDateTime;
+
+ if( GetInt32Value( nInt32, nPropId ) )
+ aValue <<= nInt32;
+ else if( GetDoubleValue( fDouble, nPropId ) )
+ aValue <<= fDouble;
+ else if( GetBoolValue( bBool, nPropId ) )
+ ::comphelper::setBOOL( aValue, bBool ? sal_True : sal_False );
+ else if( GetStringValue( aString, nPropId ) )
+ aValue <<= OUString( aString );
+ else if( GetFileTimeValue( aApiDateTime, nPropId ) )
+ {
+ aValue <<= aApiDateTime;
+ }
+ return aValue;
+}
+
+bool SfxOleSection::SetAnyValue( sal_Int32 nPropId, const Any& rValue )
+{
+ bool bInserted = true;
+ sal_Int32 nInt32 = 0;
+ double fDouble = 0.0;
+ OUString aString;
+ ::com::sun::star::util::DateTime aApiDateTime;
+
+ if( rValue.getValueType() == ::getBooleanCppuType() )
+ SetBoolValue( nPropId, ::comphelper::getBOOL( rValue ) == sal_True );
+ else if( rValue >>= nInt32 )
+ SetInt32Value( nPropId, nInt32 );
+ else if( rValue >>= fDouble )
+ SetDoubleValue( nPropId, fDouble );
+ else if( rValue >>= aString )
+ bInserted = SetStringValue( nPropId, aString );
+ else if( rValue >>= aApiDateTime )
+ {
+ SetFileTimeValue( nPropId, aApiDateTime );
+ }
+ else
+ bInserted = false;
+ return bInserted;
+}
+
+const String& SfxOleSection::GetPropertyName( sal_Int32 nPropId ) const
+{
+ return maDictProp.GetPropertyName( nPropId );
+}
+
+void SfxOleSection::SetPropertyName( sal_Int32 nPropId, const String& rPropName )
+{
+ maDictProp.SetPropertyName( nPropId, rPropName );
+}
+
+void SfxOleSection::GetPropertyIds( ::std::vector< sal_Int32 >& rPropIds ) const
+{
+ rPropIds.clear();
+ for( SfxOlePropMap::const_iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt )
+ rPropIds.push_back( aIt->first );
+}
+
+sal_Int32 SfxOleSection::GetFreePropertyId() const
+{
+ return maPropMap.empty() ? PROPID_FIRSTCUSTOM : (maPropMap.rbegin()->first + 1);
+}
+
+void SfxOleSection::ImplLoad( SvStream& rStrm )
+{
+ // read section header
+ mnStartPos = rStrm.Tell();
+ sal_uInt32 nSize;
+ sal_Int32 nPropCount;
+ rStrm >> nSize >> nPropCount;
+
+ // read property ID/position pairs
+ typedef ::std::map< sal_Int32, sal_uInt32 > SfxOlePropPosMap;
+ SfxOlePropPosMap aPropPosMap;
+ for( sal_Int32 nPropIdx = 0; (nPropIdx < nPropCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nPropIdx )
+ {
+ sal_Int32 nPropId;
+ sal_uInt32 nPropPos;
+ rStrm >> nPropId >> nPropPos;
+ aPropPosMap[ nPropId ] = nPropPos;
+ }
+
+ // read codepage property
+ SfxOlePropPosMap::iterator aCodePageIt = aPropPosMap.find( PROPID_CODEPAGE );
+ if( (aCodePageIt != aPropPosMap.end()) && SeekToPropertyPos( rStrm, aCodePageIt->second ) )
+ {
+ // codepage property must be of type signed int-16
+ sal_Int32 nPropType;
+ rStrm >> nPropType;
+ if( nPropType == PROPTYPE_INT16 )
+ LoadObject( rStrm, maCodePageProp );
+ // remove property position
+ aPropPosMap.erase( aCodePageIt );
+ }
+
+ // read dictionary property
+ SfxOlePropPosMap::iterator aDictIt = aPropPosMap.find( PROPID_DICTIONARY );
+ if( (aDictIt != aPropPosMap.end()) && SeekToPropertyPos( rStrm, aDictIt->second ) )
+ {
+ // #i66214# #i66428# applications may write broken dictionary properties in wrong sections
+ if( mbSupportsDict )
+ {
+ // dictionary property contains number of pairs in property type field
+ sal_Int32 nNameCount;
+ rStrm >> nNameCount;
+ maDictProp.SetNameCount( nNameCount );
+ LoadObject( rStrm, maDictProp );
+ }
+ // always remove position of dictionary property (do not try to read it again below)
+ aPropPosMap.erase( aDictIt );
+ }
+
+ // read other properties
+ maPropMap.clear();
+ for( SfxOlePropPosMap::const_iterator aIt = aPropPosMap.begin(), aEnd = aPropPosMap.end(); aIt != aEnd; ++aIt )
+ if( SeekToPropertyPos( rStrm, aIt->second ) )
+ LoadProperty( rStrm, aIt->first );
+}
+
+void SfxOleSection::ImplSave( SvStream& rStrm )
+{
+ /* Always export with UTF-8 encoding. All dependent properties (bytestring
+ and dictionary) will be updated automatically. */
+ maCodePageProp.SetTextEncoding( RTL_TEXTENCODING_UTF8 );
+
+ // write section header
+ mnStartPos = rStrm.Tell();
+ sal_Int32 nPropCount = static_cast< sal_Int32 >( maPropMap.size() + 1 );
+ if( maDictProp.HasPropertyNames() )
+ ++nPropCount;
+ rStrm << sal_uInt32( 0 ) << nPropCount;
+
+ // write placeholders for property ID/position pairs
+ sal_Size nPropPosPos = rStrm.Tell();
+ rStrm.SeekRel( static_cast< sal_sSize >( 8 * nPropCount ) );
+
+ // write dictionary property
+ if( maDictProp.HasPropertyNames() )
+ SaveProperty( rStrm, maDictProp, nPropPosPos );
+ // write codepage property
+ SaveProperty( rStrm, maCodePageProp, nPropPosPos );
+ // write other properties
+ for( SfxOlePropMap::const_iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt )
+ SaveProperty( rStrm, *aIt->second, nPropPosPos );
+
+ // write section size (first field in section header)
+ rStrm.Seek( STREAM_SEEK_TO_END );
+ sal_uInt32 nSectSize = static_cast< sal_uInt32 >( rStrm.Tell() - mnStartPos );
+ rStrm.Seek( mnStartPos );
+ rStrm << nSectSize;
+}
+
+bool SfxOleSection::SeekToPropertyPos( SvStream& rStrm, sal_uInt32 nPropPos ) const
+{
+ rStrm.Seek( static_cast< sal_Size >( mnStartPos + nPropPos ) );
+ return rStrm.GetErrorCode() == SVSTREAM_OK;
+}
+
+void SfxOleSection::LoadProperty( SvStream& rStrm, sal_Int32 nPropId )
+{
+ // property data type
+ sal_Int32 nPropType;
+ rStrm >> nPropType;
+ // create empty property object
+ SfxOlePropertyRef xProp;
+ switch( nPropType )
+ {
+ case PROPTYPE_INT32:
+ xProp.reset( new SfxOleInt32Property( nPropId ) );
+ break;
+ case PROPTYPE_DOUBLE:
+ xProp.reset( new SfxOleDoubleProperty( nPropId ) );
+ break;
+ case PROPTYPE_BOOL:
+ xProp.reset( new SfxOleBoolProperty( nPropId ) );
+ break;
+ case PROPTYPE_STRING8:
+ xProp.reset( new SfxOleString8Property( nPropId, maCodePageProp ) );
+ break;
+ case PROPTYPE_STRING16:
+ xProp.reset( new SfxOleString16Property( nPropId ) );
+ break;
+ case PROPTYPE_FILETIME:
+ xProp.reset( new SfxOleFileTimeProperty( nPropId ) );
+ break;
+ }
+ // load property contents
+ if( xProp.get() )
+ {
+ SetError( xProp->Load( rStrm ) );
+ maPropMap[ nPropId ] = xProp;
+ }
+}
+
+void SfxOleSection::SaveProperty( SvStream& rStrm, SfxOlePropertyBase& rProp, sal_Size& rnPropPosPos )
+{
+ rStrm.Seek( STREAM_SEEK_TO_END );
+ sal_uInt32 nPropPos = static_cast< sal_uInt32 >( rStrm.Tell() - mnStartPos );
+ // property data type
+ rStrm << rProp.GetPropType();
+ // write property contents
+ SaveObject( rStrm, rProp );
+ // align to 32-bit
+ while( (rStrm.Tell() & 3) != 0 )
+ rStrm << sal_uInt8( 0 );
+ // write property ID/position pair
+ rStrm.Seek( rnPropPosPos );
+ rStrm << rProp.GetPropId() << nPropPos;
+ rnPropPosPos = rStrm.Tell();
+}
+
+// ----------------------------------------------------------------------------
+
+ErrCode SfxOlePropertySet::LoadPropertySet( SotStorage* pStrg, const String& rStrmName )
+{
+ if( pStrg )
+ {
+ SotStorageStreamRef xStrm = pStrg->OpenSotStream( rStrmName, STREAM_STD_READ );
+ if( xStrm.Is() && (xStrm->GetError() == SVSTREAM_OK) )
+ {
+ xStrm->SetBufferSize( STREAM_BUFFER_SIZE );
+ Load( *xStrm );
+ }
+ else
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ }
+ else
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ return GetError();
+}
+
+ErrCode SfxOlePropertySet::SavePropertySet( SotStorage* pStrg, const String& rStrmName )
+{
+ if( pStrg )
+ {
+ SotStorageStreamRef xStrm = pStrg->OpenSotStream( rStrmName, STREAM_TRUNC | STREAM_STD_WRITE );
+ if( xStrm.Is() )
+ Save( *xStrm );
+ else
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ }
+ else
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ return GetError();
+}
+
+SfxOleSectionRef SfxOlePropertySet::GetSection( SfxOleSectionType eSection ) const
+{
+ return GetSection( GetSectionGuid( eSection ) );
+}
+
+SfxOleSectionRef SfxOlePropertySet::GetSection( const SvGlobalName& rSectionGuid ) const
+{
+ SfxOleSectionRef xSection;
+ SfxOleSectionMap::const_iterator aIt = maSectionMap.find( rSectionGuid );
+ if( aIt != maSectionMap.end() )
+ xSection = aIt->second;
+ return xSection;
+}
+
+SfxOleSection& SfxOlePropertySet::AddSection( SfxOleSectionType eSection )
+{
+ return AddSection( GetSectionGuid( eSection ) );
+}
+
+SfxOleSection& SfxOlePropertySet::AddSection( const SvGlobalName& rSectionGuid )
+{
+ SfxOleSectionRef xSection = GetSection( rSectionGuid );
+ if( !xSection )
+ {
+ // #i66214# #i66428# applications may write broken dictionary properties in wrong sections
+ bool bSupportsDict = rSectionGuid == GetSectionGuid( SECTION_CUSTOM );
+ xSection.reset( new SfxOleSection( bSupportsDict ) );
+ maSectionMap[ rSectionGuid ] = xSection;
+ }
+ return *xSection;
+}
+
+void SfxOlePropertySet::ImplLoad( SvStream& rStrm )
+{
+ // read property set header
+ sal_uInt16 nByteOrder;
+ sal_uInt16 nVersion;
+ sal_uInt16 nOsMinor;
+ sal_uInt16 nOsType;
+ SvGlobalName aGuid;
+ sal_Int32 nSectCount;
+ rStrm >> nByteOrder >> nVersion >> nOsMinor >> nOsType >> aGuid >> nSectCount;
+
+ // read sections
+ sal_Size nSectPosPos = rStrm.Tell();
+ for( sal_Int32 nSectIdx = 0; (nSectIdx < nSectCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nSectIdx )
+ {
+ // read section guid/position pair
+ rStrm.Seek( nSectPosPos );
+ SvGlobalName aSectGuid;
+ sal_uInt32 nSectPos;
+ rStrm >> aSectGuid >> nSectPos;
+ nSectPosPos = rStrm.Tell();
+ // read section
+ rStrm.Seek( static_cast< sal_Size >( nSectPos ) );
+ if( rStrm.GetErrorCode() == SVSTREAM_OK )
+ LoadObject( rStrm, AddSection( aSectGuid ) );
+ }
+}
+
+void SfxOlePropertySet::ImplSave( SvStream& rStrm )
+{
+ // write property set header
+ SvGlobalName aGuid;
+ sal_Int32 nSectCount = static_cast< sal_Int32 >( maSectionMap.size() );
+ rStrm << sal_uInt16( 0xFFFE ) // byte order
+ << sal_uInt16( 0 ) // version
+ << sal_uInt16( 1 ) // OS minor version
+ << sal_uInt16( 2 ) // OS type always windows for text encoding
+ << aGuid // unused guid
+ << nSectCount; // number of sections
+
+ // write placeholders for section guid/position pairs
+ sal_Size nSectPosPos = rStrm.Tell();
+ rStrm.SeekRel( static_cast< sal_sSize >( 20 * nSectCount ) );
+
+ // write sections
+ for( SfxOleSectionMap::const_iterator aIt = maSectionMap.begin(), aEnd = maSectionMap.end(); aIt != aEnd; ++aIt )
+ {
+ SfxOleSection& rSection = *aIt->second;
+ rStrm.Seek( STREAM_SEEK_TO_END );
+ sal_uInt32 nSectPos = static_cast< sal_uInt32 >( rStrm.Tell() );
+ // write the section
+ SaveObject( rStrm, rSection );
+ // write section guid/position pair
+ rStrm.Seek( nSectPosPos );
+ rStrm << aIt->first << nSectPos;
+ nSectPosPos = rStrm.Tell();
+ }
+}
+
+const SvGlobalName& SfxOlePropertySet::GetSectionGuid( SfxOleSectionType eSection )
+{
+ static const SvGlobalName saGlobalGuid( 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 );
+ static const SvGlobalName saBuiltInGuid( 0xD5CDD502, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE );
+ static const SvGlobalName saCustomGuid( 0xD5CDD505, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE );
+ static const SvGlobalName saEmptyGuid;
+ switch( eSection )
+ {
+ case SECTION_GLOBAL: return saGlobalGuid;
+ case SECTION_BUILTIN: return saBuiltInGuid;
+ case SECTION_CUSTOM: return saCustomGuid;
+ default: DBG_ERRORFILE( "SfxOlePropertySet::GetSectionGuid - unknown section type" );
+ }
+ return saEmptyGuid;
+}
+
+// ============================================================================
+
+//} // namespace
diff --git a/sfx2/source/doc/oleprops.hxx b/sfx2/source/doc/oleprops.hxx
new file mode 100755
index 000000000000..5bd586576ac8
--- /dev/null
+++ b/sfx2/source/doc/oleprops.hxx
@@ -0,0 +1,404 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General 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 <map>
+#include <boost/shared_ptr.hpp>
+#include <sot/storage.hxx>
+#include <vcl/bitmapex.hxx>
+
+#include <com/sun/star/util/DateTime.hpp>
+
+
+// ============================================================================
+
+//namespace {
+
+// ============================================================================
+// property type IDs
+const sal_Int32 PROPTYPE_INT16 = 2;
+const sal_Int32 PROPTYPE_INT32 = 3;
+const sal_Int32 PROPTYPE_FLOAT = 4;
+const sal_Int32 PROPTYPE_DOUBLE = 5;
+const sal_Int32 PROPTYPE_DATE = 7;
+const sal_Int32 PROPTYPE_STRING = 8;
+const sal_Int32 PROPTYPE_STATUS = 10;
+const sal_Int32 PROPTYPE_BOOL = 11;
+const sal_Int32 PROPTYPE_VARIANT = 12;
+const sal_Int32 PROPTYPE_INT8 = 16;
+const sal_Int32 PROPTYPE_UINT8 = 17;
+const sal_Int32 PROPTYPE_UINT16 = 18;
+const sal_Int32 PROPTYPE_UINT32 = 19;
+const sal_Int32 PROPTYPE_INT64 = 20;
+const sal_Int32 PROPTYPE_UINT64 = 21;
+const sal_Int32 PROPTYPE_STRING8 = 30;
+const sal_Int32 PROPTYPE_STRING16 = 31;
+const sal_Int32 PROPTYPE_FILETIME = 64;
+const sal_Int32 PROPTYPE_BLOB = 65;
+const sal_Int32 PROPTYPE_CLIPFMT = 71;
+
+// static property IDs
+const sal_Int32 PROPID_DICTIONARY = 0;
+const sal_Int32 PROPID_CODEPAGE = 1;
+const sal_Int32 PROPID_FIRSTCUSTOM = 2;
+
+// property IDs for GlobalDocPropertySet
+const sal_Int32 PROPID_TITLE = 2;
+const sal_Int32 PROPID_SUBJECT = 3;
+const sal_Int32 PROPID_AUTHOR = 4;
+const sal_Int32 PROPID_KEYWORDS = 5;
+const sal_Int32 PROPID_COMMENTS = 6;
+const sal_Int32 PROPID_TEMPLATE = 7;
+const sal_Int32 PROPID_LASTAUTHOR = 8;
+const sal_Int32 PROPID_REVNUMBER = 9;
+const sal_Int32 PROPID_EDITTIME = 10;
+const sal_Int32 PROPID_LASTPRINTED = 11;
+const sal_Int32 PROPID_CREATED = 12;
+const sal_Int32 PROPID_LASTSAVED = 13;
+const sal_Int32 PROPID_THUMBNAIL = 17;
+
+// predefined codepages
+const sal_uInt16 CODEPAGE_UNKNOWN = 0;
+const sal_uInt16 CODEPAGE_UNICODE = 1200;
+const sal_uInt16 CODEPAGE_UTF8 = 65001;
+
+// predefined clipboard format IDs
+const sal_Int32 CLIPFMT_WIN = -1;
+
+// predefined clipboard data format IDs
+const sal_Int32 CLIPDATAFMT_DIB = 8;
+
+// ============================================================================
+// ============================================================================
+
+/** Helper for classes that need text encoding settings.
+
+ Classes derived from this class will include functions to store and use
+ text encoding settings and to convert Windows codepage constants.
+ */
+class SfxOleTextEncoding
+{
+public:
+ inline explicit SfxOleTextEncoding() :
+ mxTextEnc( new rtl_TextEncoding( gsl_getSystemTextEncoding() ) ) {}
+ inline explicit SfxOleTextEncoding( rtl_TextEncoding eTextEnc ) :
+ mxTextEnc( new rtl_TextEncoding( eTextEnc ) ) {}
+ inline explicit SfxOleTextEncoding( sal_Int16 nCodePage ) :
+ mxTextEnc( new rtl_TextEncoding ) { SetCodePage( nCodePage ); }
+
+ /** Returns the current text encoding identifier. */
+ inline rtl_TextEncoding GetTextEncoding() const { return *mxTextEnc; }
+ /** Sets the passed text encoding. */
+ inline void SetTextEncoding( rtl_TextEncoding eTextEnc ) { *mxTextEnc = eTextEnc; }
+
+ /** Returns true, if this object contains Unicode text encoding. */
+ inline bool IsUnicode() const { return GetTextEncoding() == RTL_TEXTENCODING_UCS2; }
+ /** Sets Unicode text encoding to this object. */
+ inline void SetUnicode() { SetTextEncoding( RTL_TEXTENCODING_UCS2 ); }
+
+ /** Converts the current settings to a Windows codepage identifier. */
+ sal_uInt16 GetCodePage() const;
+ /** Sets the current text encoding from a Windows codepage identifier. */
+ void SetCodePage( sal_uInt16 nCodePage );
+
+private:
+ typedef ::boost::shared_ptr< rtl_TextEncoding > TextEncRef;
+ TextEncRef mxTextEnc;
+};
+
+// ============================================================================
+
+/** Helper for classes that need to load or save string values.
+
+ Classes derived from this class contain functions to load and save string
+ values with the text encoding passed in the constructor.
+ */
+class SfxOleStringHelper : public SfxOleTextEncoding
+{
+public:
+ /** Creates a string helper object depending on an external text encoding. */
+ inline explicit SfxOleStringHelper( const SfxOleTextEncoding& rTextEnc ) :
+ SfxOleTextEncoding( rTextEnc ) {}
+ /** Creates a string helper object with own text encoding. */
+ inline explicit SfxOleStringHelper( rtl_TextEncoding eTextEnc ) :
+ SfxOleTextEncoding( eTextEnc ) {}
+
+ /** Loads a string from the passed stream with current encoding (maybe Unicode). */
+ String LoadString8( SvStream& rStrm ) const;
+ /** Saves a string to the passed stream with current encoding (maybe Unicode). */
+ void SaveString8( SvStream& rStrm, const String& rValue ) const;
+
+ /** Loads a Unicode string from the passed stream, ignores own encoding. */
+ String LoadString16( SvStream& rStrm ) const;
+ /** Saves a Unicode string to the passed stream, ignores own encoding. */
+ void SaveString16( SvStream& rStrm, const String& rValue ) const;
+
+private:
+ String ImplLoadString8( SvStream& rStrm ) const;
+ String ImplLoadString16( SvStream& rStrm ) const;
+ void ImplSaveString8( SvStream& rStrm, const String& rValue ) const;
+ void ImplSaveString16( SvStream& rStrm, const String& rValue ) const;
+};
+
+
+// ============================================================================
+// ============================================================================
+
+/** Base class for all classes related to OLE property sets.
+
+ Derived calsses have to implement the pure virtual functions ImplLoad() and
+ ImplSave().
+ */
+class SfxOleObjectBase
+{
+public:
+ inline explicit SfxOleObjectBase() : mnErrCode( ERRCODE_NONE ) {}
+ virtual ~SfxOleObjectBase();
+
+ /** Returns true, if an error code (other than ERRCODE_NONE) is set. */
+ inline bool HasError() const { return mnErrCode != ERRCODE_NONE; }
+ /** Returns the current error code. */
+ inline ErrCode GetError() const { return mnErrCode; }
+
+ /** Loads this object from the passed stream. Calls virtual ImplLoad(). */
+ ErrCode Load( SvStream& rStrm );
+ /** Saves this object to the passed stream. Calls virtual ImplSave(). */
+ ErrCode Save( SvStream& rStrm );
+
+protected:
+ /** Sets the passed error code. Will be returned by Load() and Save() functions.
+ Always the first error code is stored. Multiple calls have no effect. */
+ inline void SetError( ErrCode nErrCode ) { if( !HasError() ) mnErrCode = nErrCode; }
+ /** Loads the passed object from the stream. Sets returned error code as own error. */
+ void LoadObject( SvStream& rStrm, SfxOleObjectBase& rObj );
+ /** Saves the passed object to the stream. Sets returned error code as own error. */
+ void SaveObject( SvStream& rStrm, SfxOleObjectBase& rObj );
+
+private:
+ /** Derived classes implement loading the object from the passed steam. */
+ virtual void ImplLoad( SvStream& rStrm ) = 0;
+ /** Derived classes implement saving the object to the passed steam. */
+ virtual void ImplSave( SvStream& rStrm ) = 0;
+
+private:
+ ErrCode mnErrCode; /// Current error code.
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Base class for all OLE property objects. */
+class SfxOlePropertyBase : public SfxOleObjectBase
+{
+public:
+ inline explicit SfxOlePropertyBase( sal_Int32 nPropId, sal_Int32 nPropType ) :
+ mnPropId( nPropId ), mnPropType( nPropType ) {}
+
+ inline sal_Int32 GetPropId() const { return mnPropId; }
+ inline sal_Int32 GetPropType() const { return mnPropType; }
+
+protected:
+ inline void SetPropId( sal_Int32 nPropId ) { mnPropId = nPropId; }
+ inline void SetPropType( sal_Int32 nPropType ) { mnPropType = nPropType; }
+
+private:
+ sal_Int32 mnPropId;
+ sal_Int32 mnPropType;
+};
+
+typedef ::boost::shared_ptr< SfxOlePropertyBase > SfxOlePropertyRef;
+
+// ============================================================================
+/** Property representing the codepage used to encode bytestrings in the entire property set. */
+class SfxOleCodePageProperty : public SfxOlePropertyBase, public SfxOleTextEncoding
+{
+public:
+ explicit SfxOleCodePageProperty();
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+};
+
+// ============================================================================
+// ============================================================================
+
+/** Property containing custom names for other properties in the property set. */
+class SfxOleDictionaryProperty : public SfxOlePropertyBase, public SfxOleStringHelper
+{
+public:
+ explicit SfxOleDictionaryProperty( const SfxOleTextEncoding& rTextEnc );
+
+ /** Returns true, if the property contains at least one custom property name. */
+ inline bool HasPropertyNames() const { return !maPropNameMap.empty(); }
+ /** Prepares the property for loading. Does not affect contained names for its own. */
+ inline void SetNameCount( sal_Int32 nNameCount ) { SetPropType( nNameCount ); }
+
+ /** Returns the custom name for the passed property ID, or an empty string, if name not found. */
+ const String& GetPropertyName( sal_Int32 nPropId ) const;
+ /** Sets a custom name for the passed property ID. */
+ void SetPropertyName( sal_Int32 nPropId, const String& rPropName );
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+private:
+ typedef ::std::map< sal_Int32, String > SfxOlePropNameMap;
+ SfxOlePropNameMap maPropNameMap;
+};
+
+// ============================================================================
+// ============================================================================
+
+/** A section in a property set. Contains properties with unique identifiers. */
+class SfxOleSection : public SfxOleObjectBase
+{
+private:
+ typedef ::std::map< sal_Int32, SfxOlePropertyRef > SfxOlePropMap;
+
+public:
+ explicit SfxOleSection( bool bSupportsDict );
+
+ /** Returns the property with the passed ID, or an empty reference, if nothing found. */
+ SfxOlePropertyRef GetProperty( sal_Int32 nPropId ) const;
+ /** Returns the value of a signed int32 property with the passed ID in rnValue.
+ @return true = Property found, rnValue is valid; false = Property not found. */
+ bool GetInt32Value( sal_Int32& rnValue, sal_Int32 nPropId ) const;
+ /** Returns the value of a floating-point property with the passed ID in rfValue.
+ @return true = Property found, rfValue is valid; false = Property not found. */
+ bool GetDoubleValue( double& rfValue, sal_Int32 nPropId ) const;
+ /** Returns the value of a boolean property with the passed ID in rbValue.
+ @return true = Property found, rbValue is valid; false = Property not found. */
+ bool GetBoolValue( bool& rbValue, sal_Int32 nPropId ) const;
+ /** Returns the value of a string property with the passed ID in rValue.
+ @return true = Property found, rValue is valid; false = Property not found. */
+ bool GetStringValue( String& rValue, sal_Int32 nPropId ) const;
+ /** Returns the value of a time stamp property with the passed ID in rValue.
+ @return true = Property found, rValue is valid; false = Property not found. */
+ bool GetFileTimeValue( ::com::sun::star::util::DateTime& rValue, sal_Int32 nPropId ) const;
+
+ /** Adds the passed property to the property set. Drops an existing old property. */
+ void SetProperty( SfxOlePropertyRef xProp );
+ /** Inserts a signed int32 property with the passed value. */
+ void SetInt32Value( sal_Int32 nPropId, sal_Int32 nValue );
+ /** Inserts a foating-point property with the passed value. */
+ void SetDoubleValue( sal_Int32 nPropId, double fValue );
+ /** Inserts a boolean property with the passed value. */
+ void SetBoolValue( sal_Int32 nPropId, bool bValue );
+ /** Inserts a string property with the passed value.
+ @return true = Property inserted; false = String was empty, property not inserted. */
+ bool SetStringValue( sal_Int32 nPropId, const String& rValue, bool bSkipEmpty = true );
+ /** Inserts a time stamp property with the passed value. */
+ void SetFileTimeValue( sal_Int32 nPropId, const ::com::sun::star::util::DateTime& rValue );
+ /** Inserts a thumbnail property from the passed meta file. */
+ void SetThumbnailValue( sal_Int32 nPropId,
+ const ::com::sun::star::uno::Sequence<sal_uInt8> & i_rData);
+ /** Inserts a BLOB property with the passed data. */
+ void SetBlobValue( sal_Int32 nPropId,
+ const ::com::sun::star::uno::Sequence<sal_uInt8> & i_rData);
+
+ /** Returns the value of the property with the passed ID in a UNO any. */
+ com::sun::star::uno::Any GetAnyValue( sal_Int32 nPropId ) const;
+ /** Inserts a property created from the passed any.
+ @return true = Property converted and inserted; false = Property type not supported. */
+ bool SetAnyValue( sal_Int32 nPropId, const com::sun::star::uno::Any& rValue );
+
+ /** Returns the custom name for the passed property ID, or an empty string, if name not found. */
+ const String& GetPropertyName( sal_Int32 nPropId ) const;
+ /** Sets a custom name for the passed property ID. */
+ void SetPropertyName( sal_Int32 nPropId, const String& rPropName );
+
+ /** Returns the identifiers of all existing properties in the passed vector. */
+ void GetPropertyIds( ::std::vector< sal_Int32 >& rPropIds ) const;
+ /** Returns a property identifier not used in this section. */
+ sal_Int32 GetFreePropertyId() const;
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+ bool SeekToPropertyPos( SvStream& rStrm, sal_uInt32 nPropPos ) const;
+ void LoadProperty( SvStream& rStrm, sal_Int32 nPropId );
+ void SaveProperty( SvStream& rStrm, SfxOlePropertyBase& rProp, sal_Size& rnPropPosPos );
+
+private:
+ SfxOlePropMap maPropMap; /// All properties in this section, by identifier.
+ SfxOleCodePageProperty maCodePageProp; /// The codepage property.
+ SfxOleDictionaryProperty maDictProp; /// The dictionary property.
+ sal_Size mnStartPos; /// Start stream position of the section.
+ bool mbSupportsDict; /// true = section supports dictionary.
+};
+
+typedef ::boost::shared_ptr< SfxOleSection > SfxOleSectionRef;
+
+// ============================================================================
+// ============================================================================
+
+/** Enumerates different section types in OLE property sets. */
+enum SfxOleSectionType
+{
+ SECTION_GLOBAL, /// Globally defined properties.
+ SECTION_BUILTIN, /// Properties built into MS Office.
+ SECTION_CUSTOM /// Custom properties.
+};
+
+// ============================================================================
+
+/** Represents a complete property set, may consist of several property sections. */
+class SfxOlePropertySet : public SfxOleObjectBase
+{
+public:
+ inline explicit SfxOlePropertySet() {}
+
+ /** Loads this object from the passed storage. */
+ ErrCode LoadPropertySet( SotStorage* pStrg, const String& rStrmName );
+ /** Saves this object to the passed storage. */
+ ErrCode SavePropertySet( SotStorage* pStrg, const String& rStrmName );
+
+ /** Returns the specified section, or an empty reference, if nothing found. */
+ SfxOleSectionRef GetSection( SfxOleSectionType eSection ) const;
+ /** Returns the specified section, or an empty reference, if nothing found. */
+ SfxOleSectionRef GetSection( const SvGlobalName& rSectionGuid ) const;
+
+ /** Creates and returns the specified section, or just returns it if it already exists. */
+ SfxOleSection& AddSection( SfxOleSectionType eSection );
+ /** Creates and returns the specified section, or just returns it if it already exists. */
+ SfxOleSection& AddSection( const SvGlobalName& rSectionGuid );
+
+private:
+ virtual void ImplLoad( SvStream& rStrm );
+ virtual void ImplSave( SvStream& rStrm );
+
+ /** Returns the GUID for the specified section. */
+ static const SvGlobalName& GetSectionGuid( SfxOleSectionType eSection );
+
+private:
+ typedef ::std::map< SvGlobalName, SfxOleSectionRef > SfxOleSectionMap;
+ SfxOleSectionMap maSectionMap;
+};
+
+//};
diff --git a/sfx2/source/doc/ownsubfilterservice.cxx b/sfx2/source/doc/ownsubfilterservice.cxx
new file mode 100644
index 000000000000..9cab42889b6e
--- /dev/null
+++ b/sfx2/source/doc/ownsubfilterservice.cxx
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+
+#include <ownsubfilterservice.hxx>
+#include <sfx2/objsh.hxx>
+
+using namespace ::com::sun::star;
+
+namespace sfx2 {
+
+//-------------------------------------------------------------------------
+OwnSubFilterService::OwnSubFilterService( const uno::Reference < lang::XMultiServiceFactory >& xFactory )
+: m_xFactory( xFactory )
+, m_pObjectShell( NULL )
+{
+}
+
+//-------------------------------------------------------------------------
+OwnSubFilterService::~OwnSubFilterService()
+{
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OwnSubFilterService::impl_getStaticSupportedServiceNames()
+{
+ uno::Sequence< ::rtl::OUString > aRet(2);
+ aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.document.OwnSubFilter");
+ aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.document.OwnSubFilter");
+ return aRet;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OwnSubFilterService::impl_getStaticImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.document.OwnSubFilter");
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL OwnSubFilterService::impl_staticCreateSelfInstance(
+ const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
+{
+ return uno::Reference< uno::XInterface >( *new OwnSubFilterService( xServiceManager ) );
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< lang::XSingleServiceFactory > SAL_CALL OwnSubFilterService::impl_createFactory(
+ const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
+{
+ return ::cppu::createSingleFactory( xServiceManager,
+ OwnSubFilterService::impl_getStaticImplementationName(),
+ OwnSubFilterService::impl_staticCreateSelfInstance,
+ OwnSubFilterService::impl_getStaticSupportedServiceNames() );
+}
+
+
+// XFilter
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL OwnSubFilterService::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
+ throw (uno::RuntimeException)
+{
+ if ( !m_pObjectShell )
+ throw uno::RuntimeException();
+
+ return m_pObjectShell->ImportFromGeneratedStream_Impl( m_xStream, aDescriptor );
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL OwnSubFilterService::cancel()
+ throw (uno::RuntimeException)
+{
+ // not implemented
+}
+
+
+// XInitialization
+
+//-------------------------------------------------------------------------
+void SAL_CALL OwnSubFilterService::initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException)
+{
+ if ( !m_xFactory.is() )
+ throw uno::RuntimeException();
+
+ if ( aArguments.getLength() != 2 )
+ throw lang::IllegalArgumentException();
+
+ if ( m_pObjectShell )
+ throw frame::DoubleInitializationException();
+
+ if ( ( aArguments[1] >>= m_xStream ) && m_xStream.is()
+ && ( aArguments[0] >>= m_xModel ) && m_xModel.is() )
+ {
+ ::com::sun::star::uno::Reference < ::com::sun::star::lang::XUnoTunnel > xObj( m_xModel, uno::UNO_QUERY_THROW );
+ ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
+ sal_Int64 nHandle = xObj->getSomething( aSeq );
+ if ( nHandle )
+ m_pObjectShell = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
+ }
+
+ if ( !m_pObjectShell )
+ throw lang::IllegalArgumentException();
+}
+
+
+// XServiceInfo
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OwnSubFilterService::getImplementationName()
+ throw ( uno::RuntimeException )
+{
+ return impl_getStaticImplementationName();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL OwnSubFilterService::supportsService( const ::rtl::OUString& ServiceName )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aSeq = impl_getStaticSupportedServiceNames();
+
+ 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 OwnSubFilterService::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return impl_getStaticSupportedServiceNames();
+}
+
+} // namespace sfx2
+
diff --git a/sfx2/source/doc/plugin.cxx b/sfx2/source/doc/plugin.cxx
new file mode 100644
index 000000000000..9ff8c73acbf6
--- /dev/null
+++ b/sfx2/source/doc/plugin.cxx
@@ -0,0 +1,266 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "plugin.hxx"
+#include <com/sun/star/plugin/XPluginManager.hpp>
+#include <com/sun/star/plugin/PluginMode.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+
+#include <tools/debug.hxx>
+#include <rtl/ustring.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svtools/miscopt.hxx>
+#include <vcl/window.hxx>
+
+using namespace ::com::sun::star;
+
+namespace sfx2
+{
+
+class PluginWindow_Impl : public Window
+{
+public:
+ uno::Reference < awt::XWindow > xWindow;
+ PluginWindow_Impl( Window* pParent )
+ : Window( pParent, WB_CLIPCHILDREN )
+ {}
+
+ virtual void Resize();
+};
+
+void PluginWindow_Impl::Resize()
+{
+ Size aSize( GetOutputSizePixel() );
+ if ( xWindow.is() )
+ xWindow->setPosSize( 0, 0, aSize.Width(), aSize.Height(), WINDOW_POSSIZE_SIZE );
+}
+
+#define PROPERTY_UNBOUND 0
+
+#define WID_COMMANDS 1
+#define WID_MIMETYPE 2
+#define WID_URL 3
+const SfxItemPropertyMapEntry* lcl_GetPluginPropertyMap_Impl()
+{
+ static SfxItemPropertyMapEntry aPluginPropertyMap_Impl[] =
+ {
+ { MAP_CHAR_LEN("PluginCommands"), WID_COMMANDS, &::getCppuType((::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >*)0), PROPERTY_UNBOUND, 0},
+ { MAP_CHAR_LEN("PluginMimeType"), WID_MIMETYPE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { MAP_CHAR_LEN("PluginURL"), WID_URL , &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ {0,0,0,0,0,0}
+ };
+ return aPluginPropertyMap_Impl;
+}
+
+SFX_IMPL_XSERVICEINFO( PluginObject, "com.sun.star.embed.SpecialEmbeddedObject", "com.sun.star.comp.sfx2.PluginObject" )
+SFX_IMPL_SINGLEFACTORY( PluginObject );
+
+PluginObject::PluginObject( const uno::Reference < lang::XMultiServiceFactory >& rFact )
+ : mxFact( rFact )
+ , maPropMap( lcl_GetPluginPropertyMap_Impl() )
+{
+}
+
+PluginObject::~PluginObject()
+{
+}
+
+void SAL_CALL PluginObject::initialize( const uno::Sequence< uno::Any >& aArguments ) throw ( uno::Exception, uno::RuntimeException )
+{
+ if ( aArguments.getLength() )
+ aArguments[0] >>= mxObj;
+}
+
+sal_Bool SAL_CALL PluginObject::load(
+ const uno::Sequence < com::sun::star::beans::PropertyValue >& /*lDescriptor*/,
+ const uno::Reference < frame::XFrame >& xFrame )
+throw( uno::RuntimeException )
+{
+ uno::Reference< plugin::XPluginManager > xPMgr( mxFact->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.plugin.PluginManager") ), uno::UNO_QUERY );
+ if (!xPMgr.is() )
+ return FALSE;
+
+ if ( SvtMiscOptions().IsPluginsEnabled() )
+ {
+ Window* pParent = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ PluginWindow_Impl* pWin = new PluginWindow_Impl( pParent );
+ pWin->SetSizePixel( pParent->GetOutputSizePixel() );
+ pWin->SetBackground();
+ pWin->Show();
+
+ ULONG nCount = maCmdList.Count();
+ uno::Sequence < ::rtl::OUString > aCmds( nCount ), aArgs( nCount );
+ ::rtl::OUString *pCmds = aCmds.getArray(), *pArgs = aArgs.getArray();
+ for( ULONG i = 0; i < nCount; i++ )
+ {
+ SvCommand & rCmd = maCmdList.GetObject( i );
+ pCmds[i] = rCmd.GetCommand();
+ pArgs[i] = rCmd.GetArgument();
+ }
+
+ mxPlugin = xPMgr->createPluginFromURL(
+ xPMgr->createPluginContext(), plugin::PluginMode::EMBED, aCmds, aArgs, uno::Reference< awt::XToolkit >(),
+ uno::Reference< awt::XWindowPeer >( pWin->GetComponentInterface() ), maURL );
+
+ if ( mxPlugin.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow( mxPlugin, uno::UNO_QUERY );
+ if ( xWindow.is() )
+ {
+ pWin->xWindow = xWindow;
+ pWin->Resize();
+ xWindow->setVisible( TRUE );
+ }
+
+ try
+ {
+ uno::Reference< awt::XControl > xControl( mxPlugin, uno::UNO_QUERY );
+ if( xControl.is() )
+ {
+ uno::Reference< awt::XControlModel > xModel = xControl->getModel();
+ uno::Reference< beans::XPropertySet > xProp( xModel, ::uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ uno::Any aValue = xProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) );
+ aValue >>= maURL;
+ aValue = xProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TYPE" ) ) );
+ aValue >>= maMimeType;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+
+ uno::Reference < awt::XWindow > xWindow( pWin->GetComponentInterface(), uno::UNO_QUERY );
+
+ // we must destroy the plugin before the parent is destroyed
+ xWindow->addEventListener( this );
+ xFrame->setComponent( xWindow, uno::Reference < frame::XController >() );
+ return mxPlugin.is() ? TRUE : FALSE;
+ }
+
+ return FALSE;
+}
+
+void SAL_CALL PluginObject::cancel() throw( com::sun::star::uno::RuntimeException )
+{
+ uno::Reference< lang::XComponent > xComp( mxPlugin, uno::UNO_QUERY );
+ if (xComp.is())
+ xComp->dispose();
+ mxPlugin = 0;
+}
+
+void SAL_CALL PluginObject::close( sal_Bool /*bDeliverOwnership*/ ) throw( com::sun::star::util::CloseVetoException, com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL PluginObject::addCloseListener( const com::sun::star::uno::Reference < com::sun::star::util::XCloseListener >& ) throw( com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL PluginObject::removeCloseListener( const com::sun::star::uno::Reference < com::sun::star::util::XCloseListener >& ) throw( com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL PluginObject::disposing( const com::sun::star::lang::EventObject& ) throw (com::sun::star::uno::RuntimeException)
+{
+ cancel();
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL PluginObject::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException )
+{
+ static uno::Reference< beans::XPropertySetInfo > xInfo = new SfxItemPropertySetInfo( &maPropMap );
+ return xInfo;
+}
+
+void SAL_CALL PluginObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aAny)
+ throw ( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if ( aPropertyName.equalsAscii("PluginURL") )
+ {
+ aAny >>= maURL;
+ }
+ else if ( aPropertyName.equalsAscii("PluginMimeType") )
+ {
+ aAny >>= maMimeType;
+ }
+ else if ( aPropertyName.equalsAscii("PluginCommands") )
+ {
+ maCmdList.Clear();
+ uno::Sequence < beans::PropertyValue > aCommandSequence;
+ if( aAny >>= aCommandSequence )
+ maCmdList.FillFromSequence( aCommandSequence );
+ }
+ else
+ throw beans::UnknownPropertyException();
+}
+
+uno::Any SAL_CALL PluginObject::getPropertyValue(const ::rtl::OUString& aPropertyName)
+ throw ( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aAny;
+ if ( aPropertyName.equalsAscii("PluginURL") )
+ {
+ aAny <<= maURL;
+ }
+ else if ( aPropertyName.equalsAscii("PluginMimeType") )
+ {
+ aAny <<= maMimeType;
+ }
+ else if ( aPropertyName.equalsAscii("PluginCommands") )
+ {
+ uno::Sequence< beans::PropertyValue > aCommandSequence;
+ maCmdList.FillSequence( aCommandSequence );
+ aAny <<= aCommandSequence;
+ }
+ else
+ throw beans::UnknownPropertyException();
+ return aAny;
+}
+
+void SAL_CALL PluginObject::addPropertyChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL PluginObject::removePropertyChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL PluginObject::addVetoableChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL PluginObject::removeVetoableChangeListener(const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener > & ) throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+}
diff --git a/sfx2/source/doc/printhelper.cxx b/sfx2/source/doc/printhelper.cxx
new file mode 100755
index 000000000000..2cd195976832
--- /dev/null
+++ b/sfx2/source/doc/printhelper.cxx
@@ -0,0 +1,906 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "printhelper.hxx"
+
+#include <com/sun/star/view/XPrintJob.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/view/PaperFormat.hpp>
+#include <com/sun/star/view/PaperOrientation.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/view/DuplexMode.hpp>
+
+#include <svl/lstner.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.hxx>
+#include <tools/urlobj.hxx>
+#include <ucbhelper/content.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <vos/mutex.hxx>
+#include <svtools/printdlg.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/event.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+struct IMPL_PrintListener_DataContainer : public SfxListener
+{
+ SfxObjectShellRef m_pObjectShell;
+ ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer;
+ uno::Reference< com::sun::star::view::XPrintJob> m_xPrintJob;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > m_aPrintOptions;
+
+ IMPL_PrintListener_DataContainer( ::osl::Mutex& aMutex)
+ : m_pObjectShell ( 0 )
+ , m_aInterfaceContainer ( aMutex )
+ {
+ }
+
+
+ void Notify( SfxBroadcaster& aBC ,
+ const SfxHint& aHint ) ;
+};
+
+awt::Size impl_Size_Object2Struct( const Size& aSize )
+{
+ awt::Size aReturnValue;
+ aReturnValue.Width = aSize.Width() ;
+ aReturnValue.Height = aSize.Height() ;
+ return aReturnValue ;
+}
+
+Size impl_Size_Struct2Object( const awt::Size& aSize )
+{
+ Size aReturnValue;
+ aReturnValue.Width() = aSize.Width ;
+ aReturnValue.Height() = aSize.Height ;
+ return aReturnValue ;
+}
+
+class SfxPrintJob_Impl : public cppu::WeakImplHelper1
+<
+ com::sun::star::view::XPrintJob
+>
+{
+ IMPL_PrintListener_DataContainer* m_pData;
+
+public:
+ SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData );
+ virtual Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPrintOptions( ) throw (RuntimeException);
+ virtual Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPrinter( ) throw (RuntimeException);
+ virtual Reference< ::com::sun::star::view::XPrintable > SAL_CALL getPrintable( ) throw (RuntimeException);
+ virtual void SAL_CALL cancelJob() throw (RuntimeException);
+};
+
+SfxPrintJob_Impl::SfxPrintJob_Impl( IMPL_PrintListener_DataContainer* pData )
+ : m_pData( pData )
+{
+}
+
+Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrintOptions() throw (RuntimeException)
+{
+ return m_pData->m_aPrintOptions;
+}
+
+Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL SfxPrintJob_Impl::getPrinter() throw (RuntimeException)
+{
+ if( m_pData->m_pObjectShell.Is() )
+ {
+ Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell->GetModel(), UNO_QUERY );
+ if ( xPrintable.is() )
+ return xPrintable->getPrinter();
+ }
+ return Sequence< ::com::sun::star::beans::PropertyValue >();
+}
+
+Reference< ::com::sun::star::view::XPrintable > SAL_CALL SfxPrintJob_Impl::getPrintable() throw (RuntimeException)
+{
+ Reference < view::XPrintable > xPrintable( m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->GetModel() : NULL, UNO_QUERY );
+ return xPrintable;
+}
+
+void SAL_CALL SfxPrintJob_Impl::cancelJob() throw (RuntimeException)
+{
+ // FIXME: how to cancel PrintJob via API?!
+ if( m_pData->m_pObjectShell.Is() )
+ m_pData->m_pObjectShell->Broadcast( SfxPrintingHint( -2 ) );
+}
+
+SfxPrintHelper::SfxPrintHelper()
+{
+ m_pData = new IMPL_PrintListener_DataContainer(m_aMutex);
+}
+
+void SAL_CALL SfxPrintHelper::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ if ( aArguments.getLength() )
+ {
+ com::sun::star::uno::Reference < com::sun::star::frame::XModel > xModel;
+ aArguments[0] >>= xModel;
+ uno::Reference < lang::XUnoTunnel > xObj( xModel, uno::UNO_QUERY );
+ uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
+ sal_Int64 nHandle = xObj->getSomething( aSeq );
+ if ( nHandle )
+ {
+ m_pData->m_pObjectShell = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
+ m_pData->StartListening(*m_pData->m_pObjectShell);
+ }
+ }
+}
+
+SfxPrintHelper::~SfxPrintHelper()
+{
+ delete m_pData;
+}
+
+namespace
+{
+ view::PaperFormat convertToPaperFormat(Paper eFormat)
+ {
+ view::PaperFormat eRet;
+ switch (eFormat)
+ {
+ case PAPER_A3:
+ eRet = view::PaperFormat_A3;
+ break;
+ case PAPER_A4:
+ eRet = view::PaperFormat_A4;
+ break;
+ case PAPER_A5:
+ eRet = view::PaperFormat_A5;
+ break;
+ case PAPER_B4_ISO:
+ eRet = view::PaperFormat_B4;
+ break;
+ case PAPER_B5_ISO:
+ eRet = view::PaperFormat_B5;
+ break;
+ case PAPER_LETTER:
+ eRet = view::PaperFormat_LETTER;
+ break;
+ case PAPER_LEGAL:
+ eRet = view::PaperFormat_LEGAL;
+ break;
+ case PAPER_TABLOID:
+ eRet = view::PaperFormat_TABLOID;
+ break;
+ case PAPER_USER:
+ default:
+ eRet = view::PaperFormat_USER;
+ break;
+ }
+ return eRet;
+ }
+
+ Paper convertToPaper(view::PaperFormat eFormat)
+ {
+ Paper eRet(PAPER_USER);
+ switch (eFormat)
+ {
+ case view::PaperFormat_A3:
+ eRet = PAPER_A3;
+ break;
+ case view::PaperFormat_A4:
+ eRet = PAPER_A4;
+ break;
+ case view::PaperFormat_A5:
+ eRet = PAPER_A5;
+ break;
+ case view::PaperFormat_B4:
+ eRet = PAPER_B4_ISO;
+ break;
+ case view::PaperFormat_B5:
+ eRet = PAPER_B5_ISO;
+ break;
+ case view::PaperFormat_LETTER:
+ eRet = PAPER_LETTER;
+ break;
+ case view::PaperFormat_LEGAL:
+ eRet = PAPER_LEGAL;
+ break;
+ case view::PaperFormat_TABLOID:
+ eRet = PAPER_TABLOID;
+ break;
+ case view::PaperFormat_USER:
+ eRet = PAPER_USER;
+ break;
+ case view::PaperFormat_MAKE_FIXED_SIZE:
+ break;
+ //deliberate no default to force warn on a new papersize
+ }
+ return eRet;
+ }
+}
+
+//________________________________________________________________________________________________________
+// XPrintable
+//________________________________________________________________________________________________________
+
+uno::Sequence< beans::PropertyValue > SAL_CALL SfxPrintHelper::getPrinter() throw(::com::sun::star::uno::RuntimeException)
+{
+ // object already disposed?
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // search for any view of this document that is currently printing
+ const Printer *pPrinter = NULL;
+ SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ? SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
+ SfxViewFrame* pFirst = pViewFrm;
+ while ( pViewFrm && !pPrinter )
+ {
+ pPrinter = pViewFrm->GetViewShell()->GetActivePrinter();
+ pViewFrm = SfxViewFrame::GetNext( *pViewFrm, m_pData->m_pObjectShell, sal_False );
+ }
+
+ // if no view is printing currently, use the permanent SfxPrinter instance
+ if ( !pPrinter && pFirst )
+ pPrinter = pFirst->GetViewShell()->GetPrinter(sal_True);
+
+ if ( !pPrinter )
+ return uno::Sequence< beans::PropertyValue >();
+
+ uno::Sequence< beans::PropertyValue > aPrinter(8);
+
+ aPrinter.getArray()[7].Name = DEFINE_CONST_UNICODE( "CanSetPaperSize" );
+ aPrinter.getArray()[7].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_PAPERSIZE ) );
+
+ aPrinter.getArray()[6].Name = DEFINE_CONST_UNICODE( "CanSetPaperFormat" );
+ aPrinter.getArray()[6].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_PAPER ) );
+
+ aPrinter.getArray()[5].Name = DEFINE_CONST_UNICODE( "CanSetPaperOrientation" );
+ aPrinter.getArray()[5].Value <<= ( pPrinter->HasSupport( SUPPORT_SET_ORIENTATION ) );
+
+ aPrinter.getArray()[4].Name = DEFINE_CONST_UNICODE( "IsBusy" );
+ aPrinter.getArray()[4].Value <<= ( pPrinter->IsPrinting() );
+
+ aPrinter.getArray()[3].Name = DEFINE_CONST_UNICODE( "PaperSize" );
+ awt::Size aSize = impl_Size_Object2Struct(pPrinter->GetPaperSize() );
+ aPrinter.getArray()[3].Value <<= aSize;
+
+ aPrinter.getArray()[2].Name = DEFINE_CONST_UNICODE( "PaperFormat" );
+ view::PaperFormat eFormat = convertToPaperFormat(pPrinter->GetPaper());
+ aPrinter.getArray()[2].Value <<= eFormat;
+
+ aPrinter.getArray()[1].Name = DEFINE_CONST_UNICODE( "PaperOrientation" );
+ view::PaperOrientation eOrient = (view::PaperOrientation)pPrinter->GetOrientation();
+ aPrinter.getArray()[1].Value <<= eOrient;
+
+ aPrinter.getArray()[0].Name = DEFINE_CONST_UNICODE( "Name" );
+ String sStringTemp = pPrinter->GetName() ;
+ aPrinter.getArray()[0].Value <<= ::rtl::OUString( sStringTemp );
+
+ return aPrinter;
+}
+
+//________________________________________________________________________________________________________
+// XPrintable
+//________________________________________________________________________________________________________
+
+void SfxPrintHelper::impl_setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter,SfxPrinter*& pPrinter,sal_uInt16& nChangeFlags,SfxViewShell*& pViewSh)
+
+{
+ // alten Printer beschaffen
+ SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
+ SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
+ if ( !pViewFrm )
+ return;
+
+ pViewSh = pViewFrm->GetViewShell();
+ pPrinter = pViewSh->GetPrinter(sal_True);
+ if ( !pPrinter )
+ return;
+
+ // new Printer-Name available?
+ nChangeFlags = 0;
+ sal_Int32 lDummy = 0;
+ for ( int n = 0; n < rPrinter.getLength(); ++n )
+ {
+ // get Property-Value from printer description
+ const beans::PropertyValue &rProp = rPrinter.getConstArray()[n];
+
+ // Name-Property?
+ if ( rProp.Name.compareToAscii( "Name" ) == 0 )
+ {
+ OUSTRING sTemp;
+ if ( ( rProp.Value >>= sTemp ) == sal_False )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+
+ String aPrinterName( sTemp ) ;
+ if ( aPrinterName != pPrinter->GetName() )
+ {
+ pPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aPrinterName );
+ nChangeFlags = SFX_PRINTER_PRINTER;
+ }
+ break;
+ }
+ }
+
+ Size aSetPaperSize( 0, 0);
+ view::PaperFormat nPaperFormat = view::PaperFormat_USER;
+
+ // other properties
+ for ( int i = 0; i < rPrinter.getLength(); ++i )
+ {
+ // get Property-Value from printer description
+ const beans::PropertyValue &rProp = rPrinter.getConstArray()[i];
+
+ // PaperOrientation-Property?
+ if ( rProp.Name.compareToAscii( "PaperOrientation" ) == 0 )
+ {
+ view::PaperOrientation eOrient;
+ if ( ( rProp.Value >>= eOrient ) == sal_False )
+ {
+ if ( ( rProp.Value >>= lDummy ) == sal_False )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ eOrient = ( view::PaperOrientation) lDummy;
+ }
+
+ if ( (Orientation) eOrient != pPrinter->GetOrientation() )
+ {
+ pPrinter->SetOrientation( (Orientation) eOrient );
+ nChangeFlags |= SFX_PRINTER_CHG_ORIENTATION;
+ }
+ }
+
+ // PaperFormat-Property?
+ else if ( rProp.Name.compareToAscii( "PaperFormat" ) == 0 )
+ {
+ if ( ( rProp.Value >>= nPaperFormat ) == sal_False )
+ {
+ if ( ( rProp.Value >>= lDummy ) == sal_False )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ nPaperFormat = ( view::PaperFormat ) lDummy;
+ }
+
+ if ( convertToPaper(nPaperFormat) != pPrinter->GetPaper() )
+ {
+ pPrinter->SetPaper( convertToPaper(nPaperFormat) );
+ nChangeFlags |= SFX_PRINTER_CHG_SIZE;
+ }
+ }
+
+ // PaperSize-Property?
+ else if ( rProp.Name.compareToAscii( "PaperSize" ) == 0 )
+ {
+ awt::Size aTempSize ;
+ if ( ( rProp.Value >>= aTempSize ) == sal_False )
+ {
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ }
+ else
+ {
+ aSetPaperSize = impl_Size_Struct2Object(aTempSize);
+ }
+ }
+
+ // PrinterTray-Property
+ else if ( rProp.Name.compareToAscii( "PrinterPaperTray" ) == 0 )
+ {
+ rtl::OUString aTmp;
+ if ( ( rProp.Value >>= aTmp ) == sal_False )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ USHORT nCount = pPrinter->GetPaperBinCount();
+ for (USHORT nBin=0; nBin<nCount; nBin++)
+ {
+ ::rtl::OUString aName( pPrinter->GetPaperBinName(nBin) );
+ if ( aName == aTmp )
+ {
+ pPrinter->SetPaperBin(nBin);
+ break;
+ }
+ }
+ }
+ }
+
+ //os 12.11.98: die PaperSize darf nur gesetzt werden, wenn tatsaechlich
+ //PAPER_USER gilt, sonst koennte vom Treiber ein falsches Format gewaehlt werden
+ if(nPaperFormat == view::PaperFormat_USER && aSetPaperSize.Width())
+ {
+ //JP 23.09.98 - Bug 56929 - MapMode von 100mm in die am
+ // Device gesetzten umrechnen. Zusaetzlich nur dann
+ // setzen, wenn sie wirklich veraendert wurden.
+ aSetPaperSize = pPrinter->LogicToPixel( aSetPaperSize, MAP_100TH_MM );
+ if( aSetPaperSize != pPrinter->GetPaperSizePixel() )
+ {
+ pPrinter->SetPaperSizeUser( pPrinter->PixelToLogic( aSetPaperSize ) );
+ nChangeFlags |= SFX_PRINTER_CHG_SIZE;
+ }
+ }
+
+ // #96772#: wait until printing is done
+ SfxPrinter* pDocPrinter = pViewSh->GetPrinter();
+ while ( pDocPrinter->IsPrinting() )
+ Application::Yield();
+}
+
+void SAL_CALL SfxPrintHelper::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter)
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ // object already disposed?
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ SfxViewShell* pViewSh = NULL;
+ SfxPrinter* pPrinter = NULL;
+ sal_uInt16 nChangeFlags = 0;
+ impl_setPrinter(rPrinter,pPrinter,nChangeFlags,pViewSh);
+ // set new printer
+ if ( pViewSh && pPrinter )
+ pViewSh->SetPrinter( pPrinter, nChangeFlags, false );
+}
+
+//________________________________________________________________________________________________________
+// ImplPrintWatch thread for asynchronous printing with moving temp. file to ucb location
+//________________________________________________________________________________________________________
+
+/* This implements a thread which will be started to wait for asynchronous
+ print jobs to temp. localy files. If they finish we move the temp. files
+ to her right locations by using the ucb.
+ */
+class ImplUCBPrintWatcher : public ::osl::Thread
+{
+ private:
+ /// of course we must know the printer which execute the job
+ SfxPrinter* m_pPrinter;
+ /// this describes the target location for the printed temp file
+ String m_sTargetURL;
+ /// it holds the temp file alive, till the print job will finish and remove it from disk automaticly if the object die
+ ::utl::TempFile* m_pTempFile;
+
+ public:
+ /* initialize this watcher but don't start it */
+ ImplUCBPrintWatcher( SfxPrinter* pPrinter, ::utl::TempFile* pTempFile, const String& sTargetURL )
+ : m_pPrinter ( pPrinter )
+ , m_sTargetURL( sTargetURL )
+ , m_pTempFile ( pTempFile )
+ {}
+
+ /* waits for finishing of the print job and moves the temp file afterwards
+ Note: Starting of the job is done outside this thread!
+ But we have to free some of the given ressources on heap!
+ */
+ void SAL_CALL run()
+ {
+ /* SAFE { */
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ while( m_pPrinter->IsPrinting() )
+ Application::Yield();
+ m_pPrinter = NULL; // don't delete it! It's borrowed only :-)
+ }
+ /* } SAFE */
+
+ // lock for further using of our member isn't neccessary - because
+ // we truns alone by defenition. Nobody join for us nor use us ...
+ ImplUCBPrintWatcher::moveAndDeleteTemp(&m_pTempFile,m_sTargetURL);
+
+ // finishing of this run() method will call onTerminate() automaticly
+ // kill this thread there!
+ }
+
+ /* nobody wait for this thread. We must kill ourself ...
+ */
+ void SAL_CALL onTerminated()
+ {
+ delete this;
+ }
+
+ /* static helper to move the temp. file to the target location by using the ucb
+ It's static to be useable from outside too. So it's not realy neccessary to start
+ the thread, if finishing of the job was detected outside this thread.
+ But it must be called without using a corresponding thread for the given parameter!
+ */
+ static void moveAndDeleteTemp( ::utl::TempFile** ppTempFile, const String& sTargetURL )
+ {
+ // move the file
+ try
+ {
+ INetURLObject aSplitter(sTargetURL);
+ String sFileName = aSplitter.getName(
+ INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::DECODE_WITH_CHARSET);
+ if (aSplitter.removeSegment() && sFileName.Len()>0)
+ {
+ ::ucbhelper::Content aSource(
+ ::rtl::OUString((*ppTempFile)->GetURL()),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >());
+
+ ::ucbhelper::Content aTarget(
+ ::rtl::OUString(aSplitter.GetMainURL(INetURLObject::NO_DECODE)),
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >());
+
+ aTarget.transferContent(
+ aSource,
+ ::ucbhelper::InsertOperation_COPY,
+ ::rtl::OUString(sFileName),
+ ::com::sun::star::ucb::NameClash::OVERWRITE);
+ }
+ }
+ catch( ::com::sun::star::ucb::ContentCreationException& ) { DBG_ERROR("content create exception"); }
+ catch( ::com::sun::star::ucb::CommandAbortedException& ) { DBG_ERROR("command abort exception"); }
+ catch( ::com::sun::star::uno::RuntimeException& ) { DBG_ERROR("runtime exception"); }
+ catch( ::com::sun::star::uno::Exception& ) { DBG_ERROR("unknown exception"); }
+
+ // kill the temp file!
+ delete *ppTempFile;
+ *ppTempFile = NULL;
+ }
+};
+
+//------------------------------------------------
+
+//________________________________________________________________________________________________________
+// XPrintable
+//________________________________________________________________________________________________________
+void SAL_CALL SfxPrintHelper::print(const uno::Sequence< beans::PropertyValue >& rOptions)
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
+ return;
+
+ // object already disposed?
+ // object already disposed?
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // get view for sfx printing capabilities
+ SfxViewFrame *pViewFrm = m_pData->m_pObjectShell.Is() ?
+ SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ) : 0;
+ if ( !pViewFrm )
+ return;
+ SfxViewShell* pView = pViewFrm->GetViewShell();
+ if ( !pView )
+ return;
+
+// SfxAllItemSet aArgs( pView->GetPool() );
+ sal_Bool bMonitor = sal_False;
+ // We need this information at the end of this method, if we start the vcl printer
+ // by executing the slot. Because if it is a ucb relevant URL we must wait for
+ // finishing the print job and move the temporary local file by using the ucb
+ // to the right location. But in case of no file name is given or it is already
+ // a local one we can supress this special handling. Because then vcl makes all
+ // right for us.
+ String sUcbUrl;
+ ::utl::TempFile* pUCBPrintTempFile = NULL;
+
+ uno::Sequence < beans::PropertyValue > aCheckedArgs( rOptions.getLength() );
+ sal_Int32 nProps = 0;
+ sal_Bool bWaitUntilEnd = sal_False;
+ sal_Int16 nDuplexMode = ::com::sun::star::view::DuplexMode::UNKNOWN;
+ for ( int n = 0; n < rOptions.getLength(); ++n )
+ {
+ // get Property-Value from options
+ const beans::PropertyValue &rProp = rOptions.getConstArray()[n];
+
+ // FileName-Property?
+ if ( rProp.Name.compareToAscii( "FileName" ) == 0 )
+ {
+ // unpack th URL and check for a valid and well known protocol
+ OUSTRING sTemp;
+ if (
+ ( rProp.Value.getValueType()!=::getCppuType((const OUSTRING*)0)) ||
+ (!(rProp.Value>>=sTemp))
+ )
+ {
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ }
+
+ String sPath ;
+ String sURL (sTemp);
+ INetURLObject aCheck(sURL );
+ if (aCheck.GetProtocol()==INET_PROT_NOT_VALID)
+ {
+ // OK - it's not a valid URL. But may it's a simple
+ // system path directly. It will be supported for historical
+ // reasons. Otherwhise we break to much external code ...
+ // We try to convert it to a file URL. If its possible
+ // we put the system path to the item set and let vcl work with it.
+ // No ucb or thread will be neccessary then. In case it couldnt be
+ // converted its not an URL nor a system path. Then we can't accept
+ // this parameter and have to throw an exception.
+ ::rtl::OUString sSystemPath(sTemp);
+ ::rtl::OUString sFileURL;
+ if (::osl::FileBase::getFileURLFromSystemPath(sSystemPath,sFileURL)!=::osl::FileBase::E_None)
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ aCheckedArgs[nProps].Name = rProp.Name;
+ aCheckedArgs[nProps++].Value <<= sFileURL;
+ // and append the local filename
+ aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
+ aCheckedArgs[nProps].Name = rtl::OUString::createFromAscii("LocalFileName");
+ aCheckedArgs[nProps++].Value <<= ::rtl::OUString( sTemp );
+ }
+ else
+ // It's a valid URL. but now we must know, if it is a local one or not.
+ // It's a question of using ucb or not!
+ if (::utl::LocalFileHelper::ConvertURLToSystemPath(sURL,sPath))
+ {
+ // it's a local file, we can use vcl without special handling
+ // And we have to use the system notation of the incoming URL.
+ // But it into the descriptor and let the slot be executed at
+ // the end of this method.
+ aCheckedArgs[nProps].Name = rProp.Name;
+ aCheckedArgs[nProps++].Value <<= sTemp;
+ // and append the local filename
+ aCheckedArgs.realloc( aCheckedArgs.getLength()+1 );
+ aCheckedArgs[nProps].Name = rtl::OUString::createFromAscii("LocalFileName");
+ aCheckedArgs[nProps++].Value <<= ::rtl::OUString( sPath );
+ }
+ else
+ {
+ // it's an ucb target. So we must use a temp. file for vcl
+ // and move it after printing by using the ucb.
+ // Create a temp file on the heap (because it must delete the
+ // real file on disk automaticly if it die - bt we have to share it with
+ // some other sources ... e.g. the ImplUCBPrintWatcher).
+ // And we put the name of this temp file to the descriptor instead
+ // of the URL. The URL we save for later using seperatly.
+ // Execution of the print job will be done later by executing
+ // a slot ...
+ pUCBPrintTempFile = new ::utl::TempFile();
+ pUCBPrintTempFile->EnableKillingFile();
+
+ //FIXME: does it work?
+ aCheckedArgs[nProps].Name = rtl::OUString::createFromAscii("LocalFileName");
+ aCheckedArgs[nProps++].Value <<= ::rtl::OUString( pUCBPrintTempFile->GetFileName() );
+ sUcbUrl = sURL;
+ }
+ }
+
+ // CopyCount-Property
+ else if ( rProp.Name.compareToAscii( "CopyCount" ) == 0 )
+ {
+ sal_Int32 nCopies = 0;
+ if ( ( rProp.Value >>= nCopies ) == sal_False )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+
+ aCheckedArgs[nProps].Name = rProp.Name;
+ aCheckedArgs[nProps++].Value <<= nCopies;
+ }
+
+ // Collate-Property
+ // Sort-Property (deprecated)
+ else if ( rProp.Name.compareToAscii( "Collate" ) == 0 ||
+ ( rProp.Name.compareToAscii( "Sort" ) == 0 ) )
+ {
+ sal_Bool bTemp = sal_Bool();
+ if ( rProp.Value >>= bTemp )
+ {
+ aCheckedArgs[nProps].Name = rtl::OUString::createFromAscii("Collate");
+ aCheckedArgs[nProps++].Value <<= bTemp;
+ }
+ else
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ }
+
+ // Pages-Property
+ else if ( rProp.Name.compareToAscii( "Pages" ) == 0 )
+ {
+ OUSTRING sTemp;
+ if( rProp.Value >>= sTemp )
+ {
+ aCheckedArgs[nProps].Name = rProp.Name;
+ aCheckedArgs[nProps++].Value <<= sTemp;
+ }
+ else
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ }
+
+ // MonitorVisible
+ else if ( rProp.Name.compareToAscii( "MonitorVisible" ) == 0 )
+ {
+ if( !(rProp.Value >>= bMonitor) )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ aCheckedArgs[nProps].Name = rProp.Name;
+ aCheckedArgs[nProps++].Value <<= bMonitor;
+ }
+
+ // Wait
+ else if ( rProp.Name.compareToAscii( "Wait" ) == 0 )
+ {
+ if ( !(rProp.Value >>= bWaitUntilEnd) )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ aCheckedArgs[nProps].Name = rProp.Name;
+ aCheckedArgs[nProps++].Value <<= bWaitUntilEnd;
+ }
+
+ else if ( rProp.Name.compareToAscii( "DuplexMode" ) == 0 )
+ {
+ if ( !(rProp.Value >>= nDuplexMode ) )
+ throw ::com::sun::star::lang::IllegalArgumentException();
+ aCheckedArgs[nProps].Name = rProp.Name;
+ aCheckedArgs[nProps++].Value <<= nDuplexMode;
+ }
+ }
+
+ if ( nProps != aCheckedArgs.getLength() )
+ aCheckedArgs.realloc(nProps);
+
+ // Execute the print request every time.
+ // It doesn'tmatter if it is a real printer used or we print to a local file
+ // nor if we print to a temp file and move it afterwards by using the ucb.
+ // That will be handled later. see pUCBPrintFile below!
+ pView->ExecPrint( aCheckedArgs, sal_True, sal_False );
+
+ // Ok - may be execution before has finished (or started!) printing.
+ // And may it was a printing to a file.
+ // Now we have to check if we can move the file (if neccessary) via ucb to his right location.
+ // Cases:
+ // a) printing finished => move the file directly and forget the watcher thread
+ // b) printing is asynchron and runs currently => start watcher thread and exit this method
+ // This thread make all neccessary things by itself.
+ if (pUCBPrintTempFile!=NULL)
+ {
+ // a)
+ SfxPrinter* pPrinter = pView->GetPrinter();
+ if ( ! pPrinter->IsPrinting() )
+ ImplUCBPrintWatcher::moveAndDeleteTemp(&pUCBPrintTempFile,sUcbUrl);
+ // b)
+ else
+ {
+ // Note: we create(d) some ressource on the heap. (thread and tep file)
+ // They will be delected by the thread automaticly if he finish his run() method.
+ ImplUCBPrintWatcher* pWatcher = new ImplUCBPrintWatcher( pPrinter, pUCBPrintTempFile, sUcbUrl );
+ pWatcher->create();
+ }
+ }
+}
+
+void IMPL_PrintListener_DataContainer::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if ( &rBC == m_pObjectShell )
+ {
+ SfxPrintingHint* pPrintHint = PTR_CAST( SfxPrintingHint, &rHint );
+ if ( pPrintHint )
+ {
+ if ( pPrintHint->GetWhich() == com::sun::star::view::PrintableState_JOB_STARTED )
+ {
+ if ( !m_xPrintJob.is() )
+ m_xPrintJob = new SfxPrintJob_Impl( this );
+/*
+ PrintDialog* pDlg = pPrintHint->GetPrintDialog();
+ Printer* pPrinter = pPrintHint->GetPrinter();
+ ::rtl::OUString aPrintFile ( ( pPrinter && pPrinter->IsPrintFileEnabled() ) ? pPrinter->GetPrintFile() : String() );
+ ::rtl::OUString aRangeText ( ( pDlg && pDlg->IsRangeChecked(PRINTDIALOG_RANGE) ) ? pDlg->GetRangeText() : String() );
+ sal_Bool bSelectionOnly = ( ( pDlg && pDlg->IsRangeChecked(PRINTDIALOG_SELECTION) ) ? sal_True : sal_False );
+
+ sal_Int32 nArgs = 2;
+ if ( aPrintFile.getLength() )
+ nArgs++;
+ if ( aRangeText.getLength() )
+ nArgs++;
+ else if ( bSelectionOnly )
+ nArgs++;
+
+ m_aPrintOptions.realloc(nArgs);
+ m_aPrintOptions[0].Name = DEFINE_CONST_UNICODE("CopyCount");
+ m_aPrintOptions[0].Value <<= (sal_Int16) (pPrinter ? pPrinter->GetCopyCount() : 1 );
+ m_aPrintOptions[1].Name = DEFINE_CONST_UNICODE("Collate");
+ m_aPrintOptions[1].Value <<= (sal_Bool) (pDlg ? pDlg->IsCollateChecked() : sal_False );
+
+ if ( bSelectionOnly )
+ {
+ m_aPrintOptions[2].Name = DEFINE_CONST_UNICODE("Selection");
+ m_aPrintOptions[2].Value <<= bSelectionOnly;
+ }
+ else if ( aRangeText.getLength() )
+ {
+ m_aPrintOptions[2].Name = DEFINE_CONST_UNICODE("Pages");
+ m_aPrintOptions[2].Value <<= aRangeText;
+ }
+
+ if ( aPrintFile.getLength() )
+ {
+ m_aPrintOptions[nArgs-1].Name = DEFINE_CONST_UNICODE("FileName");
+ m_aPrintOptions[nArgs-1].Value <<= aPrintFile;
+ }
+*/
+ m_aPrintOptions = pPrintHint->GetOptions();
+ }
+/*
+ else if ( pPrintHint->GetWhich() == -3 ) // -3 : AdditionalPrintOptions
+ {
+ uno::Sequence < beans::PropertyValue >& lOldOpts = m_aPrintOptions;
+ const uno::Sequence < beans::PropertyValue >& lNewOpts = pPrintHint->GetAdditionalOptions();
+ sal_Int32 nOld = lOldOpts.getLength();
+ sal_Int32 nAdd = lNewOpts.getLength();
+ lOldOpts.realloc( nOld + nAdd );
+
+ // assume that all new elements are overwriting old ones and so don't need to be added
+ sal_Int32 nTotal = nOld;
+ for ( sal_Int32 n=0; n<nAdd; n++ )
+ {
+ sal_Int32 m;
+ for ( m=0; m<nOld; m++ )
+ if ( lNewOpts[n].Name == lOldOpts[m].Name )
+ // new option overwrites old one
+ break;
+
+ if ( m == nOld )
+ {
+ // this is a new option, so add it to the resulting sequence - counter must be incremented
+ lOldOpts[nTotal].Name = lNewOpts[n].Name;
+ lOldOpts[nTotal++].Value = lNewOpts[n].Value;
+ }
+ else
+ // overwrite old option with new value, counter stays unmodified
+ lOldOpts[m].Value = lNewOpts[n].Value;
+ }
+
+ if ( nTotal != lOldOpts.getLength() )
+ // at least one new options has overwritten an old one, so we allocated too much
+ lOldOpts.realloc( nTotal );
+ }
+*/
+ else if ( pPrintHint->GetWhich() != -2 ) // -2 : CancelPrintJob
+ {
+ view::PrintJobEvent aEvent;
+ aEvent.Source = m_xPrintJob;
+ aEvent.State = (com::sun::star::view::PrintableState) pPrintHint->GetWhich();
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< view::XPrintJobListener >*) NULL ) );
+ if ( pContainer!=NULL )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ ((view::XPrintJobListener*)pIterator.next())->printJobEvent( aEvent );
+ }
+ }
+ }
+ }
+}
+
+void SAL_CALL SfxPrintHelper::addPrintJobListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XPrintJobListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference < view::XPrintJobListener>*)0), xListener );
+}
+
+void SAL_CALL SfxPrintHelper::removePrintJobListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XPrintJobListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference < view::XPrintJobListener>*)0), xListener );
+}
+
+
diff --git a/sfx2/source/doc/printhelper.hxx b/sfx2/source/doc/printhelper.hxx
new file mode 100755
index 000000000000..9ba05fc20cee
--- /dev/null
+++ b/sfx2/source/doc/printhelper.hxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+#include "sfx2/dllapi.h"
+#include "sal/types.h"
+
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/view/XPrintJobBroadcaster.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <osl/mutex.hxx>
+#include <cppuhelper/implbase3.hxx>
+
+struct IMPL_PrintListener_DataContainer;
+class SfxViewShell;
+class SfxPrinter;
+
+class SfxPrintHelper : public cppu::WeakImplHelper3
+ < com::sun::star::view::XPrintable
+ , com::sun::star::view::XPrintJobBroadcaster
+ , com::sun::star::lang::XInitialization >
+{
+public:
+
+ SfxPrintHelper() ;
+ virtual ~SfxPrintHelper() ;
+
+ 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);
+ virtual void SAL_CALL addPrintJobListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XPrintJobListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removePrintJobListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XPrintJobListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > SAL_CALL getPrinter() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPrinter( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& seqPrinter )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL print( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& seqOptions )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+private:
+
+ osl::Mutex m_aMutex;
+ IMPL_PrintListener_DataContainer* m_pData ;
+ virtual void impl_setPrinter(const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rPrinter,SfxPrinter*& pPrinter,sal_uInt16& nChangeFlags,SfxViewShell*& pViewSh);
+} ;
diff --git a/sfx2/source/doc/querytemplate.cxx b/sfx2/source/doc/querytemplate.cxx
new file mode 100644
index 000000000000..8e006721351a
--- /dev/null
+++ b/sfx2/source/doc/querytemplate.cxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include "querytemplate.hxx"
+#include "sfxresid.hxx"
+#include "doc.hrc"
+
+#include <vcl/svapp.hxx>
+
+namespace sfx2
+{
+
+QueryTemplateBox::QueryTemplateBox( Window* pParent, const String& rMessage ) :
+ MessBox ( pParent, 0, Application::GetDisplayName(), rMessage )
+{
+ SetImage( QueryBox::GetStandardImage() );
+ SetHelpId( MSG_QUERY_LOAD_TEMPLATE );
+
+ AddButton( String( SfxResId( STR_QRYTEMPL_UPDATE_BTN ) ), RET_YES,
+ BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_OKBUTTON | BUTTONDIALOG_FOCUSBUTTON );
+ AddButton( String( SfxResId( STR_QRYTEMPL_KEEP_BTN ) ), RET_NO, BUTTONDIALOG_CANCELBUTTON );
+}
+
+} // end of namespace sfx2
+
diff --git a/sfx2/source/doc/querytemplate.hxx b/sfx2/source/doc/querytemplate.hxx
new file mode 100644
index 000000000000..92e9f26da0a7
--- /dev/null
+++ b/sfx2/source/doc/querytemplate.hxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SFX2_QUERYTEMPLATE_HXX
+#define _SFX2_QUERYTEMPLATE_HXX
+
+#include <vcl/msgbox.hxx>
+
+namespace sfx2
+{
+
+ class QueryTemplateBox : public MessBox
+ {
+ public:
+ QueryTemplateBox( Window* pParent, const String& rMessage );
+ };
+
+} // end of namespace sfx2
+
+#endif
+
diff --git a/sfx2/source/doc/sfxacldetect.cxx b/sfx2/source/doc/sfxacldetect.cxx
new file mode 100644
index 000000000000..de6528794e20
--- /dev/null
+++ b/sfx2/source/doc/sfxacldetect.cxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef WNT
+
+// necessary to include system headers without warnings
+#ifdef _MSC_VER
+#pragma warning(disable:4668 4917)
+#endif
+
+#include <windows.h>
+#include <lmaccess.h>
+#include <sal/types.h>
+
+sal_Bool IsReadonlyAccordingACL( const sal_Unicode* pFilePath )
+{
+ sal_Bool bResult = sal_False;
+
+ sal_uInt32 nFDSize = 0;
+ GetFileSecurityW( reinterpret_cast< LPCWSTR >(pFilePath), DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, NULL, 0, &nFDSize );
+ if ( nFDSize )
+ {
+ PSECURITY_DESCRIPTOR pFileDescr = reinterpret_cast< PSECURITY_DESCRIPTOR >( malloc( nFDSize ) );
+ if ( GetFileSecurityW( reinterpret_cast< LPCWSTR >(pFilePath), DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, pFileDescr, nFDSize, &nFDSize ) )
+ {
+ HANDLE hToken = NULL;
+ if ( OpenThreadToken( GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken )
+ || OpenProcessToken( GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken) )
+ {
+ HANDLE hImpersonationToken = NULL;
+ if ( DuplicateToken( hToken, SecurityImpersonation, &hImpersonationToken) )
+ {
+ sal_uInt32 nDesiredAccess = ACCESS_WRITE;
+ GENERIC_MAPPING aGenericMapping = { ACCESS_READ, ACCESS_WRITE, 0, ACCESS_READ | ACCESS_WRITE };
+ MapGenericMask( &nDesiredAccess, &aGenericMapping );
+
+ PRIVILEGE_SET aPrivilegeSet;
+ sal_uInt32 nPrivilegeSetSize = sizeof( PRIVILEGE_SET );
+
+ sal_uInt32 nGrantedAccess;
+ BOOL bAccessible = TRUE;
+ if ( AccessCheck( pFileDescr,
+ hImpersonationToken,
+ nDesiredAccess,
+ &aGenericMapping,
+ &aPrivilegeSet,
+ &nPrivilegeSetSize,
+ &nGrantedAccess,
+ &bAccessible ) )
+ {
+ bResult = !bAccessible;
+ }
+
+ CloseHandle( hImpersonationToken );
+ }
+
+ CloseHandle( hToken );
+ }
+ }
+
+ free( pFileDescr );
+ }
+
+ return bResult;
+}
+
+#else // this is UNX
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+
+#include <sal/types.h>
+
+sal_Bool IsReadonlyAccordingACL( const sal_Unicode* )
+{
+ // to be implemented
+ return sal_False;
+}
+
+#endif
+
diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
new file mode 100644
index 000000000000..b5a9536b12c5
--- /dev/null
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -0,0 +1,4302 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+//________________________________________________________________________________________________________
+// my own includes
+//________________________________________________________________________________________________________
+
+#include <sfx2/sfxbasemodel.hxx>
+
+//________________________________________________________________________________________________________
+// include of other projects
+//________________________________________________________________________________________________________
+
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/ErrorCodeRequest.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/view/XPrintJobListener.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/frame/IllegalArgumentIOException.hpp>
+#include <com/sun/star/frame/XUntitledNumbers.hpp>
+#include <com/sun/star/frame/UntitledNumbersConst.hpp>
+#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/EmbedMapUnits.hpp>
+#include <com/sun/star/document/XStorageChangeListener.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
+#include <com/sun/star/script/provider/XScriptProvider.hpp>
+#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp>
+#include <comphelper/enumhelper.hxx> // can be removed when this is a "real" service
+
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <comphelper/processfactory.hxx> // can be removed when this is a "real" service
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <basic/sbx.hxx>
+#include <basic/sbuno.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/tempfile.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/salctype.hxx>
+#include <sot/clsids.hxx>
+#include <sot/storinfo.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svtools/transfer.hxx>
+#include <svtools/ehdl.hxx>
+#include <svtools/sfxecode.hxx>
+#include <rtl/logfile.hxx>
+#include <framework/configimporter.hxx>
+#include <framework/interaction.hxx>
+#include <framework/titlehelper.hxx>
+#include <comphelper/numberedcollection.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+//________________________________________________________________________________________________________
+// includes of my own project
+//________________________________________________________________________________________________________
+
+#include <sfx2/sfxbasecontroller.hxx>
+#include "viewfac.hxx"
+#include "workwin.hxx"
+#include <sfx2/signaturestate.hxx>
+#include <sfx2/sfxuno.hxx>
+#include <objshimp.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objuno.hxx>
+#include <sfx2/printer.hxx>
+#include <basmgr.hxx>
+#include <sfx2/event.hxx>
+#include <eventsupplier.hxx>
+#include <sfx2/evntconf.hxx>
+#include <sfx2/sfx.hrc>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include "appdata.hxx"
+#include <sfx2/docfac.hxx>
+#include <sfx2/fcontnr.hxx>
+#include "sfx2/docstoragemodifylistener.hxx"
+#include "brokenpackageint.hxx"
+#include "graphhelp.hxx"
+#include <sfx2/msgpool.hxx>
+#include <sfx2/DocumentMetadataAccess.hxx>
+
+#include <sfxresid.hxx>
+
+//________________________________________________________________________________________________________
+// const
+static const ::rtl::OUString SERVICENAME_DESKTOP = ::rtl::OUString::createFromAscii ("com.sun.star.frame.Desktop");
+
+//________________________________________________________________________________________________________
+// namespaces
+//________________________________________________________________________________________________________
+
+namespace css = ::com::sun::star;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::frame::XFrame;
+using ::com::sun::star::frame::XController;
+using ::com::sun::star::frame::XController2;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::io::IOException;
+using ::com::sun::star::lang::WrappedTargetException;
+using ::com::sun::star::uno::Type;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::document::XDocumentRecovery;
+
+/** This Listener is used to get notified when the XDocumentProperties of the
+ XModel change.
+ */
+class SfxDocInfoListener_Impl : public ::cppu::WeakImplHelper1<
+ ::com::sun::star::util::XModifyListener >
+{
+
+public:
+ SfxObjectShell& m_rShell;
+
+ SfxDocInfoListener_Impl( SfxObjectShell& i_rDoc )
+ : m_rShell(i_rDoc)
+ { };
+
+ ~SfxDocInfoListener_Impl();
+
+ virtual void SAL_CALL disposing( const lang::EventObject& )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL modified( const lang::EventObject& )
+ throw ( uno::RuntimeException );
+};
+SfxDocInfoListener_Impl::~SfxDocInfoListener_Impl()
+{
+}
+void SAL_CALL SfxDocInfoListener_Impl::modified( const lang::EventObject& )
+ throw ( uno::RuntimeException )
+{
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ // notify changes to the SfxObjectShell
+ m_rShell.FlushDocInfo();
+}
+
+void SAL_CALL SfxDocInfoListener_Impl::disposing( const lang::EventObject& )
+ throw ( uno::RuntimeException )
+{
+}
+
+//________________________________________________________________________________________________________
+// impl. declarations
+//________________________________________________________________________________________________________
+
+
+struct IMPL_SfxBaseModel_DataContainer : public ::sfx2::IModifiableDocument
+{
+ // counter for SfxBaseModel instances created.
+ static sal_Int64 g_nInstanceCounter ;
+ SfxObjectShellRef m_pObjectShell ;
+ ::rtl::OUString m_sURL ;
+ ::rtl::OUString m_sRuntimeUID ;
+ ::rtl::OUString m_aPreusedFilterName;
+ ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer ;
+ uno::Reference< uno::XInterface > m_xParent ;
+ uno::Reference< frame::XController > m_xCurrent ;
+ uno::Reference< document::XDocumentInfo > m_xDocumentInfo ;
+ uno::Reference< document::XDocumentProperties > m_xDocumentProperties;
+ uno::Reference< script::XStarBasicAccess > m_xStarBasicAccess ;
+ uno::Reference< container::XNameReplace > m_xEvents ;
+ uno::Sequence< beans::PropertyValue> m_seqArguments ;
+ uno::Sequence< uno::Reference< frame::XController > > m_seqControllers ;
+ uno::Reference< container::XIndexAccess > m_contViewData ;
+ sal_uInt16 m_nControllerLockCount ;
+ sal_Bool m_bClosed ;
+ sal_Bool m_bClosing ;
+ sal_Bool m_bSaving ;
+ sal_Bool m_bSuicide ;
+ sal_Bool m_bInitialized ;
+ sal_Bool m_bModifiedSinceLastSave;
+ uno::Reference< com::sun::star::view::XPrintable> m_xPrintable ;
+ uno::Reference< script::provider::XScriptProvider > m_xScriptProvider;
+ uno::Reference< ui::XUIConfigurationManager > m_xUIConfigurationManager;
+ ::rtl::Reference< ::sfx2::DocumentStorageModifyListener > m_pStorageModifyListen;
+ ::rtl::OUString m_sModuleIdentifier;
+ css::uno::Reference< css::frame::XTitle > m_xTitleHelper;
+ css::uno::Reference< css::frame::XUntitledNumbers > m_xNumberedControllers;
+ uno::Reference< rdf::XDocumentMetadataAccess> m_xDocumentMetadata;
+
+
+ IMPL_SfxBaseModel_DataContainer( ::osl::Mutex& rMutex, SfxObjectShell* pObjectShell )
+ : m_pObjectShell ( pObjectShell )
+ , m_aInterfaceContainer ( rMutex )
+ , m_nControllerLockCount ( 0 )
+ , m_bClosed ( sal_False )
+ , m_bClosing ( sal_False )
+ , m_bSaving ( sal_False )
+ , m_bSuicide ( sal_False )
+ , m_bInitialized ( sal_False )
+ , m_bModifiedSinceLastSave( sal_False )
+ , m_pStorageModifyListen ( NULL )
+ , m_xTitleHelper ()
+ , m_xNumberedControllers ()
+ , m_xDocumentMetadata () // lazy
+ {
+ // increase global instance counter.
+ ++g_nInstanceCounter;
+ // set own Runtime UID
+ m_sRuntimeUID = rtl::OUString::valueOf( g_nInstanceCounter );
+ }
+
+ virtual ~IMPL_SfxBaseModel_DataContainer()
+ {
+ }
+
+ // ::sfx2::IModifiableDocument
+ virtual void storageIsModified()
+ {
+ if ( m_pObjectShell.Is() && !m_pObjectShell->IsModified() )
+ m_pObjectShell->SetModified( sal_True );
+ }
+
+ uno::Reference<rdf::XDocumentMetadataAccess> GetDMA()
+ {
+ if (!m_xDocumentMetadata.is())
+ {
+ OSL_ENSURE(m_pObjectShell, "GetDMA: no object shell?");
+ if (!m_pObjectShell)
+ {
+ return 0;
+ }
+
+ const uno::Reference<uno::XComponentContext> xContext(
+ ::comphelper::getProcessComponentContext());
+ ::rtl::OUString uri;
+ const uno::Reference<frame::XModel> xModel(
+ m_pObjectShell->GetModel());
+ const uno::Reference<lang::XMultiComponentFactory> xMsf(
+ xContext->getServiceManager());
+ const uno::Reference<frame::
+ XTransientDocumentsDocumentContentFactory> xTDDCF(
+ xMsf->createInstanceWithContext(
+ ::rtl::OUString::createFromAscii( "com.sun.star.frame."
+ "TransientDocumentsDocumentContentFactory"),
+ xContext),
+ uno::UNO_QUERY_THROW);
+ const uno::Reference<ucb::XContent> xContent(
+ xTDDCF->createDocumentContent(xModel) );
+ OSL_ENSURE(xContent.is(), "GetDMA: cannot create DocumentContent");
+ if (!xContent.is())
+ {
+ return 0;
+ }
+ uri = xContent->getIdentifier()->getContentIdentifier();
+ OSL_ENSURE(uri.getLength(), "GetDMA: empty uri?");
+ if (uri.getLength() && !uri.endsWithAsciiL("/", 1))
+ {
+ uri = uri + ::rtl::OUString::createFromAscii("/");
+ }
+
+ m_xDocumentMetadata = new ::sfx2::DocumentMetadataAccess(
+ xContext, *m_pObjectShell, uri);
+ }
+ return m_xDocumentMetadata;
+ }
+
+ uno::Reference<rdf::XDocumentMetadataAccess> CreateDMAUninitialized()
+ {
+ return (m_pObjectShell)
+ ? new ::sfx2::DocumentMetadataAccess(
+ ::comphelper::getProcessComponentContext(), *m_pObjectShell)
+ : 0;
+ }
+};
+
+// static member initialization.
+sal_Int64 IMPL_SfxBaseModel_DataContainer::g_nInstanceCounter = 0;
+
+// =======================================================================================================
+
+// Listener that forwards notifications from the PrintHelper to the "real" listeners
+class SfxPrintHelperListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::view::XPrintJobListener >
+{
+public:
+ IMPL_SfxBaseModel_DataContainer* m_pData;
+ SfxPrintHelperListener_Impl( IMPL_SfxBaseModel_DataContainer* pData )
+ : m_pData( pData )
+ {}
+
+ virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException ) ;
+ virtual void SAL_CALL printJobEvent( const view::PrintJobEvent& rEvent ) throw ( uno::RuntimeException);
+};
+
+void SAL_CALL SfxPrintHelperListener_Impl::disposing( const lang::EventObject& ) throw ( uno::RuntimeException )
+{
+ m_pData->m_xPrintable = 0;
+}
+
+void SAL_CALL SfxPrintHelperListener_Impl::printJobEvent( const view::PrintJobEvent& rEvent ) throw (uno::RuntimeException)
+{
+ ::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< view::XPrintJobListener >*) NULL ) );
+ if ( pContainer!=NULL )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ ((view::XPrintJobListener*)pIterator.next())->printJobEvent( rEvent );
+ }
+}
+
+// SfxOwnFramesLocker ====================================================================================
+// allows to lock all the frames related to the provided SfxObjectShell
+class SfxOwnFramesLocker
+{
+ uno::Sequence< uno::Reference< frame::XFrame > > m_aLockedFrames;
+
+ Window* GetVCLWindow( const uno::Reference< frame::XFrame >& xFrame );
+public:
+ SfxOwnFramesLocker( SfxObjectShell* ObjechShell );
+ ~SfxOwnFramesLocker();
+ void UnlockFrames();
+};
+
+SfxOwnFramesLocker::SfxOwnFramesLocker( SfxObjectShell* pObjectShell )
+{
+ if ( !pObjectShell )
+ return;
+
+ for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjectShell );
+ pFrame;
+ pFrame = SfxViewFrame::GetNext( *pFrame, pObjectShell )
+ )
+ {
+ SfxFrame& rSfxFrame = pFrame->GetFrame();
+ try
+ {
+ // get vcl window related to the frame and lock it if it is still not locked
+ uno::Reference< frame::XFrame > xFrame = rSfxFrame.GetFrameInterface();
+ Window* pWindow = GetVCLWindow( xFrame );
+ if ( !pWindow )
+ throw uno::RuntimeException();
+
+ if ( pWindow->IsEnabled() )
+ {
+ pWindow->Disable();
+
+ try
+ {
+ sal_Int32 nLen = m_aLockedFrames.getLength();
+ m_aLockedFrames.realloc( nLen + 1 );
+ m_aLockedFrames[nLen] = xFrame;
+ }
+ catch( uno::Exception& )
+ {
+ pWindow->Enable();
+ throw;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Not possible to lock the frame window!\n" );
+ }
+ }
+}
+
+SfxOwnFramesLocker::~SfxOwnFramesLocker()
+{
+ UnlockFrames();
+}
+
+Window* SfxOwnFramesLocker::GetVCLWindow( const uno::Reference< frame::XFrame >& xFrame )
+{
+ Window* pWindow = NULL;
+
+ if ( xFrame.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow = xFrame->getContainerWindow();
+ if ( xWindow.is() )
+ pWindow = VCLUnoHelper::GetWindow( xWindow );
+ }
+
+ return pWindow;
+}
+
+void SfxOwnFramesLocker::UnlockFrames()
+{
+ for ( sal_Int32 nInd = 0; nInd < m_aLockedFrames.getLength(); nInd++ )
+ {
+ try
+ {
+ if ( m_aLockedFrames[nInd].is() )
+ {
+ // get vcl window related to the frame and unlock it
+ Window* pWindow = GetVCLWindow( m_aLockedFrames[nInd] );
+ if ( !pWindow )
+ throw uno::RuntimeException();
+
+ pWindow->Enable();
+
+ m_aLockedFrames[nInd] = uno::Reference< frame::XFrame >();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Can't unlock the frame window!\n" );
+ }
+ }
+}
+
+// SfxSaveGuard ====================================================================================
+class SfxSaveGuard
+{
+ private:
+ uno::Reference< frame::XModel > m_xModel;
+ IMPL_SfxBaseModel_DataContainer* m_pData;
+ SfxOwnFramesLocker* m_pFramesLock;
+
+ public:
+ SfxSaveGuard(const uno::Reference< frame::XModel >& xModel ,
+ IMPL_SfxBaseModel_DataContainer* pData ,
+ sal_Bool bRejectConcurrentSaveRequest);
+ ~SfxSaveGuard();
+};
+
+SfxSaveGuard::SfxSaveGuard(const uno::Reference< frame::XModel >& xModel ,
+ IMPL_SfxBaseModel_DataContainer* pData ,
+ sal_Bool bRejectConcurrentSaveRequest)
+ : m_xModel (xModel)
+ , m_pData (pData )
+ , m_pFramesLock(0 )
+{
+ static ::rtl::OUString MSG_1 = ::rtl::OUString::createFromAscii("Object already disposed." );
+ static ::rtl::OUString MSG_2 = ::rtl::OUString::createFromAscii("Concurrent save requests on the same document are not possible.");
+
+ if ( m_pData->m_bClosed )
+ throw ::com::sun::star::lang::DisposedException(
+ MSG_1,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >());
+
+ if (
+ bRejectConcurrentSaveRequest &&
+ m_pData->m_bSaving
+ )
+ throw ::com::sun::star::io::IOException(
+ MSG_2,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >());
+
+ m_pData->m_bSaving = sal_True;
+ m_pFramesLock = new SfxOwnFramesLocker(m_pData->m_pObjectShell);
+}
+
+SfxSaveGuard::~SfxSaveGuard()
+{
+ SfxOwnFramesLocker* pFramesLock = m_pFramesLock;
+ m_pFramesLock = 0;
+ delete pFramesLock;
+
+ m_pData->m_bSaving = sal_False;
+
+ // m_bSuicide was set e.g. in case somewhere tried to close a document, while it was used for
+ // storing at the same time. Further m_bSuicide was set to TRUE only if close(TRUE) was called.
+ // So the owner ship was delegated to the place where a veto exception was thrown.
+ // Now we have to call close() again and delegate the owner ship to the next one, which
+ // cant accept that. Close(FALSE) cant work in this case. Because then the document will may be never closed ...
+
+ if ( m_pData->m_bSuicide )
+ {
+ // Reset this state. In case the new close() request is not accepted by somehwere else ...
+ // it's not a good idea to have two "owners" for close .-)
+ m_pData->m_bSuicide = sal_False;
+ try
+ {
+ uno::Reference< util::XCloseable > xClose(m_xModel, uno::UNO_QUERY);
+ if (xClose.is())
+ xClose->close(sal_True);
+ }
+ catch(const util::CloseVetoException&)
+ {}
+ }
+}
+
+// =======================================================================================================
+
+//________________________________________________________________________________________________________
+// constructor
+//________________________________________________________________________________________________________
+DBG_NAME(sfx2_SfxBaseModel)
+SfxBaseModel::SfxBaseModel( SfxObjectShell *pObjectShell )
+: BaseMutex()
+, m_pData( new IMPL_SfxBaseModel_DataContainer( m_aMutex, pObjectShell ) )
+, m_bSupportEmbeddedScripts( pObjectShell && pObjectShell->Get_Impl() ? !pObjectShell->Get_Impl()->m_bNoBasicCapabilities : false )
+, m_bSupportDocRecovery( pObjectShell && pObjectShell->Get_Impl() ? pObjectShell->Get_Impl()->m_bDocRecoverySupport : false )
+{
+ DBG_CTOR(sfx2_SfxBaseModel,NULL);
+ if ( pObjectShell != NULL )
+ {
+ StartListening( *pObjectShell ) ;
+ }
+}
+
+//________________________________________________________________________________________________________
+// destructor
+//________________________________________________________________________________________________________
+
+SfxBaseModel::~SfxBaseModel()
+{
+ DBG_DTOR(sfx2_SfxBaseModel,NULL);
+}
+
+//________________________________________________________________________________________________________
+// XInterface
+//________________________________________________________________________________________________________
+
+uno::Any SAL_CALL SfxBaseModel::queryInterface( const UNOTYPE& rType ) throw( uno::RuntimeException )
+{
+ if ( ( !m_bSupportEmbeddedScripts && rType.equals( XEMBEDDEDSCRIPTS::static_type() ) )
+ || ( !m_bSupportDocRecovery && rType.equals( XDocumentRecovery::static_type() ) )
+ )
+ return Any();
+
+ return SfxBaseModel_Base::queryInterface( rType );
+}
+
+//________________________________________________________________________________________________________
+// XInterface
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::acquire() throw( )
+{
+ // Attention:
+ // Don't use mutex or guard in this method!!! Is a method of XInterface.
+
+ // Forward to baseclass
+ OWeakObject::acquire() ;
+}
+
+//________________________________________________________________________________________________________
+// XInterface
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::release() throw( )
+{
+ // Attention:
+ // Don't use mutex or guard in this method!!! Is a method of XInterface.
+
+ // Forward to baseclass
+ OWeakObject::release() ;
+}
+
+//________________________________________________________________________________________________________
+// XTypeProvider
+//________________________________________________________________________________________________________
+
+namespace
+{
+ void lcl_stripType( Sequence< Type >& io_rTypes, const Type& i_rTypeToStrip )
+ {
+ Sequence< UNOTYPE > aStrippedTypes( io_rTypes.getLength() - 1 );
+ ::std::remove_copy_if(
+ io_rTypes.getConstArray(),
+ io_rTypes.getConstArray() + io_rTypes.getLength(),
+ aStrippedTypes.getArray(),
+ ::std::bind2nd( ::std::equal_to< Type >(), i_rTypeToStrip )
+ );
+ io_rTypes = aStrippedTypes;
+ }
+}
+
+uno::Sequence< UNOTYPE > SAL_CALL SfxBaseModel::getTypes() throw( uno::RuntimeException )
+{
+ uno::Sequence< UNOTYPE > aTypes( SfxBaseModel_Base::getTypes() );
+
+ if ( !m_bSupportEmbeddedScripts )
+ lcl_stripType( aTypes, XEMBEDDEDSCRIPTS::static_type() );
+
+ if ( !m_bSupportDocRecovery )
+ lcl_stripType( aTypes, XDocumentRecovery::static_type() );
+
+ return aTypes;
+}
+
+//________________________________________________________________________________________________________
+// XTypeProvider
+//________________________________________________________________________________________________________
+
+uno::Sequence< sal_Int8 > SAL_CALL SfxBaseModel::getImplementationId() throw( uno::RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ ::osl::MutexGuard aGuard( MUTEX::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+//________________________________________________________________________________________________________
+// XStarBasicAccess
+//________________________________________________________________________________________________________
+
+uno::Reference< script::XStarBasicAccess > implGetStarBasicAccess( SfxObjectShell* pObjectShell )
+{
+ uno::Reference< script::XStarBasicAccess > xRet;
+ if( pObjectShell )
+ {
+ BasicManager* pMgr = pObjectShell->GetBasicManager();
+ xRet = getStarBasicAccess( pMgr );
+ }
+ return xRet;
+}
+
+uno::Reference< XNAMECONTAINER > SAL_CALL SfxBaseModel::getLibraryContainer() throw( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
+ if( !rxAccess.is() && m_pData->m_pObjectShell.Is() )
+ rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell );
+
+ uno::Reference< XNAMECONTAINER > xRet;
+ if( rxAccess.is() )
+ xRet = rxAccess->getLibraryContainer();
+ return xRet;
+}
+
+/**___________________________________________________________________________________________________
+ @seealso XStarBasicAccess
+*/
+void SAL_CALL SfxBaseModel::createLibrary( const ::rtl::OUString& LibName, const ::rtl::OUString& Password,
+ const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL )
+ throw(ELEMENTEXISTEXCEPTION, uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
+ if( !rxAccess.is() && m_pData->m_pObjectShell.Is() )
+ rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell );
+
+ if( rxAccess.is() )
+ rxAccess->createLibrary( LibName, Password, ExternalSourceURL, LinkTargetURL );
+}
+
+/**___________________________________________________________________________________________________
+ @seealso XStarBasicAccess
+*/
+void SAL_CALL SfxBaseModel::addModule( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName,
+ const ::rtl::OUString& Language, const ::rtl::OUString& Source )
+ throw( NOSUCHELEMENTEXCEPTION, uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
+ if( !rxAccess.is() && m_pData->m_pObjectShell.Is() )
+ rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell );
+
+ if( rxAccess.is() )
+ rxAccess->addModule( LibraryName, ModuleName, Language, Source );
+}
+
+/**___________________________________________________________________________________________________
+ @seealso XStarBasicAccess
+*/
+void SAL_CALL SfxBaseModel::addDialog( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName,
+ const ::com::sun::star::uno::Sequence< sal_Int8 >& Data )
+ throw(NOSUCHELEMENTEXCEPTION, uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
+ if( !rxAccess.is() && m_pData->m_pObjectShell.Is() )
+ rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell );
+
+ if( rxAccess.is() )
+ rxAccess->addDialog( LibraryName, DialogName, Data );
+}
+
+
+//________________________________________________________________________________________________________
+// XChild
+//________________________________________________________________________________________________________
+
+uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getParent() throw( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ return m_pData->m_xParent;
+}
+
+//________________________________________________________________________________________________________
+// XChild
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::setParent(const uno::Reference< uno::XInterface >& Parent) throw(NOSUPPORTEXCEPTION, uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ m_pData->m_xParent = Parent;
+}
+
+//________________________________________________________________________________________________________
+// XChild
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::dispose() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+
+ if ( !m_pData->m_bClosed )
+ {
+ // gracefully accept wrong dispose calls instead of close call
+ // and try to make it work (may be really disposed later!)
+ try
+ {
+ close( sal_True );
+ }
+ catch ( com::sun::star::util::CloseVetoException& )
+ {
+ }
+
+ return;
+ }
+
+ if ( m_pData->m_pStorageModifyListen.is() )
+ {
+ m_pData->m_pStorageModifyListen->dispose();
+ m_pData->m_pStorageModifyListen = NULL;
+ }
+
+ lang::EventObject aEvent( (frame::XModel *)this );
+ m_pData->m_aInterfaceContainer.disposeAndClear( aEvent );
+
+ if ( m_pData->m_xDocumentInfo.is() )
+ {
+ // as long as an SfxObjectShell is assigned to an SfxBaseModel it is still existing here
+ // so we can't dispose the shared DocumentInfoObject here
+ // uno::Reference < lang::XComponent > xComp( m_pData->m_xDocumentInfo, uno::UNO_QUERY );
+ // xComp->dispose();
+ m_pData->m_xDocumentInfo = 0;
+ }
+
+ m_pData->m_xDocumentProperties.clear();
+
+ m_pData->m_xDocumentMetadata.clear();
+
+ EndListening( *m_pData->m_pObjectShell );
+
+ m_pData->m_xCurrent = uno::Reference< frame::XController > ();
+ m_pData->m_seqControllers = uno::Sequence< uno::Reference< frame::XController > > () ;
+
+ // m_pData member must be set to zero before 0delete is called to
+ // force disposed exception whenever someone tries to access our
+ // instance while in the dtor.
+ IMPL_SfxBaseModel_DataContainer* pData = m_pData;
+ m_pData = 0;
+ delete pData;
+}
+
+//________________________________________________________________________________________________________
+// XChild
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XEVENTLISTENER >& aListener )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), aListener );
+}
+
+//________________________________________________________________________________________________________
+// XChild
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XEVENTLISTENER >& aListener )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), aListener );
+}
+
+//________________________________________________________________________________________________________
+// document::XDocumentInfoSupplier
+//________________________________________________________________________________________________________
+
+uno::Reference< document::XDocumentInfo > SAL_CALL SfxBaseModel::getDocumentInfo() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ if ( !m_pData->m_xDocumentInfo.is() )
+ {
+ // WARNING: this will only work if (when loading a document) the
+ // document meta-data has already been read and completely written
+ // into the XDocumentProperties at this point
+ // ==> DO NOT call getDocumentInfo before document info has been read!
+ uno::Reference< document::XDocumentInfo > xDocInfo =
+ new SfxDocumentInfoObject;
+ uno::Reference< document::XDocumentProperties > xDocProps =
+ getDocumentProperties();
+ uno::Sequence< uno::Any > args(1);
+ args[0] <<= xDocProps;
+ uno::Reference< lang::XInitialization > xInit(
+ xDocInfo, uno::UNO_QUERY_THROW);
+ try {
+ xInit->initialize(args);
+ ((SfxBaseModel*)this)->m_pData->m_xDocumentInfo = xDocInfo;
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (uno::Exception & e) {
+ throw lang::WrappedTargetRuntimeException(::rtl::OUString::createFromAscii(
+ "SfxBaseModel::getDocumentInfo: cannot initialize"), *this,
+ uno::makeAny(e));
+ }
+ try {
+ rtl::OUString aName = rtl::OUString::createFromAscii("MediaType");
+ uno::Reference < beans::XPropertySet > xSet(
+ getDocumentStorage(), uno::UNO_QUERY );
+ uno::Any aMediaType = xSet->getPropertyValue( aName );
+ uno::Reference < beans::XPropertySet > xDocSet(
+ m_pData->m_xDocumentInfo, uno::UNO_QUERY );
+ xDocSet->setPropertyValue( aName, aMediaType );
+ } catch (uno::Exception &) {
+ //ignore
+ }
+ }
+
+ return m_pData->m_xDocumentInfo;
+}
+
+// document::XDocumentPropertiesSupplier:
+uno::Reference< document::XDocumentProperties > SAL_CALL
+SfxBaseModel::getDocumentProperties()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ if ( !m_pData->m_xDocumentProperties.is() )
+ {
+ uno::Reference< lang::XInitialization > xDocProps(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ DEFINE_CONST_UNICODE("com.sun.star.document.DocumentProperties") ),
+ uno::UNO_QUERY_THROW);
+// xDocProps->initialize(uno::Sequence<uno::Any>());
+ m_pData->m_xDocumentProperties.set(xDocProps, uno::UNO_QUERY_THROW);
+ uno::Reference<util::XModifyBroadcaster> xMB(m_pData->m_xDocumentProperties, uno::UNO_QUERY_THROW);
+ xMB->addModifyListener(new SfxDocInfoListener_Impl(*m_pData->m_pObjectShell));
+ }
+
+ return m_pData->m_xDocumentProperties;
+}
+
+
+//________________________________________________________________________________________________________
+// XEVENTLISTENER
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::disposing( const lang::EventObject& aObject )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( impl_isDisposed() )
+ return;
+
+ uno::Reference< XMODIFYLISTENER > xMod( aObject.Source, uno::UNO_QUERY );
+ uno::Reference< XEVENTLISTENER > xListener( aObject.Source, uno::UNO_QUERY );
+ uno::Reference< XDOCEVENTLISTENER > xDocListener( aObject.Source, uno::UNO_QUERY );
+
+ if ( xMod.is() )
+ m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0), xMod );
+ else if ( xListener.is() )
+ m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), xListener );
+ else if ( xDocListener.is() )
+ m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), xListener );
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& rURL ,
+ const uno::Sequence< beans::PropertyValue >& rArgs )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ if ( rURL.getLength() == 0 && rArgs.getLength() == 1 && rArgs[0].Name.equalsAscii( "SetEmbedded" ) )
+ {
+ // allows to set a windowless document to EMBEDDED state
+ // but _only_ before load() or initNew() methods
+ if ( m_pData->m_pObjectShell.Is() && !m_pData->m_pObjectShell->GetMedium() )
+ {
+ sal_Bool bEmb = sal_Bool();
+ if ( ( rArgs[0].Value >>= bEmb ) && bEmb )
+ m_pData->m_pObjectShell->SetCreateMode_Impl( SFX_CREATE_MODE_EMBEDDED );
+ }
+
+ return sal_True;
+ }
+
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ m_pData->m_sURL = rURL;
+
+ SfxObjectShell* pObjectShell = m_pData->m_pObjectShell;
+
+ ::comphelper::NamedValueCollection aArgs( rArgs );
+
+ Sequence< sal_Int32 > aWinExtent;
+ if ( ( aArgs.get( "WinExtent" ) >>= aWinExtent )&& ( aWinExtent.getLength() == 4 ) )
+ {
+ Rectangle aVisArea( aWinExtent[0], aWinExtent[1], aWinExtent[2], aWinExtent[3] );
+ aVisArea = OutputDevice::LogicToLogic( aVisArea, MAP_100TH_MM, pObjectShell->GetMapUnit() );
+ pObjectShell->SetVisArea( aVisArea );
+ }
+
+ sal_Bool bBreakMacroSign = sal_False;
+ if ( aArgs.get( "BreakMacroSignature" ) >>= bBreakMacroSign )
+ {
+ pObjectShell->BreakMacroSign_Impl( bBreakMacroSign );
+ }
+
+ aArgs.remove( "WinExtent" );
+ aArgs.remove( "BreakMacroSignature" );
+ aArgs.remove( "Stream" );
+ aArgs.remove( "InputStream" );
+
+ // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here
+
+ m_pData->m_seqArguments = aArgs.getPropertyValues();
+
+ SfxMedium* pMedium = pObjectShell->GetMedium();
+ if ( pMedium )
+ {
+ SfxAllItemSet aSet( pObjectShell->GetPool() );
+ TransformParameters( SID_OPENDOC, rArgs, aSet );
+
+ pMedium->GetItemSet()->Put( aSet );
+ SFX_ITEMSET_ARG( &aSet, pItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if ( pItem )
+ pMedium->SetFilter(
+ pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem->GetValue() ) );
+
+ SFX_ITEMSET_ARG( &aSet, pTitleItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
+ if ( pTitleItem )
+ {
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjectShell );
+ if ( pFrame )
+ pFrame->UpdateTitle();
+ }
+ }
+ }
+
+ return sal_True ;
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+::rtl::OUString SAL_CALL SfxBaseModel::getURL() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+ return m_pData->m_sURL ;
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getArgs() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ uno::Sequence< beans::PropertyValue > seqArgsNew;
+ uno::Sequence< beans::PropertyValue > seqArgsOld;
+ SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
+
+ // we need to know which properties are supported by the transformer
+ // hopefully it is a temporary solution, I guess nonconvertable properties
+ // should not be supported so then there will be only ItemSet from medium
+
+ TransformItems( SID_OPENDOC, *(m_pData->m_pObjectShell->GetMedium()->GetItemSet()), seqArgsNew );
+ TransformParameters( SID_OPENDOC, m_pData->m_seqArguments, aSet );
+ TransformItems( SID_OPENDOC, aSet, seqArgsOld );
+
+ sal_Int32 nOrgLength = m_pData->m_seqArguments.getLength();
+ sal_Int32 nOldLength = seqArgsOld.getLength();
+ sal_Int32 nNewLength = seqArgsNew.getLength();
+
+ // "WinExtent" property should be updated always.
+ // We can store it now to overwrite an old value
+ // since it is not from ItemSet
+ Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
+ aTmpRect = OutputDevice::LogicToLogic( aTmpRect, m_pData->m_pObjectShell->GetMapUnit(), MAP_100TH_MM );
+
+ Sequence< sal_Int32 > aRectSeq(4);
+ aRectSeq[0] = aTmpRect.Left();
+ aRectSeq[1] = aTmpRect.Top();
+ aRectSeq[2] = aTmpRect.Right();
+ aRectSeq[3] = aTmpRect.Bottom();
+
+ seqArgsNew.realloc( ++nNewLength );
+ seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "WinExtent" );
+ seqArgsNew[ nNewLength - 1 ].Value <<= aRectSeq;
+
+ if ( m_pData->m_aPreusedFilterName.getLength() )
+ {
+ seqArgsNew.realloc( ++nNewLength );
+ seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "PreusedFilterName" );
+ seqArgsNew[ nNewLength - 1 ].Value <<= m_pData->m_aPreusedFilterName;
+ }
+
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell );
+ if ( pFrame )
+ {
+ SvBorder aBorder = pFrame->GetBorderPixelImpl( pFrame->GetViewShell() );
+
+ Sequence< sal_Int32 > aBorderSeq(4);
+ aBorderSeq[0] = aBorder.Left();
+ aBorderSeq[1] = aBorder.Top();
+ aBorderSeq[2] = aBorder.Right();
+ aBorderSeq[3] = aBorder.Bottom();
+
+ seqArgsNew.realloc( ++nNewLength );
+ seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "DocumentBorder" );
+ seqArgsNew[ nNewLength - 1 ].Value <<= aBorderSeq;
+ }
+
+ // only the values that are not supported by the ItemSet must be cached here
+ uno::Sequence< beans::PropertyValue > aFinalCache;
+ sal_Int32 nFinalLength = 0;
+
+ for ( sal_Int32 nOrg = 0; nOrg < nOrgLength; nOrg++ )
+ {
+ sal_Int32 nOldInd = 0;
+ while ( nOldInd < nOldLength )
+ {
+ if ( m_pData->m_seqArguments[nOrg].Name.equals( seqArgsOld[nOldInd].Name ) )
+ break;
+ nOldInd++;
+ }
+
+ if ( nOldInd == nOldLength )
+ {
+ // the entity with this name should be new for seqArgsNew
+ // since it is not supported by transformer
+
+ seqArgsNew.realloc( ++nNewLength );
+ seqArgsNew[ nNewLength - 1 ] = m_pData->m_seqArguments[nOrg];
+
+ aFinalCache.realloc( ++nFinalLength );
+ aFinalCache[ nFinalLength - 1 ] = m_pData->m_seqArguments[nOrg];
+ }
+ }
+
+ m_pData->m_seqArguments = aFinalCache;
+
+ return seqArgsNew;
+ }
+
+ return m_pData->m_seqArguments;
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::connectController( const uno::Reference< frame::XController >& xController )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+ OSL_PRECOND( xController.is(), "SfxBaseModel::connectController: invalid controller!" );
+ if ( !xController.is() )
+ return;
+
+ sal_uInt32 nOldCount = m_pData->m_seqControllers.getLength();
+ uno::Sequence< uno::Reference< frame::XController > > aNewSeq( nOldCount + 1 );
+ for ( sal_uInt32 n = 0; n < nOldCount; n++ )
+ aNewSeq.getArray()[n] = m_pData->m_seqControllers.getConstArray()[n];
+ aNewSeq.getArray()[nOldCount] = xController;
+ m_pData->m_seqControllers = aNewSeq;
+
+ if ( m_pData->m_seqControllers.getLength() == 1 )
+ {
+ SfxViewFrame* pViewFrame = SfxViewFrame::Get( xController, GetObjectShell() );
+ ENSURE_OR_THROW( pViewFrame, "SFX document without SFX view!?" );
+ pViewFrame->UpdateDocument_Impl();
+ const String sDocumentURL = GetObjectShell()->GetMedium()->GetName();
+ if ( sDocumentURL.Len() )
+ SFX_APP()->Broadcast( SfxStringHint( SID_OPENURL, sDocumentURL ) );
+ }
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::disconnectController( const uno::Reference< frame::XController >& xController ) throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ sal_uInt32 nOldCount = m_pData->m_seqControllers.getLength();
+ if ( !nOldCount )
+ return;
+
+ uno::Sequence< uno::Reference< frame::XController > > aNewSeq( nOldCount - 1 );
+ for ( sal_uInt32 nOld = 0, nNew = 0; nOld < nOldCount; ++nOld )
+ {
+ if ( xController != m_pData->m_seqControllers.getConstArray()[nOld] )
+ {
+ aNewSeq.getArray()[nNew] = m_pData->m_seqControllers.getConstArray()[nOld];
+ ++nNew;
+ }
+ }
+
+ m_pData->m_seqControllers = aNewSeq;
+
+ if ( xController == m_pData->m_xCurrent )
+ m_pData->m_xCurrent = uno::Reference< frame::XController > ();
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::lockControllers() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ ++m_pData->m_nControllerLockCount ;
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::unlockControllers() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ --m_pData->m_nControllerLockCount ;
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+sal_Bool SAL_CALL SfxBaseModel::hasControllersLocked() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+ return ( m_pData->m_nControllerLockCount != 0 ) ;
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+uno::Reference< frame::XController > SAL_CALL SfxBaseModel::getCurrentController() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ // get the last active controller of this model
+ if ( m_pData->m_xCurrent.is() )
+ return m_pData->m_xCurrent;
+
+ // get the first controller of this model
+ return m_pData->m_seqControllers.getLength() ? m_pData->m_seqControllers.getConstArray()[0] : m_pData->m_xCurrent;
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::setCurrentController( const uno::Reference< frame::XController >& xCurrentController )
+ throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ m_pData->m_xCurrent = xCurrentController;
+}
+
+//________________________________________________________________________________________________________
+// frame::XModel
+//________________________________________________________________________________________________________
+
+uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getCurrentSelection() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< uno::XInterface > xReturn;
+ uno::Reference< frame::XController > xController = getCurrentController() ;
+
+ if ( xController.is() )
+ {
+ uno::Reference< view::XSelectionSupplier > xDocView( xController, uno::UNO_QUERY );
+ if ( xDocView.is() )
+ {
+ uno::Any xSel = xDocView->getSelection();
+ xSel >>= xReturn ;
+ }
+ }
+
+ return xReturn ;
+}
+
+//________________________________________________________________________________________________________
+// XModifiable2
+//________________________________________________________________________________________________________
+
+sal_Bool SAL_CALL SfxBaseModel::disableSetModified() throw (::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw uno::RuntimeException();
+
+ sal_Bool bResult = m_pData->m_pObjectShell->IsEnableSetModified();
+ m_pData->m_pObjectShell->EnableSetModified( sal_False );
+
+ return bResult;
+}
+
+sal_Bool SAL_CALL SfxBaseModel::enableSetModified() throw (::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw uno::RuntimeException();
+
+ sal_Bool bResult = m_pData->m_pObjectShell->IsEnableSetModified();
+ m_pData->m_pObjectShell->EnableSetModified( sal_True );
+
+ return bResult;
+}
+
+sal_Bool SAL_CALL SfxBaseModel::isSetModifiedEnabled() throw (::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw uno::RuntimeException();
+
+ return m_pData->m_pObjectShell->IsEnableSetModified();
+}
+
+//________________________________________________________________________________________________________
+// XModifiable
+//________________________________________________________________________________________________________
+
+sal_Bool SAL_CALL SfxBaseModel::isModified() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->IsModified() : sal_False;
+}
+
+//________________________________________________________________________________________________________
+// XModifiable
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::setModified( sal_Bool bModified )
+ throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( m_pData->m_pObjectShell.Is() )
+ m_pData->m_pObjectShell->SetModified(bModified);
+}
+
+//________________________________________________________________________________________________________
+// XModifiable
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::addModifyListener(const uno::Reference< XMODIFYLISTENER >& xListener) throw( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+
+ m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0),xListener );
+}
+
+//________________________________________________________________________________________________________
+// XModifiable
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::removeModifyListener(const uno::Reference< XMODIFYLISTENER >& xListener) throw( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0), xListener );
+}
+
+//____________________________________________________________________________________________________
+// XCloseable
+//____________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::close( sal_Bool bDeliverOwnership ) throw (util::CloseVetoException, uno::RuntimeException)
+{
+ static ::rtl::OUString MSG_1 = ::rtl::OUString::createFromAscii("Cant close while saving.");
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( impl_isDisposed() || m_pData->m_bClosed || m_pData->m_bClosing )
+ return;
+
+ uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
+ lang::EventObject aSource (static_cast< ::cppu::OWeakObject*>(this));
+ ::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership );
+ }
+ catch( uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+
+ if ( m_pData->m_bSaving )
+ {
+ if (bDeliverOwnership)
+ m_pData->m_bSuicide = sal_True;
+ throw util::CloseVetoException(
+ MSG_1,
+ static_cast< ::com::sun::star::util::XCloseable* >(this));
+ }
+
+ // no own objections against closing!
+ m_pData->m_bClosing = sal_True;
+ pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
+ while (pCloseIterator.hasMoreElements())
+ {
+ try
+ {
+ ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource );
+ }
+ catch( uno::RuntimeException& )
+ {
+ pCloseIterator.remove();
+ }
+ }
+ }
+
+ m_pData->m_bClosed = sal_True;
+ m_pData->m_bClosing = sal_False;
+
+ dispose();
+}
+
+//____________________________________________________________________________________________________
+// XCloseBroadcaster
+//____________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::addCloseListener( const uno::Reference< XCLOSELISTENER >& xListener ) throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+
+ m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XCLOSELISTENER >*)0), xListener );
+}
+
+//____________________________________________________________________________________________________
+// XCloseBroadcaster
+//____________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::removeCloseListener( const uno::Reference< XCLOSELISTENER >& xListener ) throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XCLOSELISTENER >*)0), xListener );
+}
+
+//________________________________________________________________________________________________________
+// XPrintable
+//________________________________________________________________________________________________________
+
+uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getPrinter() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( impl_getPrintHelper() )
+ return m_pData->m_xPrintable->getPrinter();
+ else
+ return uno::Sequence< beans::PropertyValue >();
+}
+
+void SAL_CALL SfxBaseModel::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter)
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( impl_getPrintHelper() )
+ m_pData->m_xPrintable->setPrinter( rPrinter );
+}
+
+void SAL_CALL SfxBaseModel::print(const uno::Sequence< beans::PropertyValue >& rOptions)
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( impl_getPrintHelper() )
+ m_pData->m_xPrintable->print( rOptions );
+}
+
+//________________________________________________________________________________________________________
+// XStorable
+//________________________________________________________________________________________________________
+
+sal_Bool SAL_CALL SfxBaseModel::hasLocation() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->HasName() : sal_False;
+}
+
+//________________________________________________________________________________________________________
+// XStorable
+//________________________________________________________________________________________________________
+
+::rtl::OUString SAL_CALL SfxBaseModel::getLocation() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ // TODO/LATER: is it correct that the shared document returns shared file location?
+ if ( m_pData->m_pObjectShell->IsDocShared() )
+ return m_pData->m_pObjectShell->GetSharedFileURL();
+ else
+ return ::rtl::OUString(m_pData->m_pObjectShell->GetMedium()->GetName());
+ }
+
+ return m_pData->m_sURL;
+}
+
+//________________________________________________________________________________________________________
+// XStorable
+//________________________________________________________________________________________________________
+
+sal_Bool SAL_CALL SfxBaseModel::isReadonly() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->IsReadOnly() : sal_True;
+}
+
+//________________________________________________________________________________________________________
+// XStorable2
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::storeSelf( const uno::Sequence< beans::PropertyValue >& aSeqArgs )
+ throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aPerfLog, "PERFORMANCE - SfxBaseModel::storeSelf" );
+
+ SfxModelGuard aGuard( *this );
+
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeSelf" ) ) );
+ SfxSaveGuard aSaveGuard(this, m_pData, sal_False);
+
+ for ( sal_Int32 nInd = 0; nInd < aSeqArgs.getLength(); nInd++ )
+ {
+ // check that only acceptable parameters are provided here
+ if ( !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VersionComment" ) ) )
+ && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Author" ) ) )
+ && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InteractionHandler" ) ) )
+ && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) ) ) )
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "unexpected parameter for storeSelf, might be no problem if SaveAs is executed." ) ) );
+ m_pData->m_pObjectShell->StoreLog();
+
+ ::rtl::OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "Unexpected MediaDescriptor parameter: " ) );
+ aMessage += aSeqArgs[nInd].Name;
+ throw lang::IllegalArgumentException( aMessage, uno::Reference< uno::XInterface >(), 1 );
+ }
+ }
+
+ SfxAllItemSet *pParams = new SfxAllItemSet( SFX_APP()->GetPool() );
+ TransformParameters( SID_SAVEDOC, aSeqArgs, *pParams );
+
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOC, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOC), m_pData->m_pObjectShell ) );
+
+ sal_Bool bRet = sal_False;
+
+ // TODO/LATER: let the embedded case of saving be handled more careful
+ if ( m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ // If this is an embedded object that has no URL based location it should be stored to own storage.
+ // An embedded object can have a location based on URL in case it is a link, then it should be
+ // stored in normal way.
+ if ( !hasLocation() || getLocation().compareToAscii( "private:", 8 ) == 0 )
+ {
+ // actually in this very rare case only UI parameters have sence
+ // TODO/LATER: should be done later, after integration of sb19
+ bRet = m_pData->m_pObjectShell->DoSave()
+ && m_pData->m_pObjectShell->DoSaveCompleted();
+ }
+ else
+ {
+ bRet = m_pData->m_pObjectShell->Save_Impl( pParams );
+ }
+ }
+ else
+ bRet = m_pData->m_pObjectShell->Save_Impl( pParams );
+
+ DELETEZ( pParams );
+
+ sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetError() ? m_pData->m_pObjectShell->GetError()
+ : ERRCODE_IO_CANTWRITE;
+ m_pData->m_pObjectShell->ResetError();
+
+ if ( bRet )
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "successful saving." ) ) );
+ m_pData->m_aPreusedFilterName = GetMediumFilterName_Impl();
+
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOCDONE), m_pData->m_pObjectShell ) );
+ }
+ else
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing failed!" ) ) );
+ m_pData->m_pObjectShell->StoreLog();
+
+ // write the contents of the logger to the file
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOCFAILED, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOCFAILED), m_pData->m_pObjectShell ) );
+
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode );
+ }
+ }
+
+}
+
+//________________________________________________________________________________________________________
+// XStorable
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::store() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ storeSelf( uno::Sequence< beans::PropertyValue >() );
+}
+
+//________________________________________________________________________________________________________
+// XStorable
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::storeAsURL( const ::rtl::OUString& rURL ,
+ const uno::Sequence< beans::PropertyValue >& rArgs )
+ throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aPerfLog, "PERFORMANCE - SfxBaseModel::storeAsURL" );
+
+ SfxModelGuard aGuard( *this );
+
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeAsURL" ) ) );
+ SfxSaveGuard aSaveGuard(this, m_pData, sal_False);
+
+ impl_store( rURL, rArgs, sal_False );
+
+ uno::Sequence< beans::PropertyValue > aSequence ;
+ TransformItems( SID_OPENDOC, *m_pData->m_pObjectShell->GetMedium()->GetItemSet(), aSequence );
+ attachResource( rURL, aSequence );
+ }
+}
+
+//________________________________________________________________________________________________________
+// XStorable
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::storeToURL( const ::rtl::OUString& rURL ,
+ const uno::Sequence< beans::PropertyValue >& rArgs )
+ throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeToURL" ) ) );
+ SfxSaveGuard aSaveGuard(this, m_pData, sal_False);
+ impl_store( rURL, rArgs, sal_True );
+ }
+}
+
+::sal_Bool SAL_CALL SfxBaseModel::wasModifiedSinceLastSave() throw ( RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+ return m_pData->m_bModifiedSinceLastSave;
+}
+
+void SAL_CALL SfxBaseModel::storeToRecoveryFile( const ::rtl::OUString& i_TargetLocation, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException )
+{
+ SfxModelGuard aGuard( *this );
+
+ // delegate
+ SfxSaveGuard aSaveGuard( this, m_pData, sal_False );
+ impl_store( i_TargetLocation, i_MediaDescriptor, sal_True );
+
+ // no need for subsequent calls to storeToRecoveryFile, unless we're modified, again
+ m_pData->m_bModifiedSinceLastSave = sal_False;
+}
+
+void SAL_CALL SfxBaseModel::recoverFromFile( const ::rtl::OUString& i_SourceLocation, const ::rtl::OUString& i_SalvagedFile, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException )
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+
+ // delegate to our "load" method
+ ::comphelper::NamedValueCollection aMediaDescriptor( i_MediaDescriptor );
+
+ // our load implementation expects the SalvagedFile to be in the media descriptor
+ OSL_ENSURE( !aMediaDescriptor.has( "SalvagedFile" ) || ( aMediaDescriptor.getOrDefault( "SalvagedFile", ::rtl::OUString() ) == i_SalvagedFile ),
+ "SfxBaseModel::recoverFromFile: inconsistent information!" );
+ aMediaDescriptor.put( "SalvagedFile", i_SalvagedFile );
+
+ // similar for the to-be-loaded file
+ OSL_ENSURE( !aMediaDescriptor.has( "URL" ) || ( aMediaDescriptor.getOrDefault( "URL", ::rtl::OUString() ) == i_SourceLocation ),
+ "SfxBaseModel::recoverFromFile: inconsistent information!" );
+ aMediaDescriptor.put( "URL", i_SourceLocation );
+
+ load( aMediaDescriptor.getPropertyValues() );
+
+ // Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading.
+ // However, we will not do this here, as we know that our load implementation (respectively some method
+ // called from there) already did so.
+ // In particular, the load process might already have modified some elements of the media
+ // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do
+ // not want to overwrite it with the "old" elements passed to this method here.
+}
+
+//________________________________________________________________________________________________________
+// XLoadable
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::initNew()
+ throw (::com::sun::star::frame::DoubleInitializationException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::uno::Exception)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ if ( IsInitialized() )
+ throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this );
+
+ // the object shell should exist always
+ DBG_ASSERT( m_pData->m_pObjectShell.Is(), "Model is useless without an ObjectShell" );
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ if( m_pData->m_pObjectShell->GetMedium() )
+ throw DOUBLEINITIALIZATIONEXCEPTION();
+
+ sal_Bool bRes = m_pData->m_pObjectShell->DoInitNew( NULL );
+ sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetError() ?
+ m_pData->m_pObjectShell->GetError() : ERRCODE_IO_CANTCREATE;
+ m_pData->m_pObjectShell->ResetError();
+
+ if ( !bRes )
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode );
+ }
+}
+
+//________________________________________________________________________________________________________
+// XLoadable
+//________________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::load( const uno::Sequence< beans::PropertyValue >& seqArguments )
+ throw (::com::sun::star::frame::DoubleInitializationException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException,
+ ::com::sun::star::uno::Exception)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ if ( IsInitialized() )
+ throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this );
+
+ // the object shell should exist always
+ DBG_ASSERT( m_pData->m_pObjectShell.Is(), "Model is useless without an ObjectShell" );
+
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ if( m_pData->m_pObjectShell->GetMedium() )
+ // if a Medium is present, the document is already initialized
+ throw DOUBLEINITIALIZATIONEXCEPTION();
+
+ SfxMedium* pMedium = new SfxMedium( seqArguments );
+ String aFilterName;
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if( pFilterNameItem )
+ aFilterName = pFilterNameItem->GetValue();
+ if( !m_pData->m_pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ) )
+ {
+ // filtername is not valid
+ delete pMedium;
+ throw frame::IllegalArgumentIOException();
+ }
+
+ // !TODO: currently not working
+ //SFX_ITEMSET_ARG( pParams, pFrameItem, SfxFrameItem, SID_DOCFRAME, FALSE );
+ //if( pFrameItem && pFrameItem->GetFrame() )
+ //{
+ // SfxFrame* pFrame = pFrameItem->GetFrame();
+ // pMedium->SetLoadTargetFrame( pFrame );
+ //}
+
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
+ sal_Bool bSalvage = pSalvageItem ? sal_True : sal_False;
+
+ // SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
+ // sal_Bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
+ //
+ // does already happen in DoLoad call
+ //m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC );
+
+ // load document
+ sal_uInt32 nError = ERRCODE_NONE;
+ if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
+ nError=ERRCODE_IO_GENERAL;
+
+ // QUESTION: if the following happens outside of DoLoad, something important is missing there!
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > xHandler = pMedium->GetInteractionHandler();
+ if( m_pData->m_pObjectShell->GetErrorCode() )
+ {
+ nError = m_pData->m_pObjectShell->GetErrorCode();
+ if ( nError == ERRCODE_IO_BROKENPACKAGE && xHandler.is() )
+ {
+ ::rtl::OUString aDocName = pMedium->GetURLObject().getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, FALSE );
+ if ( !pRepairItem || !pRepairItem->GetValue() )
+ {
+ RequestPackageReparation* pRequest = new RequestPackageReparation( aDocName );
+ com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest > xRequest ( pRequest );
+ xHandler->handle( xRequest );
+ if( pRequest->isApproved() )
+ {
+ // broken package: try second loading and allow repair
+ pMedium->GetItemSet()->Put( SfxBoolItem( SID_REPAIRPACKAGE, sal_True ) );
+ pMedium->GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) );
+ pMedium->GetItemSet()->Put( SfxStringItem( SID_DOCINFO_TITLE, aDocName ) );
+
+ // the error must be reset and the storage must be reopened in new mode
+ pMedium->ResetError();
+ pMedium->CloseStorage();
+ m_pData->m_pObjectShell->PrepareSecondTryLoad_Impl();
+ if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
+ nError=ERRCODE_IO_GENERAL;
+ nError = m_pData->m_pObjectShell->GetErrorCode();
+ }
+ }
+
+ if ( nError == ERRCODE_IO_BROKENPACKAGE )
+ {
+ // repair either not allowed or not successful
+ NotifyBrokenPackage* pNotifyRequest = new NotifyBrokenPackage( aDocName );
+ com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest > xRequest ( pNotifyRequest );
+ xHandler->handle( xRequest );
+ }
+ }
+ }
+
+ if( m_pData->m_pObjectShell->IsAbortingImport() )
+ nError = ERRCODE_ABORT;
+
+ if( bSalvage )
+ {
+ // file recovery: restore original filter
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher();
+ const SfxFilter* pSetFilter = rMatcher.GetFilter4FilterName( pFilterItem->GetValue() );
+ pMedium->SetFilter( pSetFilter );
+ m_pData->m_pObjectShell->SetModified(sal_True);
+ }
+
+ // TODO/LATER: may be the mode should be retrieved from outside and the preused filter should not be set
+ if ( m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if ( pFilterItem )
+ m_pData->m_aPreusedFilterName = pFilterItem->GetValue();
+ }
+
+ if ( !nError )
+ nError = pMedium->GetError();
+
+ m_pData->m_pObjectShell->ResetError();
+
+ if ( nError )
+ {
+ BOOL bSilent = FALSE;
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSilentItem, SfxBoolItem, SID_SILENT, sal_False);
+ if( pSilentItem )
+ bSilent = pSilentItem->GetValue();
+
+ BOOL bWarning = ((nError & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
+ if ( nError != ERRCODE_IO_BROKENPACKAGE && !bSilent )
+ {
+ // broken package was handled already
+ if ( SfxObjectShell::UseInteractionToHandleError( xHandler, nError ) && !bWarning )
+ {
+ // abort loading (except for warnings)
+ nError = ERRCODE_IO_ABORT;
+ }
+ }
+
+ if ( m_pData->m_pObjectShell->GetMedium() != pMedium )
+ {
+ // for whatever reason document now has another medium
+ DBG_ERROR("Document has rejected the medium?!");
+ delete pMedium;
+ }
+
+ if ( !bWarning ) // #i30711# don't abort loading if it's only a warning
+ {
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ nError ? nError : ERRCODE_IO_CANTREAD );
+ }
+ }
+
+ BOOL bHidden = FALSE;
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHidItem, SfxBoolItem, SID_HIDDEN, sal_False);
+ if ( pHidItem )
+ bHidden = pHidItem->GetValue();
+ // !TODO: will be done by Framework!
+ pMedium->SetUpdatePickList( !bHidden );
+ }
+}
+
+//________________________________________________________________________________________________________
+// XTransferable
+//________________________________________________________________________________________________________
+
+uno::Any SAL_CALL SfxBaseModel::getTransferData( const DATAFLAVOR& aFlavor )
+ throw (::com::sun::star::datatransfer::UnsupportedFlavorException,
+ ::com::sun::star::io::IOException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Any aAny;
+
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ {
+ TransferableObjectDescriptor aDesc;
+
+ aDesc.maClassName = m_pData->m_pObjectShell->GetClassName();
+ aDesc.maTypeName = aFlavor.HumanPresentableName;
+
+ // TODO/LATER: ViewAspect needs to be sal_Int64
+ aDesc.mnViewAspect = sal::static_int_cast< sal_uInt16 >( embed::Aspects::MSOLE_CONTENT );
+
+ //TODO/LATER: status needs to become sal_Int64
+ aDesc.mnOle2Misc = m_pData->m_pObjectShell->GetMiscStatus();
+ Size aSize = m_pData->m_pObjectShell->GetVisArea().GetSize();
+
+ MapUnit aMapUnit = m_pData->m_pObjectShell->GetMapUnit();
+ aDesc.maSize = OutputDevice::LogicToLogic( aSize, aMapUnit, MAP_100TH_MM );
+ aDesc.maDragStartPos = Point();
+ aDesc.maDisplayName = String();
+ aDesc.mbCanLink = FALSE;
+
+ SvMemoryStream aMemStm( 1024, 1024 );
+ aMemStm << aDesc;
+ aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ {
+ try
+ {
+ utl::TempFile aTmp;
+ aTmp.EnableKillingFile( TRUE );
+ storeToURL( aTmp.GetURL(), uno::Sequence < beans::PropertyValue >() );
+ SvStream* pStream = aTmp.GetStream( STREAM_READ );
+ const sal_uInt32 nLen = pStream->Seek( STREAM_SEEK_TO_END );
+ ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( nLen );
+ pStream->Seek( STREAM_SEEK_TO_BEGIN );
+ pStream->Read( aSeq.getArray(), nLen );
+ delete pStream;
+ if( aSeq.getLength() )
+ aAny <<= aSeq;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ {
+
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
+
+ if ( pMetaFile )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+
+ pMetaFile->Write( aMemStm );
+ aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ),
+ aMemStm.Seek( STREAM_SEEK_TO_END ) );
+ }
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ m_pData->m_pObjectShell->CreatePreviewMetaFile_Impl( sal_True, sal_True );
+
+ if ( pMetaFile )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+ aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+
+ pMetaFile->Write( aMemStm );
+ aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ),
+ aMemStm.Seek( STREAM_SEEK_TO_END ) );
+ }
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
+
+ if ( pMetaFile )
+ {
+ ::boost::shared_ptr<SvMemoryStream> pStream(
+ GraphicHelper::getFormatStrFromGDI_Impl(
+ pMetaFile.get(), CVT_EMF ) );
+ if ( pStream )
+ {
+ pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+ aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
+ pStream->Seek( STREAM_SEEK_TO_END ) );
+ }
+ }
+ }
+ else if ( GraphicHelper::supportsMetaFileHandle_Impl()
+ && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) )
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
+
+ if ( pMetaFile )
+ {
+ aAny <<= reinterpret_cast< const sal_uInt64 >(
+ GraphicHelper::getEnhMetaFileFromGDI_Impl( pMetaFile.get() ) );
+ }
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
+
+ if ( pMetaFile )
+ {
+ ::boost::shared_ptr<SvMemoryStream> pStream(
+ GraphicHelper::getFormatStrFromGDI_Impl(
+ pMetaFile.get(), CVT_WMF ) );
+
+ if ( pStream )
+ {
+ pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+ aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
+ pStream->Seek( STREAM_SEEK_TO_END ) );
+ }
+ }
+ }
+ else if ( GraphicHelper::supportsMetaFileHandle_Impl()
+ && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) )
+ {
+ // means HGLOBAL handler to memory storage containing METAFILEPICT structure
+
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
+
+ if ( pMetaFile )
+ {
+ Size aMetaSize = pMetaFile->GetPrefSize();
+ aAny <<= reinterpret_cast< const sal_uInt64 >(
+ GraphicHelper::getWinMetaFileFromGDI_Impl(
+ pMetaFile.get(), aMetaSize ) );
+ }
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
+
+ if ( pMetaFile )
+ {
+ ::boost::shared_ptr<SvMemoryStream> pStream(
+ GraphicHelper::getFormatStrFromGDI_Impl(
+ pMetaFile.get(), CVT_BMP ) );
+
+ if ( pStream )
+ {
+ pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+ aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
+ pStream->Seek( STREAM_SEEK_TO_END ) );
+ }
+ }
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "image/png" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ {
+ ::boost::shared_ptr<GDIMetaFile> pMetaFile =
+ m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
+
+ if ( pMetaFile )
+ {
+ ::boost::shared_ptr<SvMemoryStream> pStream(
+ GraphicHelper::getFormatStrFromGDI_Impl(
+ pMetaFile.get(), CVT_PNG ) );
+
+ if ( pStream )
+ {
+ pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
+ aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
+ pStream->Seek( STREAM_SEEK_TO_END ) );
+ }
+ }
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ else
+ throw datatransfer::UnsupportedFlavorException();
+ }
+
+ return aAny;
+}
+
+//________________________________________________________________________________________________________
+// XTransferable
+//________________________________________________________________________________________________________
+
+
+uno::Sequence< DATAFLAVOR > SAL_CALL SfxBaseModel::getTransferDataFlavors()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ sal_Int32 nSuppFlavors = GraphicHelper::supportsMetaFileHandle_Impl() ? 10 : 8;
+ uno::Sequence< DATAFLAVOR > aFlavorSeq( nSuppFlavors );
+
+ aFlavorSeq[0].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) );
+ aFlavorSeq[0].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GDIMetaFile" ) );
+ aFlavorSeq[0].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
+
+ aFlavorSeq[1].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) );
+ aFlavorSeq[1].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GDIMetaFile" ) );
+ aFlavorSeq[1].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
+
+ aFlavorSeq[2].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) );
+ aFlavorSeq[2].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) );
+ aFlavorSeq[2].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
+
+ aFlavorSeq[3].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) );
+ aFlavorSeq[3].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows MetaFile" ) );
+ aFlavorSeq[3].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
+
+ aFlavorSeq[4].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) );
+ aFlavorSeq[4].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Star Object Descriptor (XML)" ) );
+ aFlavorSeq[4].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
+
+ aFlavorSeq[5].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"" ) );
+ aFlavorSeq[5].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Star Embed Source (XML)" ) );
+ aFlavorSeq[5].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
+
+ aFlavorSeq[6].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) );
+ aFlavorSeq[6].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) );
+ aFlavorSeq[6].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
+
+ aFlavorSeq[7].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) );
+ aFlavorSeq[7].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PNG" ) );
+ aFlavorSeq[7].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
+
+ if ( nSuppFlavors == 10 )
+ {
+ aFlavorSeq[8].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) );
+ aFlavorSeq[8].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) );
+ aFlavorSeq[8].DataType = getCppuType( (const sal_uInt64*) 0 );
+
+ aFlavorSeq[9].MimeType =
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) );
+ aFlavorSeq[9].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows MetaFile" ) );
+ aFlavorSeq[9].DataType = getCppuType( (const sal_uInt64*) 0 );
+ }
+
+ return aFlavorSeq;
+}
+
+//________________________________________________________________________________________________________
+// XTransferable
+//________________________________________________________________________________________________________
+
+
+sal_Bool SAL_CALL SfxBaseModel::isDataFlavorSupported( const DATAFLAVOR& aFlavor )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ return sal_True;
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ return sal_True;
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ return sal_True;
+ else if ( GraphicHelper::supportsMetaFileHandle_Impl()
+ && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) )
+ return sal_True;
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ return sal_True;
+ else if ( GraphicHelper::supportsMetaFileHandle_Impl()
+ && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) )
+ return sal_True;
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ return sal_True;
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ return sal_True;
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ return sal_True;
+ }
+ else if ( aFlavor.MimeType.equalsAscii( "image/png" ) )
+ {
+ if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+
+//--------------------------------------------------------------------------------------------------------
+// XEventsSupplier
+//--------------------------------------------------------------------------------------------------------
+
+uno::Reference< container::XNameReplace > SAL_CALL SfxBaseModel::getEvents() throw( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( ! m_pData->m_xEvents.is() )
+ {
+ m_pData->m_xEvents = new SfxEvents_Impl( m_pData->m_pObjectShell, this );
+ }
+
+ return m_pData->m_xEvents;
+}
+
+//--------------------------------------------------------------------------------------------------------
+// XEmbeddedScripts
+//--------------------------------------------------------------------------------------------------------
+
+uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getBasicLibraries() throw (RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries;
+ if ( m_pData->m_pObjectShell )
+ xBasicLibraries.set( m_pData->m_pObjectShell->GetBasicContainer(), UNO_QUERY_THROW );
+ return xBasicLibraries;
+}
+
+uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getDialogLibraries() throw (RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries;
+ if ( m_pData->m_pObjectShell )
+ xDialogLibraries.set( m_pData->m_pObjectShell->GetDialogContainer(), UNO_QUERY_THROW );
+ return xDialogLibraries;
+}
+
+::sal_Bool SAL_CALL SfxBaseModel::getAllowMacroExecution() throw (RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( m_pData->m_pObjectShell )
+ return m_pData->m_pObjectShell->AdjustMacroMode( String(), false );
+ return sal_False;
+}
+
+//--------------------------------------------------------------------------------------------------------
+// XScriptInvocationContext
+//--------------------------------------------------------------------------------------------------------
+
+Reference< document::XEmbeddedScripts > SAL_CALL SfxBaseModel::getScriptContainer() throw (RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ Reference< document::XEmbeddedScripts > xDocumentScripts;
+
+ try
+ {
+ Reference< frame::XModel > xDocument( this );
+ xDocumentScripts.set( xDocument, uno::UNO_QUERY );
+ while ( !xDocumentScripts.is() && xDocument.is() )
+ {
+ Reference< container::XChild > xDocAsChild( xDocument, uno::UNO_QUERY );
+ if ( !xDocAsChild.is() )
+ {
+ xDocument = NULL;
+ break;
+ }
+
+ xDocument.set( xDocAsChild->getParent(), uno::UNO_QUERY );
+ xDocumentScripts.set( xDocument, uno::UNO_QUERY );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ xDocumentScripts = NULL;
+ }
+
+ return xDocumentScripts;
+}
+
+//--------------------------------------------------------------------------------------------------------
+// XEventBroadcaster
+//--------------------------------------------------------------------------------------------------------
+
+void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XDOCEVENTLISTENER >& aListener ) throw( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+
+ m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), aListener );
+}
+
+//--------------------------------------------------------------------------------------------------------
+// XEventBroadcaster
+//--------------------------------------------------------------------------------------------------------
+
+void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XDOCEVENTLISTENER >& aListener ) throw( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), aListener );
+}
+
+//________________________________________________________________________________________________________
+// SfxListener
+//________________________________________________________________________________________________________
+
+void addTitle_Impl( Sequence < ::com::sun::star::beans::PropertyValue >& rSeq, const ::rtl::OUString& rTitle )
+{
+ sal_Int32 nCount = rSeq.getLength();
+ sal_Int32 nArg;
+
+ for ( nArg = 0; nArg < nCount; nArg++ )
+ {
+ ::com::sun::star::beans::PropertyValue& rProp = rSeq[nArg];
+ if ( rProp.Name.equalsAscii("Title") )
+ {
+ rProp.Value <<= rTitle;
+ break;
+ }
+ }
+
+ if ( nArg == nCount )
+ {
+ rSeq.realloc( nCount+1 );
+ rSeq[nCount].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Title") );
+ rSeq[nCount].Value <<= rTitle;
+ }
+}
+
+void SfxBaseModel::NotifyStorageListeners_Impl()
+{
+ uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
+
+ if ( m_pData->m_pObjectShell )
+ {
+ ::cppu::OInterfaceContainerHelper* pContainer =
+ m_pData->m_aInterfaceContainer.getContainer(
+ ::getCppuType( ( const uno::Reference< document::XStorageChangeListener >*) NULL ) );
+ if ( pContainer != NULL )
+ {
+ uno::Reference< embed::XStorage > xNewStorage = m_pData->m_pObjectShell->GetStorage();
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while ( pIterator.hasMoreElements() )
+ {
+ try
+ {
+ ((document::XStorageChangeListener*)pIterator.next())->notifyStorageChange(
+ xSelfHold,
+ xNewStorage );
+ }
+ catch( uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+ }
+}
+
+void SfxBaseModel::Notify( SfxBroadcaster& rBC ,
+ const SfxHint& rHint )
+{
+ if ( !m_pData )
+ return;
+
+ if ( &rBC == m_pData->m_pObjectShell )
+ {
+ SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint );
+ if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DOCCHANGED )
+ changing();
+
+ SfxEventHint* pNamedHint = PTR_CAST( SfxEventHint, &rHint );
+ if ( pNamedHint )
+ {
+
+ switch ( pNamedHint->GetEventId() )
+ {
+ case SFX_EVENT_STORAGECHANGED:
+ {
+ // for now this event is sent only on creation of a new storage for new document
+ // and in case of reload of medium without document reload
+ // other events are used to detect storage change
+ // NotifyStorageListeners_Impl();
+
+ if ( m_pData->m_xUIConfigurationManager.is()
+ && m_pData->m_pObjectShell->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
+ {
+ uno::Reference< XSTORAGE > xConfigStorage;
+ rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations2" ));
+
+ xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, com::sun::star::embed::ElementModes::READWRITE );
+ if ( !xConfigStorage.is() )
+ xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, com::sun::star::embed::ElementModes::READ );
+
+ if ( xConfigStorage.is() || !m_pData->m_pObjectShell->GetStorage()->hasByName( aUIConfigFolderName ) )
+ {
+ // the storage is different, since otherwise it could not be opened, so it must be exchanged
+ Reference< ui::XUIConfigurationStorage > xUIConfigStorage( m_pData->m_xUIConfigurationManager, uno::UNO_QUERY );
+ xUIConfigStorage->setStorage( xConfigStorage );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "Unexpected scenario!\n" );
+ }
+ }
+
+ ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() );
+ }
+ break;
+
+ case SFX_EVENT_LOADFINISHED:
+ {
+ impl_getPrintHelper();
+ ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() );
+ m_pData->m_bModifiedSinceLastSave = sal_False;
+ }
+ break;
+
+ case SFX_EVENT_SAVEASDOCDONE:
+ {
+ m_pData->m_sURL = m_pData->m_pObjectShell->GetMedium()->GetName();
+
+ SfxItemSet *pSet = m_pData->m_pObjectShell->GetMedium()->GetItemSet();
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs;
+ ::rtl::OUString aTitle = m_pData->m_pObjectShell->GetTitle();
+ TransformItems( SID_SAVEASDOC, *pSet, aArgs );
+ addTitle_Impl( aArgs, aTitle );
+ attachResource( m_pData->m_pObjectShell->GetMedium()->GetName(), aArgs );
+ }
+ break;
+
+ case SFX_EVENT_DOCCREATED:
+ {
+ impl_getPrintHelper();
+ m_pData->m_bModifiedSinceLastSave = sal_False;
+ }
+ break;
+
+ case SFX_EVENT_MODIFYCHANGED:
+ {
+ m_pData->m_bModifiedSinceLastSave = isModified();
+ }
+ break;
+ }
+
+ postEvent_Impl( pNamedHint->GetEventName() );
+ }
+
+ if ( pSimpleHint )
+ {
+ if ( pSimpleHint->GetId() == SFX_HINT_TITLECHANGED )
+ {
+ ::rtl::OUString aTitle = m_pData->m_pObjectShell->GetTitle();
+ addTitle_Impl( m_pData->m_seqArguments, aTitle );
+ postEvent_Impl( GlobalEventConfig::GetEventName( STR_EVENT_TITLECHANGED ) );
+ }
+ if ( pSimpleHint->GetId() == SFX_HINT_MODECHANGED )
+ {
+ postEvent_Impl( GlobalEventConfig::GetEventName( STR_EVENT_MODECHANGED ) );
+ }
+/*
+ else if ( pSimpleHint->GetId() == SFX_HINT_DYING
+ || pSimpleHint->GetId() == SFX_HINT_DEINITIALIZING )
+ {
+ SfxObjectShellLock pShellLock = m_pData->m_pObjectShellLock;
+ m_pData->m_pObjectShellLock = SfxObjectShellLock();
+ }
+*/
+ }
+ }
+}
+
+//________________________________________________________________________________________________________
+// public impl.
+//________________________________________________________________________________________________________
+
+void SfxBaseModel::NotifyModifyListeners_Impl() const
+{
+ ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0) );
+ if ( pIC )
+ {
+ lang::EventObject aEvent( (frame::XModel *)this );
+ pIC->notifyEach( &util::XModifyListener::modified, aEvent );
+ }
+
+ // this notification here is done too generously, we cannot simply assume that we're really modified
+ // now, but we need to check it ...
+ m_pData->m_bModifiedSinceLastSave = const_cast< SfxBaseModel* >( this )->isModified();
+}
+
+void SfxBaseModel::changing()
+{
+ SfxModelGuard aGuard( *this );
+
+ // the notification should not be sent if the document can not be modified
+ if ( !m_pData->m_pObjectShell.Is() || !m_pData->m_pObjectShell->IsEnableSetModified() )
+ return;
+
+ NotifyModifyListeners_Impl();
+}
+
+void SfxBaseModel::impl_change()
+{
+ // object already disposed?
+ if ( impl_isDisposed() )
+ return;
+
+ NotifyModifyListeners_Impl();
+}
+
+//________________________________________________________________________________________________________
+// public impl.
+//________________________________________________________________________________________________________
+
+SfxObjectShell* SfxBaseModel::GetObjectShell() const
+{
+ return m_pData ? (SfxObjectShell*) m_pData->m_pObjectShell : 0;
+}
+
+SfxObjectShell* SfxBaseModel::impl_getObjectShell() const
+{
+ return m_pData ? (SfxObjectShell*) m_pData->m_pObjectShell : 0;
+}
+
+//________________________________________________________________________________________________________
+// public impl.
+//________________________________________________________________________________________________________
+
+sal_Bool SfxBaseModel::IsDisposed() const
+{
+ return ( m_pData == NULL ) ;
+}
+
+sal_Bool SfxBaseModel::IsInitialized() const
+{
+ if ( !m_pData || !m_pData->m_pObjectShell )
+ {
+ OSL_ENSURE( false, "SfxBaseModel::IsInitialized: this should have been caught earlier!" );
+ return sal_False;
+ }
+
+ return m_pData->m_pObjectShell->GetMedium() != NULL;
+}
+
+sal_Bool SfxBaseModel::impl_isDisposed() const
+{
+ return ( m_pData == NULL ) ;
+}
+
+//________________________________________________________________________________________________________
+// private impl.
+//________________________________________________________________________________________________________
+
+::rtl::OUString SfxBaseModel::GetMediumFilterName_Impl()
+{
+ const SfxFilter* pFilter = NULL;
+ SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
+ if ( pMedium )
+ pFilter = pMedium->GetFilter();
+
+ if ( pFilter )
+ return pFilter->GetName();
+
+ return ::rtl::OUString();
+}
+
+void SfxBaseModel::impl_store( const ::rtl::OUString& sURL ,
+ const uno::Sequence< beans::PropertyValue >& seqArguments ,
+ sal_Bool bSaveTo )
+{
+ if( !sURL.getLength() )
+ throw frame::IllegalArgumentIOException();
+
+ //sal_Bool aSaveAsTemplate = sal_False;
+
+ sal_Bool bSaved = sal_False;
+ if ( !bSaveTo && m_pData->m_pObjectShell && sURL.getLength()
+ && sURL.compareToAscii( "private:stream", 14 ) != COMPARE_EQUAL
+ && SfxMedium::EqualURLs( getLocation(), sURL ) )
+ {
+ // this is the same file URL as the current document location, try to use storeOwn if possible
+
+ ::comphelper::SequenceAsHashMap aArgHash( seqArguments );
+ ::rtl::OUString aFilterString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
+ ::rtl::OUString aFilterName = aArgHash.getUnpackedValueOrDefault( aFilterString, ::rtl::OUString() );
+ if ( aFilterName.getLength() )
+ {
+ SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
+ if ( pMedium )
+ {
+ const SfxFilter* pFilter = pMedium->GetFilter();
+ if ( pFilter && aFilterName.equals( pFilter->GetFilterName() ) )
+ {
+ aArgHash.erase( aFilterString );
+ aArgHash.erase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) );
+
+ // if the password is changed SaveAs should be done
+ // no password for encrypted document is also a change here
+ sal_Bool bPassChanged = sal_False;
+
+ ::comphelper::SequenceAsHashMap::iterator aNewPassIter
+ = aArgHash.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ) );
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False );
+ if ( pPasswordItem && aNewPassIter != aArgHash.end() )
+ {
+ ::rtl::OUString aNewPass;
+ aNewPassIter->second >>= aNewPass;
+ bPassChanged = !aNewPass.equals( pPasswordItem->GetValue() );
+ }
+ else if ( pPasswordItem || aNewPassIter != aArgHash.end() )
+ bPassChanged = sal_True;
+
+ if ( !bPassChanged )
+ {
+ try
+ {
+ storeSelf( aArgHash.getAsConstPropertyValueList() );
+ bSaved = sal_True;
+ }
+ catch( const lang::IllegalArgumentException& )
+ {
+ // some additional arguments do not allow to use saving, SaveAs should be done
+ // but only for normal documents, the shared documents would be overwritten in this case
+ // that would mean an information loss
+ // TODO/LATER: need a new interaction for this case
+ if ( m_pData->m_pObjectShell->IsDocShared() )
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't store shared document!" ) ) );
+ m_pData->m_pObjectShell->StoreLog();
+
+ throw;
+ }
+ }
+ }
+ else if ( m_pData->m_pObjectShell->IsDocShared() )
+ {
+ // if the password is changed a special error should be used in case of shared document
+ throw task::ErrorCodeIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cant change password for shared document." ) ), uno::Reference< uno::XInterface >(), ERRCODE_SFX_SHARED_NOPASSWORDCHANGE );
+ }
+ }
+ }
+ }
+ }
+
+ if ( !bSaved && m_pData->m_pObjectShell )
+ {
+ SFX_APP()->NotifyEvent( SfxEventHint( bSaveTo ? SFX_EVENT_SAVETODOC : SFX_EVENT_SAVEASDOC, GlobalEventConfig::GetEventName( bSaveTo ? STR_EVENT_SAVETODOC : STR_EVENT_SAVEASDOC ),
+ m_pData->m_pObjectShell ) );
+
+ SfxAllItemSet *aParams = new SfxAllItemSet( SFX_APP()->GetPool() );
+ aParams->Put( SfxStringItem( SID_FILE_NAME, String(sURL) ) );
+ if ( bSaveTo )
+ aParams->Put( SfxBoolItem( SID_SAVETO, sal_True ) );
+
+ TransformParameters( SID_SAVEASDOC, seqArguments, *aParams );
+
+ SFX_ITEMSET_ARG( aParams, pCopyStreamItem, SfxBoolItem, SID_COPY_STREAM_IF_POSSIBLE, sal_False );
+
+ if ( pCopyStreamItem && pCopyStreamItem->GetValue() && !bSaveTo )
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Misuse of CopyStreamIfPossible!" ) ) );
+ m_pData->m_pObjectShell->StoreLog();
+
+ throw frame::IllegalArgumentIOException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CopyStreamIfPossible parameter is not acceptable for storeAsURL() call!") ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ sal_uInt32 nModifyPasswordHash = 0;
+ uno::Sequence< beans::PropertyValue > aModifyPasswordInfo;
+ SFX_ITEMSET_ARG( aParams, pModifyPasswordInfoItem, SfxUnoAnyItem, SID_MODIFYPASSWORDINFO, sal_False );
+ if ( pModifyPasswordInfoItem )
+ {
+ // it contains either a simple hash or a set of PropertyValues
+ // TODO/LATER: the sequence of PropertyValue should replace the hash completely in future
+ sal_Int32 nMPHTmp = 0;
+ pModifyPasswordInfoItem->GetValue() >>= nMPHTmp;
+ nModifyPasswordHash = (sal_uInt32)nMPHTmp;
+ pModifyPasswordInfoItem->GetValue() >>= aModifyPasswordInfo;
+ }
+ aParams->ClearItem( SID_MODIFYPASSWORDINFO );
+ sal_uInt32 nOldModifyPasswordHash = m_pData->m_pObjectShell->GetModifyPasswordHash();
+ m_pData->m_pObjectShell->SetModifyPasswordHash( nModifyPasswordHash );
+ uno::Sequence< beans::PropertyValue > aOldModifyPasswordInfo = m_pData->m_pObjectShell->GetModifyPasswordInfo();
+ m_pData->m_pObjectShell->SetModifyPasswordInfo( aModifyPasswordInfo );
+
+ // since saving a document modifies its DocumentInfo, the current
+ // DocumentInfo must be saved on "SaveTo", so it can be restored
+ // after saving
+ sal_Bool bCopyTo = bSaveTo ||
+ m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED;
+ uno::Reference<document::XDocumentProperties> xOldDocProps;
+ uno::Reference<document::XDocumentInfo> xOldDocInfo;
+ if ( bCopyTo )
+ {
+ xOldDocProps = getDocumentProperties();
+ if (m_pData->m_xDocumentInfo.is())
+ {
+ xOldDocInfo = getDocumentInfo();
+ const Reference<util::XCloneable> xCloneable(xOldDocInfo,
+ UNO_QUERY_THROW);
+ const Reference<document::XDocumentInfo> xNewDocInfo(
+ xCloneable->createClone(), UNO_QUERY_THROW);
+ const Reference<document::XDocumentPropertiesSupplier> xDPS(
+ xNewDocInfo, UNO_QUERY_THROW);
+ const Reference<document::XDocumentProperties> xNewDocProps(
+ xDPS->getDocumentProperties());
+ m_pData->m_xDocumentProperties = xNewDocProps;
+ m_pData->m_xDocumentInfo = xNewDocInfo;
+ }
+ else // try not to create DocumentInfo if it does not exist...
+ {
+ const Reference<util::XCloneable> xCloneable(xOldDocProps,
+ UNO_QUERY_THROW);
+ const Reference<document::XDocumentProperties> xNewDocProps(
+ xCloneable->createClone(), UNO_QUERY_THROW);
+ m_pData->m_xDocumentProperties = xNewDocProps;
+ }
+ }
+
+ sal_Bool bRet = m_pData->m_pObjectShell->APISaveAs_Impl( sURL, aParams );
+
+ if ( bCopyTo )
+ {
+ // restore DocumentInfo if a copy was created
+ m_pData->m_xDocumentProperties = xOldDocProps;
+ m_pData->m_xDocumentInfo = xOldDocInfo;
+ }
+
+ uno::Reference < task::XInteractionHandler > xHandler;
+ SFX_ITEMSET_ARG( aParams, pItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
+ if ( pItem )
+ pItem->GetValue() >>= xHandler;
+
+ DELETEZ( aParams );
+
+ sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetErrorCode();
+ if ( !bRet && !nErrCode )
+ {
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing has failed, no error is set!" ) ) );
+ nErrCode = ERRCODE_IO_CANTWRITE;
+ }
+ m_pData->m_pObjectShell->ResetError();
+
+ if ( bRet )
+ {
+ if ( nErrCode )
+ {
+ // must be a warning - use Interactionhandler if possible or abandone
+ if ( xHandler.is() )
+ {
+ // TODO/LATER: a general way to set the error context should be available
+ SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, m_pData->m_pObjectShell->GetTitle() );
+
+ ::com::sun::star::task::ErrorCodeRequest aErrorCode;
+ aErrorCode.ErrCode = nErrCode;
+ SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False );
+ }
+ }
+
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing succeeded!" ) ) );
+ if ( !bSaveTo )
+ {
+ m_pData->m_aPreusedFilterName = GetMediumFilterName_Impl();
+ m_pData->m_pObjectShell->SetModifyPasswordEntered();
+
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEASDOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVEASDOCDONE), m_pData->m_pObjectShell ) );
+ }
+ else
+ {
+ m_pData->m_pObjectShell->SetModifyPasswordHash( nOldModifyPasswordHash );
+ m_pData->m_pObjectShell->SetModifyPasswordInfo( aOldModifyPasswordInfo );
+
+ SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVETODOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVETODOCDONE), m_pData->m_pObjectShell ) );
+ }
+ }
+ else
+ {
+ // let the logring be stored to the related file
+ m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing failed!" ) ) );
+ m_pData->m_pObjectShell->StoreLog();
+
+ m_pData->m_pObjectShell->SetModifyPasswordHash( nOldModifyPasswordHash );
+ m_pData->m_pObjectShell->SetModifyPasswordInfo( aOldModifyPasswordInfo );
+
+
+ SFX_APP()->NotifyEvent( SfxEventHint( bSaveTo ? SFX_EVENT_SAVETODOCFAILED : SFX_EVENT_SAVEASDOCFAILED, GlobalEventConfig::GetEventName( bSaveTo ? STR_EVENT_SAVETODOCFAILED : STR_EVENT_SAVEASDOCFAILED),
+ m_pData->m_pObjectShell ) );
+
+ throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode );
+ }
+ }
+}
+
+//********************************************************************************************************
+
+void SfxBaseModel::postEvent_Impl( ::rtl::OUString aName )
+{
+ // object already disposed?
+ if ( impl_isDisposed() )
+ return;
+
+ DBG_ASSERT( aName.getLength(), "Empty event name!" );
+ if (!aName.getLength())
+ return;
+
+ ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer(
+ ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0) );
+ if( pIC )
+
+ {
+#ifdef DBG_UTIL
+ ByteString aTmp( "SfxEvent: ");
+ aTmp += ByteString( String(aName), RTL_TEXTENCODING_UTF8 );
+ DBG_TRACE( aTmp.GetBuffer() );
+#endif
+ document::EventObject aEvent( (frame::XModel *)this, aName );
+ ::cppu::OInterfaceContainerHelper aIC( m_aMutex );
+ uno::Sequence < uno::Reference < uno::XInterface > > aElements = pIC->getElements();
+ for ( sal_Int32 nElem=0; nElem<aElements.getLength(); nElem++ )
+ aIC.addInterface( aElements[nElem] );
+ ::cppu::OInterfaceIteratorHelper aIt( aIC );
+ while( aIt.hasMoreElements() )
+ {
+ try
+ {
+ ((XDOCEVENTLISTENER *)aIt.next())->notifyEvent( aEvent );
+ }
+ catch( uno::RuntimeException& )
+ {
+ aIt.remove();
+ }
+ }
+ }
+}
+
+uno::Reference < container::XIndexAccess > SAL_CALL SfxBaseModel::getViewData() throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( m_pData->m_pObjectShell.Is() && !m_pData->m_contViewData.is() )
+ {
+ SfxViewFrame *pActFrame = SfxViewFrame::Current();
+ if ( !pActFrame || pActFrame->GetObjectShell() != m_pData->m_pObjectShell )
+ pActFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell );
+
+ if ( !pActFrame || !pActFrame->GetViewShell() )
+ // currently no frame for this document at all or View is under construction
+ return uno::Reference < container::XIndexAccess >();
+
+ m_pData->m_contViewData = Reference < container::XIndexAccess >(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ DEFINE_CONST_UNICODE("com.sun.star.document.IndexedPropertyValues") ),
+ uno::UNO_QUERY );
+
+ if ( !m_pData->m_contViewData.is() )
+ {
+ // error: no container class available!
+ return uno::Reference < container::XIndexAccess >();
+ }
+
+ uno::Reference < container::XIndexContainer > xCont( m_pData->m_contViewData, uno::UNO_QUERY );
+ sal_Int32 nCount = 0;
+ uno::Sequence < beans::PropertyValue > aSeq;
+ ::com::sun::star::uno::Any aAny;
+ for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell ); pFrame;
+ pFrame = SfxViewFrame::GetNext( *pFrame, m_pData->m_pObjectShell ) )
+ {
+ BOOL bIsActive = ( pFrame == pActFrame );
+ pFrame->GetViewShell()->WriteUserDataSequence( aSeq );
+ aAny <<= aSeq;
+ xCont->insertByIndex( bIsActive ? 0 : nCount, aAny );
+ nCount++;
+ }
+ }
+
+ return m_pData->m_contViewData;
+}
+
+void SAL_CALL SfxBaseModel::setViewData( const uno::Reference < container::XIndexAccess >& aData ) throw(::com::sun::star::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ m_pData->m_contViewData = aData;
+}
+
+/** calls all XEventListeners */
+void SfxBaseModel::notifyEvent( const ::com::sun::star::document::EventObject& aEvent ) const
+{
+ // object already disposed?
+ if ( impl_isDisposed() )
+ return;
+
+ ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer(
+ ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0) );
+ if( pIC )
+
+ {
+ ::cppu::OInterfaceIteratorHelper aIt( *pIC );
+ while( aIt.hasMoreElements() )
+ {
+ try
+ {
+ ((XDOCEVENTLISTENER *)aIt.next())->notifyEvent( aEvent );
+ }
+ catch( uno::RuntimeException& )
+ {
+ aIt.remove();
+ }
+ }
+ }
+}
+
+/** returns true if someone added a XEventListener to this XEventBroadcaster */
+sal_Bool SfxBaseModel::hasEventListeners() const
+{
+ return !impl_isDisposed() && (NULL != m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0) ) );
+}
+
+void SAL_CALL SfxBaseModel::addPrintJobListener( const uno::Reference< view::XPrintJobListener >& xListener ) throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+
+ if ( impl_getPrintHelper() )
+ {
+ uno::Reference < view::XPrintJobBroadcaster > xPJB( m_pData->m_xPrintable, uno::UNO_QUERY );
+ if ( xPJB.is() )
+ xPJB->addPrintJobListener( xListener );
+ }
+// else
+// m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< view::XPrintJobListener >*)0), xListener );
+}
+
+void SAL_CALL SfxBaseModel::removePrintJobListener( const uno::Reference< view::XPrintJobListener >& xListener ) throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( impl_getPrintHelper() )
+ {
+ uno::Reference < view::XPrintJobBroadcaster > xPJB( m_pData->m_xPrintable, uno::UNO_QUERY );
+ if ( xPJB.is() )
+ xPJB->removePrintJobListener( xListener );
+ }
+// else
+// m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< view::XPrintJobListener >*)0), xListener );
+}
+
+// simple declaration of class SvObject is enough
+// the corresponding <so3/iface.hxx> cannon be included because it provides
+// declaration of class SvBorder that conflicts with ../../inc/viewfrm.hxx
+class SvObject;
+sal_Int64 SAL_CALL SfxBaseModel::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( GetObjectShell() )
+ {
+ SvGlobalName aName( aIdentifier );
+ if ( aName == SvGlobalName( SO3_GLOBAL_CLASSID ) )
+ return (sal_Int64)(sal_IntPtr)(SvObject*)GetObjectShell();
+ else if ( aName == SvGlobalName( SFX_GLOBAL_CLASSID ) )
+ return (sal_Int64)(sal_IntPtr)(SfxObjectShell*)GetObjectShell();
+ }
+
+ return 0;
+}
+
+//____________________________________________________________________________________________________
+// XDocumentSubStorageSupplier
+//____________________________________________________________________________________________________
+
+void SfxBaseModel::ListenForStorage_Impl( const uno::Reference< embed::XStorage >& xStorage )
+{
+ uno::Reference< util::XModifiable > xModifiable( xStorage, uno::UNO_QUERY );
+ if ( xModifiable.is() )
+ {
+ if ( !m_pData->m_pStorageModifyListen.is() )
+ {
+ m_pData->m_pStorageModifyListen = new ::sfx2::DocumentStorageModifyListener( *m_pData, Application::GetSolarMutex() );
+ }
+
+ // no need to deregister the listening for old storage since it should be disposed automatically
+ xModifiable->addModifyListener( m_pData->m_pStorageModifyListen.get() );
+ }
+}
+
+uno::Reference< XSTORAGE > SAL_CALL SfxBaseModel::getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode )
+ throw ( uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< XSTORAGE > xResult;
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ uno::Reference< embed::XStorage > xStorage = m_pData->m_pObjectShell->GetStorage();
+ if ( xStorage.is() )
+ {
+ try
+ {
+ xResult = xStorage->openStorageElement( aStorageName, nMode );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ return xResult;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getDocumentSubStoragesNames()
+ throw ( io::IOException,
+ RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ Sequence< ::rtl::OUString > aResult;
+ sal_Int32 nResultSize = 0;
+ sal_Bool bSuccess = sal_False;
+ if ( m_pData->m_pObjectShell.Is() )
+ {
+ uno::Reference < embed::XStorage > xStorage = m_pData->m_pObjectShell->GetStorage();
+ uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
+ if ( xAccess.is() )
+ {
+ Sequence< ::rtl::OUString > aTemp = xAccess->getElementNames();
+ for ( sal_Int32 n = 0; n < aTemp.getLength(); n++ )
+ {
+ if ( xStorage->isStorageElement( aTemp[n] ) )
+ {
+ aResult.realloc( ++nResultSize );
+ aResult[ nResultSize - 1 ] = aTemp[n];
+ }
+ }
+
+ bSuccess = sal_True;
+ }
+ }
+
+ if ( !bSuccess )
+ throw io::IOException();
+
+ return aResult;
+}
+
+//____________________________________________________________________________________________________
+// XScriptProviderSupplier
+//____________________________________________________________________________________________________
+
+
+uno::Reference< script::provider::XScriptProvider > SAL_CALL SfxBaseModel::getScriptProvider()
+ throw ( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< script::provider::XScriptProvider > xScriptProvider;
+
+ ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
+ Reference< script::provider::XScriptProviderFactory > xScriptProviderFactory(
+ aContext.getSingleton( "com.sun.star.script.provider.theMasterScriptProviderFactory" ), uno::UNO_QUERY_THROW );
+
+ try
+ {
+ Reference< XScriptInvocationContext > xScriptContext( this );
+ xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( xScriptContext ) ), uno::UNO_SET_THROW );
+ }
+ catch( const uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch( const lang::IllegalArgumentException& )
+ {
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString(),
+ *this,
+ ::cppu::getCaughtException()
+ );
+ }
+
+ return xScriptProvider;
+}
+
+//____________________________________________________________________________________________________
+// XUIConfigurationManagerSupplier
+//____________________________________________________________________________________________________
+
+rtl::OUString SfxBaseModel::getRuntimeUID() const
+{
+ OSL_ENSURE( m_pData->m_sRuntimeUID.getLength() > 0,
+ "SfxBaseModel::getRuntimeUID - ID is empty!" );
+ return m_pData->m_sRuntimeUID;
+}
+
+sal_Bool SfxBaseModel::hasValidSignatures() const
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( m_pData->m_pObjectShell.Is() )
+ return ( m_pData->m_pObjectShell->ImplGetSignatureState( sal_False ) == SIGNATURESTATE_SIGNATURES_OK );
+ return sal_False;
+}
+
+static void GetCommandFromSequence( rtl::OUString& rCommand, sal_Int32& nIndex, const uno::Sequence< beans::PropertyValue >& rSeqPropValue )
+{
+ rtl::OUString aCommand;
+ nIndex = -1;
+
+ for ( sal_Int32 i = 0; i < rSeqPropValue.getLength(); i++ )
+ {
+ if ( rSeqPropValue[i].Name.equalsAsciiL( "Command", 7 ))
+ {
+ rSeqPropValue[i].Value >>= rCommand;
+ nIndex = i;
+ return;
+ }
+ }
+}
+
+static void ConvertSlotsToCommands( SfxObjectShell* pDoc, uno::Reference< container::XIndexContainer >& rToolbarDefinition )
+{
+ if ( pDoc )
+ {
+ Any aAny;
+ SfxModule* pModule( pDoc->GetFactory().GetModule() );
+ rtl::OUString aSlotCmd( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ rtl::OUString aUnoCmd( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
+ uno::Sequence< beans::PropertyValue > aSeqPropValue;
+
+ for ( sal_Int32 i = 0; i < rToolbarDefinition->getCount(); i++ )
+ {
+ sal_Int32 nIndex( -1 );
+ rtl::OUString aCommand;
+
+ if ( rToolbarDefinition->getByIndex( i ) >>= aSeqPropValue )
+ {
+ GetCommandFromSequence( aCommand, nIndex, aSeqPropValue );
+ if ( nIndex >= 0 && ( aCommand.indexOf( aSlotCmd ) == 0 ))
+ {
+ rtl::OUString aSlot( aCommand.copy( 5 ));
+
+ // We have to replace the old "slot-Command" with our new ".uno:-Command"
+ const SfxSlot* pSlot = pModule->GetSlotPool()->GetSlot( USHORT( aSlot.toInt32() ));
+ if ( pSlot )
+ {
+ rtl::OUStringBuffer aStrBuf( aUnoCmd );
+ aStrBuf.appendAscii( pSlot->GetUnoName() );
+
+ aCommand = aStrBuf.makeStringAndClear();
+ aSeqPropValue[nIndex].Value <<= aCommand;
+ rToolbarDefinition->replaceByIndex( i, Any( aSeqPropValue ));
+ }
+ }
+ }
+ }
+ }
+}
+
+uno::Reference< ui::XUIConfigurationManager > SAL_CALL SfxBaseModel::getUIConfigurationManager()
+ throw ( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( !m_pData->m_xUIConfigurationManager.is() )
+ {
+ uno::Reference< ui::XUIConfigurationManager > xNewUIConfMan(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.ui.UIConfigurationManager" )),
+ uno::UNO_QUERY );
+
+ Reference< ui::XUIConfigurationStorage > xUIConfigStorage( xNewUIConfMan, uno::UNO_QUERY );
+ if ( xUIConfigStorage.is() )
+ {
+ uno::Reference< XSTORAGE > xConfigStorage;
+
+ rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations2" ));
+ // First try to open with READWRITE and then READ
+ xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READWRITE );
+ if ( xConfigStorage.is() )
+ {
+ rtl::OUString aMediaTypeProp( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ));
+ rtl::OUString aUIConfigMediaType(
+ RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.xml.ui.configuration" ) );
+ rtl::OUString aMediaType;
+ uno::Reference< beans::XPropertySet > xPropSet( xConfigStorage, uno::UNO_QUERY );
+ Any a = xPropSet->getPropertyValue( aMediaTypeProp );
+ if ( !( a >>= aMediaType ) || ( aMediaType.getLength() == 0 ))
+ {
+ a <<= aUIConfigMediaType;
+ xPropSet->setPropertyValue( aMediaTypeProp, a );
+ }
+ }
+ else
+ xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READ );
+
+ // initialize ui configuration manager with document substorage
+ xUIConfigStorage->setStorage( xConfigStorage );
+
+ // embedded objects did not support local configuration data until OOo 3.0, so there's nothing to
+ // migrate
+ if ( m_pData->m_pObjectShell->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
+ {
+ // Import old UI configuration from OOo 1.x
+ uno::Reference< XSTORAGE > xOOo1ConfigStorage;
+ rtl::OUString aOOo1UIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations" ));
+
+ // Try to open with READ
+ xOOo1ConfigStorage = getDocumentSubStorage( aOOo1UIConfigFolderName, embed::ElementModes::READ );
+ if ( xOOo1ConfigStorage.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xServiceMgr( ::comphelper::getProcessServiceFactory() );
+ uno::Sequence< uno::Reference< container::XIndexContainer > > rToolbars;
+
+ sal_Bool bImported = UIConfigurationImporterOOo1x::ImportCustomToolbars(
+ xNewUIConfMan, rToolbars, xServiceMgr, xOOo1ConfigStorage );
+ if ( bImported )
+ {
+ SfxObjectShell* pObjShell = SfxBaseModel::GetObjectShell();
+
+ char aNum[] = "private:resource/toolbar/custom_OOo1x_0";
+ char aTitle[] = "Toolbar 0";
+ sal_Int32 nNumIndex = strlen( aNum )-1;
+ sal_Int32 nTitleIndex = strlen( aTitle )-1;
+ for ( sal_Int32 i = 0; i < rToolbars.getLength(); i++ )
+ {
+ aNum[nNumIndex]++;
+ aTitle[nTitleIndex]++;
+
+ rtl::OUString aCustomTbxName( RTL_CONSTASCII_USTRINGPARAM( aNum ));
+ rtl::OUString aCustomTbxTitle( RTL_CONSTASCII_USTRINGPARAM( aTitle ));
+
+ uno::Reference< container::XIndexContainer > xToolbar = rToolbars[i];
+ ConvertSlotsToCommands( pObjShell, xToolbar );
+ if ( !xNewUIConfMan->hasSettings( aCustomTbxName ))
+ {
+ // Set UIName for the toolbar with container property
+ uno::Reference< beans::XPropertySet > xPropSet( xToolbar, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ));
+ Any aAny( aCustomTbxTitle );
+ xPropSet->setPropertyValue( aPropName, aAny );
+ }
+ catch ( beans::UnknownPropertyException& )
+ {
+ }
+ }
+
+ uno::Reference< container::XIndexAccess > xToolbarData( xToolbar, uno::UNO_QUERY );
+ xNewUIConfMan->insertSettings( aCustomTbxName, xToolbarData );
+ uno::Reference< ui::XUIConfigurationPersistence > xPersist( xNewUIConfMan, uno::UNO_QUERY );
+ xPersist->store();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ m_pData->m_xUIConfigurationManager = xNewUIConfMan;
+ }
+
+ return m_pData->m_xUIConfigurationManager;
+}
+
+//____________________________________________________________________________________________________
+// XVisualObject
+//____________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::setVisualAreaSize( sal_Int64 nAspect, const awt::Size& aSize )
+ throw ( lang::IllegalArgumentException,
+ embed::WrongStateException,
+ uno::Exception,
+ uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw uno::Exception(); // TODO: error handling
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False );
+ if ( pViewFrm && m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && !pViewFrm->GetFrame().IsInPlace() )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( pViewFrm->GetFrame().GetFrameInterface()->getContainerWindow() );
+ Size aWinSize = pWindow->GetSizePixel();
+ awt::Size aCurrent = getVisualAreaSize( nAspect );
+ Size aDiff( aSize.Width-aCurrent.Width, aSize.Height-aCurrent.Height );
+ Size aWrongDiff = OutputDevice::LogicToLogic( aDiff , m_pData->m_pObjectShell->GetMapUnit(), pWindow->GetMapMode() );
+ aDiff = pViewFrm->GetViewShell()->GetWindow()->LogicToPixel( aDiff );
+ aWinSize.Width() += aDiff.Width();
+ aWinSize.Height() += aDiff.Height();
+ pWindow->SetSizePixel( aWinSize );
+ }
+ else
+ {
+ Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
+ aTmpRect.SetSize( Size( aSize.Width, aSize.Height ) );
+ m_pData->m_pObjectShell->SetVisArea( aTmpRect );
+ }
+}
+
+awt::Size SAL_CALL SfxBaseModel::getVisualAreaSize( sal_Int64 /*nAspect*/ )
+ throw ( lang::IllegalArgumentException,
+ embed::WrongStateException,
+ uno::Exception,
+ uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw uno::Exception(); // TODO: error handling
+
+ Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
+
+#if 0
+ Window* pWindow = NULL;
+ SfxViewFrame* pViewFrm = m_pData->m_pObjectShell.Is() ?
+ SfxViewFrame::GetFirst( m_pData->m_pObjectShell, 0, sal_False ) : 0;
+
+ if ( pWindow )
+ {
+ MapMode aInternalMapMode( pViewFrm->GetWindow().GetMapMode() );
+ MapMode aExternalMapMode( m_pData->m_pObjectShell->GetMapUnit() );
+
+ aTmpRect = OutputDevice::LogicToLogic( aTmpRect, aInternalMapMode, aExternalMapMode );
+ }
+#endif
+
+ return awt::Size( aTmpRect.GetWidth(), aTmpRect.GetHeight() );
+}
+
+
+sal_Int32 SAL_CALL SfxBaseModel::getMapUnit( sal_Int64 /*nAspect*/ )
+ throw ( uno::Exception,
+ uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw uno::Exception(); // TODO: error handling
+
+ return VCLUnoHelper::VCL2UnoEmbedMapUnit( m_pData->m_pObjectShell->GetMapUnit() );
+}
+
+embed::VisualRepresentation SAL_CALL SfxBaseModel::getPreferredVisualRepresentation( ::sal_Int64 /*nAspect*/ )
+ throw ( lang::IllegalArgumentException,
+ embed::WrongStateException,
+ uno::Exception,
+ uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ datatransfer::DataFlavor aDataFlavor(
+ ::rtl::OUString::createFromAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ),
+ ::rtl::OUString::createFromAscii( "GDIMetaFile" ),
+ ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
+
+ embed::VisualRepresentation aVisualRepresentation;
+ aVisualRepresentation.Data = getTransferData( aDataFlavor );
+ aVisualRepresentation.Flavor = aDataFlavor;
+
+ return aVisualRepresentation;
+}
+
+//____________________________________________________________________________________________________
+// XStorageBasedDocument
+//____________________________________________________________________________________________________
+
+void SAL_CALL SfxBaseModel::loadFromStorage( const uno::Reference< XSTORAGE >& xStorage,
+ const uno::Sequence< beans::PropertyValue >& aMediaDescriptor )
+ throw ( lang::IllegalArgumentException,
+ DOUBLEINITIALIZATIONEXCEPTION,
+ IOEXCEPTION,
+ EXCEPTION,
+ uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+ if ( IsInitialized() )
+ throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this );
+
+ // after i36090 is fixed the pool from object shell can be used
+ // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
+ SfxAllItemSet aSet( SFX_APP()->GetPool() );
+
+ // the BaseURL is part of the ItemSet
+ SfxMedium* pMedium = new SfxMedium( xStorage, String() );
+ TransformParameters( SID_OPENDOC, aMediaDescriptor, aSet );
+ pMedium->GetItemSet()->Put( aSet );
+
+ // allow to use an interactionhandler (if there is one)
+ pMedium->UseInteractionHandler( TRUE );
+
+ SFX_ITEMSET_ARG( &aSet, pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
+ BOOL bTemplate = pTemplateItem && pTemplateItem->GetValue();
+ m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC );
+ m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = FALSE;
+
+ // load document
+ if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
+ {
+ sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode();
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ nError ? nError : ERRCODE_IO_CANTREAD );
+ }
+}
+
+void SAL_CALL SfxBaseModel::storeToStorage( const uno::Reference< XSTORAGE >& xStorage,
+ const uno::Sequence< beans::PropertyValue >& aMediaDescriptor )
+ throw ( lang::IllegalArgumentException,
+ IOEXCEPTION,
+ EXCEPTION,
+ uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< XSTORAGE > xResult;
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw IOEXCEPTION(); // TODO:
+
+ SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
+ TransformParameters( SID_SAVEASDOC, aMediaDescriptor, aSet );
+
+ // TODO/LATER: may be a special URL "private:storage" should be used
+ SFX_ITEMSET_ARG( &aSet, pItem, SfxStringItem, SID_FILTER_NAME, sal_False );
+ sal_Int32 nVersion = SOFFICE_FILEFORMAT_CURRENT;
+ if( pItem )
+ {
+ String aFilterName = pItem->GetValue();
+ const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4FilterName( aFilterName );
+ if ( pFilter && pFilter->UsesStorage() )
+ nVersion = pFilter->GetVersion();
+ }
+
+ sal_Bool bSuccess = sal_False;
+ if ( xStorage == m_pData->m_pObjectShell->GetStorage() )
+ {
+ // storing to the own storage
+ bSuccess = m_pData->m_pObjectShell->DoSave();
+ }
+ else
+ {
+ // TODO/LATER: if the provided storage has some data inside the storing might fail, probably the storage must be truncated
+ // TODO/LATER: is it possible to have a template here?
+ m_pData->m_pObjectShell->SetupStorage( xStorage, nVersion, sal_False );
+
+ // BaseURL is part of the ItemSet
+ SfxMedium aMedium( xStorage, String(), &aSet );
+ aMedium.CanDisposeStorage_Impl( FALSE );
+ if ( aMedium.GetFilter() )
+ {
+ // storing without a valid filter will often crash
+ bSuccess = m_pData->m_pObjectShell->DoSaveObjectAs( aMedium, TRUE );
+ m_pData->m_pObjectShell->DoSaveCompleted( NULL );
+ }
+ }
+
+ sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode();
+ m_pData->m_pObjectShell->ResetError();
+
+ // the warnings are currently not transported
+ if ( !bSuccess )
+ {
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ nError ? nError : ERRCODE_IO_GENERAL );
+ }
+}
+
+void SAL_CALL SfxBaseModel::switchToStorage( const uno::Reference< XSTORAGE >& xStorage )
+ throw ( lang::IllegalArgumentException,
+ IOEXCEPTION,
+ EXCEPTION,
+ uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< XSTORAGE > xResult;
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw IOEXCEPTION(); // TODO:
+
+ // the persistence should be switched only if the storage is different
+ if ( xStorage != m_pData->m_pObjectShell->GetStorage()
+ && !m_pData->m_pObjectShell->SwitchPersistance( xStorage ) )
+ {
+ sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode();
+ throw task::ErrorCodeIOException( ::rtl::OUString(),
+ uno::Reference< uno::XInterface >(),
+ nError ? nError : ERRCODE_IO_GENERAL );
+ }
+
+ m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = FALSE;
+}
+
+uno::Reference< XSTORAGE > SAL_CALL SfxBaseModel::getDocumentStorage()
+ throw ( IOEXCEPTION,
+ EXCEPTION,
+ uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ uno::Reference< XSTORAGE > xResult;
+ if ( !m_pData->m_pObjectShell.Is() )
+ throw IOEXCEPTION(); // TODO
+
+ return m_pData->m_pObjectShell->GetStorage();
+}
+
+void SAL_CALL SfxBaseModel::addStorageChangeListener(
+ const uno::Reference< document::XStorageChangeListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+
+ m_pData->m_aInterfaceContainer.addInterface(
+ ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener );
+}
+
+void SAL_CALL SfxBaseModel::removeStorageChangeListener(
+ const uno::Reference< document::XStorageChangeListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ m_pData->m_aInterfaceContainer.removeInterface(
+ ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener );
+}
+
+#include "printhelper.hxx"
+bool SfxBaseModel::impl_getPrintHelper()
+{
+ if ( m_pData->m_xPrintable.is() )
+ return true;
+ m_pData->m_xPrintable = new SfxPrintHelper();
+ uno::Reference < lang::XInitialization > xInit( m_pData->m_xPrintable, uno::UNO_QUERY );
+ uno::Sequence < uno::Any > aValues(1);
+ aValues[0] <<= uno::Reference < frame::XModel > (static_cast< frame::XModel* >(this), uno::UNO_QUERY );
+ xInit->initialize( aValues );
+ uno::Reference < view::XPrintJobBroadcaster > xBrd( m_pData->m_xPrintable, uno::UNO_QUERY );
+ xBrd->addPrintJobListener( new SfxPrintHelperListener_Impl( m_pData ) );
+ return true;
+}
+
+//=============================================================================
+// css.frame.XModule
+ void SAL_CALL SfxBaseModel::setIdentifier(const ::rtl::OUString& Identifier)
+ throw (css::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+ m_pData->m_sModuleIdentifier = Identifier;
+}
+
+//=============================================================================
+// css.frame.XModule
+ ::rtl::OUString SAL_CALL SfxBaseModel::getIdentifier()
+ throw (css::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+ if (m_pData->m_sModuleIdentifier.getLength() > 0)
+ return m_pData->m_sModuleIdentifier;
+ if (m_pData->m_pObjectShell)
+ return m_pData->m_pObjectShell->GetFactory().GetDocumentServiceName();
+ return ::rtl::OUString();
+}
+
+//=============================================================================
+css::uno::Reference< css::frame::XTitle > SfxBaseModel::impl_getTitleHelper ()
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( ! m_pData->m_xTitleHelper.is ())
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory ();
+ css::uno::Reference< css::frame::XUntitledNumbers > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::frame::XModel > xThis (static_cast< css::frame::XModel* >(this), css::uno::UNO_QUERY_THROW);
+
+ ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(xSMGR);
+ m_pData->m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
+ pHelper->setOwner (xThis );
+ pHelper->connectWithUntitledNumbers (xDesktop);
+ }
+
+ return m_pData->m_xTitleHelper;
+}
+
+//=============================================================================
+css::uno::Reference< css::frame::XUntitledNumbers > SfxBaseModel::impl_getUntitledHelper ()
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( ! m_pData->m_xNumberedControllers.is ())
+ {
+ css::uno::Reference< css::frame::XModel > xThis (static_cast< css::frame::XModel* >(this), css::uno::UNO_QUERY_THROW);
+ ::comphelper::NumberedCollection* pHelper = new ::comphelper::NumberedCollection();
+
+ m_pData->m_xNumberedControllers = css::uno::Reference< css::frame::XUntitledNumbers >(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
+
+ pHelper->setOwner (xThis);
+ pHelper->setUntitledPrefix (::rtl::OUString::createFromAscii(" : "));
+ }
+
+ return m_pData->m_xNumberedControllers;
+}
+
+//=============================================================================
+// css.frame.XTitle
+::rtl::OUString SAL_CALL SfxBaseModel::getTitle()
+ throw (css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ SfxModelGuard aGuard( *this );
+
+ ::rtl::OUString aResult = impl_getTitleHelper()->getTitle ();
+ if ( m_pData->m_pObjectShell )
+ {
+ SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
+ if ( pMedium )
+ {
+ SFX_ITEMSET_ARG( pMedium->GetItemSet(), pRepairedDocItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False );
+ if ( pRepairedDocItem && pRepairedDocItem->GetValue() )
+ aResult += String( SfxResId(STR_REPAIREDDOCUMENT) );
+ }
+
+ if ( m_pData->m_pObjectShell->IsReadOnlyUI() || (m_pData->m_pObjectShell->GetMedium() && m_pData->m_pObjectShell->GetMedium()->IsReadOnly()) )
+ aResult += ::rtl::OUString( String( SfxResId(STR_READONLY) ) );
+ else if ( m_pData->m_pObjectShell->IsDocShared() )
+ aResult += ::rtl::OUString( String( SfxResId(STR_SHARED) ) );
+
+ if ( m_pData->m_pObjectShell->GetDocumentSignatureState() == SIGNATURESTATE_SIGNATURES_OK )
+ aResult += String( SfxResId( RID_XMLSEC_DOCUMENTSIGNED ) );
+ }
+
+ return aResult;
+}
+
+//=============================================================================
+// css.frame.XTitle
+void SAL_CALL SfxBaseModel::setTitle( const ::rtl::OUString& sTitle )
+ throw (css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ SfxModelGuard aGuard( *this );
+
+ impl_getTitleHelper()->setTitle (sTitle);
+}
+
+//=============================================================================
+// css.frame.XTitleChangeBroadcaster
+void SAL_CALL SfxBaseModel::addTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
+ throw (css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
+
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY);
+ if (xBroadcaster.is ())
+ xBroadcaster->addTitleChangeListener (xListener);
+}
+
+//=============================================================================
+// css.frame.XTitleChangeBroadcaster
+void SAL_CALL SfxBaseModel::removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
+ throw (css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ SfxModelGuard aGuard( *this );
+
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY);
+ if (xBroadcaster.is ())
+ xBroadcaster->removeTitleChangeListener (xListener);
+}
+
+//=============================================================================
+// css.frame.XUntitledNumbers
+::sal_Int32 SAL_CALL SfxBaseModel::leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent )
+ throw (css::lang::IllegalArgumentException,
+ css::uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+
+ return impl_getUntitledHelper ()->leaseNumber (xComponent);
+}
+
+//=============================================================================
+// css.frame.XUntitledNumbers
+void SAL_CALL SfxBaseModel::releaseNumber( ::sal_Int32 nNumber )
+ throw (css::lang::IllegalArgumentException,
+ css::uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+ impl_getUntitledHelper ()->releaseNumber (nNumber);
+}
+
+//=============================================================================
+// css.frame.XUntitledNumbers
+void SAL_CALL SfxBaseModel::releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent )
+ throw (css::lang::IllegalArgumentException,
+ css::uno::RuntimeException )
+{
+ SfxModelGuard aGuard( *this );
+ impl_getUntitledHelper ()->releaseNumberForComponent (xComponent);
+}
+
+//=============================================================================
+// css.frame.XUntitledNumbers
+::rtl::OUString SAL_CALL SfxBaseModel::getUntitledPrefix()
+ throw (css::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+ return impl_getUntitledHelper ()->getUntitledPrefix ();
+}
+
+//=============================================================================
+// css::frame::XModel2
+css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxBaseModel::getControllers()
+ throw (css::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ sal_Int32 c = m_pData->m_seqControllers.getLength();
+ sal_Int32 i = 0;
+ css::uno::Sequence< css::uno::Any > lEnum(c);
+ for (i=0; i<c; ++i)
+ lEnum[i] <<= m_pData->m_seqControllers[i];
+
+ ::comphelper::OAnyEnumeration* pEnum = new ::comphelper::OAnyEnumeration(lEnum);
+ css::uno::Reference< css::container::XEnumeration > xEnum(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY_THROW);
+ return xEnum;
+}
+
+//=============================================================================
+// css::frame::XModel2
+css::uno::Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getAvailableViewControllerNames()
+ throw (css::uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory();
+ const sal_Int32 nViewFactoryCount = rDocumentFactory.GetViewFactoryCount();
+
+ Sequence< ::rtl::OUString > aViewNames( nViewFactoryCount );
+ for ( sal_Int32 nViewNo = 0; nViewNo < nViewFactoryCount; ++nViewNo )
+ aViewNames[nViewNo] = rDocumentFactory.GetViewFactory( nViewNo ).GetViewName();
+ return aViewNames;
+}
+
+//=============================================================================
+// css::frame::XModel2
+css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createDefaultViewController( const css::uno::Reference< css::frame::XFrame >& i_rFrame )
+ throw (css::uno::RuntimeException ,
+ css::lang::IllegalArgumentException,
+ css::uno::Exception )
+{
+ SfxModelGuard aGuard( *this );
+
+ const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory();
+ const ::rtl::OUString sDefaultViewName = rDocumentFactory.GetViewFactory( 0 ).GetViewName();
+
+ aGuard.clear();
+
+ return createViewController( sDefaultViewName, Sequence< PropertyValue >(), i_rFrame );
+}
+
+//=============================================================================
+namespace sfx { namespace intern {
+
+ /** a class which, in its dtor, cleans up variuos objects (well, at the moment only the frame) collected during
+ the creation of a document view, unless the creation was successful.
+ */
+ class SAL_DLLPRIVATE ViewCreationGuard
+ {
+ public:
+ ViewCreationGuard()
+ :m_bSuccess( false )
+ {
+ }
+
+ ~ViewCreationGuard()
+ {
+ if ( !m_bSuccess )
+ impl_closeAll();
+ }
+
+ void takeFrameOwnership( SfxFrame* i_pFrame )
+ {
+ OSL_PRECOND( !m_aWeakFrame, "ViewCreationGuard::takeFrameOwnership: already have a frame!" );
+ OSL_PRECOND( i_pFrame != NULL, "ViewCreationGuard::takeFrameOwnership: invalid frame!" );
+ m_aWeakFrame = i_pFrame;
+ }
+
+ void releaseAll()
+ {
+ m_bSuccess = true;
+ }
+
+ private:
+ void impl_closeAll()
+ {
+ if ( m_aWeakFrame && !m_aWeakFrame->GetCurrentDocument() )
+ {
+ m_aWeakFrame->SetFrameInterface_Impl( NULL );
+ m_aWeakFrame->DoClose();
+ }
+ }
+
+ private:
+ bool m_bSuccess;
+ SfxFrameWeak m_aWeakFrame;
+ };
+} }
+
+//=============================================================================
+SfxViewFrame* SfxBaseModel::FindOrCreateViewFrame_Impl( const Reference< XFrame >& i_rFrame, ::sfx::intern::ViewCreationGuard& i_rGuard ) const
+{
+ SfxViewFrame* pViewFrame = NULL;
+ for ( pViewFrame = SfxViewFrame::GetFirst( GetObjectShell(), FALSE );
+ pViewFrame;
+ pViewFrame= SfxViewFrame::GetNext( *pViewFrame, GetObjectShell(), FALSE )
+ )
+ {
+ if ( pViewFrame->GetFrame().GetFrameInterface() == i_rFrame )
+ break;
+ }
+ if ( !pViewFrame )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ for ( SfxFrame* pCheckFrame = SfxFrame::GetFirst();
+ pCheckFrame;
+ pCheckFrame = SfxFrame::GetNext( *pCheckFrame )
+ )
+ {
+ if ( pCheckFrame->GetFrameInterface() == i_rFrame )
+ {
+ if ( ( pCheckFrame->GetCurrentViewFrame() != NULL )
+ || ( pCheckFrame->GetCurrentDocument() != NULL )
+ )
+ // Note that it is perfectly letgitimate that during loading into an XFrame which already contains
+ // a document, there exist two SfxFrame instances bound to this XFrame - the old one, which will be
+ // destroyed later, and the new one, which we're going to create
+ continue;
+
+ OSL_ENSURE( false, "SfxBaseModel::FindOrCreateViewFrame_Impl: there already is an SfxFrame for the given XFrame, but no view in it!" );
+ // nowadays, we're the only instance allowed to create an SfxFrame for an XFrame, so this case here should not happen
+ break;
+ }
+ }
+ #endif
+
+ SfxFrame* pTargetFrame = SfxFrame::Create( i_rFrame );
+ ENSURE_OR_THROW( pTargetFrame, "could not create an SfxFrame" );
+ i_rGuard.takeFrameOwnership( pTargetFrame );
+
+ // prepare it
+ pTargetFrame->PrepareForDoc_Impl( *GetObjectShell() );
+
+ // create view frame
+ pViewFrame = new SfxViewFrame( *pTargetFrame, GetObjectShell() );
+ }
+ return pViewFrame;
+}
+
+//=============================================================================
+// css::frame::XModel2
+css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createViewController(
+ const ::rtl::OUString& i_rViewName, const Sequence< PropertyValue >& i_rArguments, const Reference< XFrame >& i_rFrame )
+ throw (css::uno::RuntimeException ,
+ css::lang::IllegalArgumentException,
+ css::uno::Exception )
+{
+ SfxModelGuard aGuard( *this );
+
+ if ( !i_rFrame.is() )
+ throw css::lang::IllegalArgumentException( ::rtl::OUString(), *this, 3 );
+
+ // find the proper SFX view factory
+ SfxViewFactory* pViewFactory = GetObjectShell()->GetFactory().GetViewFactoryByViewName( i_rViewName );
+ if ( !pViewFactory )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
+
+ // determine previous shell (used in some special cases)
+ Reference< XController > xPreviousController( i_rFrame->getController() );
+ const Reference< XModel > xMe( this );
+ if ( ( xPreviousController.is() )
+ && ( xMe != xPreviousController->getModel() )
+ )
+ {
+ xPreviousController.clear();
+ }
+ SfxViewShell* pOldViewShell = SfxViewShell::Get( xPreviousController );
+ OSL_ENSURE( !xPreviousController.is() || ( pOldViewShell != NULL ),
+ "SfxBaseModel::createViewController: invalid old controller!" );
+
+ // a guard which will clean up in case of failure
+ ::sfx::intern::ViewCreationGuard aViewCreationGuard;
+
+ // determine the ViewFrame belonging to the given XFrame
+ SfxViewFrame* pViewFrame = FindOrCreateViewFrame_Impl( i_rFrame, aViewCreationGuard );
+ OSL_POSTCOND( pViewFrame, "SfxBaseModel::createViewController: no frame?" );
+
+ // delegate to SFX' view factory
+ pViewFrame->GetBindings().ENTERREGISTRATIONS();
+ SfxViewShell* pViewShell = pViewFactory->CreateInstance( pViewFrame, pOldViewShell );
+ pViewFrame->GetBindings().LEAVEREGISTRATIONS();
+ ENSURE_OR_THROW( pViewShell, "invalid view shell provided by factory" );
+
+ // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also
+ pViewFrame->GetDispatcher()->SetDisableFlags( 0 );
+ pViewFrame->SetViewShell_Impl( pViewShell );
+
+ // remember ViewID
+ pViewFrame->SetCurViewId_Impl( pViewFactory->GetOrdinal() );
+
+ // ensure a default controller, if the view shell did not provide an own implementation
+ if ( !pViewShell->GetController().is() )
+ pViewShell->SetController( new SfxBaseController( pViewShell ) );
+
+ // pass the creation arguments to the controller
+ SfxBaseController* pBaseController = pViewShell->GetBaseController_Impl();
+ ENSURE_OR_THROW( pBaseController, "invalid controller implementation!" );
+ pBaseController->SetCreationArguments_Impl( i_rArguments );
+
+ // some initial view settings, coming from our most recent attachResource call
+ ::comphelper::NamedValueCollection aDocumentLoadArgs( getArgs() );
+ if ( aDocumentLoadArgs.getOrDefault( "ViewOnly", false ) )
+ pViewFrame->GetFrame().SetMenuBarOn_Impl( FALSE );
+
+ const sal_Int16 nPluginMode = aDocumentLoadArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) );
+ if ( nPluginMode == 1 )
+ {
+ pViewFrame->ForceOuterResize_Impl( FALSE );
+ pViewFrame->GetBindings().HidePopups( TRUE );
+
+ SfxFrame& rFrame = pViewFrame->GetFrame();
+ // MBA: layoutmanager of inplace frame starts locked and invisible
+ rFrame.GetWorkWindow_Impl()->MakeVisible_Impl( FALSE );
+ rFrame.GetWorkWindow_Impl()->Lock_Impl( TRUE );
+
+ rFrame.GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER );
+ pViewFrame->GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER );
+ }
+
+ // tell the guard we were successful
+ aViewCreationGuard.releaseAll();
+
+ // outta gere
+ return pBaseController;
+}
+
+//=============================================================================
+// RDF DocumentMetadataAccess
+
+// ::com::sun::star::rdf::XRepositorySupplier:
+uno::Reference< rdf::XRepository > SAL_CALL
+SfxBaseModel::getRDFRepository() throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->getRDFRepository();
+}
+
+// ::com::sun::star::rdf::XNode:
+::rtl::OUString SAL_CALL
+SfxBaseModel::getStringValue() throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->getStringValue();
+}
+
+// ::com::sun::star::rdf::XURI:
+::rtl::OUString SAL_CALL
+SfxBaseModel::getNamespace() throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->getNamespace();
+}
+
+::rtl::OUString SAL_CALL
+SfxBaseModel::getLocalName() throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->getLocalName();
+}
+
+// ::com::sun::star::rdf::XDocumentMetadataAccess:
+uno::Reference< rdf::XMetadatable > SAL_CALL
+SfxBaseModel::getElementByMetadataReference(
+ const ::com::sun::star::beans::StringPair & i_rReference)
+throw (uno::RuntimeException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->getElementByMetadataReference(i_rReference);
+}
+
+uno::Reference< rdf::XMetadatable > SAL_CALL
+SfxBaseModel::getElementByURI(const uno::Reference< rdf::XURI > & i_xURI)
+throw (uno::RuntimeException, lang::IllegalArgumentException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->getElementByURI(i_xURI);
+}
+
+uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL
+SfxBaseModel::getMetadataGraphsWithType(
+ const uno::Reference<rdf::XURI> & i_xType)
+throw (uno::RuntimeException, lang::IllegalArgumentException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->getMetadataGraphsWithType(i_xType);
+}
+
+uno::Reference<rdf::XURI> SAL_CALL
+SfxBaseModel::addMetadataFile(const ::rtl::OUString & i_rFileName,
+ const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ container::ElementExistException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->addMetadataFile(i_rFileName, i_rTypes);
+}
+
+uno::Reference<rdf::XURI> SAL_CALL
+SfxBaseModel::importMetadataFile(::sal_Int16 i_Format,
+ const uno::Reference< io::XInputStream > & i_xInStream,
+ const ::rtl::OUString & i_rFileName,
+ const uno::Reference< rdf::XURI > & i_xBaseURI,
+ const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ datatransfer::UnsupportedFlavorException,
+ container::ElementExistException, rdf::ParseException, io::IOException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->importMetadataFile(i_Format,
+ i_xInStream, i_rFileName, i_xBaseURI, i_rTypes);
+}
+
+void SAL_CALL
+SfxBaseModel::removeMetadataFile(
+ const uno::Reference< rdf::XURI > & i_xGraphName)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ container::NoSuchElementException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->removeMetadataFile(i_xGraphName);
+}
+
+void SAL_CALL
+SfxBaseModel::addContentOrStylesFile(const ::rtl::OUString & i_rFileName)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ container::ElementExistException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->addContentOrStylesFile(i_rFileName);
+}
+
+void SAL_CALL
+SfxBaseModel::removeContentOrStylesFile(const ::rtl::OUString & i_rFileName)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ container::NoSuchElementException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->removeContentOrStylesFile(i_rFileName);
+}
+
+void SAL_CALL
+SfxBaseModel::loadMetadataFromStorage(
+ uno::Reference< embed::XStorage > const & i_xStorage,
+ uno::Reference<rdf::XURI> const & i_xBaseURI,
+ uno::Reference<task::XInteractionHandler> const & i_xHandler)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(
+ m_pData->CreateDMAUninitialized());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ try {
+ xDMA->loadMetadataFromStorage(i_xStorage, i_xBaseURI, i_xHandler);
+ } catch (lang::IllegalArgumentException &) {
+ throw; // not initialized
+ } catch (uno::Exception &) {
+ // UGLY: if it's a RuntimeException, we can't be sure DMA is initialzed
+ m_pData->m_xDocumentMetadata = xDMA;
+ throw;
+ }
+ m_pData->m_xDocumentMetadata = xDMA;
+
+}
+
+void SAL_CALL
+SfxBaseModel::storeMetadataToStorage(
+ uno::Reference< embed::XStorage > const & i_xStorage)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->storeMetadataToStorage(i_xStorage);
+}
+
+void SAL_CALL
+SfxBaseModel::loadMetadataFromMedium(
+ const uno::Sequence< beans::PropertyValue > & i_rMedium)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(
+ m_pData->CreateDMAUninitialized());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ try {
+ xDMA->loadMetadataFromMedium(i_rMedium);
+ } catch (lang::IllegalArgumentException &) {
+ throw; // not initialized
+ } catch (uno::Exception &) {
+ // UGLY: if it's a RuntimeException, we can't be sure DMA is initialzed
+ m_pData->m_xDocumentMetadata = xDMA;
+ throw;
+ }
+ m_pData->m_xDocumentMetadata = xDMA;
+}
+
+void SAL_CALL
+SfxBaseModel::storeMetadataToMedium(
+ const uno::Sequence< beans::PropertyValue > & i_rMedium)
+throw (uno::RuntimeException, lang::IllegalArgumentException,
+ lang::WrappedTargetException)
+{
+ SfxModelGuard aGuard( *this );
+
+ const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
+ if (!xDMA.is()) {
+ throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
+ "model has no document metadata"), *this );
+ }
+
+ return xDMA->storeMetadataToMedium(i_rMedium);
+}
+
diff --git a/sfx2/source/doc/sfxmodelfactory.cxx b/sfx2/source/doc/sfxmodelfactory.cxx
new file mode 100644
index 000000000000..714dfc2ea824
--- /dev/null
+++ b/sfx2/source/doc/sfxmodelfactory.cxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+#include "sfx2/sfxmodelfactory.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/namedvaluecollection.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#include <algorithm>
+#include <functional>
+
+//........................................................................
+namespace sfx2
+{
+//........................................................................
+
+ /** === 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::lang::XMultiServiceFactory;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::lang::XSingleServiceFactory;
+ using ::com::sun::star::lang::XServiceInfo;
+ using ::com::sun::star::beans::NamedValue;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::lang::XInitialization;
+ /** === end UNO using === **/
+
+ //====================================================================
+ //= SfxModelFactory - declaration
+ //====================================================================
+ typedef ::cppu::WeakImplHelper2 < XSingleServiceFactory
+ , XServiceInfo
+ > SfxModelFactory_Base;
+ /** implements a XSingleServiceFactory which can be used to created instances
+ of classes derived from SfxBaseModel
+
+ In opposite to the default implementations from module cppuhelper, this
+ factory evaluates certain creation arguments (passed to createInstanceWithArguments)
+ and passes them to the factory function of the derived class.
+ */
+ class SfxModelFactory : public SfxModelFactory_Base
+ {
+ public:
+ SfxModelFactory(
+ const Reference< XMultiServiceFactory >& _rxServiceFactory,
+ const ::rtl::OUString& _rImplementationName,
+ const SfxModelFactoryFunc _pComponentFactoryFunc,
+ const Sequence< ::rtl::OUString >& _rServiceNames
+ );
+
+ // XSingleServiceFactory
+ virtual Reference< XInterface > SAL_CALL createInstance( ) throw (Exception, RuntimeException);
+ virtual Reference< XInterface > SAL_CALL createInstanceWithArguments( const Sequence< Any >& aArguments ) throw (Exception, 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);
+
+ protected:
+ virtual ~SfxModelFactory();
+
+ private:
+ Reference< XInterface > impl_createInstance( const sal_uInt64 _nCreationFlags ) const;
+
+ private:
+ const Reference< XMultiServiceFactory > m_xServiceFactory;
+ const ::rtl::OUString m_sImplementationName;
+ const Sequence< ::rtl::OUString > m_aServiceNames;
+ const SfxModelFactoryFunc m_pComponentFactoryFunc;
+ };
+
+ //====================================================================
+ //= SfxModelFactory - implementation
+ //====================================================================
+ //--------------------------------------------------------------------
+ SfxModelFactory::SfxModelFactory( const Reference< XMultiServiceFactory >& _rxServiceFactory,
+ const ::rtl::OUString& _rImplementationName, const SfxModelFactoryFunc _pComponentFactoryFunc,
+ const Sequence< ::rtl::OUString >& _rServiceNames )
+ :m_xServiceFactory( _rxServiceFactory )
+ ,m_sImplementationName( _rImplementationName )
+ ,m_aServiceNames( _rServiceNames )
+ ,m_pComponentFactoryFunc( _pComponentFactoryFunc )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ SfxModelFactory::~SfxModelFactory()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XInterface > SfxModelFactory::impl_createInstance( const sal_uInt64 _nCreationFlags ) const
+ {
+ return (*m_pComponentFactoryFunc)( m_xServiceFactory, _nCreationFlags );
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL SfxModelFactory::createInstance( ) throw (Exception, RuntimeException)
+ {
+ return createInstanceWithArguments( Sequence< Any >() );
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ struct IsSpecialArgument : public ::std::unary_function< Any, bool >
+ {
+ static bool isSpecialArgumentName( const ::rtl::OUString& _rValueName )
+ {
+ return _rValueName.equalsAscii( "EmbeddedObject" )
+ || _rValueName.equalsAscii( "EmbeddedScriptSupport" )
+ || _rValueName.equalsAscii( "DocumentRecoverySupport" );
+ }
+
+ bool operator()( const Any& _rArgument ) const
+ {
+ NamedValue aNamedValue;
+ if ( ( _rArgument >>= aNamedValue ) && isSpecialArgumentName( aNamedValue.Name ) )
+ return true;
+ PropertyValue aPropertyValue;
+ if ( ( _rArgument >>= aPropertyValue ) && isSpecialArgumentName( aPropertyValue.Name ) )
+ return true;
+ return false;
+ }
+ };
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL SfxModelFactory::createInstanceWithArguments( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
+ {
+ ::comphelper::NamedValueCollection aArgs( _rArguments );
+ const sal_Bool bEmbeddedObject = aArgs.getOrDefault( "EmbeddedObject", sal_False );
+ const sal_Bool bScriptSupport = aArgs.getOrDefault( "EmbeddedScriptSupport", sal_True );
+ const sal_Bool bDocRecoverySupport = aArgs.getOrDefault( "DocumentRecoverySupport", sal_True );
+
+ sal_uInt64 nCreationFlags =
+ ( bEmbeddedObject ? SFXMODEL_EMBEDDED_OBJECT : 0 )
+ | ( bScriptSupport ? 0 : SFXMODEL_DISABLE_EMBEDDED_SCRIPTS )
+ | ( bDocRecoverySupport ? 0 : SFXMODEL_DISABLE_DOCUMENT_RECOVERY );
+
+ Reference< XInterface > xInstance( impl_createInstance( nCreationFlags ) );
+
+ // to mimic the bahaviour of the default factory's createInstanceWithArguments, we initialize
+ // the object with the given arguments, stripped by the three special ones
+ Sequence< Any > aStrippedArguments( _rArguments.getLength() );
+ Any* pStrippedArgs = aStrippedArguments.getArray();
+ Any* pStrippedArgsEnd = ::std::remove_copy_if(
+ _rArguments.getConstArray(),
+ _rArguments.getConstArray() + _rArguments.getLength(),
+ pStrippedArgs,
+ IsSpecialArgument()
+ );
+ aStrippedArguments.realloc( pStrippedArgsEnd - pStrippedArgs );
+
+ if ( aStrippedArguments.getLength() )
+ {
+ Reference< XInitialization > xModelInit( xInstance, UNO_QUERY );
+ OSL_ENSURE( xModelInit.is(), "SfxModelFactory::createInstanceWithArguments: no XInitialization!" );
+ if ( xModelInit.is() )
+ xModelInit->initialize( aStrippedArguments );
+ }
+
+ return xInstance;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL SfxModelFactory::getImplementationName( ) throw (RuntimeException)
+ {
+ return m_sImplementationName;
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Bool SAL_CALL SfxModelFactory::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
+ {
+ return ::std::find(
+ m_aServiceNames.getConstArray(),
+ m_aServiceNames.getConstArray() + m_aServiceNames.getLength(),
+ _rServiceName
+ ) != m_aServiceNames.getConstArray() + m_aServiceNames.getLength();
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL SfxModelFactory::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ return m_aServiceNames;
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XSingleServiceFactory > createSfxModelFactory( const Reference< XMultiServiceFactory >& _rxServiceFactory,
+ const ::rtl::OUString& _rImplementationName, const SfxModelFactoryFunc _pComponentFactoryFunc,
+ const Sequence< ::rtl::OUString >& _rServiceNames )
+ {
+ return new SfxModelFactory( _rxServiceFactory, _rImplementationName, _pComponentFactoryFunc, _rServiceNames );
+ }
+
+//........................................................................
+} // namespace sfx2
+//........................................................................
diff --git a/sfx2/source/doc/syspath.cxx b/sfx2/source/doc/syspath.cxx
new file mode 100755
index 000000000000..a1025370ed24
--- /dev/null
+++ b/sfx2/source/doc/syspath.cxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: shutdowniconw32.cxx,v $
+* $Revision: 1.48 $
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+// Comment out precompiled statement due to redefinition errors
+#include "precompiled_sfx2.hxx"
+
+#include "syspath.hxx"
+
+extern "C" bool GetUserTemplateLocation(sal_Unicode*, int nSize);
+
+bool SystemPath::GetUserTemplateLocation(sal_Unicode* pFolder, int nSize )
+{
+#ifdef WNT
+ return ::GetUserTemplateLocation( pFolder, nSize );
+#else
+ (void)pFolder;
+ (void)nSize;
+ return false;
+#endif
+}
diff --git a/sfx2/source/doc/syspath.hxx b/sfx2/source/doc/syspath.hxx
new file mode 100644
index 000000000000..015c16f18d26
--- /dev/null
+++ b/sfx2/source/doc/syspath.hxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: shutdowniconw32.cxx,v $
+* $Revision: 1.48 $
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General 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 __SYSPATH_HXX__
+#define __SYSPATH_HXX__
+//#pragma warning(disable:4917)
+
+#include <sfx2/dllapi.h>
+
+class SFX2_DLLPUBLIC SystemPath
+{
+public:
+ static bool GetUserTemplateLocation(sal_Unicode*, int nSize);
+};
+
+#endif
+
diff --git a/sfx2/source/doc/syspathw32.cxx b/sfx2/source/doc/syspathw32.cxx
new file mode 100644
index 000000000000..73bd84f5249a
--- /dev/null
+++ b/sfx2/source/doc/syspathw32.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: shutdowniconw32.cxx,v $
+* $Revision: 1.48 $
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+************************************************************************/
+
+#ifdef WNT
+#ifdef _MSC_VER
+#pragma warning(disable:4917)
+#endif
+#include <shlobj.h>
+
+static bool _SHGetSpecialFolderW32( int nFolderID, WCHAR* pszFolder, int nSize )
+{
+ LPITEMIDLIST pidl;
+ HRESULT hHdl = SHGetSpecialFolderLocation( NULL, nFolderID, &pidl );
+
+ if( hHdl == NOERROR )
+ {
+ WCHAR *lpFolder = static_cast< WCHAR* >( HeapAlloc( GetProcessHeap(), 0, 16000 ));
+
+ SHGetPathFromIDListW( pidl, lpFolder );
+ wcsncpy( pszFolder, lpFolder, nSize );
+
+ HeapFree( GetProcessHeap(), 0, lpFolder );
+ IMalloc *pMalloc;
+ if( NOERROR == SHGetMalloc(&pMalloc) )
+ {
+ pMalloc->Free( pidl );
+ pMalloc->Release();
+ }
+ }
+ return true;
+}
+
+#endif
+
+// Copied from sal/types.h to circumvent problems with precompiled headers
+// and redefinitions of BOOL, INT32 and other types. Unfortunately tools
+// also define these type incompatible with Win32 types which leads from
+// time to time to very nasty compilation errors. If someone finds a better
+// way to solve these probs please remove this copied part!
+typedef unsigned short sal_uInt16;
+#if ( defined(WIN32) && !defined(__MINGW32__) )
+ typedef wchar_t sal_Unicode;
+#else
+ typedef sal_uInt16 sal_Unicode;
+#endif
+
+extern "C" bool GetUserTemplateLocation(sal_Unicode* pFolder, int nSize)
+{
+#ifdef WNT
+ return _SHGetSpecialFolderW32( CSIDL_TEMPLATES, pFolder, nSize );
+#else
+ (void)pFolder;
+ (void)nSize;
+ return false;
+#endif
+}