diff options
author | Norbert Thiebaud <nthiebaud@gmail.com> | 2012-09-01 09:49:15 -0500 |
---|---|---|
committer | Norbert Thiebaud <nthiebaud@gmail.com> | 2012-10-16 11:08:16 -0500 |
commit | 87293419e4ceea4db8104197ae001f1a087ea449 (patch) | |
tree | 9a707ff7f6d0c490d8d2b3a89e8e7d441d5b9ea7 /bf_so3 | |
parent | 4781be1277dfb218b66fb787e5ec9a2ed7d9011d (diff) |
move binfilter structure one directory up
Change-Id: I0d6772e8b1206f8bfdb43122a47958fecf586a40
Diffstat (limited to 'bf_so3')
57 files changed, 23301 insertions, 0 deletions
diff --git a/bf_so3/inc/absdev.hxx b/bf_so3/inc/absdev.hxx new file mode 100644 index 000000000..2c581fb6e --- /dev/null +++ b/bf_so3/inc/absdev.hxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef _SOT_ABSDEV_HXX +#define _SOT_ABSDEV_HXX + +#include <tools/solar.h> + +class JobSetup; +class AbstractDeviceData +{ +protected: + JobSetup * pJobSetup; +public: + virtual ~AbstractDeviceData() {} + virtual AbstractDeviceData * Copy() const = 0; + virtual sal_Bool Equals( const AbstractDeviceData & ) const = 0; + + JobSetup * GetJobSetup() const { return pJobSetup; } +}; + +#endif // _SOT_ABSDEV_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/inc/binddata.hxx b/bf_so3/inc/binddata.hxx new file mode 100644 index 000000000..00e913ef8 --- /dev/null +++ b/bf_so3/inc/binddata.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef _BINDDATA_HXX +#define _BINDDATA_HXX + +#include <bf_svtools/bf_solar.h> +#include <bf_tools/string.hxx> +#include <vector> + +namespace binfilter +{ + +class SvBindingTransportFactory; +typedef ::std::vector< SvBindingTransportFactory* > SvBindingTransportFactoryList; + +class SvLockBytesFactory; +typedef ::std::vector< SvLockBytesFactory* > SvLockBytesFactoryList; + +class SvBindingData_Impl; + +/*======================================================================== + * + * SvBindingData interface. + * + *======================================================================*/ +struct SvBindingData +{ + /** Representation. + */ + SvBindingTransportFactoryList m_aTransportFactories; + SvLockBytesFactoryList m_aLockBytesFactories; + + SvBindingData_Impl *m_pImpl; + + /** Construction/Destruction. + */ + SvBindingData (void); + ~SvBindingData (void); + + /** Get/Delete. + */ + static SvBindingData* Get (void); + static void Delete (void); + + /** HasHttpCache. + */ + BOOL HasHttpCache (void); + + /** ShouldUseFtpProxy. + */ + BOOL ShouldUseFtpProxy (const String &rUrl); +}; + +#define BAPP() (SvBindingData::Get()) + +} + +#endif /* _BINDDATA_HXX */ + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/inc/insdlg.hxx b/bf_so3/inc/insdlg.hxx new file mode 100644 index 000000000..8f5951b64 --- /dev/null +++ b/bf_so3/inc/insdlg.hxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef _INSDLG_HXX +#define _INSDLG_HXX + +#include <tools/globname.hxx> +#include <bf_svtools/ownlist.hxx> +#include <bf_so3/so2ref.hxx> + +#include "bf_so3/so3dllapi.h" + +class SvAppletObject; + +#ifndef SV_DECL_SVBASELINK2_DEFINED +#define SV_DECL_SVBASELINK2_DEFINED +SV_DECL_REF(SvBaseLink2) +#endif + +namespace binfilter +{ +#ifndef SO2_DECL_SVINPLACEOBJECT_DEFINED +#define SO2_DECL_SVINPLACEOBJECT_DEFINED +SO2_DECL_REF(SvInPlaceObject) +#endif + +/********************** SvObjectServer *********************************** +*************************************************************************/ +class SO3_DLLPUBLIC SvObjectServer +{ +private: + SvGlobalName aClassName; + String aHumanName; + +public: + SvObjectServer( const SvGlobalName & rClassP, const String & rHumanP ) : + aClassName( rClassP ), + aHumanName( rHumanP ) {} + + const SvGlobalName & GetClassName() const { return aClassName; } + const String & GetHumanName() const { return aHumanName; } +}; + +class SO3_DLLPRIVATE SvObjectServerList +{ + PRV_SV_DECL_OWNER_LIST(SvObjectServerList,SvObjectServer) + SO3_DLLPRIVATE const SvObjectServer * Get( const SvGlobalName & ) const; + SO3_DLLPRIVATE void Remove( const SvGlobalName & ); + + SO3_DLLPRIVATE void FillInsertObjects(); +}; + +} // namespace so3 + +#endif // _INSDLG_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/inc/soimpl.hxx b/bf_so3/inc/soimpl.hxx new file mode 100644 index 000000000..16ba7971e --- /dev/null +++ b/bf_so3/inc/soimpl.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef _SOIMPL_HXX +#define _SOIMPL_HXX + +#include "absdev.hxx" +#include <vcl/jobset.hxx> + +namespace binfilter +{ + +/********************** JobSetupWrapper *********************************/ +class JobSetupWrapper : public AbstractDeviceData +{ +public: + JobSetup aJobSetup; + + JobSetupWrapper( const JobSetup & rJS ); + virtual AbstractDeviceData * Copy() const; + virtual BOOL Equals( const AbstractDeviceData & rAD ) const; +}; + +} + +#endif // _SOIMPL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/inc/svuidlg.hrc b/bf_so3/inc/svuidlg.hrc new file mode 100644 index 000000000..8c95b875e --- /dev/null +++ b/bf_so3/inc/svuidlg.hrc @@ -0,0 +1,27 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#define BMP_PLUGIN 32000 +#define BMP_OLEOBJ 32001 + +// Strings +#define STR_ERROR_DDE 32013 +#define STR_VERB_OPEN 32016 +#define STR_QUERYUPDATELINKS 32022 +#define STR_VERB_PROPS 32025 +#define STR_FURTHER_OBJECT 32026 diff --git a/bf_so3/source/copied/makefile.mk b/bf_so3/source/copied/makefile.mk new file mode 100644 index 000000000..9264d22f6 --- /dev/null +++ b/bf_so3/source/copied/makefile.mk @@ -0,0 +1,29 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ := ..$/..$/.. +PRJNAME := binfilter +TARGET := so3_copied + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +SLOFILES = $(SLO)$/staticbaseurl.obj + +.INCLUDE: target.mk diff --git a/bf_so3/source/copied/staticbaseurl.cxx b/bf_so3/source/copied/staticbaseurl.cxx new file mode 100644 index 000000000..7cbb4ac02 --- /dev/null +++ b/bf_so3/source/copied/staticbaseurl.cxx @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "sal/config.h" + +#include "bf_so3/staticbaseurl.hxx" + +#include "com/sun/star/ucb/XCommandEnvironment.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "comphelper/processfactory.hxx" +#include "rtl/instance.hxx" +#include "rtl/textenc.h" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "bf_svtools/urihelper.hxx" +#include "tools/debug.hxx" +#include "bf_tools/string.hxx" +#include "tools/urlobj.hxx" +#include "ucbhelper/content.hxx" + +namespace { + +struct BaseURIRef: public rtl::Static< INetURLObject, BaseURIRef > {}; + +com::sun::star::uno::Any GetCasePreservedURL(INetURLObject const & aObj) { + DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); + if (aObj.GetProtocol() == INET_PROT_FILE) { + try { + com::sun::star::uno::Any aVoidArgument; + ucbhelper::Content aCnt( + aObj.GetMainURL(INetURLObject::NO_DECODE), + com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >(), + comphelper::getProcessComponentContext()); + return aCnt.executeCommand( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("getCasePreservingURL")), + aVoidArgument); + } catch (com::sun::star::uno::Exception &) { + DBG_WARNING("Any other exception"); + } + } + return com::sun::star::uno::Any(); +} + +} + +namespace binfilter { namespace StaticBaseUrl { + +String RelToAbs( + String const & rTheRelURIRef, bool bIgnoreFragment, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, rtl_TextEncoding eCharset, + INetURLObject::FSysStyle eStyle) +{ + // Backwards compatibility: + if (rTheRelURIRef.Len() == 0 || rTheRelURIRef.GetChar(0) == '#') { + return rTheRelURIRef; + } + INetURLObject aTheAbsURIRef; + return (BaseURIRef::get().GetNewAbsURL( + rTheRelURIRef, &aTheAbsURIRef, eEncodeMechanism, eCharset, + eStyle, bIgnoreFragment) + || eEncodeMechanism != INetURLObject::WAS_ENCODED + || eDecodeMechanism != INetURLObject::DECODE_TO_IURI + || eCharset != RTL_TEXTENCODING_UTF8) + ? String(aTheAbsURIRef.GetMainURL(eDecodeMechanism, eCharset)) + : rTheRelURIRef; +} + +String AbsToRel( + String const & rTheAbsURIRef, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, rtl_TextEncoding eCharset, + INetURLObject::FSysStyle eStyle) +{ + INetURLObject const & rINetURLObject = BaseURIRef::get(); + com::sun::star::uno::Any aAny; + if ( rINetURLObject.GetProtocol() != INET_PROT_NOT_VALID ) + aAny = GetCasePreservedURL(rINetURLObject); + rtl::OUString aBaseURL; + sal_Bool success = (aAny >>= aBaseURL); + if (success) { + INetURLObject aAbsURIRef(rTheAbsURIRef,eEncodeMechanism,eCharset); + com::sun::star::uno::Any aAny2(GetCasePreservedURL(aAbsURIRef)); + rtl::OUString aAbsURL; + success = (aAny2 >>= aAbsURL); + if (success) { + return INetURLObject::GetRelURL( + aBaseURL, aAbsURL, INetURLObject::WAS_ENCODED, eDecodeMechanism, + RTL_TEXTENCODING_UTF8, eStyle); + } else { + return INetURLObject::GetRelURL( + aBaseURL, rTheAbsURIRef, eEncodeMechanism, eDecodeMechanism, + eCharset, eStyle); + } + } else { + return INetURLObject::GetRelURL( + rINetURLObject.GetMainURL(INetURLObject::NO_DECODE), rTheAbsURIRef, + eEncodeMechanism, eDecodeMechanism, eCharset, eStyle); + } +} + +bool SetBaseURL( + String const & rTheBaseURIRef, INetURLObject::EncodeMechanism eMechanism, + rtl_TextEncoding eCharset) +{ + return BaseURIRef::get().SetURL(rTheBaseURIRef, eMechanism, eCharset); +} + +String GetBaseURL( + INetURLObject::DecodeMechanism eMechanism, rtl_TextEncoding eCharset) +{ + return BaseURIRef::get().GetMainURL(eMechanism, eCharset); +} + +String SmartRelToAbs( + String const & rTheRelURIRef, bool bIgnoreFragment, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, rtl_TextEncoding eCharset, + INetURLObject::FSysStyle eStyle) +{ + return ::binfilter::SmartRel2Abs( + INetURLObject(GetBaseURL()), rTheRelURIRef, + ::binfilter::GetMaybeFileHdl(), true, bIgnoreFragment, eEncodeMechanism, + eDecodeMechanism, eCharset, false, eStyle); +} + +} } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/data/makefile.mk b/bf_so3/source/data/makefile.mk new file mode 100644 index 000000000..207af10c9 --- /dev/null +++ b/bf_so3/source/data/makefile.mk @@ -0,0 +1,38 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. +SUBPRJ=..$/.. + +PRJNAME=binfilter +TARGET=so3_data + + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk +.INCLUDE : $(SUBPRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/pseudo.obj \ + + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/bf_so3/source/data/pseudo.cxx b/bf_so3/source/data/pseudo.cxx new file mode 100644 index 000000000..4a1f1ec86 --- /dev/null +++ b/bf_so3/source/data/pseudo.cxx @@ -0,0 +1,328 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <bf_so3/pseudo.hxx> +#include <tools/date.hxx> +#include <tools/debug.hxx> +#include <bf_tools/unqid.hxx> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/menu.hxx> +#include <bf_so3/embobj.hxx> +#include <bf_so3/client.hxx> +#include <bf_so3/svstor.hxx> +#include "bf_so3/soerr.hxx" + +namespace binfilter { + +//========================================================================= +//==================class SvVerb=========================================== +//========================================================================= +PRV_SV_IMPL_OWNER_LIST(SvVerbList,SvVerb) + +namespace +{ + UniqueItemId lclCreateUniqueId() + { + static UniqueIdContainer aUniqueIdContainer(UNIQUEID_SV_BEGIN); + return aUniqueIdContainer.CreateId(); + } +} + +//========================================================================= +SvVerb::SvVerb +( + long nIdP, /* Identifer des Verbs */ + const String & rNameP, /* Name des Verbs, sprachabh"angig */ + BOOL bConstP, /* TRUE, dieses Verb ver"andert das Objekt nicht */ + BOOL bOnMenuP /* TRUE, dieses Verb soll im Menu erscheinen */ +) +{ + nId = nIdP; + aName = rNameP; + aMenuId = lclCreateUniqueId(); + bConst = bConstP; + bOnMenu = bOnMenuP; +} + +//========================================================================= +SvVerb::SvVerb +( + const SvVerb & rObj +) +{ + nId = rObj.nId; + aName = rObj.aName; + aMenuId = rObj.aMenuId; + bConst = rObj.bConst; + bOnMenu = rObj.bOnMenu; +} + +//========================================================================= +SvVerb & SvVerb::operator = +( + const SvVerb & rObj +) +{ + if( this != &rObj ) + { + nId = rObj.nId; + aName = rObj.aName; + aMenuId = rObj.aMenuId; + bConst = rObj.bConst; + bOnMenu = rObj.bOnMenu; + } + return *this; +} + +//========================================================================= +SvVerb::~SvVerb() +{ + // UniqueId wird freigegeben +} + +//========================================================================= +//==================class SvPseudoObject=================================== +//========================================================================= +SV_IMPL_FACTORY(SvPseudoObjectFactory) + { + } +}; +TYPEINIT1(SvPseudoObjectFactory,SvFactory); + +SO2_IMPL_STANDARD_CLASS1_DLL(SvPseudoObject,SvPseudoObjectFactory,SvObject, + 0x2A499E61L, 0x733F, 0x101C, + 0x8D,0x86,0x4A,0x04,0x12,0x94,0x26,0x0D) +//========================================================================= +SvPseudoObject::SvPseudoObject() +/* [Beschreibung] + + Konstruktor der Klasse SvPseudoObject. +*/ + : pVerbs ( NULL ) + , bDeleteVerbs ( FALSE ) +{ +} + +//========================================================================= +SvPseudoObject::~SvPseudoObject() +/* [Beschreibung] + + Destruktor der Klasse SvPeudoObjekt. Das Objekt tr"agt sich selber + aus der <Running Object Table> aus. +*/ +{ + if( bDeleteVerbs ) // Selbst erzeugt ? + delete pVerbs; +} + +//========================================================================= +::IUnknown * SvPseudoObject::GetMemberInterface( const SvGlobalName & ) +/* [Beschreibung] + + Jede Klasse muss eine Abfrage auf die Ole-Interfaces unterst"utzen. + Es d"urfen nur die eigenen Ole-Interfaces und nicht die der + Super-Klassen abgefragt werden. Siehe <So Ole-Unterst"utzung>. +*/ +{ + return NULL; +} + +//========================================================================= +void SvPseudoObject::FillClass +( + SvGlobalName * pClassName, /* Der Typ der Klasse */ + ULONG * pFormat, /* Das Dateiformat in dem geschrieben wird */ + String * pAppName, /* Der Applikationsname */ + String * pFullTypeName, /* Der genaue Name des Typs */ + String * pShortTypeName, /* Der kurze Name des Typs */ + long /*nFileFormat */ /* F"ur dieses Office-Format sollen die + Parameter gef"ullt werden */ +) const +/* [Beschreibung] + + Diese Methode liefert Informationen "uber den Typ und das Dateiformat + des Objektes. Alle Parameter werden von der Methode gefuellt. + + [R"uckgabewert] + + *pClassName Liefert den Typ-Identifier des Objektes. + *pFormat Immer 0, siehe aber <SvEmbeddedObject::FillClass> + *pAppName Den sprachabh"angigen Applikationsnamen. + *pFullTypeName Den sprachabh"angigen Namen des Typs. + *pShortTypeName Den kurzen sprachabh"angigen Namen des Typs. Er darf + nicht l"anger als 15 Zeichen sein. + + [Beispiel] + + MyClass::FillClass( ... ) + { + *pClassName = *SvFactory::GetSvFactory(); // keine emulation + *pFormat = 0; + *pAppName = "StarDivison Calc 3.0"; + *pFullTypeName = "StarDivison Calc 3.0 Tabelle"; + *pShortTypeName = "Tabelle"; + } + + [Querverweise] + + <SvPersist::FillClass()> +*/ +{ + *pFormat = 0; + *pFullTypeName = *pShortTypeName = *pAppName = String(); + *pClassName = SvGlobalName(); + + if( Owner() ) + { + *pClassName = *GetSvFactory(); + *pAppName = Application::GetDisplayName(); + } +} + +//========================================================================= +SvGlobalName SvPseudoObject::GetClassName() const +/* [Beschreibung] + + Ruft <SvPseudoObject::FillClass> auf, um den Typ des Objektes zu bekommen. + + [R"uckgabewert] + + SvGlobalName Der Typ des Objektes. +*/ +{ + SvGlobalName aName; + String aAppName, aFullTypeName, aShortTypeName; + ULONG nFormat; + + FillClass( &aName, &nFormat, &aAppName, &aFullTypeName, + &aShortTypeName ); + return aName; +} + +//========================================================================= +ErrCode SvPseudoObject::Verb +( + long nVerb, /* Der Index in die Verbtabelle */ + SvEmbeddedClient * pCl, /* Die Container-Seite mit dem der + Objekt-Server ggf. kommuniziert. + */ + Window * pWin, /* Das Fenster in dem das Objekt + dargestellt wird. */ + const Rectangle * pWorkRectPixel /* Die Position und Gr"osse des + Objektes im Container */ +) +/* [Beschreibung] + + Der Objekt-Server wird mit nVerb beauftragt eine bestimmte Aktion + auszufuehren. Dies kann z.B. das Abspielen eines Sound's oder Video's + sein. Ebenso kann es das oeffnen und Anzeigen eines Dokumentes + bedeuten. Es gibt einige Default-Verben: + SVVERB_SHOW, Anzeigen des Objektes + SVVERB_OPEN, Anzeigen des Objektes im eigenen Dokumentfenster + SVVERB_HIDE, Das Objekt nicht mehr anzeigen. + SVVERB_UIACTIVATE, Das Objekt UI-Aktivieren. + SVVERB_IPACTIVATE, Das Objekt IP-Aktivieren. + + [Anmerkung] + Einige Verben machen nur IP-Aktivierung sinn. Mehr ueber IP-Aktivierung + in der Klasse <SvInPLaceObjekt>. + +*/ +{ + (void)nVerb; + (void)pCl; + (void)pWin; + (void)pWorkRectPixel; + + ErrCode nRet = ERRCODE_SO_GENERALERROR; + return nRet; +} + +//========================================================================= +BOOL SvPseudoObject::Close() +/* [Beschreibung] + + Versucht alle zum Objekt bestehenden Verbindungen abzubrechen. + + [Anmerkung] + + Handelt es sich um einen Link, dann muss die Verbindung zur Quelle + abgebrochen werden. +*/ +{ + return TRUE; +} + +//========================================================================= +void SvPseudoObject::SetVerbList +( + SvVerbList * pVerbsP /* die Verbliste wird "ubernommen, + sie darf nicht zerst"ort werden, bevor + sie nicht mit SetVerbList( NULL ) oder + automatisch im Destruktor ausgetragen wurde */ + , BOOL bDelete +) +/* [Beschreibung] + + Setzen der Verbliste, diese wird dann in + <SvPseudoObject::GetVerbList> zur"uckgegeben. +*/ +{ + if( bDeleteVerbs ) + delete pVerbs; + + bDeleteVerbs = bDelete; + pVerbs = pVerbsP; +} + + +//========================================================================= +const SvVerbList & SvPseudoObject::GetVerbList() const +/* [Beschreibung] + + Die Verbliste des Objektes wird zur"uckgegeben. +*/ +{ + if( pVerbs ) // darf, wegen Unique Id's nicht geaendert werden + return *pVerbs; + + ((SvPseudoObject *)this)->pVerbs = new SvVerbList(); + ((SvPseudoObject *)this)->bDeleteVerbs = TRUE; + + return *pVerbs; +} + +//========================================================================= +ULONG SvPseudoObject::GetMiscStatus() const +/* [Beschreibung] + + Diese Methode liefert weitere Informationen "uber das Objekt. +*/ +{ + ULONG nMisc = 0; + return nMisc; +} + + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/dialog/insdlg.cxx b/bf_so3/source/dialog/insdlg.cxx new file mode 100644 index 000000000..bb63e560f --- /dev/null +++ b/bf_so3/source/dialog/insdlg.cxx @@ -0,0 +1,189 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#define _INSDLG_CXX + +#include <stdio.h> +#include "insdlg.hxx" + +#include <tools/urlobj.hxx> +#include <tools/debug.hxx> +#include <bf_svtools/urihelper.hxx> +#include <vcl/button.hxx> +#include <vcl/fixed.hxx> +#include <vcl/group.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/svapp.hxx> + +#include <svuidlg.hrc> +#include <bf_so3/svstor.hxx> +#include <bf_so3/ipobj.hxx> +#include "bf_so3/plugin.hxx" +#include "bf_so3/applet.hxx" +#include "bf_so3/outplace.hxx" +#include "bf_so3/staticbaseurl.hxx" + +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <comphelper/processfactory.hxx> + +#include <osl/file.hxx> +#include <sot/stg.hxx> + +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <comphelper/processfactory.hxx> + +#define _SVSTDARR_STRINGSDTOR +#include <bf_svtools/svstdarr.hxx> + +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::rtl; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::ui::dialogs; + +namespace binfilter +{ + +/********************** SvObjectServerList ******************************** +**************************************************************************/ +PRV_SV_IMPL_OWNER_LIST( SvObjectServerList, SvObjectServer ) + +/************************************************************************* +|* SvObjectServerList::SvObjectServerList() +|* +|* Beschreibung +*************************************************************************/ +const SvObjectServer * SvObjectServerList::Get( const SvGlobalName & rName ) const +{ + for( ULONG i = 0; i < Count(); i++ ) + { + if( rName == GetObject( i ).GetClassName() ) + return &GetObject( i ); + } + return NULL; +} + +void SvObjectServerList::Remove( const SvGlobalName & rName ) +{ + SvObjectServer * pS = (SvObjectServer *)aTypes.First(); + while( pS ) + { + if( rName == pS->GetClassName() ) + { + Remove(); + pS = (SvObjectServer *)aTypes.GetCurObject(); + } + else + pS = (SvObjectServer *)aTypes.Next(); + } +} + +//--------------------------------------------------------------------- +void SvObjectServerList::FillInsertObjects() +/* [Beschreibung] + + Die Liste wird mit allen Typen gef"ullt, die im Insert-Dialog + ausgew"ahlt werden k"onnen. +*/ +{ + try{ + Reference< XMultiServiceFactory > _globalMSFactory= comphelper::getProcessServiceFactory(); + if( _globalMSFactory.is()) + { + OUString sProviderService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" )); + Reference<XMultiServiceFactory > sProviderMSFactory( + _globalMSFactory->createInstance( sProviderService ),UNO_QUERY ); + + if( sProviderMSFactory.is()) + { + OUString sReaderService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )); + Sequence< Any > aArguments( 1 ); + aArguments[0] <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Office.Common" )); + + Reference< XHierarchicalNameAccess > xHierNameAccess( + sProviderMSFactory->createInstanceWithArguments( sReaderService,aArguments ), + UNO_QUERY ); + + if( xHierNameAccess.is()) + { + OUString sTagName( RTL_CONSTASCII_USTRINGPARAM( "OfficeObjects" )); + Any _a= xHierNameAccess->getByHierarchicalName(sTagName); + Reference<XNameAccess> nameAccess; + _a >>= nameAccess; + if( nameAccess.is()) + { + Sequence<OUString> seqNames= nameAccess->getElementNames(); + OUString sSeparator( OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ))); + for(int i=0; i<seqNames.getLength(); i++) + { + + OUString sComponentName= sTagName + sSeparator + seqNames[i] + sSeparator + + OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" )); + OUString sKey= sTagName + sSeparator + seqNames[i] + sSeparator + + OUString( RTL_CONSTASCII_USTRINGPARAM( "Key" )); + Any anyName= xHierNameAccess->getByHierarchicalName(sComponentName); + Any anyKey= xHierNameAccess->getByHierarchicalName( sKey); + + anyName >>= sComponentName; + anyKey >>= sKey; + + SvGlobalName aClassName; + if( aClassName.MakeId( String(sKey.getStr()))) + { + if( !Get( aClassName ) ) + // noch nicht eingetragen + Append( SvObjectServer( aClassName, String( sComponentName.getStr() ) ) ); + + } + } + } + } + } + + } + + +#ifdef WNT + //SvGlobalName aOleFact = *SvOutPlaceObject::ClassFactory(); + //String aOleObj( SoResid( STR_FURTHER_OBJECT ) ); + //Append( SvObjectServer( aOleFact, aOleObj ) ); + OSL_FAIL( "non-working code!" ); + // TODO: dead corpses +#endif + + }catch( com::sun::star::container::NoSuchElementException) + { + }catch( ::com::sun::star::uno::Exception) + { + } + catch(...) + { + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/dialog/ipwin.cxx b/bf_so3/source/dialog/ipwin.cxx new file mode 100644 index 000000000..cb2b672a3 --- /dev/null +++ b/bf_so3/source/dialog/ipwin.cxx @@ -0,0 +1,762 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/accessibility/AccessibleRole.hpp> + +#include <bf_so3/ipenv.hxx> +#include <bf_so3/ipobj.hxx> +#include "bf_so3/ipwin.hxx" + +namespace binfilter { + +/************************************************************************/ +/************************************************************************* +|* SvResizeHelper::SvResizeHelper() +|* +|* Beschreibung +*************************************************************************/ +SvResizeHelper::SvResizeHelper() + : aBorder( 5, 5 ) + , nGrab( -1 ) + , bResizeable( TRUE ) +{ +} + +/************************************************************************* +|* SvResizeHelper::FillHandleRects() +|* +|* Beschreibung: Die acht Handles zum vergroessern +*************************************************************************/ +void SvResizeHelper::FillHandleRectsPixel( Rectangle aRects[ 8 ] ) const +{ + // nur wegen EMPTY_RECT + Point aBottomRight = aOuter.BottomRight(); + + // Links Oben + aRects[ 0 ] = Rectangle( aOuter.TopLeft(), aBorder ); + // Oben Mitte + aRects[ 1 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2, + aOuter.Top() ), + aBorder ); + // Oben Rechts + aRects[ 2 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, + aOuter.Top() ), + aBorder ); + // Mitte Rechts + aRects[ 3 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, + aOuter.Center().Y() - aBorder.Height() / 2 ), + aBorder ); + // Unten Rechts + aRects[ 4 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, + aBottomRight.Y() - aBorder.Height() +1 ), + aBorder ); + // Mitte Unten + aRects[ 5 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2, + aBottomRight.Y() - aBorder.Height() +1), + aBorder ); + // Links Unten + aRects[ 6 ] = Rectangle( Point( aOuter.Left(), + aBottomRight.Y() - aBorder.Height() +1), + aBorder ); + // Mitte Links + aRects[ 7 ] = Rectangle( Point( aOuter.Left(), + aOuter.Center().Y() - aBorder.Height() / 2 ), + aBorder ); +} + +/************************************************************************* +|* SvResizeHelper::FillMoveRectsPixel() +|* +|* Beschreibung: Die vier Kanten werden berechnet +*************************************************************************/ +void SvResizeHelper::FillMoveRectsPixel( Rectangle aRects[ 4 ] ) const +{ + // Oben + aRects[ 0 ] = aOuter; + aRects[ 0 ].Bottom() = aRects[ 0 ].Top() + aBorder.Height() -1; + // Rechts + aRects[ 1 ] = aOuter; + aRects[ 1 ].Left() = aRects[ 1 ].Right() - aBorder.Width() -1; + //Unten + aRects[ 2 ] = aOuter; + aRects[ 2 ].Top() = aRects[ 2 ].Bottom() - aBorder.Height() -1; + //Links + aRects[ 3 ] = aOuter; + aRects[ 3 ].Right() = aRects[ 3 ].Left() + aBorder.Width() -1; +} + +/************************************************************************* +|* SvResizeHelper::Draw() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeHelper::Draw( OutputDevice * pDev ) +{ + pDev->Push(); + pDev->SetMapMode( MapMode() ); + Color aColBlack; + Color aFillColor( COL_LIGHTGRAY ); + + pDev->SetFillColor( aFillColor ); + pDev->SetLineColor(); + + Rectangle aMoveRects[ 4 ]; + FillMoveRectsPixel( aMoveRects ); + USHORT i; + for( i = 0; i < 4; i++ ) + pDev->DrawRect( aMoveRects[ i ] ); + if( bResizeable ) + { + // Handles malen + pDev->SetFillColor( aColBlack ); + Rectangle aRects[ 8 ]; + FillHandleRectsPixel( aRects ); + for( i = 0; i < 8; i++ ) + pDev->DrawRect( aRects[ i ] ); + } + pDev->Pop(); +} + +/************************************************************************* +|* SvResizeHelper::InvalidateBorder() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeHelper::InvalidateBorder( Window * pWin ) +{ + Rectangle aMoveRects[ 4 ]; + FillMoveRectsPixel( aMoveRects ); + for( USHORT i = 0; i < 4; i++ ) + pWin->Invalidate( aMoveRects[ i ] ); +} + +/************************************************************************* +|* SvResizeHelper::SelectBegin() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvResizeHelper::SelectBegin( Window * pWin, const Point & rPos ) +{ + if( -1 == nGrab ) + { + nGrab = SelectMove( pWin, rPos ); + if( -1 != nGrab ) + { + aSelPos = rPos; // Start-Position merken + pWin->CaptureMouse(); + return TRUE; + } + } + return FALSE; +} + +/************************************************************************* +|* SvResizeHelper::SelectMove() +|* +|* Beschreibung +*************************************************************************/ +short SvResizeHelper::SelectMove( Window * pWin, const Point & rPos ) +{ + if( -1 == nGrab ) + { + if( bResizeable ) + { + Rectangle aRects[ 8 ]; + FillHandleRectsPixel( aRects ); + for( USHORT i = 0; i < 8; i++ ) + if( aRects[ i ].IsInside( rPos ) ) + return i; + } + // Move-Rect ueberlappen Handles + Rectangle aMoveRects[ 4 ]; + FillMoveRectsPixel( aMoveRects ); + for( USHORT i = 0; i < 4; i++ ) + if( aMoveRects[ i ].IsInside( rPos ) ) + return 8; + } + else + { + Rectangle aRect( GetTrackRectPixel( rPos ) ); + aRect.SetSize( pWin->PixelToLogic( aRect.GetSize() ) ); + aRect.SetPos( pWin->PixelToLogic( aRect.TopLeft() ) ); + pWin->ShowTracking( aRect ); + } + return nGrab; +} + +Point SvResizeHelper::GetTrackPosPixel( const Rectangle & rRect ) const +{ + // wie das Rechteck zurueckkommt ist egal, es zaehlt welches Handle + // initial angefasst wurde + Point aPos; + Rectangle aRect( rRect ); + aRect.Justify(); + // nur wegen EMPTY_RECT + Point aBR = aOuter.BottomRight(); + Point aTR = aOuter.TopRight(); + Point aBL = aOuter.BottomLeft(); + switch( nGrab ) + { + case 0: + aPos = aRect.TopLeft() - aOuter.TopLeft(); + break; + case 1: + aPos.Y() = aRect.Top() - aOuter.Top(); + break; + case 2: + aPos = aRect.TopRight() - aTR; + break; + case 3: + aPos.X() = aRect.Right() - aTR.X(); + break; + case 4: + aPos = aRect.BottomRight() - aBR; + break; + case 5: + aPos.Y() = aRect.Bottom() - aBR.Y(); + break; + case 6: + aPos = aRect.BottomLeft() - aBL; + break; + case 7: + aPos.X() = aRect.Left() - aOuter.Left(); + break; + case 8: + aPos = aRect.TopLeft() - aOuter.TopLeft(); + break; + } + return aPos += aSelPos; +} + +/************************************************************************* +|* SvResizeHelper::GetTrackRectPixel() +|* +|* Beschreibung +*************************************************************************/ +Rectangle SvResizeHelper::GetTrackRectPixel( const Point & rTrackPos ) const +{ + Rectangle aTrackRect; + if( -1 != nGrab ) + { + Point aDiff = rTrackPos - aSelPos; + aTrackRect = aOuter; + Point aBR = aOuter.BottomRight(); + switch( nGrab ) + { + case 0: + aTrackRect.Top() += aDiff.Y(); + aTrackRect.Left() += aDiff.X(); + break; + case 1: + aTrackRect.Top() += aDiff.Y(); + break; + case 2: + aTrackRect.Top() += aDiff.Y(); + aTrackRect.Right() = aBR.X() + aDiff.X(); + break; + case 3: + aTrackRect.Right() = aBR.X() + aDiff.X(); + break; + case 4: + aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); + aTrackRect.Right() = aBR.X() + aDiff.X(); + break; + case 5: + aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); + break; + case 6: + aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); + aTrackRect.Left() += aDiff.X(); + break; + case 7: + aTrackRect.Left() += aDiff.X(); + break; + case 8: + aTrackRect.SetPos( aTrackRect.TopLeft() + aDiff ); + break; + } + } + return aTrackRect; +} + +void SvResizeHelper::ValidateRect( Rectangle & rValidate ) const +{ + switch( nGrab ) + { + case 0: + if( rValidate.Top() > rValidate.Bottom() ) + { + rValidate.Top() = rValidate.Bottom(); + rValidate.Bottom() = RECT_EMPTY; + } + if( rValidate.Left() > rValidate.Right() ) + { + rValidate.Left() = rValidate.Right(); + rValidate.Right() = RECT_EMPTY; + } + break; + case 1: + if( rValidate.Top() > rValidate.Bottom() ) + { + rValidate.Top() = rValidate.Bottom(); + rValidate.Bottom() = RECT_EMPTY; + } + break; + case 2: + if( rValidate.Top() > rValidate.Bottom() ) + { + rValidate.Top() = rValidate.Bottom(); + rValidate.Bottom() = RECT_EMPTY; + } + if( rValidate.Left() > rValidate.Right() ) + rValidate.Right() = RECT_EMPTY; + break; + case 3: + if( rValidate.Left() > rValidate.Right() ) + rValidate.Right() = RECT_EMPTY; + break; + case 4: + if( rValidate.Top() > rValidate.Bottom() ) + rValidate.Bottom() = RECT_EMPTY; + if( rValidate.Left() > rValidate.Right() ) + rValidate.Right() = RECT_EMPTY; + break; + case 5: + if( rValidate.Top() > rValidate.Bottom() ) + rValidate.Bottom() = RECT_EMPTY; + break; + case 6: + if( rValidate.Top() > rValidate.Bottom() ) + rValidate.Bottom() = RECT_EMPTY; + if( rValidate.Left() > rValidate.Right() ) + { + rValidate.Left() = rValidate.Right(); + rValidate.Right() = RECT_EMPTY; + } + break; + case 7: + if( rValidate.Left() > rValidate.Right() ) + { + rValidate.Left() = rValidate.Right(); + rValidate.Right() = RECT_EMPTY; + } + break; + } + if( rValidate.Right() == RECT_EMPTY ) + rValidate.Right() = rValidate.Left(); + if( rValidate.Bottom() == RECT_EMPTY ) + rValidate.Bottom() = rValidate.Top(); + + // Mindestgr"osse 5 x 5 + if( rValidate.Left() + 5 > rValidate.Right() ) + rValidate.Right() = rValidate.Left() +5; + if( rValidate.Top() + 5 > rValidate.Bottom() ) + rValidate.Bottom() = rValidate.Top() +5; +} + +/************************************************************************* +|* SvResizeHelper::SelectRelease() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvResizeHelper::SelectRelease( Window * pWin, const Point & rPos, + Rectangle & rOutPosSize ) +{ + if( -1 != nGrab ) + { + rOutPosSize = GetTrackRectPixel( rPos ); + rOutPosSize.Justify(); + nGrab = -1; + pWin->ReleaseMouse(); + pWin->HideTracking(); + return TRUE; + } + return FALSE; +} + +/************************************************************************* +|* SvResizeHelper::Release() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeHelper::Release( Window * pWin ) +{ + if( nGrab != -1 ) + { + pWin->ReleaseMouse(); + pWin->HideTracking(); + nGrab = -1; + } +} +/************************************************************************/ +/************************************************************************* +|* SvResizeWindow::SvResizeWindow() +|* +|* Beschreibung +*************************************************************************/ +SvResizeWindow::SvResizeWindow +( + Window * pParent +) + : Window( pParent, WB_CLIPCHILDREN ) + , nMoveGrab( -1 ) + , pObjWin( NULL ) +{ + SetBackground(); + aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) ); +} + +/************************************************************************* +|* SvResizeWindow::AdjustObjWin() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::AdjustObjWin() +{ + if( pObjWin ) + { + Rectangle aRect = GetInnerRectPixel(); + pObjWin->SetPosSizePixel( aRect.TopLeft(), + aRect.GetSize() ); + } +} + +/************************************************************************* +|* SvResizeWindow::SetObjWin() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::SetObjWin( Window * pNewWin ) +{ + pObjWin = pNewWin; + AdjustObjWin(); +} + +/************************************************************************* +|* SvResizeWindow::CalcInnerRectPixel() +|* +|* Beschreibung +*************************************************************************/ +Rectangle SvResizeWindow::CalcInnerRectPixel( const Point & rPos, + const Size & rSize ) const +{ + Rectangle aInner( rPos, rSize ); + return aInner -= GetAllBorderPixel(); +} + +/************************************************************************* +|* SvResizeWindow::GetInnerRectPixel() +|* +|* Beschreibung +*************************************************************************/ +Rectangle SvResizeWindow::GetInnerRectPixel() const +{ + return CalcInnerRectPixel( Point(), GetOutputSizePixel() ); +} + +/************************************************************************* +|* SvResizeWindow::SelectMouse() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::SelectMouse( const Point & rPos ) +{ + short nGrab = aResizer.SelectMove( this, rPos ); + if( nGrab >= 4 ) + nGrab -= 4; + if( nMoveGrab != nGrab ) + { // Pointer hat sich geaendert + if( -1 == nGrab ) + SetPointer( aOldPointer ); + else + { + PointerStyle aStyle = POINTER_MOVE; + if( nGrab == 3 ) + aStyle = POINTER_ESIZE; + else if( nGrab == 2 ) + aStyle = POINTER_NESIZE; + else if( nGrab == 1 ) + aStyle = POINTER_SSIZE; + else if( nGrab == 0 ) + aStyle = POINTER_SESIZE; + if( nMoveGrab == -1 ) // das erste mal + { + aOldPointer = GetPointer(); + SetPointer( Pointer( aStyle ) ); + } + else + SetPointer( Pointer( aStyle ) ); + } + nMoveGrab = nGrab; + } +} + +/************************************************************************* +|* SvResizeWindow::MouseButtonDown() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::MouseButtonDown( const MouseEvent & rEvt ) +{ + if( aResizer.SelectBegin( this, rEvt.GetPosPixel() ) ) + SelectMouse( rEvt.GetPosPixel() ); +} + +/************************************************************************* +|* SvResizeWindow::MouseMove() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::MouseMove( const MouseEvent & rEvt ) +{ + if( aResizer.GetGrab() == -1 ) + SelectMouse( rEvt.GetPosPixel() ); + else + { + Rectangle aRect( aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) ); + Point aDiff = GetPosPixel() + aPosCorrection; + aRect.SetPos( aRect.TopLeft() + aDiff ); + aRect -= GetAllBorderPixel(); + aResizer.ValidateRect( aRect ); + + QueryObjAreaPixel( aRect ); + aRect += GetAllBorderPixel(); + aRect.SetPos( aRect.TopLeft() - aDiff ); + Point aPos = aResizer.GetTrackPosPixel( aRect ); + + SelectMouse( aPos ); + } +} + +/************************************************************************* +|* SvResizeWindow::MouseButtonUp() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::MouseButtonUp( const MouseEvent & rEvt ) +{ + if( aResizer.GetGrab() != -1 ) + { + Rectangle aRect( aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) ); + Point aDiff = GetPosPixel() + aPosCorrection; + aRect.SetPos( aRect.TopLeft() + aDiff ); + aRect -= GetAllBorderPixel(); + aResizer.ValidateRect( aRect ); + QueryObjAreaPixel( aRect ); + + Rectangle aOutRect; + if( aResizer.SelectRelease( this, rEvt.GetPosPixel(), aOutRect ) ) + { + nMoveGrab = -1; + SetPointer( aOldPointer ); + RequestObjAreaPixel( aRect ); + } + } +} + +/************************************************************************* +|* SvResizeWindow::KeyEvent() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::KeyInput( const KeyEvent & rEvt ) +{ + if( rEvt.GetKeyCode().GetCode() == KEY_ESCAPE ) + aResizer.Release( this ); +} + +/************************************************************************* +|* SvResizeWindow::Resize() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::Resize() +{ + aResizer.InvalidateBorder( this ); // alten Bereich + aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) ); + aResizer.InvalidateBorder( this ); // neuen Bereich + AdjustObjWin(); +} + +/************************************************************************* +|* SvResizeWindow::SetInnerPosSizePixel() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::SetInnerPosSizePixel( const Point & rPos, + const Size & rSize ) +{ + Rectangle aRect( rPos, rSize ); + aRect += GetAllBorderPixel(); + SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() ); +} + +//========================================================================= +void SvResizeWindow::QueryObjAreaPixel +( + Rectangle & rRect/* Das innere Rechteck von dem alle Borders + abgezogen sind. */ +) +/* [Beschreibung] + + Es wird gefragt, ob die angegebene Groesse uebernommen werden soll. + Ist das der Fall, dann wird rRect nicht veraendert. Ansonsten wird + rRect auf den gew"unschten Wert gesetzt. + +*/ +{ + (void)rRect; +} + +//========================================================================= +void SvResizeWindow::RequestObjAreaPixel +( + const Rectangle & rRect /* Das innere Rechteck von dem alle Borders + abgezogen sind. */ +) +/* [Beschreibung] + + Die Methode setzt die Position und Gr"osse des Fensters mit + <SvResizeWindow::SetPosSizePixel()>. +*/ +{ + Rectangle aRect = rRect; + aRect += GetAllBorderPixel(); + SetPosSizePixel( aRect.TopLeft() - aPosCorrection, + aRect.GetSize() ); +} + +/************************************************************************* +|* SvResizeWindow::Paint() +|* +|* Beschreibung +*************************************************************************/ +void SvResizeWindow::Paint( const Rectangle & /*rRect*/ ) +{ + aResizer.Draw( this ); +} + +/************************************************************************/ +/************************************************************************* +|* SvInPlaceWindow::SvInPlaceWindow() +|* +|* Beschreibung +*************************************************************************/ +SvInPlaceWindow::SvInPlaceWindow( Window * pParent, SvInPlaceEnvironment * pIPEnvP ) + : SvResizeWindow( pParent ) + , pIPEnv( pIPEnvP ) +{ + aResizer.SetResizeable( (pIPEnv->GetIPObj()->GetMiscStatus() & SVOBJ_MISCSTATUS_NOTRESIZEABLE) == 0 ); +} + +/************************************************************************* +|* SvInPlaceWindow::KeyEvent() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceWindow::KeyInput( const KeyEvent & rEvt ) +{ + SvResizeWindow::KeyInput( rEvt ); + if( rEvt.GetKeyCode().GetCode() == KEY_ESCAPE ) + { + pIPEnv->GetIPObj()->DoInPlaceActivate( FALSE ); + } +} + +//========================================================================= +void SvInPlaceWindow::QueryObjAreaPixel +( + Rectangle & rRect /* Das innere Rechteck von dem alle Borders + abgezogen sind. */ +) +/* [Beschreibung] + + Es wird gefragt, ob die angegebene Groesse uebernommen werden soll. + Ist das der Fall, dann wird rRect nicht veraendert. Ansonsten wird + rRect auf den gew"unschten Wert gesetzt. + + [Querverweise] + + <SvResizeWindow::QueryObjAreaPixel> +*/ +{ + pIPEnv->QueryObjAreaPixel( rRect ); +} + +//========================================================================= +void SvInPlaceWindow::RequestObjAreaPixel +( + const Rectangle & rRect /* Das innere Rechteck von dem alle Borders + abgezogen sind. */ +) +/* [Beschreibung] + + Die Methode setzt die Position und Gr"osse des Fensters mit + <SvResizeWindow::SetPosSizePixel()>. +*/ +{ + pIPEnv->GetContainerEnv()->RequestObjAreaPixel( rRect ); + pIPEnv->GetIPObj()->SendViewChanged(); +} + +/************************************************************************/ +/************************************************************************* +|* SvInPlaceClipWindow::SvInPlaceClipWindow() +|* +|* Beschreibung +*************************************************************************/ +SvInPlaceClipWindow::SvInPlaceClipWindow( Window * pParent ) + : Window( pParent, WB_CLIPCHILDREN ) + , pResizeWin( NULL ) +{ + SetBackground(); + SetAccessibleRole( ::com::sun::star::accessibility::AccessibleRole::EMBEDDED_OBJECT ); +} + +/************************************************************************* +|* SvInPlaceClipWindow::SetObjRects() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceClipWindow::SetRectsPixel( const Rectangle & rObjRect, + const Rectangle & rInPlaceWinMaxRect ) +{ + // Merken fuer Border Aenderungen + aMaxClip = rInPlaceWinMaxRect; + + // Umschliessendes Rechteck einschliesslich Tools + Rectangle aOuter( rObjRect ); + aOuter += pResizeWin->GetAllBorderPixel(); + + // Clip-Window-Groesse berechnen + Rectangle aClip( rInPlaceWinMaxRect ); + aClip = aClip.GetIntersection( aOuter ); + SetPosSizePixel( aClip.TopLeft(), aClip.GetSize() ); + + // Correction fuer Request setzen + pResizeWin->SetPosCorrectionPixel( aClip.TopLeft() ); + + // Resize-Window relativ zu Clip-Window berechnen + pResizeWin->SetInnerPosSizePixel( rObjRect.TopLeft() - aClip.TopLeft(), + rObjRect.GetSize() ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/dialog/makefile.mk b/bf_so3/source/dialog/makefile.mk new file mode 100644 index 000000000..ffd4f1fb0 --- /dev/null +++ b/bf_so3/source/dialog/makefile.mk @@ -0,0 +1,46 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. +SUBPRJ=..$/.. + +PRJINC=$(SUBPRJ) + +PRJNAME=binfilter +TARGET=so3_dialog + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk +.INCLUDE : $(SUBPRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + + +SLOFILES=\ + $(SLO)$/insdlg.obj \ + $(SLO)$/plfilter.obj \ + $(SLO)$/ipwin.obj + + +EXCEPTIONSFILES= \ + $(SLO)$/plfilter.obj \ + $(SLO)$/insdlg.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/bf_so3/source/dialog/plfilter.cxx b/bf_so3/source/dialog/plfilter.cxx new file mode 100644 index 000000000..638b899de --- /dev/null +++ b/bf_so3/source/dialog/plfilter.cxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <set> +#include <map> + +#include <tools/debug.hxx> +#include <vcl/stdtext.hxx> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/plugin/PluginDescription.hpp> +#include <com/sun/star/plugin/XPluginManager.hpp> + +using namespace std; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::plugin; + +namespace binfilter { + +struct ltstr +{ + bool operator()( const String& s1, const String& s2 ) const + { + return ( s1.CompareTo( s2 ) == COMPARE_LESS ); + } +}; + +typedef set< String, ltstr > StrSet; +typedef map< String, StrSet, ltstr > FilterMap; + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/applet2.cxx b/bf_so3/source/inplace/applet2.cxx new file mode 100644 index 000000000..696394f50 --- /dev/null +++ b/bf_so3/source/inplace/applet2.cxx @@ -0,0 +1,845 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ctype.h> +#include <stdio.h> + +#include "bf_so3/applet.hxx" +#include <tools/urlobj.hxx> +#include <tools/debug.hxx> +#include "insdlg.hxx" +#include <svuidlg.hrc> +#include <bf_so3/ipenv.hxx> +#include "bf_so3/ipclient.hxx" +#include <bf_so3/svstor.hxx> +#include "bf_so3/ipwin.hxx" +#include "bf_so3/soerr.hxx" +#include <vcl/syschild.hxx> +#include <sot/formats.hxx> +#include <comphelper/classids.hxx> + +#include <comphelper/processfactory.hxx> +#include <rtl/ustring.hxx> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/uno/XComponentContext.hpp" + +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +namespace binfilter { + +#define SoResId( id ) ResId( id, *SOAPP->GetResMgr() ) + +// forward declarations +class SvAppletEnvironment; + +//========================================================================= +//========================================================================= +//========================================================================= +struct SvAppletData_Impl +/* [Beschreibung] + + In diesem struct werden sich Member von SvAppletData gemerkt, um + nicht immer inkompatibel zu werden. +*/ +{ + SvAppletEnvironment * pAppletEnv; + SvCommandList aCmdList; + String aClass; + XubString aName; + XubString aCodeBase; + BOOL bMayScript; + INetURLObject * pDocBase; // Ist nicht persistent + + SvAppletData_Impl() + : pAppletEnv( NULL ) + , bMayScript( FALSE ) + , pDocBase( NULL ) + {} +}; + +//========================================================================= +//============== SvAppletEnvironment ====================================== +//========================================================================= +class SvAppletEnvironment : public SvInPlaceEnvironment +{ +protected: + virtual void RectsChangedPixel( const Rectangle & rObjRect, + const Rectangle & rClip ); + virtual void ShowIPObj( BOOL bShow ); +public: + SvAppletEnvironment( SvContainerEnvironment *, + SvAppletObject * ); + ~SvAppletEnvironment(); + +#ifdef SOLAR_JAVA + virtual void appletResize( const Size & ); + virtual void showDocument( const INetURLObject &, const XubString & ); + virtual void showStatus( const XubString & ); +#endif +}; + +class NoCursorWindow : public Window +{ +public: + NoCursorWindow( Window* pParent, WinBits nStyle ) + : Window( pParent, nStyle ) {} + + virtual long Notify( NotifyEvent& rNEvt ); +}; + +long NoCursorWindow::Notify( NotifyEvent& rNEvt ) +{ + if( rNEvt.GetType() == EVENT_KEYINPUT ) + { + KeyEvent rKEvt = *rNEvt.GetKeyEvent(); + + if( !rKEvt.GetKeyCode().GetModifier() ) + { + USHORT nCode = rKEvt.GetKeyCode().GetCode(); + switch( nCode ) + { + case KEY_HOME: + case KEY_END: + case KEY_UP: + case KEY_DOWN: + case KEY_LEFT: + case KEY_RIGHT: + return 1; + } + } + } + return Window::Notify( rNEvt ); +} + +//========================================================================= +SvAppletEnvironment::SvAppletEnvironment +( + SvContainerEnvironment * pFrm, /* Das Callback Gegenst"uck zum + InPlace-Environment */ + SvAppletObject * pObj_ /* Das zum Environment geh"orende + Objekt */ +) +/* [Beschreibung] + + Das Environment wird im <SvAppletObject::InPlaceActivate()> angelegt. + Durch die Verbindung mit dem Container Environment kann "uber die + UI-Tools und Fenster verhandelt werden. + + [Querverweise] + + <SvInPlaceEnvironment>, <SvContainerEnvironment> +*/ + : SvInPlaceEnvironment( pFrm, pObj_ ) +{ + // Das Border- und Clip-Window werden erzeugt + MakeWindows(); + SvInPlaceWindow * pBW = GetBorderWin(); + pBW->SetHatchBorderPixel( Size() ); + + // Eigentliches Fenster erzeugen, es muss ein AppletWindow sein + Window * pWin; + pWin = new SystemChildWindow( pBW, WB_CLIPCHILDREN ); + pWin->SetBackground(); + SetEditWin( pWin ); + pWin->Show(); + + // Fenster zuordnen (fuers Resize) + pBW->SetObjWin( pWin ); +} + +//========================================================================= +SvAppletEnvironment::~SvAppletEnvironment() +/* [Beschreibung] + + Die angelegten Fenster werden zerst"ort. +*/ +{ + Window * pAppletWin = GetEditWin(); + // statt DeleteEditWin() auf NULL setzen und durch den Manager + // zerst"oren + SetEditWin( NULL ); + delete pAppletWin; + DeleteWindows(); +} + +//========================================================================= +void SvAppletEnvironment::RectsChangedPixel +( + const Rectangle & rObjRect, /* Position und Gr"osse relativ zum + EditWin des Containers */ + const Rectangle & rClip /* Clipping des Containers auf das Objekt */ +) +/* [Beschreibung] + + Der Container "andert die Gr"osse oder Position des Objektes. Dies + wird an das Applet gemeldet. + + [Querverweise] + + <SvInPlaceEnvironment::RectsChangedPixel()> +*/ +{ + SvInPlaceEnvironment::RectsChangedPixel( rObjRect, rClip ); +} + +//========================================================================= +void SvAppletEnvironment::ShowIPObj +( + BOOL bShow /* TRUE, IP-Window anzeigen. + FALSE, IP-Window nicht anzeigen */ +) +/* [Beschreibung] + + Anzeigen de IP-Windows. Es wird nur angezeigt, wenn es nicht im + Hintergrund gestartet werden soll. +*/ +{ + SvInPlaceEnvironment::ShowIPObj( bShow ); +} + +#ifdef SOLAR_JAVA +//========================================================================= +void SvAppletEnvironment::showStatus( const XubString & rStatus ) +{ + GetContainerEnv()->SetStatusText( rStatus ); +} + +//========================================================================= +void SvAppletEnvironment::showDocument +( + const INetURLObject & rURL, + const XubString & rTarget +) +{ + GetContainerEnv()->ShowDocument( rURL, rTarget ); +} + +//========================================================================= +void SvAppletEnvironment::appletResize( const Size & ) +{ +} + + +#endif + +//========================================================================= +//============== SvAppletObject =========================================== +//========================================================================= +SO2_IMPL_BASIC_CLASS1_DLL( SvAppletObject, SvFactory, SvInPlaceObject, + SvGlobalName( SO3_APPLET_CLASSID ) ) + + +//========================================================================= +SvAppletObject::SvAppletObject() + : pImpl( new SvAppletData_Impl ) +/* [Beschreibung] + + Konstruktor der Klasse SvAppletObject. Die Verbliste und das + Format werden global initialisiert. +*/ +{ + SoDll * pSoApp = SOAPP; + if( !pSoApp->pAppletVerbList ) + { + pSoApp->pAppletVerbList = new SvVerbList(); + // Alle unterstuetzten Verben anlegen + pSoApp->pAppletVerbList->Append( + SvVerb( 0, SoResId( STR_VERB_OPEN ).toString() ) ); + pSoApp->pAppletVerbList->Append( + SvVerb( SVVERB_PROPS, SoResId( STR_VERB_PROPS ).toString() ) ); + pSoApp->nAppletDocFormat = SOT_FORMATSTR_ID_APPLETOBJECT; + } + // Verben der Superklasse bekanntgeben, um GetVerbs nicht + // ueberlagern zu muessen + SetVerbList( pSoApp->pAppletVerbList ); +} + +//========================================================================= +SvAppletObject::~SvAppletObject() +/* [Beschreibung] + + Destruktor der Klasse SvAppletObject. +*/ +{ + DELETEZ( pImpl->pDocBase ); + delete pImpl; +} + +//========================================================================= +BOOL SvAppletObject::StartApplet() +{ + return FALSE; +} + +//========================================================================= +void SvAppletObject::DataChanged_Impl +( + BOOL bOnlyEmbedSource /* TRUE, es "andert sich nur die persistenten + Daten. FALSE, auch das MetaFile "andert + sich */ +) +/* [Beschreibung] + + Wenn die Daten sich "andern, muss das Modiy-Flag gesetzt werden. + Ausserdem m"ussen alle angemeldeten Advises benachrichtigt werden. + In Abh"angigkeit des Parameters wird angezeigt, dass sich auch + die View und das Mtf ge"andert hat. +*/ +{ + if( IsEnableSetModified() ) + { // nicht im init oder deinit + SetModified( TRUE ); + if( !bOnlyEmbedSource ) + ViewChanged( ASPECT_CONTENT ); + } +} + +//========================================================================= +void SvAppletObject::FillClass +( + SvGlobalName * pClassName, /* Der Typ der Klasse */ + ULONG * pFormat, /* Das Dateiformat in dem geschrieben wird */ + String * pAppName, /* Der Applikationsname */ + String * pFullTypeName, /* Der genaue Name des Typs */ + String * pShortTypeName, /* Der kurze Name des Typs */ + long /*nFileFormat*/ /* F"ur dieses Office-Format sollen die + Parameter gef"ullt werden */ +) const +/* [Beschreibung] + + Mit dieser Methode werden Informationen "uber das Objekt angefordert. + Wird das Objekt gesichert, dann werden diese Informationen in den + Storage geschrieben. + + [Anmerkung] + + Da diese Information nicht vom Applet ermittelt werden kann, m"ussen + Standardwerte angegeben werden. Dies bedeutet, von aussen gibt es + nur den Typ Applet, in den man nicht hinein schauen kann. +*/ +{ + *pClassName = *GetSvFactory(); + *pFormat = SOAPP->nAppletDocFormat; + *pAppName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "StarDivision Applet 1.0" ) ); + *pFullTypeName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "StarDivision Applet 1.0" ) ); + *pShortTypeName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Applet" ) ); +} + + +//========================================================================= +void SvAppletObject::Open +( + BOOL bOpen /* TRUE, es handelt sich um eine Open. + FALSE, es handelt sich um Close. */ +) +/* [Beschreibung] + + Die Verbindung zum Client wird ge"offnet oder geschlossen. + + [Querverweise] + + <SvEmbeddedObject::Open()> +*/ +{ + // l"asst Environment los + SvInPlaceObject::Open( bOpen ); +} + +//========================================================================= +static sal_Bool isAppletEnabled(); +void SvAppletObject::InPlaceActivate +( + BOOL bActivate /* TRUE, InPlace Aktivierung beginnt. + FALSE, InPlace Aktivierung endet. */ +) +/* [Beschreibung] + + Das Objekt wird InPlace aktiviert oder deaktiviert. + + [Querverweise] + + <SvInPlaceObject::InPlaceActivate()> +*/ +{ + sal_Bool bEnabled= isAppletEnabled(); + if( bActivate && bEnabled) + { + SvContainerEnvironment * pEnv; + pEnv = GetIPClient()->GetEnv(); + pImpl->pAppletEnv = new SvAppletEnvironment( pEnv, this ); + + // wird in die Verwaltung eingesetzt + SetIPEnv( pImpl->pAppletEnv ); + + if( !StartApplet() ) + { + DoClose(); + return; + } + } + // SvInPlaceObject::InPlaceActivate must not be called if SetIPEnv has not been + // called (see above). It is possibe that the status of the "Enable Applet" option + // changes between the calls InPlaceActivate( true) and InPlaceActiveFalse. + if( (bEnabled && pImpl->pAppletEnv) || + (!bActivate && pImpl->pAppletEnv) ) + { + SvInPlaceObject::InPlaceActivate( bActivate ); + } + if( !bActivate && pImpl->pAppletEnv ) + DELETEZ( pImpl->pAppletEnv ); +} + +// This function detects if Applets are enabled. This option can be selected in the +// options dialog (StarOffice node->security) +static sal_Bool isAppletEnabled() +{ + sal_Bool bValue= sal_False; + + Reference<XInterface> xConfRegistry = ::comphelper::getProcessServiceFactory()->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationRegistry"))); + if(!xConfRegistry.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), Reference<XInterface>()); + + Reference<XSimpleRegistry> xConfRegistry_simple(xConfRegistry, UNO_QUERY); + if(!xConfRegistry_simple.is()) throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), Reference<XInterface>()); + + xConfRegistry_simple->open(OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common")), sal_True, sal_False); + Reference<XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey(); + + if (xRegistryRootKey.is()) + { + Reference<XRegistryKey> key_Enable = xRegistryRootKey->openKey(OUString( + RTL_CONSTASCII_USTRINGPARAM("Java/Applet/Enable"))); + if (key_Enable.is()) + { + bValue= key_Enable->getLongValue() != 0; + } + } + xConfRegistry_simple->close(); + return bValue; +} +//========================================================================= +ErrCode SvAppletObject::Verb +( + long nVerb, /* welche Art des Aktivierens ist + gew"unscht */ + SvEmbeddedClient * pCl, /* Callback-Svhnittstelle des Aufruffers */ + Window * pWin, /* Parent auf dem aktiviert werden soll */ + const Rectangle * pWorkRectPixel/* Position und Gr"osse, an der das Objekt + aktiviert werden soll */ +) +/* [Beschreibung] + + Es wird Versucht ein Applet zu starten. Es gibt nur die M"oglichkeit + InPlace zu aktivieren. Deshalb sind auch nur die Verben gestattet, + die dies ausl"osen. + + [R"uckgabewert] + + ErrCode ERRCODE_NONE, es wurde InPlace aktiviert. + ERRCODE_SO_NOT_INPLACEACTIVE, es wurde nicht InPlace + aktiviert. + + [Querverweise] + + <SvPseudoObject::Verb> +*/ +{ + (void)pCl; + (void)pWin; + (void)pWorkRectPixel; + + ErrCode nRet = ERRCODE_SO_GENERALERROR; + + switch( nVerb ) + { + case SVVERB_PROPS: + { + OSL_FAIL( "non-working code!" ); + // TODO: dead corpses + nRet = 0; + break; + } + case SVVERB_SHOW: + break; + + case SVVERB_IPACTIVATE: + break; + + case 0L: + nRet = GetProtocol().IPProtocol(); + break; + case SVVERB_HIDE: + nRet = DoInPlaceActivate( FALSE ); + break; + default: + nRet = ERRCODE_SO_GENERALERROR; + break; + } + return nRet; +} + +//========================================================================= +void SvAppletObject::SetVisArea +( + const Rectangle & rVisArea /* neue Position und Groesse des + sichtbaren Ausschnitts */ +) +/* [Beschreibung] + + Der sichtbare Ausschnitt beginnt immer an der Position (0, 0). +*/ +{ + Rectangle aR( rVisArea ); + aR.SetPos( Point() ); + SvInPlaceObject::SetVisArea( aR ); + + DataChanged_Impl( TRUE ); +} + +//========================================================================= +// aus PlugIn +void SoPaintReplacement( const Rectangle &rRect, String &rText, + OutputDevice *pOut ); + +//========================================================================= +void SvAppletObject::Draw +( + OutputDevice * pDev, /* in dieses Device findet die Ausgabe statt */ + const JobSetup &, /* fuer dieses Device soll formatiert werden */ + USHORT nAspect /* Darstellungsvariante des Objektes */ +) +/* [Beschreibung] + + Ein Ausgabe ist nicht m"oglich. Deswegen wird eine Bitmap + und als Unterschrift der URL ausgegeben, + + [Querverweise] + + <SvEmbeddedObject::Draw> +*/ +{ + Rectangle aVisArea_ = GetVisArea( nAspect ); + SoPaintReplacement( aVisArea_, pImpl->aClass, pDev ); +} + +//========================================================================= +BOOL SvAppletObject::InitNew +( + SvStorage * pStor /* Storage auf dem das Objekt arbeitet. Der kann + auch NULL sein, das Bedeutet, es wird auf einem + tempor"aren Storage gearbeitet */ +) +/* [Beschreibung] + + Nach dem Konstruktor muss diese Methode oder Load gerufen werden, + um das Objekt zu initialisieren. + <SvPersist::InitNew> + + [R"uckgabewert] + + BOOL TRUE, Initialisierung hat geklappt. + FALSE, Initialisierung hat nicht geklappt, das Objekt + muss sofort freigegeben werden. + + [Querverweise] + +*/ +{ + if( SvInPlaceObject::InitNew( pStor ) ) + { + // Standardgr"osse + SetVisArea( Rectangle( Point(), Size( 5000, 5000 ) ) ); + return TRUE; + } + return FALSE; +} + +//========================================================================= +#define DOCNAME "Applet" +#define APPLET_VERS 1 + +BOOL SvAppletObject::Load +( + SvStorage * pStor /* Storage aus dem das Objekt geladen wird. */ +) +/* [Beschreibung] + + Nach dem Konstruktor muss diese Methode oder InitNew gerufen werden, + um das Objekt zu initialisieren. + + [R"uckgabewert] + + BOOL TRUE, das Objekt wurde geladen. + FALSE, das Objekt wurde nicht geladen, es + muss sofort freigegeben werden. + + [Querverweise] + + <SvPersist::Load> +*/ +{ + if( SvInPlaceObject::Load( pStor ) ) + { + SvStorageStreamRef xStm; + xStm = pStor->OpenStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( DOCNAME ) ), STREAM_STD_READ ); + xStm->SetVersion( pStor->GetVersion() ); + xStm->SetBufferSize( 8192 ); + + // nicht vorhandener Stream ist kein Fehler + if( xStm->GetError() == SVSTREAM_FILE_NOT_FOUND ) + return TRUE; + + BYTE nVer; + *xStm >> nVer; + if( nVer == APPLET_VERS ) + { + *xStm >> pImpl->aCmdList; + pImpl->aClass = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(*xStm, + RTL_TEXTENCODING_ASCII_US ); + pImpl->aName = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(*xStm, + RTL_TEXTENCODING_ASCII_US); + pImpl->aCodeBase = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(*xStm, + RTL_TEXTENCODING_ASCII_US); + *xStm >> pImpl->bMayScript; + } + else + xStm->SetError( ERRCODE_IO_WRONGVERSION ); + + return xStm->GetError() == ERRCODE_NONE; + } + return FALSE; +} + +//========================================================================= +void SvAppletObject::HandsOff() +/* [Beschreibung] + + Ab diesen Zeitpunkt, bis zum <SvAppletObject::SaveCompleted>, + darf auf den Storage im Objekt nicht zugegriffen werden. + + [Querverweise] + + <SvPersist::HandsOff> +*/ +{ + SvInPlaceObject::HandsOff(); +} + +//========================================================================= +ULONG SvAppletObject::GetMiscStatus() const +/* [Beschreibung] + + Da ein Applet immer aktiviert wird, es ein Link ist und er + keine UI-Tools braucht, muss dieser Status zur"uckgegeben werden. + + [R"uckgabewert] + + ULONG Es wird immer SVOBJ_MISCSTATUS_LINK, + SVOBJ_MISCSTATUS_INSIDEOUT und + SVOBJ_MISCSTATUS_ACTIVATEWHENVISIBLE zur"uckgegeben + + [Querverweise] + + <SvPseudoObject::GetMiscStatus()> +*/ +{ + ULONG nMisc = 0; + + //nMisc = SVOBJ_MISCSTATUS_LINK; + nMisc |= SVOBJ_MISCSTATUS_INSIDEOUT; + nMisc |= SVOBJ_MISCSTATUS_ACTIVATEWHENVISIBLE; + nMisc |= SVOBJ_MISCSTATUS_ALWAYSACTIVATE; + nMisc |= SVOBJ_MISCSTATUS_SPECIALOBJECT; + return nMisc; +} + +//========================================================================= +BOOL SvAppletObject::IsLink() const +/* [Beschreibung] + + Dieser Typ von Objekt ist immer ein Link. + + [R"uckgabewert] + + BOOL Immer TRUE. + + [Querverweise] + + <SvPseudoObject::IsLink()> +*/ +{ + return FALSE; +} + +//========================================================================= +void SvAppletObject::SetCommandList +( + const SvCommandList & rList /* Die Liste der Kommnados */ +) +/* [Beschreibung] + + Die Liste der Kommandos, die "ubergeben werden, wenn das Applet + gestartet wird. + + [Anmerkung] + + Ein bereits gestartetes Applet wird dadurch nicht beeinflusst. + Die neuen Kommandos werden erst beim n"achsten starten ausgew"ahlt. +*/ +{ + pImpl->aCmdList = rList; + + DataChanged_Impl( TRUE ); +} + +//========================================================================= +const SvCommandList & SvAppletObject::GetCommandList() const +/* [Beschreibung] + + Die Liste der Kommandos, die in <SetCommandList> "ubergeben werden, + werden zur"uckgegeben. +*/ +{ + return pImpl->aCmdList; +} + +//========================================================================= +void SvAppletObject::SetClass +( + const String & rClass /* Der Verweis auf die Appletklasse */ +) +/* [Beschreibung] + + Der Verweis auf die Appletklasse wird "uebergeben. Dies entspricht + dem "code" Attribut des Applet-Tags in HTML. + + [Anmerkung] + + Ein bereits gestartetes Applet wird dadurch nicht beeinflusst. + Die neue Quelle wird erst beim n"achsten starten ausgew"ahlt. +*/ +{ + if( pImpl->aClass != rClass ) + { + pImpl->aClass = rClass; + DataChanged_Impl( FALSE ); + } +} + +//========================================================================= +const String & SvAppletObject::GetClass() const +/* [Beschreibung] + + Der Verweis auf die Quelle wird zur"uckgegeben + +*/ +{ + return pImpl->aClass; +} + +//========================================================================= +void SvAppletObject::SetName +( + const XubString & rName /* Name des Applets */ +) +/* [Beschreibung] + + Der Verweis auf den name des Applet wird "uebergeben. Dies entspricht + dem "namee" Attribut des Applet-Tags in HTML. + + [Anmerkung] + + Ein bereits gestartetes Applet wird dadurch nicht beeinflusst. +*/ +{ + if( pImpl->aName != rName ) + { + pImpl->aName = rName; + DataChanged_Impl( FALSE ); + } +} + +//========================================================================= +const XubString & SvAppletObject::GetName() const +/* [Beschreibung] + + Der Name des Applets wird zur"uckgegeben + +*/ +{ + return pImpl->aName; +} + +//========================================================================= +void SvAppletObject::SetCodeBase +( + const XubString & rCodeBase /* Der Verweis auf den Code + Appletklasse */ +) +/* [Beschreibung] + + Der Verweis auf den Code der Appletklasse wird "uebergeben. + Dies entspricht dem "codebase" Attribut des Applet-Tags in HTML. + + [Anmerkung] + + Ein bereits gestartetes Applet wird dadurch nicht beeinflusst. +*/ +{ + if( pImpl->aCodeBase != rCodeBase ) + { + pImpl->aCodeBase = rCodeBase; + DataChanged_Impl( FALSE ); + } +} + +//========================================================================= +const XubString & SvAppletObject::GetCodeBase() const +/* [Beschreibung] + + Der Verweis auf die Quelle wird zur"uckgegeben + +*/ +{ + return pImpl->aCodeBase; +} + +//========================================================================= +void SvAppletObject::SetMayScript( BOOL bMayScript ) +{ + pImpl->bMayScript = bMayScript; +} + +//========================================================================= +BOOL SvAppletObject::IsMayScript() const +{ + return pImpl->bMayScript; +} + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/client.cxx b/bf_so3/source/inplace/client.cxx new file mode 100644 index 000000000..314d5f0c6 --- /dev/null +++ b/bf_so3/source/inplace/client.cxx @@ -0,0 +1,528 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + +#ifdef WNT +#include <bf_svtools/bf_prewin.h> +#include <windows.h> +#include <bf_svtools/bf_postwin.h> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/sysdata.hxx> +#endif + +#include <vcl/salbtype.hxx> +#include <vcl/window.hxx> +#include <bf_so3/client.hxx> +#include <tools/debug.hxx> +#include <tools/urlobj.hxx> +#include <bf_so3/embobj.hxx> +#include "bf_so3/soerr.hxx" + +namespace binfilter { + +TYPEINIT0(SvClientData); + +SvClientData::SvClientData( SvEmbeddedClient * pCl, Window * pWin ) + : pClient( pCl ) + , aScaleWidth( 1, 1 ) + , aScaleHeight( 1, 1 ) + , pEditWin( pWin ) + , bInvalidate( pWin != NULL ) +{ +} + +SvClientData::~SvClientData() +{ +} + +void SvClientData::Invalidate() +/* [Beschreibung] + + Der Bereich des Objektes auf dem EditWin wird f"ur ung"ultig + erkl"art, sodass ein asynchroner PaintEvent generiert wird. Dies + passiert nur, wenn die Methode <SvClientData::IsInvalidate> TRUE + liefert. + + [Querverweise] + + <Window::Paint>, <SvClientData::GetEditWin>, + <SvClientData::SetInvalidate>. +*/ +{ + if( bInvalidate ) + { + Rectangle aR = GetObjArea(); + aR.SetSize( Size( Fraction( aR.GetWidth() ) * aScaleWidth, + Fraction( aR.GetHeight() ) * aScaleHeight ) ); + pEditWin->Invalidate( aR ); + } +} + +Window * SvClientData::GetEditWin() const +/* [Beschreibung] + + Diese Methode liefert das Fenster in dem das Objekt im + Container dargestellt wird. Dieses Fenster wird als Parent bei + InPlace-Aktivit"at benutzt. + + [R"uckgabewert] + + Window * Das Fenster in dem das Objekt dargestellt wird. + NULL, wenn das Objekt nciht dargestellt wird oder der + Client kein Fenster liefert. +*/ +{ + return pEditWin; +} + +void SvClientData::SetSizeScale +( + const Fraction & rScaleWidth, + const Fraction & rScaleHeight +) +/* [Beschreibung] + + Hat das Objekt abweichend vom OutputDevice des EditWin eine andere + Skalierung, dann muss diese mitgeteilt werden. Die Skalierung ist + relativ zum Outputdevice und bezieht sich nur auf die Gr"osse des + Objektes. +*/ +{ + aScaleWidth = rScaleWidth; + aScaleHeight = rScaleHeight; +} + +BOOL SvClientData::SetObjArea +( + const Rectangle & rArea +) +/* [Beschreibung] + + Die Gr"oesse des Objektes innerhalb des Containers in Einheiten + des EditWin wird gesetzt. Die Methode l"ost ein + <SvClientData::Invalidate> auf den alten und den neuen Bereich aus, + wenn sich diese unterscheiden. + + [Querverweise] + + <SvClientData::GetObjArea>, <SvClientData::SetObjAreaPixel> +*/ +{ + if( rArea != aObjRect ) + { + Invalidate(); // auf Alte + aObjRect = rArea; + Invalidate(); // auf Neue + return TRUE; // Bereich hat sich geandert + } + return FALSE; // Bereich hat sich geandert +} + +Rectangle SvClientData::GetObjArea() const +/* [Beschreibung] + + [R"uckgabewert] + + Rectangle Die Gr"oesse des Objektes innerhalb des Containers + in Einheiten des EditWin wir zur"uckgegeben. + + [Querverweise] + + <SvClientData::SetObjArea>, <SvClientData::GetObjAreaPixel> + +*/ +{ + return aObjRect; +} + +Rectangle SvClientData::PixelObjAreaToLogic +( + const Rectangle & rPixRect +) const +/* [Beschreibung] + + [R"uckgabewert] + + Rectangle rPixRect wird in Einheiten des EditWin, unter + Ber"ucksichtigung der extra Skalierung, umgerechnet. + + [Querverweise] + + <SvClientData::SetSizeScale>, <SvClientData::LogicObjAreaToPixel> + +*/ +{ + Rectangle aR = rPixRect; + if( pEditWin ) + { + aR.SetSize( pEditWin->PixelToLogic( aR.GetSize() ) ); + aR.SetPos( pEditWin->PixelToLogic( aR.TopLeft() ) ); + } + aR.SetSize( Size( Fraction( aR.GetWidth() ) / aScaleWidth, + Fraction( aR.GetHeight() ) / aScaleHeight ) ); + + return aR; +} + +#include <math.h> + +Rectangle SvClientData::LogicObjAreaToPixel +( + const Rectangle & rRect +) const +/* [Beschreibung] + + [R"uckgabewert] + + Rectangle rRect in Einheiten des EditWin wird, unter + Ber"ucksichtigung der extra Skalierung, in Pixel + umgerechnet. + + [Querverweise] + + <SvClientData::SetSizeScale>, <SvClientData::PixelObjAreaToLogic> + +*/ +{ + Rectangle aR( rRect ); + // *must* happen before LogicToPixel conversion, as: + // scaling down to pixel is integer, which leads to + // rounding errors (#89984#) + aR.SetSize( Size( FRound( double(Fraction( aR.GetWidth() ) * aScaleWidth) ), + FRound( double(Fraction( aR.GetHeight() ) * aScaleHeight ) ) ) ); + // Wenn kein Window, dann extern und somit Pixel + if( pEditWin ) + { + aR.SetSize( pEditWin->LogicToPixel( aR.GetSize() ) ); + aR.SetPos( pEditWin->LogicToPixel( aR.TopLeft() ) ); + } + return aR; +} + +/************** class SvEmbeddedClient **************************************/ +SV_IMPL_FACTORY(SvEmbeddedClientFactory) + { + } +}; +TYPEINIT1(SvEmbeddedClientFactory,SvFactory); + +SO2_IMPL_STANDARD_CLASS1_DLL(SvEmbeddedClient,SvEmbeddedClientFactory,SvObject, + 0xE4CAFE00L, 0x73AE, 0x101B, + 0x80,0x4C,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD ); + +::IUnknown * SvEmbeddedClient::GetMemberInterface( const SvGlobalName & rName ) +{ + (void)rName; + return NULL; +} + +/************************************************************************ +|* SvEmbeddedClient::SvEmbeddedClient() +*************************************************************************/ +//==============SvEmbeddedClient=========================================== +#define INIT_CTOR \ + pParent ( NULL ) \ + , nAspect ( ASPECT_CONTENT ) \ + , bAutoForce ( TRUE ) \ + , bDeleteData ( FALSE ) \ + , bCanPlugIn ( FALSE ) + +SvEmbeddedClient::SvEmbeddedClient() + : pData( NULL ) + , INIT_CTOR +{ +} + +SvEmbeddedClient::~SvEmbeddedClient() +{ + if( bDeleteData ) + delete pData; +} + +void SvEmbeddedClient::MakeViewData() +/* [Beschreibung] + + Der Client liefert ein View-Environment, der IP-Aktivierung oder + das Invalidieren des Objektbereichs in der View des Containers + ermoeglicht. Wenn in dieser virtuellen Methode das Environment + erzeugt wird, dann muss es mit <SvClientData::SetClientData> + eingesetzt werden. Von den Klassen <SvClientData> oder + <SvContainerEnvironment> muss ein Konstruktor gerufen werden, der + ein <SvEmbeddedClient> !ubergeben bekommt. + Wenn keine View vorhanden ist, dann wird wird in dieser Methode + nichts getan oder eine View angelegt. + + [Beispiel] + // die n"chsten beiden Zeilen sind Optional + if( !HasView() ) + CreateView(); + + if( HasView() ) + { + SvClientData * pD = new SvClientData( this, aView.GetEditWin() ); + SetViewData( pD ); + } + + [Querverweise] + + <SvEmbeddedClient::HasViewData>, <SvEmbeddedClient::FreeViewData> +*/ +{ + if( !Owner() && !pData ) + { + pData = new SvClientData( this ); + bDeleteData = TRUE; + // In ImpOleObject::DoVerb "ubergebenes Rectangle + pData->SetObjAreaPixel( aDoVerbRectPixel ); + } +} + +void SvEmbeddedClient::FreeViewData +( + SvClientData * pDataP /* View-Daten die zerst"ort werden k"onnen */ +) +/* [Beschreibung] + + Die View-Daten k"onnen freigegeben werden. Werden sie zerst"ort, + dann m"ussen sie vorher mit <SvEmbeddedClient::SetViewData( NULL )> + ausgetragen werden. + + [Beispiel] + ...::FreeViewData( SvClientData * pData ) + { + SetViewData( NULL ); + delete pData; + } + + [Querverweise] + + <SvEmbeddedClient::HasViewData>, <SvEmbeddedClient::FreeViewData> +*/ +{ +#ifdef DBG_UTIL + DBG_ASSERT( pDataP == pData, "pDataP != pData!" ); +#else + (void)pDataP; +#endif + if( !Owner() && bDeleteData ) + { + delete pData; + pData = NULL; + } +} + +SvClientData * SvEmbeddedClient::GetClientData() +/* [Beschreibung] + + Gibt die View-Daten zur"uck. Neue View-Daten werden + nur angelegt, wenn der Client "Connected" ist. + + [R"uckgabewert] + + SvContainerEnvironment * Das Environment zu diesem Client wird + zur"uckgegeben. + + [Querverweise] + + <SvProtocol::IsConnect>, <SvEmbeddedClient::MakeViewData> +*/ +{ + if( !pData && GetProtocol().IsConnect() ) + MakeViewData(); + return pData; +} + +BOOL SvEmbeddedClient::CanPlugIn() +{ + return bCanPlugIn; +} + +ErrCode SvEmbeddedClient::GetContURL +( + INetURLObject & rURL /* Hier wird der URL des Containers + abgelegt. */ +) +/* [Beschreibung] + + Die URL des Dokumentes wird zur"uckgegeben. Defaultm"assig wird + versucht die URL aus dem Moniker zu generieren. + + [R"uckgabewert] + + ERRCODE_NONE, In rURL steht der URL des Dokumentes. + ERRCODE_SO_GENERALERROR, rURL ist leer. + + [Querverweise] + + <SvEmbeddedClient::GetObjMoniker()> +*/ +{ + (void)rURL; + ULONG nRet = ERRCODE_SO_GENERALERROR; + return nRet; +} + +void SvEmbeddedClient::Embedded( BOOL bEmbed ) +{ +#ifdef DBG_UTIL_PROT + String aTest( "Client---Embedded---" ); + aTest += Owner() ? "Intern" : "Extern: "; + aTest += bEmbed ? "TRUE" : "FALSE"; + OSL_TRACE( "%s", aTest.GetBuffer() ); +#endif + + if( Owner() ) + { + if( !bEmbed && pData && pData->pEditWin ) + { + pData->pEditWin->ToTop( TOTOP_FOREGROUNDTASK ); + } + + SvClientData * pD = GetClientData(); + if( pD ) + pD->Invalidate(); + } + if( !bEmbed && HasViewData() ) + FreeViewData( pData ); +} + +void SvEmbeddedClient::PlugIn( BOOL bPlugIn ) +{ +#ifdef DBG_UTIL_PROT + String aTest( "Client---PlugIn---" ); + aTest += Owner() ? "Intern" : "Extern: "; + aTest += bPlugIn ? "TRUE" : "FALSE"; + OSL_TRACE( "%s", aTest.GetBuffer() ) +#else + (void)bPlugIn; +#endif + +} + +void SvEmbeddedClient::ViewChanged( USHORT nAspectP ) +{ + if( Owner() ) + { + if( GetAspect() == nAspectP ) + { + SvClientData * pD = GetClientData(); + if( pD ) + pD->Invalidate(); + } + } +} + +BOOL SvEmbeddedClient::SaveObject() +{ + BOOL bRet = FALSE; + if( Owner() ) + { + SvEmbeddedObject * pE = GetEmbedObj(); + if( pE ) + { + bRet = false; + // was pE->DoSaveCompleted(); but return value is not checked + } + } + return bRet; +} + +SvEmbeddedObjectRef SvEmbeddedClient::GetContainer() +/* [Beschreibung] + + Diese Methode liefert den Container (Dokument), in dem das, + mit dem Client verbundene, Objekt enthalten ist. + + [R"uckgabewert] + + SvEmbeddedObjectRef Der Container des Objektes oder NULL, wenn + das Objekt nirgentwo enthalten ist. +*/ +{ + SvEmbeddedObjectRef xCont; + if( Owner() ) + { + if( GetParent() ) + xCont = GetParent()->GetEmbedObj(); + else + { + SvEmbeddedObject * pE = GetEmbedObj(); + if( pE ) + // nutzt die Hierarchie der SvPersist-Objekte fuer Default + xCont = SvEmbeddedObjectRef( pE->GetParent() ); + } + } + return xCont; +} + +void SvEmbeddedClient::MakeVisible() +/* [Beschreibung] + + Das Objekt, mit dem dieser Client verbunden ist, soll in den + sichtbaren Bereich des Containers geschoben werden. +*/ +{ + if( GetParent() ) + GetParent()->MakeVisible(); + +} + +/************************************************************************* +|* InPlace Protocoll +*************************************************************************/ +void SvEmbeddedClient::Connected( BOOL bConnect ) +{ // Zu dieser Methode gibt es kein Ole2 aequivalent +#ifdef DBG_UTIL_PROT + String aTest( "Client---Connected---" ); + aTest += Owner() ? "Intern" : "Extern: "; + aTest += bConnect ? "TRUE" : "FALSE"; + OSL_TRACE( "%s", aTest.GetBuffer() ) +#endif + if( !bConnect && HasViewData() ) + FreeViewData( pData ); +} + +void SvEmbeddedClient::Closed() +{ + // genau in diesem muss die InClose-Variable zurueckgesetzt werden + SvEditObjectProtocol aProt_( GetProtocol() ); + aProt_.SetInClosed( TRUE ); + if( Owner() ) + GetProtocol().Reset(); + aProt_.SetInClosed( FALSE ); +} + +void SvEmbeddedClient::Opened( BOOL bOpen ) +{ +#ifdef DBG_UTIL_PROT + String aTest( "Client---Opened---" ); + aTest += Owner() ? "Intern" : "Extern: "; + aTest += bOpen ? "TRUE" : "FALSE"; + OSL_TRACE( "%s", aTest.GetBuffer() ) +#else + (void)bOpen; +#endif + +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/embobj.cxx b/bf_so3/source/inplace/embobj.cxx new file mode 100644 index 000000000..76d91a861 --- /dev/null +++ b/bf_so3/source/inplace/embobj.cxx @@ -0,0 +1,913 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + + + +#include <bf_so3/embobj.hxx> + +#include <vcl/cvtgrf.hxx> +#include <vcl/gdimtf.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/svapp.hxx> +#include <vcl/virdev.hxx> +#include <sot/storinfo.hxx> +#include <absdev.hxx> +#include <tools/debug.hxx> +#include <sot/exchange.hxx> + +#include <soimpl.hxx> +#include "bf_so3/outplace.hxx" +#include <bf_so3/client.hxx> +#include <bf_so3/svstor.hxx> +#include <bf_so3/so2dll.hxx> +#include "bf_so3/soerr.hxx" +#include <svuidlg.hrc> + +#include <bf_svtools/filter.hxx> +#include <viscache.hxx> +#include <sot/formats.hxx> + +namespace binfilter { + +/************** class SvEmbeddedInfoObject ***************************************/ +/*************************************************************************/ +SV_IMPL_PERSIST1(SvEmbeddedInfoObject,SvInfoObject) + +/************************************************************************ +|* SvEmbeddedInfoObject::SvEmbeddedInfoObject() +|* SvEmbeddedInfoObject::~SvEmbeddedInfoObject() +|* +|* Beschreibung +*************************************************************************/ +SvEmbeddedInfoObject::SvEmbeddedInfoObject() : + nViewAspect( ASPECT_CONTENT ) +{ +} + +SvEmbeddedInfoObject::SvEmbeddedInfoObject( SvEmbeddedObject * pObj, + const String & rName ) + : SvInfoObject( pObj, rName ), + nViewAspect( ASPECT_CONTENT ) + +{ +} + +SvEmbeddedInfoObject::SvEmbeddedInfoObject( const String& rObjName, + const SvGlobalName& rClassName ) + : SvInfoObject( rObjName, rClassName ), + nViewAspect( ASPECT_CONTENT ) + +{ +} + +SvEmbeddedInfoObject::~SvEmbeddedInfoObject() +{ +} + +/************************************************************************ +|* SvEmbeddedInfoObject::MakeCopy() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedInfoObject::Assign( const SvInfoObject * pObj ) +{ + SvInfoObject::Assign( pObj ); + SvEmbeddedInfoObject * pI = PTR_CAST(SvEmbeddedInfoObject, pObj ); + if( pI ) + { + aVisArea = pI->aVisArea; + } +} + +/************************************************************************ +|* SvEmbeddedInfoObject::Load() +|* SvEmbeddedInfoObject::Save() +|* +|* Beschreibung +*************************************************************************/ +#define INFO_VERSION (BYTE)2 +void SvEmbeddedInfoObject::Load( SvPersistStream & rStm ) +{ + SvInfoObject::Load( rStm ); + BYTE nVers = 0; + rStm >> nVers; + DBG_ASSERT( nVers == INFO_VERSION, "SvInfoObject version conflict" ); + if( nVers != INFO_VERSION ) + rStm.SetError( SVSTREAM_WRONGVERSION ); + else + { + BOOL bIsLink; + rStm >> bIsLink; + rStm >> aVisArea; + } +} + +void SvEmbeddedInfoObject::Save( SvPersistStream & ) {} + +/************************************************************************ +|* SvEmbeddedInfoObject::SetObj() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedInfoObject::SetObj( SvPersist * pObjP ) +{ + SvInfoObject::SetObj( pObjP ); + SvEmbeddedObject * pObj = GetEmbed(); + if( pObj && !pObj->Owner() ) + pObj->SvEmbeddedObject::SetVisArea( aVisArea ); +} + +/************************************************************************ +|* SvEmbeddedInfoObject::IsLink() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvEmbeddedInfoObject::IsLink() const +{ + return FALSE; +} + +/************************************************************************ +|* SvEmbeddedInfoObject::GetVisArea() +|* +|* Beschreibung +*************************************************************************/ +const Rectangle & SvEmbeddedInfoObject::GetVisArea() const +{ + SvEmbeddedObject * pObj = GetEmbed(); + if( pObj ) + ((SvEmbeddedInfoObject *)this)->aVisArea = pObj->GetVisArea(); + return aVisArea; +} + +UINT32 SvEmbeddedInfoObject::GetViewAspect() const +{ + SvEmbeddedObject * pObj = GetEmbed(); + if( pObj ) + ((SvEmbeddedInfoObject *)this)->nViewAspect = pObj->GetViewAspect(); + return nViewAspect; +} + +/************************************************************************* +|* +|* SvEmbeddedObject::Factory() +|* +*************************************************************************/ +SO2_IMPL_CLASS2_DLL(SvEmbeddedObject,SvFactory,SvPersist,SvPseudoObject, + SvGlobalName( 0xBB0D2800L, 0x73EE, 0x101B, + 0x80,0x4C,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD) ) + +::IUnknown * SvEmbeddedObject::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +/************************************************************************ +|* SvEmbeddedObject::SvEmbeddedObject() +|* +|* Beschreibung +*************************************************************************/ +SvEmbeddedObject::SvEmbeddedObject() + : bAutoSave ( TRUE ) + , bAutoHatch ( TRUE ) + , nMapUnit ( MAP_100TH_MM ) +{ +} + + +SvEmbeddedObject::~SvEmbeddedObject() +{ +} + +/// Direct sent, when ViewChange is called. So nothing to do +void SvEmbeddedObject::SendViewChanged() +{ +} + +void SvEmbeddedObject::ViewChanged( USHORT nAspect) +{ + SvEmbeddedClient * pCl = GetClient(); + if( pCl ) + pCl->ViewChanged( nAspect ); +} + + +/************************************************************************* +|* SvEmbeddedObject::GetGDIMetaFile() +|* +|* Beschreibung +*************************************************************************/ + +GDIMetaFile& SvEmbeddedObject::GetGDIMetaFile( GDIMetaFile& rMTF ) +{ + rMTF.Clear(); + return rMTF; +} + +BOOL SvEmbeddedObject::SetData( const String& ) +{ + return FALSE; +} + +/************************************************************************* +|* SvEmbeddedObject::Load() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvEmbeddedObject::Load( SvStorage * pStor ) +{ + SvGlobalName aClassName = pStor->GetClassName(); + + SvGlobalName aActualClassName = + SvFactory::GetAutoConvertTo( aClassName ); + + if( aActualClassName == *GetSvFactory() ) + return SvPersist::Load( pStor ); + else + { // Ich bin es nicht selbst + return SvPersist::Load( pStor ); + } +} + +/************************************************************************* +|* SvEmbeddedObject::LoadContent() +|* +|* Beschreibung +*************************************************************************/ +#define EMBEDDED_OBJECT_VERSION (BYTE)0 +void SvEmbeddedObject::LoadContent( SvStream & rStm, BOOL bOwner_ ) +{ + SvPersist::LoadContent( rStm, bOwner_ ); + if( rStm.GetError() != SVSTREAM_OK ) + return; + + if( bOwner_ ) + { + BYTE nVers; + rStm >> nVers; + DBG_ASSERT( nVers == EMBEDDED_OBJECT_VERSION, "version conflict" ); + + if( nVers != EMBEDDED_OBJECT_VERSION ) + rStm.SetError( SVSTREAM_WRONGVERSION ); + else + { + // Sichtbaren Bereich setzten + rStm >> aVisArea; + USHORT nUnit; + rStm >> nUnit; + SetMapUnit( (MapUnit)nUnit ); + } + } +} + +/************************************************************************* +|* SvEmbeddedObject::SaveContent() +|* +|* Beschreibung +*************************************************************************/ + +static void WriteExtContent( SvStream & rStm, const GDIMetaFile & rMtf, + USHORT nAspect, ULONG nAdviseModes ) +{ + Impl_OlePres aEle( FORMAT_GDIMETAFILE ); + // Die Groesse in 1/100 mm umrechnen + // Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird, + // versucht SV einen BestMatchden richtigen Wert zu raten. + Size aSize = rMtf.GetPrefSize(); + MapMode aMMSrc = rMtf.GetPrefMapMode(); + MapMode aMMDst( MAP_100TH_MM ); + aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst ); + aEle.SetSize( aSize ); + aEle.SetAspect( nAspect ); + aEle.SetAdviseFlags( nAdviseModes ); + aEle.SetMtf( rMtf ); + aEle.Write( rStm ); +} + + +void SvEmbeddedObject::SaveContent( SvStream & rStm, BOOL bOwner_ ) +{ + SvPersist::SaveContent( rStm, bOwner_ ); + if( bOwner_ ) + { + rStm << (BYTE)EMBEDDED_OBJECT_VERSION; + rStm << GetVisArea(); + rStm << (USHORT)GetMapUnit(); + } +} + + +BOOL SvEmbeddedObject::MakeContentStream( SotStorage * pStor, + const GDIMetaFile & rMtf ) +{ + // MAC MPW mag's sonst nicht ... + String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) ); + SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream ); + xStm->SetVersion( pStor->GetVersion() ); + + xStm->SetBufferSize( 8192 ); + WriteExtContent( *xStm, rMtf, ASPECT_CONTENT, 2 ); + xStm->SetBufferSize( 0 ); + return xStm->GetError() == SVSTREAM_OK; +} + +BOOL SvEmbeddedObject::MakeContentStream( SvStorage * pStor, + const GDIMetaFile & rMtf ) +{ + return MakeContentStream( (SotStorage *)pStor, rMtf ); +} + +//========================================================================= +void SvEmbeddedObject::FillClass +( + SvGlobalName * pClassName, /* Der Typ der Klasse */ + ULONG * pFormat, /* Das Dateiformat in dem geschrieben wird */ + String * pAppName, /* Der Applikationsname */ + String * pFullTypeName, /* Der genaue Name des Typs */ + String * pShortTypeName, /* Der kurze Name des Typs */ + long nFileFormat /* Fuer dieses Office-Format sollen die + Parameter gefuellt werden */ +) const +/* [Beschreibung] + + Die Methoden <SvPersist::FillClass> und <SvPseudoObject::FillClass> + setzen nicht alle Parameter. <SvPersist::FillClass> setzt die + Parameter pClassName und pFormat. <SvPseudoObject::FillClass> setzt + die restlichen Parmeter. +*/ +{ + SvGlobalName aName; + ULONG nFormat; + + SvPersist::FillClass( pClassName, pFormat, pAppName, pFullTypeName, + pShortTypeName, nFileFormat ); + SvPseudoObject::FillClass( &aName, &nFormat, pAppName, pFullTypeName, + pShortTypeName, nFileFormat ); +} + +/************************************************************************* +|* SvEmbeddedObject::SetModified() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedObject::SetModified( BOOL bModifiedP ) +{ + ASSERT_INIT() + SvPersist::SetModified( bModifiedP ); + + if( IsEnableSetModified() ) + { + SvEmbeddedObjectRef xPar = this; + + while( xPar.Is() ) + { + xPar->SetModifyTime( GetModifyTime() ); + + SvPersist * pP = xPar->GetParent(); + xPar = pP; + + // Fuer diesen Fall muss der gesammte Ablauf noch + // einmal geprueft werden + DBG_ASSERT( (xPar.Is() && pP) || (!pP && !xPar.Is()), + "Persist-Parent ist kein EmbeddedObject" ); + } + } +} + + +/************************************************************************* +|* SvEmbeddedObject::GetMiscStatus() +|* +|* Beschreibung +*************************************************************************/ +ULONG SvEmbeddedObject::GetMiscStatus() const +{ + return SvPseudoObject::GetMiscStatus(); +} + +/************************************************************************* +|* SvEmbeddedObject::DoOpen() +|* +|* Beschreibung +*************************************************************************/ +ErrCode SvEmbeddedObject::DoOpen( BOOL bOpen ) +{ + if( !aProt.IsConnect() ) + return ERRCODE_SO_GENERALERROR; + if( aProt.IsOpen() == bOpen ) + return ERRCODE_NONE; + + SvEmbeddedObjectRef xHoldAliveDuringCall( this ); + + if( !bOpen ) + aProt.Reset2Open(); + + + // Ein Open kommt nicht von Ole2 + // loest eventuell ein Close aus + // Saved, wenn AutoSave + aProt.Opened( bOpen ); + + return (aProt.IsOpen() == bOpen) ? ERRCODE_NONE : ERRCODE_SO_GENERALERROR; +} + +/************************************************************************* +|* SvEmbeddedObject::DoEmbed() +|* +|* Beschreibung +*************************************************************************/ +ErrCode SvEmbeddedObject::DoEmbed( BOOL bEmbed ) +{ + if( aProt.IsEmbed() == bEmbed ) + return ERRCODE_NONE; + + if( !bEmbed ) + aProt.Reset2Embed(); + + ErrCode nRet = ERRCODE_NONE; + if( Owner() ) + { + if( bEmbed ) + // falls IP-Active + aProt.Reset2Open(); + aProt.Embedded( bEmbed ); + } + + if( aProt.IsEmbed() != bEmbed && !ERRCODE_TOERROR( nRet ) ) + nRet = ERRCODE_SO_GENERALERROR; + return nRet; +} + +/************************************************************************* +|* SvEmbeddedObject::Embed() +|* +|* Beschreibung +*************************************************************************/ +#ifdef DBG_UTIL_PROT +void SvEmbeddedObject::Embed( BOOL bEmbed ) +#else +void SvEmbeddedObject::Embed( BOOL ) +#endif +{ +#ifdef DBG_UTIL_PROT + String aTest( "Object---Embed---" ); + aTest += Owner() ? "Intern" : "Extern: "; + aTest += bEmbed ? "TRUE" : "FALSE"; + OSL_TRACE( "%s", aTest.GetBuffer() ) +#endif +} + +//========================================================================= +ErrCode SvEmbeddedObject::DoPlugIn( BOOL bPlugIn ) +/* [Beschreibung] + + [Rueckgabewert] + + BOOL TRUE, das Objekt ist im PlugIn-Zustand. + FALSE, das Objekt ist nicht im PlugIn-Zustand. + + + [Querverweise] +*/ +{ + if( aProt.IsPlugIn() == bPlugIn ) + return ERRCODE_NONE; + + ErrCode nRet = ERRCODE_NONE; + if( !bPlugIn ) + aProt.Reset2PlugIn(); + + if( Owner() ) + { + if( bPlugIn ) + // falls IP-Active + aProt.Reset2Open(); + aProt.PlugIn( bPlugIn ); + } + + if( aProt.IsPlugIn() != bPlugIn && !ERRCODE_TOERROR( nRet ) ) + nRet = ERRCODE_SO_GENERALERROR; + return nRet; +} + +//========================================================================= +#ifdef DBG_UTIL_PROT +void SvEmbeddedObject::PlugIn( BOOL bPlugIn ) +#else +void SvEmbeddedObject::PlugIn( BOOL ) +#endif +{ +#ifdef DBG_UTIL_PROT + String aTest( "Object---PlugIn---" ); + aTest += Owner() ? "Intern" : "Extern: "; + aTest += bPlugIn ? "TRUE" : "FALSE"; + OSL_TRACE( "%s", aTest.GetBuffer() ) +#endif +} + +/************************************************************************* +|* SvEmbeddedObject::Verb() +|* +|* Beschreibung +*************************************************************************/ +ErrCode SvEmbeddedObject::Verb +( + long nVerb, + SvEmbeddedClient * pCl, + Window * pWin, + const Rectangle * pWorkRectPixel +) +{ + ErrCode nRet = ERRCODE_NONE; + if( Owner() ) + { + if( nVerb == SVVERB_OPEN ) + nRet = GetProtocol().EmbedProtocol(); + else + nRet = GetProtocol().PlugInProtocol(); + } + else + { + nRet = SvPseudoObject::Verb( nVerb, pCl, pWin, pWorkRectPixel ); + } + return nRet; +} + +/************************************************************************* +|* SvEmbeddedObject::DocumentNameChanged() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedObject::DocumentNameChanged( const String & /*rDocName*/ ) +{ +} + +//========================================================================= +// locker die Struktur von Windows kopiert +struct MY_GUID +{ + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + BYTE Data4[8]; +}; + +void SvEmbeddedObject::Connect +( + BOOL bConnect /* TRUE, connect. FALSE, disconnect */ +) +/* [Beschreibung] + + Ist bConnect == TRUE, dann wurde das Objekt mit einem + <SvEmbeddedClient> verbunden. Diesen kann man mit + <SvEmbeddedObject::GetClient> erfragen. + Ist bConnect == TRUE, dann wurde das Objekt von dem Client getrennt, + mit dem es vorher verbunden war. + + [Querverweise] + + <SvPseudoObject::DoClose> +*/ +{ + if( Owner() ) + { + SvEmbeddedObjectRef xCont = GetClient()->GetContainer(); + // Owner muss abgefragt werden, da Ole2 sonst streikt + if( xCont.Is() && xCont->Owner() ) + xCont->Lock( bConnect ); + } +} + +/************************************************************************* +|* SvEmbeddedObject::Close() +|* +|* Beschreibung: Close darf mehrmals gerufen werden +*************************************************************************/ +BOOL SvEmbeddedObject::Close() +{ + const SvInfoObjectMemberList * pChildList_ = GetObjectList(); + if( pChildList_ ) + { + ULONG nCount = pChildList_->Count(); + for( ULONG i = 0; i < nCount; i++ ) + { + SvInfoObject * pIO = pChildList_->GetObject( i ); + SvPersist * pPer = pIO->GetPersist(); + SvEmbeddedObjectRef xEO( pPer ); + if( xEO.Is() ) + xEO->DoClose(); + } + } + + // Unter Ole2 muss Close() vor SetClientSite( NULL ) gerufen werden. + aProt.Reset2Connect(); + SvPseudoObject::Close(); + // Jetzt SetClientSite( NULL ). + aProt.Reset(); + return TRUE; +} + +/************************************************************************* +|* SvEmbeddedObject::Open() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedObject::Open( BOOL bOpen ) +{ +#ifdef DBG_UTIL_PROT + String aTest( "Object---Open---" ); + aTest += Owner() ? "Intern" : "Extern: "; + aTest += bOpen ? "TRUE" : "FALSE"; + OSL_TRACE( "%s", aTest.GetBuffer() ) +#endif + + SendViewChanged(); + // kein Autosave im HandsOff State + if( bAutoSave && !bOpen && !IsHandsOff()) + { + SvEmbeddedClient * pCl = GetClient(); + if( pCl ) + pCl->SaveObject(); + } + +} + + + + + +/************************************************************************* +|* SvEmbeddedObject::SetGetVisArea() +|* +|* Beschreibung +*************************************************************************/ +const Rectangle & SvEmbeddedObject::SetGetVisArea( const Rectangle & rArea ) +{ + // nicht auf Gleichheit optimieren, da der Server sie jederzeit + // modifizieren darf + if( Owner() ) + // muss, weil SetVisArea ist virtuell ist + SetVisArea( rArea ); + return aVisArea; +} + +/************************************************************************* +|* SvEmbeddedObject::SetVisArea() +|* SvEmbeddedObject::GetVisArea() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedObject::SetVisArea( const Rectangle & rArea ) +{ + if( Owner() ) + aVisArea = rArea; + else + SetGetVisArea( rArea ); +} + +void SvEmbeddedObject::SetVisAreaSize( const Size & rSize ) +{ + SetVisArea( Rectangle( GetVisArea().TopLeft(), rSize ) ); +} + +Rectangle SvEmbeddedObject::GetVisArea( USHORT nAspect ) const +{ + if( nAspect == ASPECT_CONTENT ) + return 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 & SvEmbeddedObject::GetVisArea() const +{ + ((SvEmbeddedObject *)this)->aVisArea = GetVisArea( ASPECT_CONTENT ); + return aVisArea; +} + +UINT32 SvEmbeddedObject::GetViewAspect() const +{ + return ASPECT_CONTENT; +} + +/************************************************************************* +|* SvEmbeddedObject::DrawHatch() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedObject::DrawHatch( OutputDevice * pDev, const Point & rViewPos, + const Size &rSize ) +{ + GDIMetaFile * pMtf = pDev->GetConnectMetaFile(); + if( pMtf && pMtf->IsRecord() ) + return; + + SvEmbeddedClient * pCl = GetClient(); + if( pCl && pCl->Owner() && bAutoHatch + && pDev->GetOutDevType() == OUTDEV_WINDOW + && GetProtocol().IsEmbed() ) + { + pDev->Push(); + pDev->SetLineColor( Color( COL_BLACK ) ); + + Size aPixSize = pDev->LogicToPixel( rSize ); + aPixSize.Width() -= 1; + aPixSize.Height() -= 1; + Point aPixViewPos = pDev->LogicToPixel( rViewPos ); + INT32 nMax = aPixSize.Width() + aPixSize.Height(); + for( INT32 i = 5; i < nMax; i += 5 ) + { + Point a1( aPixViewPos ), a2( aPixViewPos ); + if( i > aPixSize.Width() ) + a1 += Point( aPixSize.Width(), i - aPixSize.Width() ); + else + a1 += Point( i, 0 ); + if( i > aPixSize.Height() ) + a2 += Point( i - aPixSize.Height(), aPixSize.Height() ); + else + a2 += Point( 0, i ); + + pDev->DrawLine( pDev->PixelToLogic( a1 ), pDev->PixelToLogic( a2 ) ); + } + pDev->Pop(); + } +} + + +/************************************************************************* +|* SvEmbeddedObject::DoDraw() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedObject::DoDraw( OutputDevice * pDev, const Point & rViewPos, + const Size &rSize, + const JobSetup & rSetup, USHORT nAspect ) +{ + if( Owner() ) + { + 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() ); + + Point aOrg = rViewPos; + aMod.SetMapUnit( MAP_100TH_MM ); + aSize = pDev->LogicToLogic( GetVisArea( nAspect ).GetSize(), &aMod, &aWilliMode ); + DoDraw( pDev, aOrg, aXF, aYF, rSetup, aSize, nAspect ); + } + } +} + +/************************************************************************* +|* SvEmbeddedObject::DoDraw() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedObject::DoDraw( OutputDevice * pDev, const Point & rViewPos, + const Fraction & rScaleX, + const Fraction & rScaleY, + const JobSetup & rSetup, const Size& rSize, + USHORT nAspect ) +{ + Rectangle aVisArea_ = GetVisArea( nAspect ); + // MapUnit des Ziels + MapMode aMapMode( GetMapUnit() ); + aMapMode.SetScaleX( rScaleX ); + aMapMode.SetScaleY( rScaleY ); + + if( Owner() ) + { + // 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; + } + if( pDev->IsClipRegion() && pDev->GetOutDevType() != OUTDEV_PRINTER ) + { + aRegion = pDev->PixelToLogic( aRegion ); + pDev->SetClipRegion( aRegion ); + } + if( pMtf ) + pMtf->Record( pDev ); + + SvOutPlaceObjectRef xOutRef( this ); + if ( xOutRef.Is() ) + xOutRef->DrawObject( pDev, rSetup, rSize, nAspect ); + else + Draw( pDev, rSetup, nAspect ); + DrawHatch( pDev, aVisArea_.TopLeft(), aVisArea_.GetSize() ); + + // Deviceeinstellungen wieder herstellen + pDev->Pop(); + } + else + { + Size aSize = aVisArea_.GetSize(); + pDev->LogicToLogic( rViewPos, NULL, &aMapMode ); + DoDraw( pDev, rViewPos, aSize, rSetup, nAspect ); + } +} + +/************************************************************************* +|* SvEmbeddedObject::Draw() +|* +|* Beschreibung +*************************************************************************/ +void SvEmbeddedObject::Draw( OutputDevice * /*pDev*/, + const JobSetup & /*rSetup*/, USHORT /*nAspect*/ ) +{ +} + +/************************************************************************* +|* SvEmbeddedObject::GetDocumentPrinter() +|* +|* Beschreibung: +*************************************************************************/ +Printer * SvEmbeddedObject::GetDocumentPrinter() +{ + SvEmbeddedObjectRef xParent( GetParent() ); + if( xParent.Is() ) + return xParent->GetDocumentPrinter(); + return NULL; +} + +/************************************************************************* +|* SvEmbeddedObject::GetDocumentRefDev() +|* +|* Beschreibung: +*************************************************************************/ +OutputDevice* SvEmbeddedObject::GetDocumentRefDev() +{ + SvEmbeddedObjectRef xParent( GetParent() ); + if( xParent.Is() ) + return xParent->GetDocumentRefDev(); + return NULL; +} + +/************************************************************************* +|* SvEmbeddedObject::ConvertToOle1() +|* +|* Beschreibung: +*************************************************************************/ +struct ClsIDs { + UINT32 nId; + const sal_Char* pSvrName; + const sal_Char* pDspName; +}; + +void SvEmbeddedObject::OnDocumentPrinterChanged( Printer * ) +{ +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/ipclient.cxx b/bf_so3/source/inplace/ipclient.cxx new file mode 100644 index 000000000..b5178bea8 --- /dev/null +++ b/bf_so3/source/inplace/ipclient.cxx @@ -0,0 +1,319 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + + +#include "bf_so3/ipclient.hxx" +#include <tools/debug.hxx> +#include <vcl/wrkwin.hxx> + +#include <bf_so3/so2dll.hxx> +#include <bf_so3/ipobj.hxx> +#include <bf_so3/ipenv.hxx> +#include "bf_so3/soerr.hxx" + +namespace binfilter { + +//========================================================================= +//========================================================================= +//========================================================================= +SV_IMPL_FACTORY(SvInPlaceClientFactory) + { + } +}; +TYPEINIT1(SvInPlaceClientFactory,SvFactory); + +SO2_IMPL_STANDARD_CLASS1_DLL(SvInPlaceClient,SvInPlaceClientFactory,SvEmbeddedClient, + 0x35356980L, 0x795D, 0x101B, + 0x80,0x4C,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD ) + +//========================================================================= +/* [Beschreibung] + + Makro, um fuer die verschiedenen Konstruktoren die gleich + Initialisierung sicherzustellen. +*/ +#define INIT_CLIENT_CTOR \ + pObjI ( NULL ) + +//========================================================================= +SvInPlaceClient::SvInPlaceClient() + : INIT_CLIENT_CTOR +/* [Beschreibung] + + Dieser Konstruktor wird verwendet, wenn man sich vom Client abgeleitet + hat oder wenn man einen Client zu einem Objekt erstellen will. +*/ +{ +} + +//========================================================================= +SvInPlaceClient::~SvInPlaceClient() +/* [Beschreibung] + + Destruktor der Klasse SvInPlaceClient. Wurde das Environment noch + nicht freigegeben, dann passiert dies hier. + + [Querverweise] +*/ +{ + DBG_ASSERT( LIST_ENTRY_NOTFOUND == GetIPActiveClientList().GetPos( this ), + "ip-client in ip-client-list" ); + +} + +//========================================================================= +::IUnknown * SvInPlaceClient::GetMemberInterface( const SvGlobalName & rName ) +{ + (void)rName; + return NULL; +} + +//========================================================================= +BOOL SvInPlaceClient::CanInPlaceActivate() const +/* [Beschreibung] + + Gibt an, ob der Container zum jetzigen Zeitpunkt IP-Aktivierung + unterst"utzt. + + [R"uckgabewert] + + BOOL TRUE, der Container unterst"utzt zur Zeit IP-Aktivierung. + FALSE, der Container unterst"utzt zur Zeit keine + IP-Aktivierung. +*/ +{ + BOOL bRet = FALSE; + if( Owner() ) + { + bRet = GetAspect() == ASPECT_CONTENT; + if( bRet ) + // Nur IP gestatten, wenn das Environment verf"ugbar ist + bRet = NULL != ((SvInPlaceClient *)this)->GetEnv(); + } + return bRet; +} + +//========================================================================= +SvInPlaceClientList & SvInPlaceClient::GetIPActiveClientList() +/* [Beschreibung] + + Gibt die Liste aller zu diesem Zeitpunkt IP-Aktiven Clients + zur"uck. + + [R"uckgabewert] + + SvInPlaceClientList & Die Liste der Clients. +*/ +{ + SoDll * pSoApp = SOAPP; + if( !pSoApp->pIPActiveClientList ) + pSoApp->pIPActiveClientList = new SvInPlaceClientList(); + return *pSoApp->pIPActiveClientList; +} + +//========================================================================= +void SvInPlaceClient::MakeViewData() +/* [Beschreibung] + + Gibt das ContainerEnvironment zur"uck. Wurde es nicht im + Konstruktor "ubergeben, dann muss diese Methode "uberladen + werden. + + [R"uckgabewert] + + SvClientData * Das Environment zu diesem Client wird zur"uckgegeben. + + [Querverweise] + + <SvEmbeddedClient::MakeViewData>, <SvEmbeddedClient::FreeViewData> +*/ +{ + + if( !Owner() && !HasViewData() && GetProtocol().IsConnect() ) + { + pData = new SvContainerEnvironment( this ); + bDeleteData = TRUE; + } + else + SvEmbeddedClient::MakeViewData(); +} + +//========================================================================= +SvContainerEnvironment * SvInPlaceClient::GetEnv() +/* [Beschreibung] + + Gibt das ContainerEnvironment zur"uck. Ein neues Environment + wird nur angelegt, wenn der Client "Connected" ist. + + [R"uckgabewert] + + SvContainerEnvironment * Das Environment zu diesem Client wird + zur"uckgegeben. + + [Querverweise] + + <SvProtocol::IsConnect>, <SvInPlaceClient::MakeViewData> +*/ +{ + if( !pData && GetProtocol().IsConnect() ) + MakeViewData(); + return PTR_CAST( SvContainerEnvironment, pData ); +} + +//========================================================================= +void SvInPlaceClient::MakeVisible() +/* [Beschreibung] + + Das Objekt, mit dem dieses Environment verbunden ist, soll in den + sichtbaren Bereich des Containers geschoben werden. Als Default wird + das Top- und das DocWindow angezeigt. +*/ +{ + SvEmbeddedClient::MakeVisible(); + if( Owner() ) + { + SvContainerEnvironment * pEnv = GetEnv(); + if( pEnv ) + { + WorkWindow * pDoc = pEnv->GetDocWin(); + WorkWindow * pTop = pEnv->GetTopWin(); + if( pDoc ) + { + if( pDoc->IsMinimized() ) + pDoc->Restore(); + //pDoc->ToTop(); + pDoc->Show(); + } + if( pTop ) + { + if( pTop->IsMinimized() ) + pTop->Restore(); + //pTop->ToTop(); + pTop->Show(); + } + } + } +} + +//========================================================================= +void SvInPlaceClient::Opened +( + BOOL bOpen /* TRUE, in den Open-Status. + FALSE, in den Connect-Status. */ +) +/* [Beschreibung] + + Dieser Handler wird gerufen, wenn der Open-Status aktiviert oder + deaktiviert wird. + Ist bOpen == FALSE, wird die Verbindung aller Environment-Kinder + abgebrochen. +*/ +{ + SvEmbeddedClient::Opened( bOpen ); +} + +#ifdef WAR_NUR_EIN_TEST +//========================================================================= +void SvInPlaceClient::Embedded +( + BOOL bEmbed /* TRUE, in den Embed-Status. FALSE, in den Open-Status. */ +) +/* [Beschreibung] + + Dieser Handler wird gerufen, wenn der Embed-Status aktiviert oder + deaktiviert wird. + Es wird zuerst die <SvEmbeddedClient::Embedded()> gerufen. Ist + bEmbed == FALSE, wird die Verbindung aller Environment-Kinder + abgebrochen. +*/ +{ + SvEmbeddedClient::Embedded( bEmbed ); + if( !bEmbed ) + { + SvContainerEnvironment * pEnv = GetEnv(); + if( pEnv ) + pEnv->ResetChilds(); + } +} +#endif + +//========================================================================= +void SvInPlaceClient::InPlaceActivate +( + BOOL bActivate /* TRUE, in den InPlace-Status. + FALSE, in den Open-Status. */ +) +/* [Beschreibung] + + Dieser Handler wird gerufen, wenn der InPlace-Status aktiviert oder + deaktiviert wird. + Ist bActivate == FALSE, wird die Verbindung aller Environment-Kinder + abgebrochen. +*/ +{ + if( !bActivate && HasViewData() ) + FreeViewData( pData ); +} + +//========================================================================= +void SvInPlaceClient::UIActivate +( + BOOL bUIActivate /* TRUE, in den UI-Status. + FALSE, in den IP-Status */ +) +/* [Beschreibung] + + Dieser Handler wird gerufen, wenn der UI-Status aktiviert oder + deaktiviert wird. +*/ +{ + if( Owner() ) + { + if( !bUIActivate ) + { + SvInPlaceEnvironment * pActEnv = SOAPP->pUIShowIPEnv; + SvContainerEnvironment * pEnv = GetEnv(); + if( !pActEnv ) + { + pEnv->GetIPEnv()->DoShowIPObj( FALSE ); + if( pEnv->GetParent() ) + // ein Deactivate ohne ein Activate + pEnv->GetParent()->ShowUIByChildDeactivate(); + } + + } + } +} + +//========================================================================= +void SvInPlaceClient::DeactivateAndUndo() +{ +} + +//========================================================================= +void SvInPlaceClient::DiscardUndoState() +{ +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/ipenv.cxx b/bf_so3/source/inplace/ipenv.cxx new file mode 100644 index 000000000..94ac53618 --- /dev/null +++ b/bf_so3/source/inplace/ipenv.cxx @@ -0,0 +1,997 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + +#include <bf_so3/ipenv.hxx> +#include <bf_so3/iface.hxx> + +#include <tools/debug.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/svapp.hxx> +#include <vcl/accel.hxx> +#include <bf_so3/so2dll.hxx> +#include <bf_so3/ipobj.hxx> +#include "bf_so3/ipclient.hxx" +#include "bf_so3/ipwin.hxx" + +class INetURLObject; + +namespace binfilter { + +//========================================================================= +//==========SvContainerEnvironment========================================= +//========================================================================= + +SO2_IMPL_INTERFACE1(SvAppFrame,SvObject) + +::IUnknown * SvAppFrame::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +//========================================================================= +SvAppFrame::~SvAppFrame() +/* [Beschreibung] + + Destruktor der Klasse SvAppFrame. + + [Querverweise] + + <SvInPlaceClient> +*/ +{ +} + +//========================================================================= +//========================================================================= +//========================================================================= +SO2_IMPL_INTERFACE1(SvDocFrame,SvObject) + +::IUnknown * SvDocFrame::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +//========================================================================= +SvDocFrame::~SvDocFrame() +/* [Beschreibung] + + Destruktor der Klasse SvDocFrame. + + [Querverweise] + + <SvInPlaceClient> +*/ +{ +} + +//========================================================================= +//==========SvContainerEnvironment========================================= +//========================================================================= +static void InsertInContList( SvContainerEnvironment * p ) +{ + SoDll * pSoApp = SOAPP; + if( !pSoApp->pContEnvList ) + pSoApp->pContEnvList = new SvContainerEnvironmentList(); + pSoApp->pContEnvList->push_back( p ); +} + +#define INIT_CTOR \ + pOleInfo ( NULL ) \ + , hOleMenuDesc ( 0 ) \ + , nCount1 ( 0 ) \ + , nCount2 ( 0 ) \ + , nCount3 ( 0 ) \ + , nMenuUseCount ( 0 ) \ + , pAccel ( NULL ) \ + , aClipAreaPixel( 0, 0, 0x7FFF, 0x7FFF ) \ + , bDfltUIAction ( TRUE ) \ + , bDeleteTopWin ( FALSE ) \ + , bDeleteDocWin ( FALSE ) \ + , bDeleteEditWin ( FALSE ) + +TYPEINIT1(SvContainerEnvironment,SvClientData); + +//========================================================================= +SvContainerEnvironment::SvContainerEnvironment +( + SvInPlaceClient * pCl, + WorkWindow * pTopWinP, + WorkWindow * pDocWinP, + Window * pEditWin_ +) + : SvClientData( pCl, pEditWin_ ) + , pIPEnv( NULL ) + , pObj( pCl ) + , pParent( NULL ) + , pTopWin( pTopWinP ) + , pDocWin( pDocWinP ) + , INIT_CTOR +{ + InsertInContList( this ); +} + +//========================================================================= +SvContainerEnvironment::~SvContainerEnvironment() +/* [Beschreibung] + + Im Destruktor werden alle selbsterzeugten Fenster zerst"ort. + + [Querverweise] +*/ +{ + DBG_ASSERT( !pIPEnv, "IPEnv exist" ); + + if( bDeleteEditWin ) + { + Window * pWin = SvClientData::GetEditWin(); + SetEditWin( NULL ); + delete pWin; + } + if( bDeleteDocWin ) + delete pDocWin; + if( bDeleteTopWin ) + delete pTopWin; + + SoDll * pSoApp = SOAPP; + for( SvContainerEnvironmentList::iterator it = pSoApp->pContEnvList->begin(); + it < pSoApp->pContEnvList->end(); + ++it + ) + { + if ( *it == this ) + { + pSoApp->pContEnvList->erase( it ); + break; + } + } + + delete pAccel; + + DBG_ASSERT( !xAppFrame.Is() || 1 == xAppFrame->GetRefCount(), + "can't destroy xAppFrame" ); + DBG_ASSERT( !xDocFrame.Is() || 1 == xDocFrame->GetRefCount(), + "can't destroy xDocFrame" ); +} + +/************************************************************************ +|* SvContainerEnvironment::IsStub() +|* +|* Beschreibung: +*************************************************************************/ +BOOL SvContainerEnvironment::IsStub() const +{ + if( pParent ) + return pParent->IsStub(); + return pObj != NULL && !pObj->Owner(); +} + +/************************************************************************ +|* SvContainerEnvironment::ShowUIByChildDeactivate() +|* +|* Beschreibung: +*************************************************************************/ +void SvContainerEnvironment::ShowUIByChildDeactivate() +{ + if( pObj && pObj->GetProtocol().IsInPlaceActive() ) + { // gibt es einen IP-Client und ist dieser IP-Active + // dann UI aktivieren + pObj->GetIPObj()->DoUIActivate( TRUE ); + } + else if( pParent ) + pParent->ShowUIByChildDeactivate(); +} + +#ifdef Brauch_ich_nicht_mehr +//========================================================================= +void SvContainerEnvironment::DeleteWindows_Impl() +/* [Beschreibung] + + Die Fenster pEditWin, pDocWin und pTopWin werden in dieser + Reihenfolge gel"oscht. +*/ +{ + if( bDeleteEditWin ) + { + // erst austragen, dann l"oschen + Window * pWin = SvClientData::GetEditWin(); + SetEditWin( NULL ); + delete pWin; + } + if( bDeleteDocWin ) + delete pDocWin; + if( bDeleteTopWin ) + delete pTopWin; + bDeleteEditWin = bDeleteDocWin = bDeleteTopWin = FALSE; +} +#endif + +//========================================================================= +WorkWindow * SvContainerEnvironment::GetTopWin() const +{ + return pTopWin; +} + +//========================================================================= +WorkWindow * SvContainerEnvironment::GetDocWin() const +{ + return pDocWin; +} + +//========================================================================= +Window * SvContainerEnvironment::GetEditWin() const +{ + return SvClientData::GetEditWin(); +} + +/************************************************************************ +|* SvContainerEnvironment::QueryMenu() +|* +|* Beschreibung +*************************************************************************/ +MenuBar * SvContainerEnvironment::QueryMenu +( + USHORT * , + USHORT * , + USHORT * +) +{ + return 0; +} + +/************************************************************************ +|* SvContainerEnvironment::SetInPlaceMenu() +|* +|* Beschreibung +*************************************************************************/ +void SvContainerEnvironment::SetInPlaceMenu( MenuBar *, BOOL ) +{ +} + +/************************************************************************ +|* SvContainerEnvironment::MenuReleased() +|* +|* Beschreibung +*************************************************************************/ +void SvContainerEnvironment::MenuReleased() +{ +} + +/************************************************************************ +|* SvContainerEnvironment::UIToolsShown() +|* +|* Beschreibung +*************************************************************************/ +void SvContainerEnvironment::UIToolsShown( BOOL /* bShow */ ) +{ +} + +/************************************************************************* +|* SvContainerEnvironment::GetAccel() +|* +|* Beschreibung +*************************************************************************/ +Accelerator * SvContainerEnvironment::GetAccel() +{ + DBG_ASSERT( !pObj || pObj->Owner(), + "cannot convert HACCEL to Accelerator (not implemented)" ); + if( !pAccel && pParent ) + return pParent->GetAccel(); + return pAccel; +} + +/************************************************************************* +|* SvContainerEnvironment::DispatchAccel() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvContainerEnvironment::DispatchAccel( const KeyCode & rCode ) +{ + if( pParent ) + return pParent->DispatchAccel( rCode ); + + return FALSE; +} + +/************************************************************************* +|* SvContainerEnvironment::OutDevScaleChanged() +|* +|* Beschreibung +*************************************************************************/ +void SvContainerEnvironment::OutDevScaleChanged() +{ + if( pIPEnv ) + pIPEnv->DoRectsChanged(); +} + +/************************************************************************* +|* SvClientData::SetSizeScale() +|* +|* Beschreibung +*************************************************************************/ +void SvContainerEnvironment::SetSizeScale( const Fraction & rScaleWidth, + const Fraction & rScaleHeight ) +{ + if( GetScaleWidth() != rScaleWidth || GetScaleHeight() != rScaleHeight ) + { + SvClientData::SetSizeScale( rScaleWidth, rScaleHeight ); + OutDevScaleChanged(); + } +} + +/************************************************************************* +|* SvInPLaceClient::SetObjArea() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvContainerEnvironment::SetObjArea( const Rectangle & rArea ) +{ + if( SvClientData::SetObjArea( rArea ) ) + { + if( pIPEnv ) + pIPEnv->DoRectsChanged(); + return TRUE; + } + return FALSE; +} + +/************************************************************************* +|* SvContainerEnvironment::GetObjArea() +|* +|* Beschreibung +*************************************************************************/ +Rectangle SvContainerEnvironment::GetObjArea() const +{ + return SvClientData::GetObjArea(); +} + +/************************************************************************* +|* SvContainerEnvironment::PixelObjVisAreaToLogic() +|* +|* Beschreibung: Der Return ist in logischen Koordinaten des Objektes +*************************************************************************/ +Rectangle SvContainerEnvironment::PixelObjVisAreaToLogic( + const Rectangle & rObjRect ) const +{ + DBG_ASSERT( pIPEnv, "no InPlaceEnvironment" ); + + SvInPlaceObject * pIPObj = pIPEnv->GetIPObj(); + + Window * pWin; + if( !pObj || pObj->Owner() ) + pWin = GetEditWin(); + else + pWin = pIPEnv->GetEditWin(); + + MapMode aClientMap( pWin->GetMapMode().GetMapUnit() ); + MapMode aObjMap( pIPObj->GetMapUnit() ); + + // VisArea entsprechend der Groessenaenderung anpassen + Rectangle aRect = pIPObj->GetVisArea(); + + // Wenn die linke obere Ecke verschoben wird, auch die linke + // obere Ecke der VisArea verschieben. Dies aber nur, wenn gleichzeitig + // die Groesse geaendert wird. + Rectangle aOldArea = GetObjAreaPixel(); + long nWidth = aOldArea.GetWidth(); + if( nWidth && nWidth != rObjRect.GetWidth() ) + { + // Differenz berechnen + long n = rObjRect.Left() - aOldArea.Left(); + // Breite in Pixel des Orginal + // 3 Satz, Linke Seite entsprechend Vergroessern + aRect.Left() += n * aRect.GetWidth() / nWidth; + } + long nHeight = aOldArea.GetHeight(); + if( nHeight && nHeight != rObjRect.GetHeight() ) + { + long n = rObjRect.Top() - aOldArea.Top(); + aRect.Top() += n * aRect.GetHeight() / nHeight; + } + + Size aSize; + // Scale und OutDev richtig + aSize = pWin->PixelToLogic( rObjRect.GetSize() ); + // Skalierung bei der Visarea nicht beruecksichtigen + aSize = pWin->LogicToLogic( aSize, &aClientMap, &aObjMap ); + aSize.Width() = Fraction( aSize.Width() ) / GetScaleWidth(); + aSize.Height() = Fraction( aSize.Height() ) / GetScaleHeight(); + + aRect.SetSize( aSize ); + return aRect; +} + +/************************************************************************* +|* SvContainerEnvironment::RequestObjAreaPixel() +|* +|* Beschreibung +*************************************************************************/ +void SvContainerEnvironment::RequestObjAreaPixel( const Rectangle & rObjRect ) +{ + // IP-Win wurde veraendert, Client anpassen + // Position im Client setzen + if( !pIPEnv ) + { + SetObjAreaPixel( rObjRect ); + return; + } + + Rectangle aOldAreaPixel = GetObjAreaPixel(); + if( rObjRect == aOldAreaPixel ) + return; + + pIPEnv->LockRectsChanged(); + + Rectangle aOldArea = GetObjArea(); + Rectangle aArea = PixelObjAreaToLogic( rObjRect ); + // Dies muss vor dem setzen der neuen ObjArea erfolgen, da die + // alte ObjArea benoetigt wird + // Ist in Objekt Koordinaten + Rectangle aObjVisArea = PixelObjVisAreaToLogic( rObjRect ); + SvInPlaceObjectRef xIPObj = pIPEnv->GetIPObj(); + Rectangle aOldObjVisArea = xIPObj->GetVisArea(); + if( rObjRect.GetSize() == aOldAreaPixel.GetSize() ) + { + // Die Grosse aendert sich nur durch Pixel-Rundung, + // deshalb die alte logische Groesse nehmen + aObjVisArea.SetSize( aOldObjVisArea.GetSize() ); + aArea.SetSize( aOldArea.GetSize() ); + } + + if( rObjRect.TopLeft() == aOldAreaPixel.TopLeft() ) + { + // Die Position aendert sich nur durch Pixel-Rundung, + // deshalb die alte logische Position nehmen + aObjVisArea.SetPos( aOldObjVisArea.TopLeft() ); + aArea.SetPos( aOldArea.TopLeft() ); + } + + + // Dadurch wird eine zu fruehe Ausgabe unterbunden + BOOL bInval = IsInvalidate(); + if( xIPObj->GetProtocol().IsInPlaceActive() ) + SetInvalidate( FALSE ); + + SetObjArea( aArea ); + SetInvalidate( bInval ); + + xIPObj->SetVisArea( aObjVisArea ); + + // innerhalb der Verhandlung nicht neu updaten + pIPEnv->UnlockRectsChanged(); + pIPEnv->DoRectsChanged(); +} + +/************************************************************************* +|* SvContainerEnvironment::Scroll() +|* +|* Beschreibung +*************************************************************************/ +void SvContainerEnvironment::Scroll( const Size & rSize ) +{ + if( !rSize.Width() && !rSize.Height() ) + // doch nicht gescrollt + return; + + if( !pObj || pObj->Owner() ) + { + // Da in Scroll der Origin versetzt wird, + // aendern sich die Pixel Koordinaten + pIPEnv->DoRectsChanged(); + } +} + +/************************************************************************ +|* SvContainerEnvironment::RequestTopToolSpacePixel() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvContainerEnvironment::RequestTopToolSpacePixel( const SvBorder & rInner ) +{ + if( pParent ) + return pParent->RequestTopToolSpacePixel( rInner ); + + BOOL bRet = FALSE; + if( !pObj || pObj->Owner() ) + { + bRet = TRUE; + } + return bRet; +} + +/************************************************************************ +|* SvContainerEnvironment::RequestDocToolSpacePixel() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvContainerEnvironment::RequestDocToolSpacePixel( const SvBorder & rInner ) +{ + if( pParent ) + return pParent->RequestDocToolSpacePixel( rInner ); + + BOOL bRet = FALSE; + if( !pObj || pObj->Owner() ) + { + bRet = TRUE; + } + return bRet; +} + +/************************************************************************ +|* SvContainerEnvironment::SetTopToolSpacePixel() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvContainerEnvironment::SetTopToolSpacePixel( const SvBorder & rInner ) +{ + if( pParent ) + return pParent->SetTopToolSpacePixel( rInner ); + + if( !pObj || pObj->Owner() ) + { + if( RequestTopToolSpacePixel( rInner ) ) + { + // Sind Top- und EditWin unterschiedlich, dann muss das EditWin + // neu angeordnet werden. Dies muss von dem abgeleiteten + // Environment geleistet werden. + // Sind sie gleich, kann die Anordnung automatisch geschehen + return GetEditWin() == GetTopWin(); + } + return FALSE; + } + return FALSE; +} + +/************************************************************************ +|* SvContainerEnvironment::SetDocToolSpacePixel() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvContainerEnvironment::SetDocToolSpacePixel( const SvBorder & rInner ) +{ + if( pParent ) + return pParent->SetDocToolSpacePixel( rInner ); + + if( !pObj || pObj->Owner() ) + { + if( RequestDocToolSpacePixel( rInner ) ) + { + // Sind Doc- und EditWin unterschiedlich, dann muss das EditWin + // neu angeordnet werden. Dies muss von dem abgeleiteten + // Environment geleistet werden. + // Sind sie gleich, kann die Anordnung automatisch geschehen + return GetEditWin() == GetDocWin(); + } + } + return FALSE; +} + +/************************************************************************ +|* SvContainerEnvironment::GetTopOuterRectPixel() +|* +|* Beschreibung +*************************************************************************/ +Rectangle SvContainerEnvironment::GetTopOuterRectPixel() const +{ + if( pParent ) + return pParent->GetTopOuterRectPixel(); + + Rectangle aOuter; + if( !pObj || pObj->Owner() ) + { + aOuter = Rectangle( Point(), pTopWin->GetOutputSizePixel() ); + aOuter -= aTopBorder; + } + + return aOuter; +} + +/************************************************************************ +|* SvContainerEnvironment::GetDocOuterRectPixel() +|* +|* Beschreibung +*************************************************************************/ +Rectangle SvContainerEnvironment::GetDocOuterRectPixel() const +{ + if( pParent ) + return pParent->GetDocOuterRectPixel(); + + Rectangle aOuter; + if( !pObj || pObj->Owner() ) + { + aOuter = Rectangle( Point(), pDocWin->GetOutputSizePixel() ); + aOuter -= aDocBorder; + } + + return aOuter; +} + + +/************************************************************************ +|* SvContainerEnvironment::SetStatusText() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvContainerEnvironment::SetStatusText( const String & rText ) +{ + if( pParent ) + return pParent->SetStatusText( rText ); + + return FALSE; +} + +//========================================================================= +void SvContainerEnvironment::ShowDocument +( + const INetURLObject &, /* Die URL, die angezeigt werden soll. */ + const XubString & /* Spezifiert den Frame, in dem das Dokument + angezeigt werden soll. + "_self", show in current frame. + "_parent", show in parent frame. + "_top", show in top-most frame. + "_blank", show in new unnamed top-level + window. + name, show in a new top-level named name. + */ +) +/* [Beschreibung] + + Show a new document in a target window or frame. This may be ignored + by the applet context. + + [Querverweise] + + <SjAppletContext::ShowDocument> +*/ +{ +} + +/************** SvInPlaceEnvironment *********************************************** +**************************************************************************/ +SvInPlaceEnvironment::SvInPlaceEnvironment( SvContainerEnvironment * pCl, + SvInPlaceObject * pObjP ) + : nChangeRectsLockCount( 0 ) + , bShowUITools( FALSE ) + , bTopWinResize( FALSE ) + , bDocWinResize( FALSE ) + , bDeleteEditWin( FALSE ) + , pUIMenu( NULL ) + , pClientMenu( NULL ) + , pClipWin( NULL ) + , pBorderWin( NULL ) + , pEditWin( NULL ) + , pContEnv( pCl ) + , pObj( pObjP ) +{ + pContEnv->SetIPEnv( this ); +} + +/*************************************************************************/ +SvInPlaceEnvironment::~SvInPlaceEnvironment() +{ + DBG_ASSERT( !bShowUITools, "UI-Tools werden noch angezeigt" ); + DoShowUITools( FALSE ); + if( bDeleteEditWin ) + delete pEditWin; + pContEnv->ResetIPEnv(); +} + +//========================================================================= +Window * SvInPlaceEnvironment::GetEditWin() +{ + return pEditWin; +} + +//========================================================================= +MenuBar * SvInPlaceEnvironment::QueryMenu +( + USHORT *, + USHORT *, + USHORT * +) +{ + return NULL; +} + +/*************************************************************************/ +void SvInPlaceEnvironment::DoShowIPObj( BOOL bShow ) +{ + if( bShow ) + DoRectsChanged(); + ShowIPObj( bShow ); +} + +/*************************************************************************/ +void SvInPlaceEnvironment::ShowIPObj( BOOL bShow ) +{ + if( pClipWin ) + { + if( bShow ) + GetClipWin()->Show(); + else + GetClipWin()->Hide(); + } +} + +/*************************************************************************/ +void SvInPlaceEnvironment::DoShowUITools( BOOL bShow ) +{ + + //DBG_ASSERT( !bShow || !bShowUITools, "bShowUITools && bShow" ); + if( bShow == bShowUITools ) + // bei soviel Activate/Deactivate ist es besser dies zu gestatten + return; + + if( bShow && !GetContainerEnv()->IsStub() ) + { + SoDll * pSoApp = SOAPP; + // SvInPlaceEnvironment * pUIEnv = pSoApp->pUIShowIPEnv; + // unbedingt zuerst setzen + pSoApp->pUIShowIPEnv = this; + + // kein Child darf UI-Aktiv sein + SvContainerEnvironment * pEnv = GetContainerEnv(); + + // kein Parent darf UI-Aktiv sein + SvContainerEnvironment * pPar = pEnv->GetParent(); + while( pPar && pPar->GetIPClient() ) + { + pPar->GetIPClient()->GetProtocol().Reset2InPlaceActive(); + pPar = pPar->GetParent(); + } + } + else if( !bShow && !GetContainerEnv()->IsStub() ) + { + SoDll * pSoApp = SOAPP; + if( pSoApp->pUIShowIPEnv == this ) + pSoApp->pUIShowIPEnv = NULL; + } + + if( bShow ) + // bei Show == TRUE zuerst den Conatiner benachrichtigen + GetContainerEnv()->UIToolsShown( bShow ); + // Flag muss gesetzt werden, son kommt Resize nicht durch + bShowUITools = bShow; + + if( GetIPObj()->Owner() && pUIMenu ) + GetContainerEnv()->SetInPlaceMenu( pUIMenu, bShow ); + if( bShow ) + { + if( GetIPObj()->Owner() ) + { + if( !bTopWinResize ) + // Anordnen der Tools anstossen + DoTopWinResize(); + if( !bDocWinResize ) + // Anordnen der Tools anstossen + DoDocWinResize(); + } + } + else + { + // Anordnen der Tools anstossen + bTopWinResize = FALSE; + bDocWinResize = FALSE; + } + + ShowUITools( bShow ); + if( !bShow ) + // bei Show == FALSE zuletzt den Conatiner benachrichtigen + GetContainerEnv()->UIToolsShown( bShow ); +} + +/*************************************************************************/ +void SvInPlaceEnvironment::ShowUITools( BOOL ) +{ +} + +//========================================================================= +void SvInPlaceEnvironment::DoTopWinResize() +/* [Beschreibung] + + Es wird nur die Methode <SvInPlaceEnvironment::TopWinResize> + gerufen, wenn die UI-Tools angezeigt werden. Ausserdem wird + ein Status gespeichert, der Anzeigt, ob vor dem + <SvInPlaceEnvironment::ShowUITools> ein TopWinResize gerufen werden + muss. +*/ +{ + if( bShowUITools ) + { + bTopWinResize = TRUE; + TopWinResize(); + } + else + bTopWinResize = FALSE; +} + +//========================================================================= +void SvInPlaceEnvironment::TopWinResize() +/* [Beschreibung] + + Die Gr"osse des TopWin hat sich ge"andert. Die Methode wird vor + ShowUITools( TRUE ) mindestens einmal gerufen. + Die Defaultaktion ist: + GetContainerEnv()->SetTopToolSpacePixel( SvBorder() ); + + [!Owner] + + Die Methode wird an den Server weitergeleitet. Dies geschieht nur + wenn das pActiveObj gesetzt ist. + + [Querverweise] + + <IOleInPlaceActiveObject::ResizeBorder> +*/ +{ + bTopWinResize = TRUE; + + if( pObj->Owner() ) + GetContainerEnv()->SetTopToolSpacePixel( SvBorder() ); +} + +//========================================================================= +void SvInPlaceEnvironment::DoDocWinResize() +{ +/* [Beschreibung] + + Es wird nur die Methode <SvInPlaceEnvironment::DocWinResize> + gerufen, wenn die UI-Tools angezeigt werden. Ausserdem wird + ein Status gespeichert, der Anzeigt, ob vor dem + <SvInPlaceEnvironment::ShowUITools> ein DocWinResize gerufen werden + muss. +*/ + + if( bShowUITools ) + { + bDocWinResize = TRUE; + DocWinResize(); + } + else + bDocWinResize = FALSE; +} + +//========================================================================= +void SvInPlaceEnvironment::DocWinResize() +/* [Beschreibung] + + Die Gr"osse des DocWin hat sich ge"andert. Die Methode wird vor + ShowUITools( TRUE ) mindestens einmal gerufen. + + [!Owner] + Die Methode wird an den Server weitergeleitet. Dies geschieht nur + wenn das pActiveObj gesetzt ist. + + [Querverweise] + + <IOleInPlaceActiveObject::ResizeBorder> +*/ +{ + bDocWinResize = TRUE; +} + +/*************************************************************************/ +void SvInPlaceEnvironment::RectsChangedPixel( const Rectangle & rObjRect, + const Rectangle & rClip ) +{ + if( pObj->Owner() ) + { + if( pClipWin ) + pClipWin->SetRectsPixel( rObjRect, rClip ); + } +} + +/**************************************************************************/ +void SvInPlaceEnvironment::MakeWindows() +{ + // Fenster fuers Clipping erzeugen + pClipWin = new SvInPlaceClipWindow( pContEnv->GetEditWin() ); + // Fenster fuer den Border Erzeugen + pBorderWin = new SvInPlaceWindow( pClipWin, this ); + pBorderWin->Show(); + + // Fenstergroesse mit Beachtung der Border setzen + Rectangle aRect( pContEnv->GetObjAreaPixel() ); + pBorderWin->SetInnerPosSizePixel( aRect.TopLeft(), aRect.GetSize() ); + + // Fenster zuordnen (fuers Resize) + pClipWin->SetResizeWin( pBorderWin ); +} + +/**************************************************************************/ +void SvInPlaceEnvironment::DeleteWindows() +{ + // Fenster zuordnen (fuers Resize) + pClipWin->Hide(); + pClipWin->SetResizeWin( NULL ); + delete pBorderWin; + pBorderWin = NULL; + delete pClipWin; + pClipWin = NULL; +} + +/************************************************************************ +|* SvInPlaceEnvironment::QueryRectsChanged() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceEnvironment::QueryObjAreaPixel( Rectangle & ) const +{ +} + +/************************************************************************ +|* SvInPlaceEnvironment::LockRectsChanged(); +|* SvInPlaceEnvironment::UnlockRectsChanged(); +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceEnvironment::LockRectsChanged() +{ + nChangeRectsLockCount++; +} + +void SvInPlaceEnvironment::UnlockRectsChanged() +{ + nChangeRectsLockCount--; +} + +/************************************************************************ +|* SvInPlaceEnvironment::DoRectsChanged() +|* +|* Beschreibung: Die Methode darf den Handler nur rufen, wenn die +|* Bereiche Werte groesser als Null haben. Ausserdem muss +|* sichergestellt sein, das der Handler fuer dieselben +|* Werte nicht zweimal gerufen wird. +*************************************************************************/ +void SvInPlaceEnvironment::DoRectsChanged( BOOL bIfEqual ) +{ + if( nChangeRectsLockCount ) return; + + Rectangle aClipAreaPixel = pContEnv->GetClipAreaPixel(); + if( aClipAreaPixel.GetWidth() > 0 && aClipAreaPixel.GetHeight() > 0 ) + { + Rectangle aObjRect = pContEnv->GetObjAreaPixel(); + + if( aObjRect.GetWidth() > 0 && aObjRect.GetHeight() > 0 ) + if( bIfEqual || + (aOldObjAreaPixel != aObjRect + || aClipAreaPixel != aOldClipAreaPixel) ) + { + aOldObjAreaPixel = aObjRect; + aOldClipAreaPixel = aClipAreaPixel; + + RectsChangedPixel( aObjRect, aClipAreaPixel ); + } + } +} + +/************************************************************************* +|* SvInPlaceEnvironment::DispatchAccel() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvInPlaceEnvironment::DispatchAccel( const KeyCode & ) +{ + return FALSE; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/ipobj.cxx b/bf_so3/source/inplace/ipobj.cxx new file mode 100644 index 000000000..c8cfc9eb8 --- /dev/null +++ b/bf_so3/source/inplace/ipobj.cxx @@ -0,0 +1,412 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + +#include <vcl/bitmap.hxx> +#include <bf_so3/ipobj.hxx> +#include <tools/debug.hxx> +#include "bf_so3/ipclient.hxx" +#include <svuidlg.hrc> +#include "bf_so3/ipwin.hxx" +#include <bf_so3/ipenv.hxx> +#include "bf_so3/soerr.hxx" +#include "bf_so3/outplace.hxx" + +namespace binfilter { + +/************** class SvInPlaceObject ***********************************/ +SV_IMPL_FACTORY(SvInPlaceObjectFactory) + { + } +}; +TYPEINIT1(SvInPlaceObjectFactory,SvFactory); + +SO2_IMPL_STANDARD_CLASS1_DLL(SvInPlaceObject,SvInPlaceObjectFactory,SvEmbeddedObject, + 0x5D4C00E0L, 0x7959, 0x101B, + 0x80,0x4C,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD ) + +::IUnknown * SvInPlaceObject::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +/************************************************************************ +|* SvInPlaceObject::SvInPlaceObject() +|* +|* Beschreibung +*************************************************************************/ +#define INIT_CTOR() \ + : pObjI( NULL ) \ + , pActiveObj( NULL ) \ + , pIPEnv( NULL ) \ + , bIsUndoable( FALSE ) \ + , bDeleteIPEnv( FALSE ) + +SvInPlaceObject::SvInPlaceObject() + INIT_CTOR() +{ +} + +SvInPlaceObject::~SvInPlaceObject() +{ +} + + +/************************************************************************ +|* SvInPlaceObject::SetIPEnv() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceObject::SetIPEnv( SvInPlaceEnvironment * pFrm ) +{ + DBG_ASSERTWARNING( pIPEnv || pFrm, "already NULL" ); + DBG_ASSERT( !pIPEnv || !pFrm, "IPEnv exist" ); + pIPEnv = pFrm; +} + +/************************************************************************* +|* SvInPlaceObject::Verb() +|* +|* Beschreibung +*************************************************************************/ +ErrCode SvInPlaceObject::Verb +( + long nVerb, + SvEmbeddedClient * pCl, + Window * pWin, + const Rectangle * pWorkRectPixel +) +{ + SvInPlaceClient * pICl = GetIPClient(); + if( !pICl ) + return SvEmbeddedObject::Verb( nVerb, pCl, pWin, pWorkRectPixel ); + + ErrCode nRet = ERRCODE_NONE; + + if( Owner() ) + { + // sonst funktioniert WordPad als Container nicht + //bGroesseNachTreten = FALSE; + switch ( nVerb ) + { + case SVVERB_SHOW: + nRet = GetProtocol().UIProtocol(); + break; + case SVVERB_OPEN: + nRet = GetProtocol().EmbedProtocol(); + break; + case SVVERB_HIDE: + nRet = DoInPlaceActivate( FALSE ); + break; + case SVVERB_UIACTIVATE: + nRet = GetProtocol().UIProtocol(); + break; + case SVVERB_IPACTIVATE: + nRet = GetProtocol().IPProtocol(); + break; + default: + if( nVerb >= 0 ) + nRet = GetProtocol().UIProtocol(); + } + } + else + { + nRet = SvEmbeddedObject::Verb( nVerb, pCl, pWin, pWorkRectPixel ); + } + return nRet; +} + +/************************************************************************ +|* SvInPlaceObject::Open() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceObject::Open( BOOL bOpen ) +{ + SvEmbeddedObject::Open( bOpen ); +} + +/************************************************************************ +|* SvInPlaceObject::DoInPlaceActivate() +|* +|* Beschreibung +*************************************************************************/ +ErrCode SvInPlaceObject::DoInPlaceActivate( BOOL bActivate ) +{ + if( aProt.IsInPlaceActive() == bActivate ) + return ERRCODE_NONE; + + SvInPlaceObjectRef aAlive( this ); // wegen Reset2Connect + if( !bActivate ) + aProt.Reset2InPlaceActive(); + if( Owner() ) + aProt.InPlaceActivate( bActivate ); + return (aProt.IsInPlaceActive() == bActivate) ? + ERRCODE_NONE : ERRCODE_SO_NOT_INPLACEACTIVE; +} + +//========================================================================= +void SvInPlaceObject::InPlaceActivate +( + BOOL bActivate /* Zeigt an, ob aktiviert oder deaktiviert wird. */ +) +/* [Beschreibung] + + Diese Methode zeigt das IP-Window an. Wenn bActive == TRUE ist, + wird die Methode <SvInPLaceObject::DoMergePalette()> gerufen, die + daf"ur sorgt, dass die Palette zwischen Container und Objekt + abgestimmt werden kann. + Ist bActive == FALSE, dann wird das Container-Menu freigegeben + und das in <SvInPlaceObject::SetIPEnv> gemerkte + <SvInPlaceEnvironment> vergessen. + + [Anmerkung] + + Sollte die IP-Aktivierung scheitern, muss das <SvInPlaceEnvironment> + mit "SetIPEnv( NULL )" zur"uckgesetzt werden. + + [Beispiel] + + ...::InPlaceActivate( BOOL bActivate ) + { + if( bActivate ) + { + SvContainerEnvironment * pEnv; + pEnv = GetIPClient()->GetEnv(); + pMyEnv = new MyInPlaceEnvironment( pEnv, this ); + + // wird in die Verwaltung eingesetzt + SetIPEnv( pMyEnv ); + + if( "Kann nicht aktiviert werden" ) + { + SetIPEnv( NULL ); + DELETEZ( pMyEnv ); + DoClose(); + return; + } + } + SvInPlaceObject::InPlaceActivate( bActivate ); + if( bActivate ) + { + DELETEZ( pMyEnv ); + } + } + + + [Querverweise] + + <SvEditProtocol> +*/ +{ + if( Owner() ) + { + if( bActivate ) + { + DBG_ASSERT( pIPEnv, "set SvInPlaceEnvironment in InPlaceActivate bevor call to superclass" ); + + if( GetClient()->Owner() ) + // sonst nur bei Ole-SetInPlaceActiveObj + DoMergePalette(); + } + else + { + SendViewChanged(); + } + pIPEnv->DoShowIPObj( bActivate ); + } + else + { + if( bActivate ) + { + // Weil SetActiveObject zu spaet kommt + if( !pIPEnv ) + { + pIPEnv = new SvInPlaceEnvironment( GetIPClient()->GetEnv(), this ); + bDeleteIPEnv = TRUE; + } + } + } + + if( !bActivate && pIPEnv ) + { + if( bDeleteIPEnv ) + { + delete pIPEnv; + bDeleteIPEnv = FALSE; + } + pIPEnv = NULL; + } +} + +/************************************************************************ +|* SvInPlaceObject::DoUIActivate() +|* +|* Beschreibung +*************************************************************************/ +ErrCode SvInPlaceObject::DoUIActivate( BOOL bActivate ) +{ + SvInPlaceObjectRef aAlive( this ); // wegen Reset2Connect + if( aProt.IsUIActive() == bActivate ) + return ERRCODE_NONE; + if( !bActivate ) + aProt.Reset2UIActive(); + if( Owner() ) + { + aProt.UIActivate( bActivate ); + } + return (aProt.IsUIActive() == bActivate) ? + ERRCODE_NONE : ERRCODE_SO_NOT_INPLACEACTIVE; +} + +/************************************************************************ +|* SvInPlaceObject::UIActivate() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceObject::UIActivate( BOOL bActivate ) +{ + // bei !bActivate siehe IPClient::UIActivate + if( bActivate ) + pIPEnv->ShowIPObj( bActivate ); + pIPEnv->DoShowUITools( bActivate ); +} + +/************************************************************************ +|* SvInPlaceObject::TopWinActivate() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceObject::TopWinActivate( BOOL ) +{ +} + + +/************************************************************************ +|* SvInPlaceObject::DocWinActivate() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceObject::DocWinActivate( BOOL bActivate ) +{ + if( pIPEnv ) + { + if( GetProtocol().IsUIActive() ) + pIPEnv->DoShowUITools( bActivate ); + } +} + +/************************************************************************ +|* SvInPlaceObject::DoMergePalette() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvInPlaceObject::DoMergePalette() +{ + return FALSE; +} + +/************************************************************************ +|* SvInPlaceObject::MergePalette() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvInPlaceObject::MergePalette( const Palette & ) +{ + return FALSE; +} + +/************************************************************************* +|* SvInPlaceObject::SetVisArea() +|* +|* Beschreibung +*************************************************************************/ +void SvInPlaceObject::SetVisArea( const Rectangle & rVisArea ) +{ + SvEmbeddedObject::SetVisArea( rVisArea ); +} + +/************************************************************************* +|* SvInPlaceObject::ReactivateAndUndo() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvInPlaceObject::ReactivateAndUndo() +{ + return FALSE; +} + +//========================================================================= +//==============class SvDeathObject======================================== +//========================================================================= +SvDeathObject::SvDeathObject +( + const Rectangle & rVisArea /* Die VisArea wird sofort eingesetzt */ +) +/* [Beschreibung] + + Das Objekt wird mit der VisArea erzeugt. Es ruft im Konstruktor + <SvPersist::DoInitNew>. Es darf also nicht von aussen gerufen werden. +*/ +{ + AddNextRef(); + DoInitNew( NULL ); + SetVisArea( rVisArea ); + RestoreNoDelete(); + ReleaseRef(); +} + +//========================================================================= +ErrCode SvDeathObject::Verb +( + long, + SvEmbeddedClient *, + Window *, + const Rectangle * +) +/* [Beschreibung] + + Lehnt alle Verben ab und gibt immer FALSE zur"uck. +*/ +{ + return ERRCODE_SO_GENERALERROR; +} + +//========================================================================= +#define SoResId( id ) ResId( id, *SOAPP->GetResMgr() ) +void SvDeathObject::Draw +( + OutputDevice * pOut, + const JobSetup &, + USHORT +) +/* [Beschreibung] + + Gibt ein Symbol aus, dass das Objekt nicht geladen werden konnte. +*/ +{ + Rectangle aR = GetVisArea(); + Bitmap aBmp( SoResId( BMP_OLEOBJ ) ); + pOut->DrawBitmap( aR.TopLeft(), aR.GetSize(), aBmp ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/makefile.mk b/bf_so3/source/inplace/makefile.mk new file mode 100644 index 000000000..5b7a4b98c --- /dev/null +++ b/bf_so3/source/inplace/makefile.mk @@ -0,0 +1,54 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. +SUBPRJ=..$/.. + +PRJINC=$(SUBPRJ) + +PRJNAME=binfilter +TARGET=so3_inplace + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk +.INCLUDE : $(SUBPRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/applet2.obj \ + $(SLO)$/outplace.obj \ + $(SLO)$/embobj.obj \ + $(SLO)$/client.obj \ + $(SLO)$/ipobj.obj \ + $(SLO)$/ipclient.obj \ + $(SLO)$/protocol.obj \ + $(SLO)$/soconv.obj \ + $(SLO)$/ipenv.obj \ + $(SLO)$/plugin.obj + + +EXCEPTIONSFILES= \ + $(SLO)$/applet2.obj \ + $(SLO)$/plugin.obj + + +# --- Tagets ------------------------------------------------------- + + +.INCLUDE : target.mk diff --git a/bf_so3/source/inplace/outplace.cxx b/bf_so3/source/inplace/outplace.cxx new file mode 100644 index 000000000..73870b1b6 --- /dev/null +++ b/bf_so3/source/inplace/outplace.cxx @@ -0,0 +1,1392 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/datatransfer/XSystemTransferable.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <cppuhelper/implbase2.hxx> + +#ifdef WNT +#include <../ole/socont.h> +#include <vcl/sysdata.hxx> +#endif + +#include <tools/debug.hxx> +#include <tools/cachestr.hxx> +#include <sot/storinfo.hxx> +#include <sot/stg.hxx> +#include <vcl/gdimtf.hxx> +#include <vcl/cvtgrf.hxx> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> +#include <svuidlg.hrc> +#include <bf_so3/svstor.hxx> +#include "bf_so3/soerr.hxx" +#include <soimpl.hxx> +#include "insdlg.hxx" +#include "bf_so3/outplace.hxx" +#include <viscache.hxx> +#include <osl/module.hxx> +#include <sot/formats.hxx> +#include <bf_svtools/filter.hxx> +#include <comphelper/classids.hxx> +#include <rtl/process.h> +#include <unotools/tempfile.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <bf_svtools/wmf.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::datatransfer; + +namespace binfilter { + +#ifdef WNT +static BOOL bOleInited = FALSE; +inline void InitOle() +{ + if( !bOleInited ) + { + OleInitialize( NULL ); + bOleInited = TRUE; + } +} + +class OLEWrapper_Impl : public cppu::WeakImplHelper2 +< + com::sun::star::lang::XComponent, + com::sun::star::lang::XUnoTunnel +> +{ + CSO_Cont* pOleContent; + +public: + + OLEWrapper_Impl( CSO_Cont* pCont ) + : pOleContent( pCont ) + {} + + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException) ; + + // XComponent + virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); +}; + +sal_Int64 SAL_CALL OLEWrapper_Impl::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException) +{ + SvGlobalName aName; + aName.MakeFromMemory( (void*) aIdentifier.getConstArray() ); + if ( aName.GetCLSID() == pOleContent->GetCLSID() ) + { + return (sal_Int64) (IUnknown*) pOleContent->GetOleObj(); + } + else + return 0; +} + +void SAL_CALL OLEWrapper_Impl::dispose() throw (::com::sun::star::uno::RuntimeException) +{ +} + +void SAL_CALL OLEWrapper_Impl::addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >&) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void SAL_CALL OLEWrapper_Impl::removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >&) throw (::com::sun::star::uno::RuntimeException) +{ +} +#endif + +//------------------------------------------------------------------------------- +BOOL Impl_OlePres::Read( SvStream & rStm ) +{ + ULONG nBeginPos = rStm.Tell(); + INT32 n; + rStm >> n; + if( n != -1 ) + { + pBmp = new Bitmap; + rStm >> *pBmp; + if( rStm.GetError() == SVSTREAM_OK ) + { + nFormat = FORMAT_BITMAP; + aSize = pBmp->GetPrefSize(); + MapMode aMMSrc; + if( !aSize.Width() || !aSize.Height() ) + { + // letzte Chance + aSize = pBmp->GetSizePixel(); + aMMSrc = MAP_PIXEL; + } + else + aMMSrc = pBmp->GetPrefMapMode(); + MapMode aMMDst( MAP_100TH_MM ); + aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst ); + return TRUE; + } + else + { + delete pBmp; + pBmp = NULL; + + pMtf = new GDIMetaFile(); + rStm.ResetError(); + rStm >> *pMtf; + if( rStm.GetError() == SVSTREAM_OK ) + { + nFormat = FORMAT_GDIMETAFILE; + aSize = pMtf->GetPrefSize(); + MapMode aMMSrc = pMtf->GetPrefMapMode(); + MapMode aMMDst( MAP_100TH_MM ); + aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst ); + return TRUE; + } + else + { + delete pMtf; + pMtf = NULL; + } + } + + } + + rStm.ResetError(); + rStm.Seek( nBeginPos ); + nFormat = ReadClipboardFormat( rStm ); + // JobSetup, bzw. TargetDevice ueberlesen + // Information aufnehmen, um sie beim Schreiben nicht zu verlieren + nJobLen = 0; + rStm >> nJobLen; + if( nJobLen >= 4 ) + { + nJobLen -= 4; + if( nJobLen ) + { + pJob = new BYTE[ nJobLen ]; + rStm.Read( pJob, nJobLen ); + } + } + else + { + rStm.SetError( SVSTREAM_GENERALERROR ); + return FALSE; + } + UINT32 nAsp; + rStm >> nAsp; + USHORT nSvAsp = USHORT( nAsp ); + SetAspect( nSvAsp ); + rStm.SeekRel( 4 ); //L-Index ueberlesen + rStm >> nAdvFlags; + rStm.SeekRel( 4 ); //Compression + UINT32 nWidth = 0; + UINT32 nHeight = 0; + UINT32 nSize = 0; + rStm >> nWidth >> nHeight >> nSize; + aSize.Width() = nWidth; + aSize.Height() = nHeight; + + if( nFormat == FORMAT_GDIMETAFILE ) + { + pMtf = new GDIMetaFile(); + ReadWindowMetafile( rStm, *pMtf, NULL ); + } + else if( nFormat == FORMAT_BITMAP ) + { + pBmp = new Bitmap(); + rStm >> *pBmp; + } + else + { + BYTE* p = new BYTE[ nSize ]; + rStm.Read( p, nSize ); + delete [] p; + return FALSE; + } + return TRUE; +} + +/************************************************************************/ +void Impl_OlePres::Write( SvStream & rStm ) +{ + WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE ); + rStm << (INT32)(nJobLen +4); // immer leeres TargetDevice + if( nJobLen ) + rStm.Write( pJob, nJobLen ); + rStm << (UINT32)nAspect; + rStm << (INT32)-1; //L-Index immer -1 + rStm << (INT32)nAdvFlags; + rStm << (INT32)0; //Compression + rStm << (INT32)aSize.Width(); + rStm << (INT32)aSize.Height(); + ULONG nPos = rStm.Tell(); + rStm << (INT32)0; + + if( GetFormat() == FORMAT_GDIMETAFILE && pMtf ) + { + // Immer auf 1/100 mm, bis Mtf-Loesung gefunden + // Annahme (keine Skalierung, keine Org-Verschiebung) + DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ), + "X-Skalierung im Mtf" ); + DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ), + "Y-Skalierung im Mtf" ); + DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(), + "Origin-Verschiebung im Mtf" ); + MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit(); + if( MAP_100TH_MM != nMU ) + { + Size aPrefS( pMtf->GetPrefSize() ); + Size aS( aPrefS ); + aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM ); + + pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ), + Fraction( aS.Height(), aPrefS.Height() ) ); + pMtf->SetPrefMapMode( MAP_100TH_MM ); + pMtf->SetPrefSize( aS ); + } + WriteWindowMetafileBits( rStm, *pMtf ); + } + else + { + OSL_FAIL( "unknown format" ); + } + ULONG nEndPos = rStm.Tell(); + rStm.Seek( nPos ); + rStm << (UINT32)(nEndPos - nPos - 4); + rStm.Seek( nEndPos ); +} + +Impl_OlePres * CreateCache_Impl( SotStorage * pStor ) +{ + SotStorageStreamRef xOleObjStm =pStor->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ), + STREAM_READ | STREAM_NOCREATE ); + if( xOleObjStm->GetError() ) + return NULL; + SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm ); + if( xOleObjStor->GetError() ) + return NULL; + + String aStreamName; + if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) ) ) ) + aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) ); + else if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ) ) ) + aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ); + + if( aStreamName.Len() == 0 ) + return NULL; + + + for( USHORT i = 1; i < 10; i++ ) + { + SotStorageStreamRef xStm = xOleObjStor->OpenSotStream( aStreamName, + STREAM_READ | STREAM_NOCREATE ); + if( xStm->GetError() ) + break; + + xStm->SetBufferSize( 8192 ); + Impl_OlePres * pEle = new Impl_OlePres( 0 ); + if( pEle->Read( *xStm ) && !xStm->GetError() ) + { + if( pEle->GetFormat() == FORMAT_GDIMETAFILE || pEle->GetFormat() == FORMAT_BITMAP ) + return pEle; + } + delete pEle; + aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres00" ) ); + aStreamName += String( i ); + }; + return NULL; +} + + +//========================================================================= +struct SvOutPlace_Impl +/* [Beschreibung] + + In diesem struct werden sich Member von SvOutPlaceObject gemerkt, um + nicht immer inkompatibel zu werden. +*/ +{ + SvVerbList aVerbs; + Impl_OlePres * pOP; + UINT32 dwAspect; + bool bSetExtent; + SvStorageRef xWorkingStg; + BOOL bGetVisAreaFromInfoEle; // can only by read after load in FF 4.0 + BOOL bGetVisAreaFromOlePress; // can only by read if OlePress representation is there + ::com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > m_xComponent; +#ifdef WNT + CSO_Cont * pSO_Cont; +#endif + + SvOutPlace_Impl() + : pOP( NULL ) + , dwAspect( ASPECT_CONTENT ) + , bSetExtent( false ) + , bGetVisAreaFromInfoEle( FALSE ) + , bGetVisAreaFromOlePress( FALSE ) +#ifdef WNT + , pSO_Cont( NULL ) +#endif + {} +}; + +//========================================================================= +//============== SvOutPlaceObject =========================================== +//========================================================================= +SO2_IMPL_BASIC_CLASS1( SvOutPlaceObject, SvFactory, SvInPlaceObject, + SvGlobalName( SO3_OUT_CLASSID ) ) + +//========================================================================= +SvOutPlaceObject::SvOutPlaceObject() + : pImpl( new SvOutPlace_Impl ) +/* [Beschreibung] + + Konstruktor der Klasse SvOutPlaceObject. Die Verbliste und das + Format werden global initialisiert. +*/ +{ +} + +//========================================================================= +SvOutPlaceObject::~SvOutPlaceObject() +/* [Beschreibung] + + Destruktor der Klasse SvOutPlaceObject. +*/ +{ +#ifdef WNT + if( pImpl->pSO_Cont ) + { + pImpl->pSO_Cont->Close( FALSE ); + pImpl->pSO_Cont->Release(); + if ( pImpl->m_xComponent.is() ) + { + pImpl->m_xComponent->dispose(); + pImpl->m_xComponent = NULL; + } + } + +#endif + delete pImpl->pOP; + delete pImpl; +} + +#ifdef WNT +void SvOutPlaceObject::ClearCache() +{ + delete pImpl->pOP; + pImpl->pOP = NULL; +} + +SotStorage * SvOutPlaceObject::GetWorkingStorage() +{ + return pImpl->xWorkingStg; +} +#endif + +//========================================================================= +const SvVerbList & SvOutPlaceObject::GetVerbList() const +/* [Beschreibung] + + Liefert eine Liste der Aktionen zurueck, die auf diesem Objekt ausgefuehrt werden koennen. +*/ +{ +#ifdef WNT + if( !pImpl->aVerbs.Count() ) + { + InitOle(); + ((SvOutPlaceObject *)this)->LoadSO_Cont(); + if( pImpl->pSO_Cont && pImpl->pSO_Cont->GetOleObj() ) + { + LPENUMOLEVERB pEnum; + if( SUCCEEDED( pImpl->pSO_Cont->GetOleObj()->EnumVerbs( &pEnum ) ) ) + { + #define MAX_ELE 20 + OLEVERB szEle[ MAX_ELE ]; + HRESULT nErr; + ULONG nNo; + // Aktuelle Elemente holen und hochzaehlen + do + { + nErr = pEnum->Next( MAX_ELE, szEle, &nNo ); + if( S_OK == GetScode( nErr ) + || S_FALSE == GetScode( nErr ) ) + { + for( ULONG i = 0; i < nNo; i++ ) + { + sal_Unicode * pName = reinterpret_cast<sal_Unicode*>(szEle[ i ].lpszVerbName); + if( pName ) + { + String aName; + while( *pName ) + aName += *pName++; + + // Windows accelerator to vcl accelerator + const sal_Unicode* pStr = aName.GetBuffer(); + USHORT n = 0; + while ( *pStr ) + { + if ( *pStr == '&' ) + { + if ( *(pStr+1) == '&' ) + { + aName.Erase( n, 1 ); + pStr = aName.GetBuffer() + n; + } + else + { + aName.SetChar(n, '~' ); + pStr = aName.GetBuffer() + n; + } + } + else + { + if ( *pStr == '~' ) + { + aName.Insert( '~', n ); + pStr = aName.GetBuffer() + n; + pStr++; + n++; + } + } + pStr++; + n++; + } + + BOOL bNeverDirty = FALSE; + BOOL bOnContMenu = FALSE; + if( szEle[ i ].grfAttribs & OLEVERBATTRIB_NEVERDIRTIES ) + bNeverDirty = TRUE; + if( szEle[ i ].grfAttribs & OLEVERBATTRIB_ONCONTAINERMENU ) + bOnContMenu = TRUE; + SvVerb aVerb( szEle[ i ].lVerb, + aName, + bNeverDirty, + bOnContMenu ); + pImpl->aVerbs.Append( aVerb ); + } + } + } + else + break; + } + while( nNo == MAX_ELE ); + pEnum->Release(); + } + } + } +#endif + return pImpl->aVerbs; +} + +//========================================================================= +void SvOutPlaceObject::DataChanged_Impl +( + BOOL bOnlyEmbedSource /* TRUE, es "andert sich nur die persistenten + Daten. FALSE, auch das MetaFile "andert + sich */ +) +/* [Beschreibung] + + Wenn die Daten sich "andern, muss das Modiy-Flag gesetzt werden. + Ausserdem m"ussen alle angemeldeten Advises benachrichtigt werden. + In Abh"angigkeit des Parameters wird angezeigt, dass sich auch + die View und das Mtf ge"andert hat. +*/ +{ + if( IsEnableSetModified() ) + { // nicht im init oder deinit + SetModified( TRUE ); + if( bOnlyEmbedSource ) + ViewChanged( ASPECT_CONTENT ); + } +} + +//========================================================================= +#ifdef WNT +void SvOutPlaceObject::LoadSO_Cont() +{ + if( !pImpl->pSO_Cont && pImpl->xWorkingStg->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ) ) ) + { + Rectangle aVisRect = GetVisArea( ASPECT_CONTENT ); + //Rectangle aVisRect = GetVisArea( (UINT16)pImpl->dwAspect ); + RECTL aRect; + aRect.top = aVisRect.Top(); + aRect.left = aVisRect.Left(); + if( aVisRect.Right() == RECT_EMPTY ) + aRect.right = aRect.left; + else + aRect.right = (aVisRect.Right() +1); + if( aVisRect.Bottom() == RECT_EMPTY ) + aRect.bottom = aRect.top; + else + aRect.bottom = (aVisRect.Bottom() +1); + + InitOle(); + pImpl->pSO_Cont = new CSO_Cont( 1, NULL, this ); + pImpl->pSO_Cont->AddRef(); + pImpl->pSO_Cont->Load( pImpl->xWorkingStg, pImpl->dwAspect, pImpl->bSetExtent, aRect ); + } +} +#endif + +//========================================================================= +void SvOutPlaceObject::FillClass +( + SvGlobalName * pClassName, /* Der Typ der Klasse */ + ULONG * pFormat, /* Das Dateiformat in dem geschrieben wird */ + String * pAppName, /* Der Applikationsname */ + String * pFullTypeName, /* Der genaue Name des Typs */ + String * pShortTypeName, /* Der kurze Name des Typs */ + long /*nFileFormat*/ /* F"ur dieses Office-Format sollen die + Parameter gef"ullt werden */ +) const +/* [Beschreibung] + + Mit dieser Methode werden Informationen "uber das Objekt angefordert. + Wird das Objekt gesichert, dann werden diese Informationen in den + Storage geschrieben. + + [Anmerkung] + + Da diese Information nicht vom Applet ermittelt werden kann, m"ussen + Standardwerte angegeben werden. Dies bedeutet, von aussen gibt es + nur den Typ Applet, in den man nicht hinein schauen kann. +*/ +{ + *pClassName = *GetSvFactory(); + *pFormat = SOT_FORMATSTR_ID_OUTPLACE_OBJ; + *pAppName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "OutPlace Object 1.0" ) ); + *pFullTypeName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "OutPlace Object 1.0" ) ); + *pShortTypeName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "OutPlace Object" ) ); +} + + +#ifdef WNT +extern "C" { +typedef UINT STDAPICALLTYPE OleUIInsertObjectW_Type(LPOLEUIINSERTOBJECTW); +typedef UINT STDAPICALLTYPE OleUIInsertObjectA_Type(LPOLEUIINSERTOBJECTA); +} +#endif + +SvInPlaceObjectRef SvOutPlaceObject::InsertObject +( + Window *, + SvStorage * pIStorage, + BOOL & bOk, + const SvGlobalName& rName, + String & rFileName +) +{ + SvOutPlaceObjectRef xRet; + bOk = TRUE; + //rTypeName.Erase(); + rFileName.Erase(); +#ifdef WNT + InitOle(); + OLEUIINSERTOBJECT io; + DWORD dwData=0; + TCHAR szFile[CCHPATHMAX]; + + memset(&io, 0, sizeof(io)); + + io.cbStruct=sizeof(io); + io.hWndOwner=GetActiveWindow(); + + szFile[0]=0; + io.lpszFile=szFile; + io.cchFile=CCHPATHMAX; + + io.dwFlags=IOF_SELECTCREATENEW | IOF_DISABLELINK; + io.clsid = rName.GetCLSID(); + + osl::Module aOleDlgLib; + if( !aOleDlgLib.load( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "oledlg" ) ) ) ) + return &xRet; + +#ifdef UNICODE + OleUIInsertObjectW_Type * pInsertFct = (OleUIInsertObjectW_Type *) + aOleDlgLib.getSymbol( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "OleUIInsertObjectW" ) ) ); +#else + OleUIInsertObjectA_Type * pInsertFct = (OleUIInsertObjectA_Type *) + aOleDlgLib.getSymbol( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "OleUIInsertObjectA" ) ) ); +#endif + if( !pInsertFct ) + return &xRet; + + //if (OLEUI_OK==uTemp) + { + TENANTTYPE tType; + LPVOID pv; + FORMATETC fe; + + SETDefFormatEtc(fe, 0, TYMED_NULL); + + if (io.dwFlags & IOF_SELECTCREATENEW) + { + tType=TENANTTYPE_EMBEDDEDOBJECT; + pv=&io.clsid; + } + else + { + tType=TENANTTYPE_EMBEDDEDFILE; + pv=szFile; + rFileName.Assign( String( szFile, osl_getThreadTextEncoding() ) ); + } + + if ((io.dwFlags & IOF_CHECKDISPLAYASICON) + && NULL!=io.hMetaPict) + { + fe.dwAspect=DVASPECT_ICON; + dwData=(DWORD)(UINT)io.hMetaPict; + } + + xRet = new SvOutPlaceObject(); + xRet->DoInitNew( pIStorage ); + + xRet->pImpl->pSO_Cont = new CSO_Cont( 1, NULL, xRet ); + xRet->pImpl->pSO_Cont->AddRef(); + + POINTL ptl; + SIZEL szl; + UINT uRet = xRet->pImpl->pSO_Cont->Create(tType, pv, &fe, &ptl, &szl, pIStorage, NULL, dwData); + if (CREATE_FAILED==uRet) + { + xRet = SvOutPlaceObjectRef(); + bOk = FALSE; + } + else + { + xRet->pImpl->pSO_Cont->Invalidate(); + if( tType == TENANTTYPE_EMBEDDEDFILE ) + xRet->pImpl->pSO_Cont->Update(); + + xRet->SetVisAreaSize( Size( szl.cx, szl.cy ) ); + WIN_BOOL fSetExtent; + xRet->pImpl->pSO_Cont->GetInfo( xRet->pImpl->dwAspect, fSetExtent ); + xRet->pImpl->bSetExtent = fSetExtent; + + //Free this regardless of what we do with it. + StarObject_MetafilePictIconFree(io.hMetaPict); + } + } +#else + (void)pIStorage; + (void)rName; +#endif + return &xRet; +} + + +//========================================================================= +struct SO3_DLLPRIVATE SvObjectServerListHolder +{ + ::binfilter::SvObjectServerList mObjList; + SvObjectServerListHolder() { mObjList.FillInsertObjects(); } +}; + +const ::binfilter::SvObjectServer* SvOutPlaceObject::GetInternalServer_Impl( const SvGlobalName& aGlobName ) +{ + static SvObjectServerListHolder aObj; + + const ::binfilter::SvObjectServer* pObjServ = NULL; + + if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) ) + pObjServ = aObj.mObjList.Get( SvGlobalName( SO3_SW_CLASSID_60 ) ); + else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) ) + pObjServ = aObj.mObjList.Get( SvGlobalName( SO3_SC_CLASSID_60 ) ); + else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) ) + pObjServ = aObj.mObjList.Get( SvGlobalName( SO3_SIMPRESS_CLASSID_60 ) ); + else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) ) + pObjServ = aObj.mObjList.Get( SvGlobalName( SO3_SDRAW_CLASSID_60 ) ); + else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) ) + pObjServ = aObj.mObjList.Get( SvGlobalName( SO3_SM_CLASSID_60 ) ); + else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) ) + pObjServ = aObj.mObjList.Get( SvGlobalName( SO3_SCH_CLASSID_60 ) ); + + return pObjServ; +} + +#ifdef WNT + +/* The function creates an wrapper for an MS Ole object. The argument xTrans provides the data + needed for the creation of the MS OLE object. +*/ +SvInPlaceObjectRef SvOutPlaceObject::CreateFromData( const Reference<XTransferable>& xTrans, + SvStorage* pIStorage) +{ + SvOutPlaceObjectRef xRet; + InitOle(); + IDataObject * pDO = NULL; + Reference<XSystemTransferable> xSys( xTrans, UNO_QUERY); + if( xSys.is()) + { + sal_uInt8 arId[16]; + rtl_getGlobalProcessId( arId); + + Any data= xSys->getData( Sequence<sal_Int8>( (sal_Int8*) arId, 16)); + sal_uInt32 npData; + if( data >>= npData) + { + pDO= reinterpret_cast<IDataObject*>( npData); + + TENANTTYPE tType; + HRESULT hr = OleQueryCreateFromData( pDO ); + if( S_OK == GetScode( hr ) ) + tType=TENANTTYPE_EMBEDDEDOBJECTFROMDATA; + else if( OLE_S_STATIC == GetScode( hr ) ) + tType=TENANTTYPE_STATIC; + else + { + pDO->Release(); + return &xRet; + } + xRet = new SvOutPlaceObject(); + xRet->DoInitNew( pIStorage ); + + xRet->pImpl->pSO_Cont = new CSO_Cont( 1, NULL, xRet ); + xRet->pImpl->pSO_Cont->AddRef(); + POINTL ptl; + SIZEL szl; + FORMATETC fe; + SETDefFormatEtc(fe, 0, TYMED_NULL); + UINT uRet = xRet->pImpl->pSO_Cont->Create(tType, pDO, &fe, &ptl, &szl, pIStorage, NULL, 0 ); + + if (CREATE_FAILED==uRet) + xRet = SvOutPlaceObjectRef(); + else + { + xRet->pImpl->pSO_Cont->Update(); + xRet->pImpl->pSO_Cont->Invalidate(); + xRet->SetVisAreaSize( Size( szl.cx, szl.cy ) ); + WIN_BOOL fSetExtent; + xRet->pImpl->pSO_Cont->GetInfo( xRet->pImpl->dwAspect, fSetExtent ); + xRet->pImpl->bSetExtent = fSetExtent; + } + pDO->Release(); + } + } + return &xRet; + +} + +//========================================================================= +SvGlobalName SvOutPlaceObject::GetCLSID( const String & rFileName ) +{ + SvGlobalName aCLSID; + InitOle(); + OLECHAR szFile[CCHPATHMAX]; + + if( rFileName.Len() >= CCHPATHMAX ) + return aCLSID; + + const sal_Unicode * pStr = rFileName.GetBuffer(); + int i = 0; + while( *pStr ) + szFile[i++] = *pStr++; + szFile[i]=0; + + CLSID aClsId; + if( SUCCEEDED( GetClassFile( szFile, &aClsId ) ) ) + { + // this method should return no CLSID in case of native XML format + SvGlobalName aFromWin = SvGlobalName( aClsId ); + if ( !GetInternalServer_Impl( aFromWin ) ) + aCLSID = SvGlobalName( aClsId ); + } + return aCLSID; +} +#endif + +//========================================================================= +void SvOutPlaceObject::Open( BOOL bOpen ) +{ +#ifdef WNT + if( !bOpen ) + { + if( pImpl->pSO_Cont ) + { + WIN_BOOL fSetExtent; + pImpl->pSO_Cont->GetInfo( pImpl->dwAspect, fSetExtent ); + pImpl->bSetExtent = fSetExtent; + pImpl->pSO_Cont->Close( IsAutoSave() && IsModified() && !IsHandsOff() ); + pImpl->pSO_Cont->Release(); + pImpl->pSO_Cont = NULL; + if ( pImpl->m_xComponent.is() ) + { + pImpl->m_xComponent->dispose(); + pImpl->m_xComponent = NULL; + } + } + } +#endif + SvInPlaceObject::Open( bOpen ); +} + +//========================================================================= +void SvOutPlaceObject::Embed +( + BOOL bActivate /* TRUE, OutPlace Aktivierung beginnt. + FALSE, OutPlace Aktivierung endet. */ +) +/* [Beschreibung] + + Das Objekt wird PutPlace aktiviert oder deaktiviert. + + [Querverweise] + + <SvInPlaceObject::Embed()> +*/ +{ + SvInPlaceObject::Embed( bActivate ); +#ifdef WNT + if( !bActivate ) + { + if( pImpl->pSO_Cont ) + { + SIZEL aS; + if ( pImpl->pSO_Cont->GetExtent( &aS ) ) + SvInPlaceObject::SetVisArea( Rectangle( Point(), Size( aS.cx, aS.cy ) ) ); + } + } +#endif +} + +//========================================================================= +ErrCode SvOutPlaceObject::Verb +( + long nVerb, /* welche Art des Aktivierens ist + gew"unscht */ + SvEmbeddedClient *, /* Callback-Svhnittstelle des Aufruffers */ + Window * pWin, /* Parent auf dem aktiviert werden soll */ + const Rectangle * /* Position und Gr"osse, an der das Objekt + aktiviert werden soll */ +) +/* [Beschreibung] + + Es wird Versucht ein Applet zu starten. Es gibt nur die M"oglichkeit + InPlace zu aktivieren. Deshalb sind auch nur die Verben gestattet, + die dies ausl"osen. + + [R"uckgabewert] + + ErrCode ERRCODE_NONE, es wurde InPlace aktiviert. + ERRCODE_SO_NOT_INPLACEACTIVE, es wurde nicht InPlace + aktiviert. + + [Querverweise] + + <SvPseudoObject::Verb> +*/ +{ + ErrCode nRet = ERRCODE_SO_GENERALERROR; +#ifdef WNT + DoOpen( TRUE ); + LoadSO_Cont(); + if( pImpl->pSO_Cont ) + { + HWND hWnd = NULL; + if( pWin ) + { + const SystemChildData* pCD = pWin->GetSystemData(); + if( pCD ) + // hier wird das C++-Wrapper-Objekt fuer ein Java-Objekt erzeugt + hWnd = (HWND)pCD->hWnd; + } + if( pImpl->pSO_Cont->Activate(nVerb, hWnd) ) + { + pImpl->pSO_Cont->Update(); + nRet = ERRCODE_NONE; + } + } +#else + (void)pWin; + (void)nVerb; +#endif + + return nRet; +} + +//========================================================================= +void SvOutPlaceObject::SetVisArea +( + const Rectangle & rVisArea /* neue Position und Groesse des + sichtbaren Ausschnitts */ +) +/* [Beschreibung] + + Der sichtbare Ausschnitt beginnt immer an der Position (0, 0). +*/ +{ + Rectangle aOldVisArea = GetVisArea( + sal::static_int_cast< USHORT >( GetViewAspect() ) ); + if( rVisArea.GetSize() != aOldVisArea.GetSize() ) + { + if( !aOldVisArea.IsEmpty() ) + pImpl->bSetExtent = true; + + aOldVisArea.SetSize( rVisArea.GetSize() ); + SvInPlaceObject::SetVisArea( aOldVisArea ); +#ifdef WNT + if( pImpl->pSO_Cont ) + { + SIZEL aS = { rVisArea.GetSize().Width(), rVisArea.GetSize().Height() }; + pImpl->pSO_Cont->SizeSet( &aS, FALSE, TRUE ); + } +#endif + + DataChanged_Impl( TRUE ); + } +} + +//========================================================================= +Rectangle SvOutPlaceObject::GetVisArea( USHORT nAspect ) const +{ + if( pImpl->bGetVisAreaFromInfoEle ) + { + pImpl->bGetVisAreaFromInfoEle = FALSE; + SvPersist * pPar = GetParent(); + if( pPar ) + { + SvInfoObject * p = pPar->Find( this ); + SvEmbeddedInfoObject * pEle = PTR_CAST( SvEmbeddedInfoObject, p ); + if( pEle ) + { + BOOL bIsEnableSetModified = IsEnableSetModified(); + if( bIsEnableSetModified ) + ((SvOutPlaceObject *)this)->EnableSetModified( FALSE ); + ((SvOutPlaceObject *)this)->SetVisArea( pEle->GetInfoVisArea() ); + if( bIsEnableSetModified ) + ((SvOutPlaceObject *)this)->EnableSetModified( TRUE ); + } + else if( p ) + // a bug in 4.0 file formats, save SvInfoObject instead of SvEmbeddedInfoObject + ((SvOutPlaceObject *)this)->SvInPlaceObject::SetVisArea( Rectangle( Point(), Size( 5000, 5000 ) ) ); + } + } + else if( pImpl->bGetVisAreaFromOlePress ) + { + pImpl->bGetVisAreaFromOlePress = FALSE; + + if( !pImpl->pOP ) + pImpl->pOP = CreateCache_Impl( pImpl->xWorkingStg ); + + if( pImpl->pOP ) + { + GDIMetaFile * pMtf = pImpl->pOP->GetMetaFile(); + if( pMtf ) + { + ((SvOutPlaceObject *)this)->SetVisArea( Rectangle( Point(), pMtf->GetPrefSize() ) ); + } + else + { + Bitmap * pBmp = pImpl->pOP->GetBitmap(); + if( pBmp ) + ((SvOutPlaceObject *)this)->SetVisArea( Rectangle( Point(), pBmp->GetPrefSize() ) ); + } + } + } + + Rectangle aRect = SvInPlaceObject::GetVisArea( nAspect ); +#ifdef WNT + if( pImpl->pSO_Cont && nAspect == GetViewAspect() ) + { + SIZEL aS; + if ( pImpl->pSO_Cont->GetExtent( &aS ) ) + aRect.SetSize( Size( aS.cx, aS.cy ) ); + } +#endif + return aRect; +} + +UINT32 SvOutPlaceObject::GetViewAspect() const +{ + if ( pImpl->dwAspect ) + return pImpl->dwAspect; + + SvPersist * pPar = GetParent(); + if( pPar ) + { + SvInfoObject * p = pPar->Find( this ); + SvEmbeddedInfoObject * pEle = PTR_CAST( SvEmbeddedInfoObject, p ); + if( pEle ) + { + pImpl->dwAspect = pEle->GetInfoViewAspect(); + return pImpl->dwAspect; + } + } + + return ASPECT_CONTENT; +} + + +//========================================================================= +// aus PlugIn +void SoPaintReplacement( const Rectangle &rRect, String &rText, + OutputDevice *pOut ); + +//========================================================================= +void SvOutPlaceObject::ViewChanged( USHORT nAspects ) +{ + SvInPlaceObject::ViewChanged( nAspects ); +} + +//========================================================================= +void SvOutPlaceObject::Draw +( + OutputDevice * pDev, /* in dieses Device findet die Ausgabe statt */ + const JobSetup &, /* fuer dieses Device soll formatiert werden */ + USHORT /* Darstellungsvariante des Objektes */ +) +/* [Beschreibung] + + Ein Ausgabe ist nicht m"oglich. Deswegen wird eine Bitmap + und als Unterschrift der URL ausgegeben, + + [Querverweise] + + <SvInPlaceObject::Draw> +*/ +{ + if( !pImpl->pOP ) + pImpl->pOP = CreateCache_Impl( pImpl->xWorkingStg ); + + Rectangle aOutRect = GetVisArea( ASPECT_CONTENT ); + if( pImpl->pOP ) + { + GDIMetaFile * pMtf = pImpl->pOP->GetMetaFile(); + if( pMtf ) + { + pMtf->WindStart(); + pMtf->Play( pDev, aOutRect.TopLeft(), aOutRect.GetSize() ); + } + else + { + Bitmap * pBmp = pImpl->pOP->GetBitmap(); + if( pBmp ) + pDev->DrawBitmap( aOutRect.TopLeft(), aOutRect.GetSize(), *pBmp ); + } + + return; + } + else + { +#ifdef WNT + BOOL bPlayed = FALSE; + if (!pImpl->pSO_Cont) + LoadSO_Cont(); + if( pImpl->pSO_Cont ) + { + long nMapMode; + Size aSize; + HMETAFILE hMet; + if ( pImpl->pSO_Cont->GetMetaFile( nMapMode, aSize, hMet ) ) + { + ULONG nBufSize = GetMetaFileBitsEx( hMet, 0, NULL ); + unsigned char* pBuf = new unsigned char[nBufSize+22]; + *((long*)pBuf) = 0x9ac6cdd7L; + *((short*)(pBuf+6)) = (SHORT) 0; + *((short*)(pBuf+8)) = (SHORT) 0; + *((short*)(pBuf+10)) = (SHORT) aSize.Width(); + *((short*)(pBuf+12)) = (SHORT) aSize.Height(); + *((short*)(pBuf+14)) = (USHORT) 2540; + if ( nBufSize && nBufSize == GetMetaFileBitsEx( hMet, nBufSize, pBuf+22 ) ) + { + SvMemoryStream aStream( pBuf, nBufSize+22, STREAM_READ ); + aStream.Seek(0); + GDIMetaFile aMtf; + if( ReadWindowMetafile( aStream, aMtf, NULL ) ) + { + aMtf.WindStart(); + MapMode aMode( MAP_100TH_MM ); + Size aSize = OutputDevice::LogicToLogic( aOutRect.GetSize(), aMode, pDev->GetMapMode() ); + aMtf.Play( pDev, Point(), aSize ); + bPlayed = TRUE; + } + } + + DeleteMetaFile( hMet ); + delete[] pBuf; + } + } + + if ( !bPlayed ) +#endif + { + Rectangle aVisArea_ = GetVisArea( ASPECT_CONTENT ); + String a = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "SvOutPlaceObject" ) ); + SoPaintReplacement( aVisArea_, a, pDev ); + } + } +} + + +//========================================================================= +BOOL SvOutPlaceObject::InitNew +( + SvStorage * pStor /* Storage auf dem das Objekt arbeitet. Der kann + auch NULL sein, das Bedeutet, es wird auf einem + tempor"aren Storage gearbeitet */ +) +/* [Beschreibung] + + Nach dem Konstruktor muss diese Methode oder Load gerufen werden, + um das Objekt zu initialisieren. + <SvPersist::InitNew> + + [R"uckgabewert] + + BOOL TRUE, Initialisierung hat geklappt. + FALSE, Initialisierung hat nicht geklappt, das Objekt + muss sofort freigegeben werden. + + [Querverweise] + +*/ +{ + pImpl->xWorkingStg = pStor; + if( SvInPlaceObject::InitNew( pStor ) ) + { + // Standardgr"osse + SetVisArea( Rectangle( Point(), Size( 5000, 5000 ) ) ); + return TRUE; + } + return FALSE; +} + +//========================================================================= +#define DOCNAME "OutPlace Object" + +BOOL SvOutPlaceObject::Load +( + SvStorage * pStor /* Storage aus dem das Objekt geladen wird. */ +) +/* [Beschreibung] + + Nach dem Konstruktor muss diese Methode oder InitNew gerufen werden, + um das Objekt zu initialisieren. + + [R"uckgabewert] + + BOOL TRUE, das Objekt wurde geladen. + FALSE, das Objekt wurde nicht geladen, es + muss sofort freigegeben werden. + + [Querverweise] + + <SvPersist::Load> +*/ +{ + pImpl->xWorkingStg = pStor; + if( SvInPlaceObject::Load( pStor ) ) + { + BOOL bNewVersion = pStor->IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ) ); + if( bNewVersion ) + { + SvStorageStreamRef xStm; + xStm = pImpl->xWorkingStg->OpenStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( DOCNAME ) ), STREAM_STD_READ ); + xStm->SetVersion( pImpl->xWorkingStg->GetVersion() ); + xStm->SetBufferSize( 8192 ); + + // nicht vorhandener Stream ist kein Fehler + if( xStm->GetError() == SVSTREAM_FILE_NOT_FOUND ) + { + pImpl->bGetVisAreaFromOlePress = TRUE; + pImpl->dwAspect = 0; + + return TRUE; + } + + UINT16 nLen; + *xStm >> nLen; + *xStm >> pImpl->dwAspect; + BOOL b; + *xStm >> b; + pImpl->bSetExtent = b; + + if( pStor->GetVersion() <= SOFFICE_FILEFORMAT_40 || pStor->GetVersion() >= SOFFICE_FILEFORMAT_60 ) + { + pImpl->xWorkingStg = new SvStorage( FALSE, String(), STREAM_STD_READWRITE, STORAGE_DELETEONRELEASE ); + pStor->CopyTo( pImpl->xWorkingStg ); + } + + return xStm->GetError() == ERRCODE_NONE; + } + else + { + pImpl->bGetVisAreaFromInfoEle = TRUE; + + pImpl->dwAspect = 0; + + pImpl->xWorkingStg = new SvStorage( FALSE, String(), STREAM_STD_READWRITE, + STORAGE_DELETEONRELEASE ); + + SetupStorage( pImpl->xWorkingStg ); + SotStorageStreamRef xOleObjStm = pImpl->xWorkingStg->OpenSotStream( + String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ), STREAM_STD_READWRITE ); + if( xOleObjStm->GetError() ) + return FALSE; + + SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm ); + if( xOleObjStor->GetError() ) + return FALSE; + + xOleObjStm->SetBufferSize( 0xff00 ); + + pStor->CopyTo( xOleObjStor ); + xOleObjStor->Commit(); + xOleObjStor.Clear(); + + xOleObjStm->Commit(); + + return xOleObjStm->GetError() == ERRCODE_NONE; + } + } + return FALSE; +} + +//========================================================================= +void SvOutPlaceObject::HandsOff() +{ + if( HasStorage() && pImpl->xWorkingStg == GetStorage() ) + pImpl->xWorkingStg.Clear(); + SvInPlaceObject::HandsOff(); +} + +com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > SvOutPlaceObject::GetUnoComponent() const +{ +#ifdef WNT + if ( !pImpl->m_xComponent.is() ) + { + if ( !pImpl->pSO_Cont ) + ((SvOutPlaceObject*)this)->LoadSO_Cont(); + if ( pImpl->pSO_Cont ) + pImpl->m_xComponent = new OLEWrapper_Impl( pImpl->pSO_Cont ); + } +#endif + return pImpl->m_xComponent; +} + +SvGlobalName SvOutPlaceObject::GetObjectCLSID() +{ + SvGlobalName aRet; +#ifdef WNT + if(pImpl->pSO_Cont) + aRet = pImpl->pSO_Cont->GetCLSID(); +#endif + return aRet; +} + +void SvOutPlaceObject::DrawObject +( + OutputDevice * pDev, /* in dieses Device findet die Ausgabe statt */ + const JobSetup &, /* fuer dieses Device soll formatiert werden */ + const Size& +#if defined WNT + rSize +#endif + , + USHORT +) +/* [Beschreibung] + + Ein Ausgabe ist nicht m"oglich. Deswegen wird eine Bitmap + und als Unterschrift der URL ausgegeben, + + [Querverweise] + + <SvInPlaceObject::Draw> +*/ +{ + if( !pImpl->pOP ) + pImpl->pOP = CreateCache_Impl( pImpl->xWorkingStg ); + + Rectangle aOutRect = GetVisArea( ASPECT_CONTENT ); + if( pImpl->pOP ) + { + GDIMetaFile * pMtf = pImpl->pOP->GetMetaFile(); + if( pMtf ) + { + pMtf->WindStart(); + pMtf->Play( pDev, aOutRect.TopLeft(), aOutRect.GetSize() ); + } + else + { + Bitmap * pBmp = pImpl->pOP->GetBitmap(); + if( pBmp ) + pDev->DrawBitmap( aOutRect.TopLeft(), aOutRect.GetSize(), *pBmp ); + } + + return; + } + else + { +#ifdef WNT + BOOL bPlayed = FALSE; + if (!pImpl->pSO_Cont) + LoadSO_Cont(); + + if( pImpl->pSO_Cont ) + { + long nMapMode; + Size aSize; + HMETAFILE hMet; + if ( pImpl->pSO_Cont->GetMetaFile( nMapMode, aSize, hMet ) ) + { + ULONG nBufSize = GetMetaFileBitsEx( hMet, 0, NULL ); + unsigned char* pBuf = new unsigned char[nBufSize+22]; + *((long*)pBuf) = 0x9ac6cdd7L; + *((short*)(pBuf+6)) = (SHORT) 0; + *((short*)(pBuf+8)) = (SHORT) 0; + *((short*)(pBuf+10)) = (SHORT) aSize.Width(); + *((short*)(pBuf+12)) = (SHORT) aSize.Height(); + *((short*)(pBuf+14)) = (USHORT) 2540; + if ( nBufSize && nBufSize == GetMetaFileBitsEx( hMet, nBufSize, pBuf+22 ) ) + { + SvMemoryStream aStream( pBuf, nBufSize+22, STREAM_READ ); + aStream.Seek(0); + GDIMetaFile aMtf; + if( ReadWindowMetafile( aStream, aMtf, NULL ) ) + { + aMtf.WindStart(); + MapMode aMode( MAP_100TH_MM ); + Size aSize = OutputDevice::LogicToLogic( rSize, aMode, pDev->GetMapMode() ); + aMtf.Play( pDev, Point(), aSize ); + bPlayed = TRUE; + } + } + + DeleteMetaFile( hMet ); + delete[] pBuf; + } + } + + if ( !bPlayed ) +#endif + { + Rectangle aVisArea_ = GetVisArea( ASPECT_CONTENT ); + String a = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "SvOutPlaceObject" ) ); + SoPaintReplacement( aVisArea_, a, pDev ); + } + } +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/plugin.cxx b/bf_so3/source/inplace/plugin.cxx new file mode 100644 index 000000000..4ef1d6213 --- /dev/null +++ b/bf_so3/source/inplace/plugin.cxx @@ -0,0 +1,914 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ctype.h> +#include <stdio.h> + +#include <vcl/bitmap.hxx> +#include "bf_so3/plugin.hxx" +#include <comphelper/classids.hxx> +#include <sot/exchange.hxx> +#include <vcl/svapp.hxx> +#include <vcl/stdtext.hxx> +#include <tools/debug.hxx> +#include <comphelper/processfactory.hxx> + +#include "bf_so3/ipclient.hxx" +#include <bf_so3/svstor.hxx> +#include "bf_so3/ipwin.hxx" +#include <svuidlg.hrc> +#include <tools/urlobj.hxx> +#include "bf_so3/soerr.hxx" +#include "bf_so3/staticbaseurl.hxx" + +#define SoResId( id ) ResId( id, *SOAPP->GetResMgr() ) + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/plugin/PluginMode.hpp> +#include <com/sun/star/plugin/XPlugin.hpp> +#include <com/sun/star/plugin/XPluginManager.hpp> + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::plugin; + +using ::rtl::OUString; +using ::rtl::OUStringToOString; + +namespace binfilter { + +class SvPlugInEnvironment_Impl +{ +public: + Reference< XPlugin > _xPlugin; + String _aMimeType; +}; + +//========================================================================= +SvPlugInEnvironment::SvPlugInEnvironment +( + SvContainerEnvironment * pFrm, /* Das Callback Gegenst"uck zum + InPlace-Environment */ + SvPlugInObject * pObjP /* Das zum Environment geh"orende + Objekt */ +) + : SvInPlaceEnvironment( pFrm, pObjP ) + , pObj( pObjP ) + , pImpl( new SvPlugInEnvironment_Impl ) +/* [Beschreibung] + + Das Environment wird im <SvPlugInObject::InPlaceActivate()> angelegt. + Durch die Verbindung mit dem Container Environment kann "uber die + UI-Tools und Fenster verhandelt werden. + + [Querverweise] + + <SvInPlaceEnvironment>, <SvContainerEnvironment> +*/ +{ + // Das Border- und Clip-Window werden erzeugt + MakeWindows(); + SvInPlaceWindow * pBW = GetBorderWin(); + pBW->SetHatchBorderPixel( Size() ); +} + + +BOOL SvPlugInEnvironment::MIMETypeDetected( const String& rMIME ) +{ + (void)rMIME; + + // obsolete -> should be removed + return TRUE; +} + + +//========================================================================= +SvPlugInEnvironment::~SvPlugInEnvironment() +/* [Beschreibung] + + Die angelegten Fenster werden zerst"ort. +*/ +{ + Reference< XComponent > xComp( pImpl->_xPlugin, UNO_QUERY ); + if (xComp.is()) + xComp->dispose(); + + // statt DeleteEditWin() auf NULL setzen und durch den Manager + // zerst"oren + SetEditWin( NULL ); + DeleteWindows(); + delete pImpl; +} + +//========================================================================= +void * SvPlugInEnvironment::GetJavaPeer +( + Window * //pPlugWin Plugin, zu dem die JavaKlasse besorgt wird +) +{ + return NULL; +} + +//========================================================================= +void SvPlugInEnvironment::DocWinResize() +/* [Beschreibung] + + Ist es ein Full-PlugIn, dann wird das IP-Fenster entsprechend + der Gr"osse des DocWindows angepasst. + + [Querverweise] + + <SvPlugInEnvironment::RectsChangedPixel()> +*/ +{ +} + +//========================================================================= +void SvPlugInEnvironment::RectsChangedPixel +( + const Rectangle & rObjRect, /* Position und Gr"osse relativ zum + EditWin des Containers */ + const Rectangle & rClip /* Clipping des Containers auf das Objekt */ +) +/* [Beschreibung] + + Der Container "andert die Gr"osse oder Position des Objektes. Dies + wird an das PlugIn gemeldet. + + [Querverweise] + + <SvInPlaceEnvironment::RectsChangedPixel()> +*/ +{ + Reference< awt::XWindow > xWindow( pImpl->_xPlugin, UNO_QUERY ); + if (xWindow.is()) + xWindow->setPosSize( 0, 0, rObjRect.getWidth(), rObjRect.getHeight(), WINDOW_POSSIZE_SIZE ); + SvInPlaceEnvironment::RectsChangedPixel( rObjRect, rClip ); +} + +//========================================================================= +struct SvPlugInData_Impl +/* [Beschreibung] + + In diesem struct werden sich Member von SvPlugInData gemerkt, um + nicht immer inkompatibel zu werden. +*/ +{ + BOOL bRegisterFailed; /* TRUE, wenn das registrieren + eines PlugIns nicht klappt */ + SvPlugInData_Impl() + : bRegisterFailed( FALSE ) + {} +}; + +//========================================================================= +//============== SvPlugInObject =========================================== +//========================================================================= +SO2_IMPL_BASIC_CLASS1_DLL( SvPlugInObject, SvFactory, SvInPlaceObject, + SvGlobalName( SO3_PLUGIN_CLASSID ) ) +// SvGlobalName( 0xc1b5d281, 0x4870, 0x11d0, +// 0x89, 0xca, 0x0, 0x80, 0x29, 0xe4, 0xb0, 0xb1) ) + + +//========================================================================= +SvPlugInObject::SvPlugInObject() + : pPlugInEnv( NULL ) + , pImpl( new SvPlugInData_Impl ) + , pURL( NULL ) + , nPlugInMode( PLUGIN_EMBEDED ) // muss noch ge"ndert werden +/* [Beschreibung] + + Konstruktor der Klasse SvPlugInObject. Die Verbliste und das + Format werden global initialisiert. +*/ +{ + SoDll * pSoApp = SOAPP; + if( !pSoApp->pPlugInVerbList ) + { + pSoApp->pPlugInVerbList = new SvVerbList(); + // Alle unterstuetzten Verben anlegen + pSoApp->pPlugInVerbList->Append( + SvVerb( 0, SoResId( STR_VERB_OPEN ).toString() ) ); + pSoApp->nPlugInDocFormat = + SotExchange::RegisterFormatName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PlugIn Object" ) ) ); + } + // Verben der Superklasse bekanntgeben, um GetVerbs nicht + // ueberlagern zu muessen + SetVerbList( pSoApp->pPlugInVerbList ); +} + +//========================================================================= +SvPlugInObject::~SvPlugInObject() +/* [Beschreibung] + + Destruktor der Klasse SvPlugInObject. +*/ +{ + delete pURL; + delete pImpl; +} + +BOOL SvPlugInObject::StartPlugIn( ) +/* [Beschreibung] + + Die Methode startet das PlugIn. Es ist notwendig, dass das Objekt + im InPlace-Active ist. +*/ +{ + SvPlugInEnvironment* pEnv = (SvPlugInEnvironment*)GetIPEnv(); + if( !pEnv ) + return FALSE; + + ULONG nCount = aCmdList.Count(); + Sequence< OUString > aCmds( nCount ), aArgs( nCount ); + OUString *pCmds = aCmds.getArray(), *pArgs = aArgs.getArray(); + for( ULONG i = 0; i < nCount; i++ ) + { + SvCommand & rCmd = aCmdList.GetObject( i ); + pCmds[i] = rCmd.GetCommand(); + pArgs[i] = rCmd.GetArgument(); + } + + Reference< XMultiServiceFactory > xFac( ::comphelper::getProcessServiceFactory() ); + Reference< XPluginManager > xPMgr( xFac->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.plugin.PluginManager" )) ), UNO_QUERY ); + if (! xPMgr.is() ) + ShowServiceNotAvailableError( NULL, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PluginManager" ) ), TRUE ); + + SvInPlaceWindow * pBW = pEnv->GetBorderWin(); + DBG_ASSERT( pBW, "### no border window!" ); + + INT16 nMode = (PlugInMode)nPlugInMode == PLUGIN_EMBEDED ? PluginMode::EMBED : PluginMode::FULL; + if (xPMgr.is() && pBW) + { + Reference< XPlugin > xPlugin = xPMgr->createPluginFromURL( + xPMgr->createPluginContext(), nMode, aCmds, aArgs, Reference< awt::XToolkit >(), + Reference< awt::XWindowPeer >( pBW->GetComponentInterface() ), + pURL ? pURL->GetMainURL( INetURLObject::NO_DECODE ) : rtl::OUString() ); + + if( ! GetIPEnv() ) + return FALSE; + // Environment can be discarded already by Application::Reschedule + + pEnv->pImpl->_xPlugin = xPlugin; + + if (pEnv->pImpl->_xPlugin.is()) + { + pEnv->SetEditWin( pBW ); + // Fenster zuordnen (fuers Resize) + pBW->SetObjWin( pBW ); + + Reference< awt::XWindow > xWindow( pEnv->pImpl->_xPlugin, UNO_QUERY ); + if (xWindow.is()) + { + Size aSize( pBW->GetSizePixel() ); + xWindow->setPosSize( 0, 0, aSize.getWidth(), aSize.getHeight(), WINDOW_POSSIZE_SIZE ); + xWindow->setVisible( TRUE ); + } + if( ! pURL ) + { + try + { + Reference< awt::XControl > xControl( pEnv->pImpl->_xPlugin, UNO_QUERY ); + if( xControl.is() ) + { + Reference< awt::XControlModel > xModel = xControl->getModel(); + Reference< XPropertySet > xProp( xModel, UNO_QUERY ); + if( xProp.is() ) + { + Any aValue = xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ); + OUString aVal; + aValue >>= aVal; + pURL = new INetURLObject( String( aVal ) ); + } + } + } + catch(...) + { + } + } + } + } + + return !pImpl->bRegisterFailed; +} + + +//========================================================================= +void SvPlugInObject::DataChanged_Impl +( + BOOL bOnlyEmbedSource /* TRUE, es "andert sich nur die persistenten + Daten. FALSE, auch das MetaFile "andert + sich */ +) +/* [Beschreibung] + + Wenn die Daten sich "andern, muss das Modiy-Flag gesetzt werden. + Ausserdem m"ussen alle angemeldeten Advises benachrichtigt werden. + In Abh"angigkeit des Parameters wird angezeigt, dass sich auch + die View und das Mtf ge"andert hat. +*/ +{ + if( IsEnableSetModified() ) + { // nicht im init oder deinit + SetModified( TRUE ); + if( !bOnlyEmbedSource ) + ViewChanged( ASPECT_CONTENT ); + } +} + +//========================================================================= +void SvPlugInObject::FillClass +( + SvGlobalName * pClassName, /* Der Typ der Klasse */ + ULONG * pFormat, /* Das Dateiformat in dem geschrieben wird */ + String * pAppName, /* Der Applikationsname */ + String * pFullTypeName, /* Der genaue Name des Typs */ + String * pShortTypeName, /* Der kurze Name des Typs */ + long /*nFileFormat*/ /* F"ur dieses Office-Format sollen die + Parameter gef"ullt werden */ +) const +/* [Beschreibung] + + Mit dieser Methode werden Informationen "uber das Objekt angefordert. + Wird das Objekt gesichert, dann werden diese Informationen in den + Storage geschrieben. + + [Anmerkung] + + Da diese Information nicht vom PlugIn ermittelt werden kann, m"ussen + Standardwerte angegeben werden. Dies bedeutet, von aussen gibt es + nur den Typ PlugIn, in den man nicht hinein schauen kann. +*/ +{ + *pClassName = *GetSvFactory(); + *pFormat = SOAPP->nPlugInDocFormat; + *pAppName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PlugIn" ) ); + *pFullTypeName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PlugIn" ) ); + *pShortTypeName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PlugIn" ) ); +} + + +//========================================================================= +void SvPlugInObject::Open +( + BOOL bOpen /* TRUE, es handelt sich um eine Open. + FALSE, es handelt sich um Close. */ +) +/* [Beschreibung] + + Die Verbindung zum Client wird ge"offnet oder geschlossen. + + [Querverweise] + + <SvEmbeddedObject::Open()> +*/ +{ + // l"asst Environment los + SvInPlaceObject::Open( bOpen ); +} + +//========================================================================= +void SvPlugInObject::Embed +( + BOOL bEmbed /* TRUE, OutPlace Aktivierung beginnt. + FALSE, OutPlace Aktivierung endet. */ +) +/* [Beschreibung] + + Das Objekt wird OutPlace aktiviert oder deaktiviert. Es soll nicht + aktiviert werden k"onnen. Die Aktivierung wird abgebrochen. + + [Querverweise] + + <SvEmbeddedObject::Embed()> +*/ +{ + if( bEmbed ) + DoClose(); +} + +//========================================================================= +void SvPlugInObject::InPlaceActivate +( + BOOL bActivate /* TRUE, InPlace Aktivierung beginnt. + FALSE, InPlace Aktivierung endet. */ +) +/* [Beschreibung] + + Das Objekt wird InPlace aktiviert oder deaktiviert. + + [Querverweise] + + <SvInPlaceObject::InPlaceActivate()> +*/ +{ + if( bActivate ) + { + SvContainerEnvironment * pEnv; + pEnv = GetIPClient()->GetEnv(); + // Wenn schon eines drin sitzt, ist es das des Sfx + pPlugInEnv = (SvPlugInEnvironment*) GetIPEnv(); + if( !pPlugInEnv ) + { + pPlugInEnv = new SvPlugInEnvironment( pEnv, this ); + // wird in die Verwaltung eingesetzt + SetIPEnv( pPlugInEnv ); + } + + StartPlugIn(); + } + + SvInPlaceObject::InPlaceActivate( bActivate ); + + if( !bActivate ) + { + DELETEZ( pPlugInEnv ); + SetIPEnv( pPlugInEnv ); + } +} + +//========================================================================= +ErrCode SvPlugInObject::Verb +( + long nVerb, /* welche Art des Aktivierens ist + gew"unscht */ + SvEmbeddedClient * pCl, /* Callback-Svhnittstelle des Aufruffers */ + Window * pWin, /* Parent auf dem aktiviert werden soll */ + const Rectangle * pWorkRectPixel/* Position und Gr"osse, an der das Objekt + aktiviert werden soll */ +) +/* [Beschreibung] + + Es wird Versucht ein PlugIn zu starten. Es gibt nur die M"oglichkeit + InPlace zu aktivieren. Deshalb sind auch nur die Verben gestattet, + die dies ausl"osen. + + [R"uckgabewert] + + ErrCode ERRCODE_NONE, es wurde InPlace aktiviert. + ERRCODE_SO_NOT_INPLACEACTIVE, es wurde nicht InPlace + aktiviert. + + [Querverweise] + + <SvPseudoObject::Verb> +*/ +{ + (void)pCl; + (void)pWin; + (void)pWorkRectPixel; + + ErrCode nRet = ERRCODE_SO_NOT_INPLACEACTIVE; + Reference< XMultiServiceFactory > xFac( ::comphelper::getProcessServiceFactory() ); + Sequence< OUString > aNames( xFac->getAvailableServiceNames() ); + const OUString * pNames = aNames.getConstArray(); + INT32 nPos; + for ( nPos = aNames.getLength(); nPos--; ) + { + if (pNames[nPos].compareToAscii("com.sun.star.plugin.PluginManager") == 0) + break; + } + if (nPos < 0 || pImpl->bRegisterFailed) + return nRet; + + switch( nVerb ) + { + case SVVERB_SHOW: + case SVVERB_IPACTIVATE: + case 0L: + if( PLUGIN_EMBEDED == ((PlugInMode)nPlugInMode) ) + nRet = GetProtocol().IPProtocol(); + else + nRet = GetProtocol().UIProtocol(); + break; + case SVVERB_HIDE: + nRet = DoInPlaceActivate( FALSE ); + break; + } + return nRet; +} + +//========================================================================= +void SvPlugInObject::SetVisArea +( + const Rectangle & rVisArea /* neue Position und Groesse des + sichtbaren Ausschnitts */ +) +/* [Beschreibung] + + Der sichtbare Ausschnitt beginnt immer an der Position (0, 0). +*/ +{ + Rectangle aR( rVisArea ); + aR.SetPos( Point() ); + SvInPlaceObject::SetVisArea( aR ); + + DataChanged_Impl( TRUE ); +} + +//========================================================================= +void SoPaintReplacement( const Rectangle &rRect, String &rText, + OutputDevice *pOut ) +{ + MapMode aMM( MAP_APPFONT ); + Size aAppFontSz = pOut->LogicToLogic( Size( 0, 8 ), &aMM, NULL ); + Font aFnt( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Helvetica" ) ), aAppFontSz ); + aFnt.SetTransparent( TRUE ); + aFnt.SetColor( Color( COL_LIGHTRED ) ); + aFnt.SetWeight( WEIGHT_BOLD ); + aFnt.SetFamily( FAMILY_SWISS ); + + pOut->Push(); + pOut->SetBackground(); + pOut->SetFont( aFnt ); + + Point aPt; + // Nun den Text so skalieren, dass er in das Rect passt. + // Wir fangen mit der Defaultsize an und gehen 1-AppFont runter + for( USHORT i = 8; i > 2; i-- ) + { + aPt.X() = (rRect.GetWidth() - pOut->GetTextWidth( rText )) / 2; + aPt.Y() = (rRect.GetHeight() - pOut->GetTextHeight()) / 2; + + BOOL bTiny = FALSE; + if( aPt.X() < 0 ) bTiny = TRUE, aPt.X() = 0; + if( aPt.Y() < 0 ) bTiny = TRUE, aPt.Y() = 0; + if( bTiny ) + { + // heruntergehen bei kleinen Bildern + aFnt.SetSize( Size( 0, aAppFontSz.Height() * i / 8 ) ); + pOut->SetFont( aFnt ); + } + else + break; + } + + Bitmap aBmp( SoResId( BMP_PLUGIN ) ); + long nHeight = rRect.GetHeight() - pOut->GetTextHeight(); + long nWidth = rRect.GetWidth(); + if( nHeight > 0 ) + { + aPt.Y() = nHeight; + Point aP = rRect.TopLeft(); + Size aBmpSize = aBmp.GetSizePixel(); + // Bitmap einpassen + if( nHeight * 10 / nWidth + > aBmpSize.Height() * 10 / aBmpSize.Width() ) + { + // nach der Breite ausrichten + // Proportion beibehalten + long nH = nWidth * aBmpSize.Height() / aBmpSize.Width(); + // zentrieren + aP.Y() += (nHeight - nH) / 2; + nHeight = nH; + } + else + { + // nach der H"ohe ausrichten + // Proportion beibehalten + long nW = nHeight * aBmpSize.Width() / aBmpSize.Height(); + // zentrieren + aP.X() += (nWidth - nW) / 2; + nWidth = nW; + } + pOut->DrawBitmap( aP, Size( nWidth, nHeight ), aBmp ); + } + + pOut->IntersectClipRegion( rRect ); + aPt += rRect.TopLeft(); + pOut->DrawText( aPt, rText ); + pOut->Pop(); +} + +//========================================================================= +void SvPlugInObject::Draw +( + OutputDevice * pDev, /* in dieses Device findet die Ausgabe statt */ + const JobSetup &, /* fuer dieses Device soll formatiert werden */ + USHORT nAspect /* Darstellungsvariante des Objektes */ +) +/* [Beschreibung] + + Ein Ausgabe ist nicht m"oglich. Deswegen wird eine Bitmap + und als Unterschrift der URL ausgegeben, + + [Querverweise] + + <SvEmbeddedObject::Draw> +*/ +{ + Rectangle aVisArea_ = GetVisArea( nAspect ); + String aOut; + if( pURL) + aOut = pURL->GetMainURL(INetURLObject::DECODE_TO_IURI); + SoPaintReplacement( aVisArea_, aOut, pDev ); +} + +//========================================================================= +BOOL SvPlugInObject::InitNew +( + SvStorage * pStor /* Storage auf dem das Objekt arbeitet. Der kann + auch NULL sein, das Bedeutet, es wird auf einem + tempor"aren Storage gearbeitet */ +) +/* [Beschreibung] + + Nach dem Konstruktor muss diese Methode oder Load gerufen werden, + um das Objekt zu initialisieren. + <SvPersist::InitNew> + + [R"uckgabewert] + + BOOL TRUE, Initialisierung hat geklappt. + FALSE, Initialisierung hat nicht geklappt, das Objekt + muss sofort freigegeben werden. + + [Querverweise] + +*/ +{ + if( SvInPlaceObject::InitNew( pStor ) ) + { + // Standardgr"osse + SetVisArea( Rectangle( Point(), Size( 10000, 10000 ) ) ); + return TRUE; + } + return FALSE; +} + +//========================================================================= +#define DOCNAME "plugin" +#define PLUGIN_VERS 2 + +BOOL SvPlugInObject::Load +( + SvStorage * pStor /* Storage aus dem das Objekt geladen wird. */ +) +/* [Beschreibung] + + Nach dem Konstruktor muss diese Methode oder InitNew gerufen werden, + um das Objekt zu initialisieren. + + [R"uckgabewert] + + BOOL TRUE, das Objekt wurde geladen. + FALSE, das Objekt wurde nicht geladen, es + muss sofort freigegeben werden. + + [Querverweise] + + <SvPersist::Load> +*/ +{ + if( SvInPlaceObject::Load( pStor ) ) + { + SvStorageStreamRef xStm; + xStm = pStor->OpenStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( DOCNAME ) ), STREAM_STD_READ ); + xStm->SetVersion( pStor->GetVersion() ); + xStm->SetBufferSize( 8192 ); + + // nicht vorhandener Stream ist kein Fehler + if( xStm->GetError() == SVSTREAM_FILE_NOT_FOUND ) + return TRUE; + + BYTE nVer; + *xStm >> nVer; + if( nVer == 1 || nVer == PLUGIN_VERS ) + { + *xStm >> nPlugInMode; + // we only support embedding + nPlugInMode = (USHORT)PLUGIN_EMBEDED; + + *xStm >> aCmdList; + DBG_ASSERT( !pURL, "pURL exists in load" ); + BYTE bURLExist; + *xStm >> bURLExist; + if( bURLExist ) + { + if( nVer == 1 ) + { + String aURL = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(*xStm, + RTL_TEXTENCODING_ASCII_US); + pURL = new INetURLObject( aURL ); + // Ignore, not necessary + BOOL bStrict; + *xStm >> bStrict; + } + else + { + String aURL = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(*xStm, + RTL_TEXTENCODING_ASCII_US); + pURL = new INetURLObject( + ::binfilter::StaticBaseUrl::RelToAbs( aURL )); + } + } + + String aMimeType = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(*xStm, + RTL_TEXTENCODING_ASCII_US); + } + else + xStm->SetError( ERRCODE_IO_WRONGVERSION ); + + return xStm->GetError() == ERRCODE_NONE; + } + return FALSE; +} + +//========================================================================= +void SvPlugInObject::HandsOff() +/* [Beschreibung] + + Ab diesen Zeitpunkt, bis zum <SvPlugInObject::SaveCompleted>, + darf auf den Storage im Objekt nicht zugegriffen werden. + + [Querverweise] + + <SvPersist::HandsOff> +*/ +{ + SvInPlaceObject::HandsOff(); +} + +//========================================================================= +ULONG SvPlugInObject::GetMiscStatus() const +/* [Beschreibung] + + Da ein PlugIn immer aktiviert wird, es ein Link ist und er + keine UI-Tools braucht, muss dieser Status zur"uckgegeben werden. + + [R"uckgabewert] + + ULONG Es wird immer SVOBJ_MISCSTATUS_LINK, + SVOBJ_MISCSTATUS_INSIDEOUT und + SVOBJ_MISCSTATUS_ACTIVATEWHENVISIBLE zur"uckgegeben + + [Querverweise] + + <SvPseudoObject::GetMiscStatus()> +*/ +{ + ULONG nMisc = 0; + + //nMisc = SVOBJ_MISCSTATUS_LINK; + if( PLUGIN_EMBEDED == ((PlugInMode)nPlugInMode) ) + { + nMisc |= SVOBJ_MISCSTATUS_INSIDEOUT; + if( !pImpl->bRegisterFailed ) + nMisc |= SVOBJ_MISCSTATUS_ACTIVATEWHENVISIBLE; + } + else if( PLUGIN_FULL == ((PlugInMode)nPlugInMode) ) + { + nMisc |= SVOBJ_MISCSTATUS_INSIDEOUT; + } + + nMisc |= SVOBJ_MISCSTATUS_SPECIALOBJECT; + return nMisc; +} + +//========================================================================= +BOOL SvPlugInObject::IsLink() const +/* [Beschreibung] + + Dieser Typ von Objekt ist immer ein Link. + + [R"uckgabewert] + + BOOL Immer TRUE. + + [Querverweise] + + <SvPseudoObject::IsLink()> +*/ +{ + //return TRUE; + return FALSE; +} + +//========================================================================= +void SvPlugInObject::SetCommandList +( + const SvCommandList & rList /* Die Liste der Kommnados */ +) +/* [Beschreibung] + + Die Liste der Kommandos, die "ubergeben werden, wenn das PlugIn + gestartet wird. + + [Anmerkung] + + Ein bereits gestartetes PlugIn wird dadurch nicht beeinflusst. + Die neuen Kommandos werden erst beim n"achsten starten ausgew"ahlt. +*/ +{ + aCmdList = rList; + + DataChanged_Impl( TRUE ); +} + +//========================================================================= +void SvPlugInObject::SetURL +( + const INetURLObject & rURL /* Der Verweis auf die Quelle */ +) +/* [Beschreibung] + + Der Verweis auf die Quelle wird "uebergeben. + + [Anmerkung] + + Ein bereits gestartetes PlugIn wird dadurch nicht beeinflusst. + Die neue Quelle wird erst beim n"achsten starten ausgew"ahlt. +*/ +{ + if( !pURL ) + { + pURL = new INetURLObject( rURL ); + } + else if( *pURL != rURL ) + { + *pURL = rURL; + DataChanged_Impl( FALSE ); + } +} + +//========================================================================= +void SvPlugInObject::SetMimeType +( + const String & rMimeType +) +{ + (void)rMimeType; +} + +//========================================================================= +const String & SvPlugInObject::GetMimeType() const +{ + static String aEmpty; + SvPlugInEnvironment* pEnv = (SvPlugInEnvironment*)GetIPEnv(); + if( pEnv ) + { + try + { + Reference< awt::XControl > xControl( pEnv->pImpl->_xPlugin, UNO_QUERY ); + if( xControl.is() ) + { + Reference< awt::XControlModel > xModel = xControl->getModel(); + Reference< XPropertySet > xProp( xModel, UNO_QUERY ); + if( xProp.is() ) + { + Any aValue = xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TYPE" ) ) ); + OUString aVal; + aValue >>= aVal; + pEnv->pImpl->_aMimeType = aVal; +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "got mimetype %s from plugin\n", OUStringToOString( pEnv->pImpl->_aMimeType, RTL_TEXTENCODING_ASCII_US ).getStr() ); +#endif + } + } + } + catch(...) + { + } + + return pEnv->pImpl->_aMimeType; + } + return aEmpty; +} + +//========================================================================= +void SvPlugInObject::SetPlugInMode +( + USHORT nPlugIn /* Der Modus in dem das PlugIn gestartet werden soll. + Um nicht inet.hxx zu includen. */ +) +{ + (void)nPlugIn; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/protocol.cxx b/bf_so3/source/inplace/protocol.cxx new file mode 100644 index 000000000..7fda4cb99 --- /dev/null +++ b/bf_so3/source/inplace/protocol.cxx @@ -0,0 +1,1219 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + +#include <bf_so3/protocol.hxx> +#include <tools/debug.hxx> + +#include <bf_so3/so2dll.hxx> +#include <bf_so3/ipobj.hxx> +#include "bf_so3/ipclient.hxx" +#include <bf_so3/ipenv.hxx> +#include "bf_so3/soerr.hxx" + +namespace binfilter { + +#define DBG_PROTREC(FuncName) \ + OSL_TRACE( FuncName ) + + +/************** struct ImplSvEditObjectProtocol ***************************/ +class ImplSvEditObjectProtocol +{ +public: + USHORT nRefCount; + BOOL bConnect:1, + bOpen:1, + bEmbed:1, + bPlugIn:1, + bIPActive:1, + bUIActive:1; + BOOL bCliConnect:1, + bCliOpen:1, + bCliEmbed:1, + bCliPlugIn:1, + bCliIPActive:1, + bCliUIActive:1; + BOOL bSvrConnect:1, + bSvrOpen:1, + bSvrEmbed:1, + bSvrPlugIn:1, + bSvrIPActive:1, + bSvrUIActive:1; + BOOL bLastActionConnect:1, + bLastActionOpen:1, + bLastActionEmbed:1, + bLastActionPlugIn:1, + bLastActionIPActive:1, + bLastActionUIActive:1; + + BOOL bTopWinActive:1, + bDocWinActive:1, + bInClosed:1; + + SvEmbeddedObjectRef aObj; + SvEmbeddedClientRef aClient; + SvInPlaceObjectRef aIPObj; + SvInPlaceClientRef aIPClient; + + ImplSvEditObjectProtocol(); +#ifdef DBG_UTIL + ~ImplSvEditObjectProtocol(); + void ClassInvariant() const; +#endif + + void MakeVisible(); + // Protokolle + ErrCode EmbedProtocol(); + ErrCode PlugInProtocol(); + ErrCode IPProtocol(); + ErrCode UIProtocol(); + + // Welche Protokolle werden unterstuetzt + BOOL CanEmbedProtocol() const; + BOOL CanPlugInProtocol() const; + BOOL CanInPlaceProtocol() const; + BOOL CanUIProtocol() const; + + // Protokoll zurueckfahren + BOOL Reset(); + BOOL Reset2Connect(); + BOOL Reset2Open(); + BOOL Reset2InPlaceActive(); + + // Einzelschritte der Protokolle + void Connected( BOOL bOpen ); + void Opened( BOOL bOpen ); + void Embedded( BOOL bEmbed ); + void PlugIn( BOOL bPlugIn ); + void InPlaceActivate( BOOL bActivate ); + void UIActivate( BOOL bActivate ); + void TopWinActivate( BOOL bActivate ); + void SetTopUIActiveClient( BOOL bTopWinAct, BOOL bUIAct ); + void DocWinActivate( BOOL bActivate ); +}; + +//========================================================================= +ImplSvEditObjectProtocol::ImplSvEditObjectProtocol() +{ + nRefCount = 0; + bConnect = bCliConnect = bSvrConnect = bLastActionConnect = FALSE; + bOpen = bCliOpen = bSvrOpen = bLastActionOpen = FALSE; + bEmbed = bCliEmbed = bSvrEmbed = bLastActionEmbed = FALSE; + bPlugIn = bCliPlugIn = bSvrPlugIn = bLastActionPlugIn = FALSE; + bIPActive = bCliIPActive = bSvrIPActive = bLastActionIPActive = FALSE; + bUIActive = bCliUIActive = bSvrUIActive = bLastActionUIActive = FALSE; + bTopWinActive = FALSE; + bDocWinActive = FALSE; + bInClosed = FALSE; +} + +//========================================================================= +#ifdef DBG_UTIL +ImplSvEditObjectProtocol::~ImplSvEditObjectProtocol() +{ +} +#endif + +//========================================================================= +#define IS_CONNECT() \ + (bConnect || bCliConnect || bSvrConnect ) +#define IS_ALL_CONNECT() \ + (bConnect && bCliConnect && bSvrConnect ) +#define IS_OPEN() \ + (bOpen || bCliOpen || bSvrOpen ) +#define IS_ALL_OPEN() \ + (bOpen && bCliOpen && bSvrOpen ) +#define IS_EMBED() \ + (bEmbed || bCliEmbed || bSvrEmbed ) +#define IS_PLUGIN() \ + (bPlugIn || bCliPlugIn || bSvrPlugIn ) +#define IS_IPACTIVE() \ + (bIPActive || bCliIPActive || bSvrIPActive ) +#define IS_ALL_IPACTIVE() \ + (bIPActive && bCliIPActive && bSvrIPActive ) +#define IS_UIACTIVE() \ + (bUIActive || bCliUIActive || bSvrUIActive ) + +#ifdef DBG_UTIL +void ImplSvEditObjectProtocol::ClassInvariant() const +{ + DBG_ASSERT( IS_ALL_CONNECT() || + (!IS_OPEN() && !IS_EMBED() && !IS_PLUGIN() + && !IS_IPACTIVE() && !IS_UIACTIVE()), + "not full connect, with higher status" ); + DBG_ASSERT( IS_ALL_OPEN() || + (!IS_EMBED() && !IS_PLUGIN() && !IS_IPACTIVE() && !IS_UIACTIVE()), + "not full open, with higher status" ); + DBG_ASSERT( IS_ALL_IPACTIVE() || !IS_UIACTIVE(), + "not full ipactive, with higher status" ); + DBG_ASSERT( !IS_EMBED() || + (IS_EMBED() && !IS_PLUGIN() && !IS_IPACTIVE() && !IS_UIACTIVE()), + "embed and active or plugin" ); + DBG_ASSERT( !IS_PLUGIN() || + (IS_PLUGIN() && !IS_EMBED() && !IS_IPACTIVE() && !IS_UIACTIVE()), + "plugin, and active or embed" ); + DBG_ASSERT( !IS_IPACTIVE() || + (IS_IPACTIVE() && !IS_EMBED() && !IS_PLUGIN() ), + "active and embed or plugin" ); + + DBG_ASSERT( !IS_UIACTIVE() || + (IS_ALL_OPEN() && IS_ALL_CONNECT() + && IS_ALL_IPACTIVE()), + "uiactive, without full lower status" ); + DBG_ASSERT( !IS_IPACTIVE() || + (IS_ALL_OPEN() && IS_ALL_CONNECT()), + "ipactive, without full lower status" ); + DBG_ASSERT( !IS_OPEN() || IS_ALL_CONNECT(), + "open, without full lower status" ); + DBG_ASSERT( !IS_EMBED() || + (IS_ALL_OPEN() && IS_ALL_CONNECT()), + "embed, without full lower status" ); + DBG_ASSERT( !IS_PLUGIN() || + (IS_ALL_OPEN() && IS_ALL_CONNECT()), + "plugin, without full lower status" ); +} +#define CLASS_INVARIANT ClassInvariant(); +#else +#define CLASS_INVARIANT +#endif + +void SvEditObjectProtocol::Imp_DeleteDefault() +{ + delete SOAPP->pIEOPDflt; + SOAPP->pIEOPDflt = NULL; +} + +/************** class SvEditObjectProtocol **********************************/ +/************************************************************************ +|* +|* SvEditObjectProtocol::SvEditObjectProtocol() +|* SvEditObjectProtocol::operator = () +|* SvEditObjectProtocol::~SvEditObjectProtocol() +|* SvEditObjectProtocol::Release() +|* +*************************************************************************/ +SvEditObjectProtocol::SvEditObjectProtocol() +{ + pImp = new ImplSvEditObjectProtocol(); + pImp->nRefCount = 1; +} + +SvEditObjectProtocol::SvEditObjectProtocol( const SvEditObjectProtocol & rObj ) +{ + pImp = rObj.pImp; + pImp->nRefCount++; +} + +SvEditObjectProtocol & SvEditObjectProtocol::operator = ( const SvEditObjectProtocol & rObj ) +{ + if( rObj.pImp == pImp ) + return *this; + rObj.pImp->nRefCount++; + Release(); + pImp = rObj.pImp; + return *this; +} + +SvEditObjectProtocol::~SvEditObjectProtocol() +{ + Release(); +} + +BOOL SvEditObjectProtocol::Release() +{ + if( 1 == pImp->nRefCount ) + { + Reset(); + delete pImp; + return TRUE; + } + else + --pImp->nRefCount; + return FALSE; +} + +/************************************************************************ +|* +|* SvEditObjectProtocol::GetObj() +|* SvEditObjectProtocol::GetClient() +|* +*************************************************************************/ +SvEmbeddedObject * SvEditObjectProtocol::GetObj() const +{ + return pImp->aObj; +} +SvInPlaceObject * SvEditObjectProtocol::GetIPObj() const +{ + return pImp->aIPObj; +} +SvEmbeddedClient * SvEditObjectProtocol::GetClient() const +{ + return pImp->aClient; +} +SvInPlaceClient * SvEditObjectProtocol::GetIPClient() const +{ + return pImp->aIPClient; +} + +/************************************************************************ +|* +|* SvEditObjectProtocol::IsConnect() +|* SvEditObjectProtocol::IsOpen() +|* SvEditObjectProtocol::IsEmbed() +|* SvEditObjectProtocol::IsInPlaceActive() +|* SvEditObjectProtocol::IsUIActive() +|* +*************************************************************************/ +BOOL SvEditObjectProtocol::IsConnect() const +{ + return pImp->bConnect; +} +BOOL SvEditObjectProtocol::IsOpen() const +{ + return pImp->bOpen; +} +BOOL SvEditObjectProtocol::IsEmbed() const +{ + return pImp->bEmbed; +} +BOOL SvEditObjectProtocol::IsPlugIn() const +{ + return pImp->bPlugIn; +} +BOOL SvEditObjectProtocol::IsInPlaceActive() const +{ + return pImp->bIPActive; +} +BOOL SvEditObjectProtocol::IsUIActive() const +{ + return pImp->bUIActive; +} + +//========================================================================= +void ImplSvEditObjectProtocol::MakeVisible() +/* [Beschreibung] + + Zeigt das Objekt an, wenn das Objekt IP, Embed oder PlugIn-aktiv ist. + + [Querverweise] + +*/ +{ + if( bIPActive || bEmbed || bPlugIn ) + aClient->MakeVisible(); +} + +//========================================================================= +ErrCode ImplSvEditObjectProtocol::EmbedProtocol() +{ + CLASS_INVARIANT + + if( !aClient.Is() || !aObj.Is() ) + return ERRCODE_SO_GENERALERROR; + + ErrCode nRet = ERRCODE_NONE; + if( !bIPActive && !bEmbed && !bPlugIn && aObj->Owner() ) + { + if( !bOpen ) + { + nRet = aObj->DoOpen( TRUE ); + if( ERRCODE_TOERROR( nRet ) ) + // Abbrechen, wenn nicht geoeffnet werden kann + return nRet; + } + else + // in den offen-Status zurueck + Reset2Open(); + + if( !bIPActive && !bEmbed && !bPlugIn ) + { // der Status in dem wir nach Embed wechseln koennen + nRet = aObj->DoEmbed( TRUE ); + } + } + + MakeVisible(); + // IPProtocol ist TRUE, wenn eines der drei Protokolle + // gefahren werden konnte + if( !bIPActive && !bEmbed && !bPlugIn && !ERRCODE_TOERROR( nRet ) ) + nRet = ERRCODE_SO_NOT_INPLACEACTIVE; + return nRet; +} + +ErrCode SvEditObjectProtocol::EmbedProtocol() +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + return pImp->EmbedProtocol(); +} + +//========================================================================= +ErrCode ImplSvEditObjectProtocol::PlugInProtocol() +/* [Beschreibung] + + Unterst"utzt der Client das PlugIn-Protokol, dann wird dieses + ausgefuehrt. Ansonsten wird das + <SvEditObjectProtocol::EmbedProtocol()> aktiviert. + + [R"uckgabewert] + + BOOL Befindet sich das Protokol im Status Embed, InPlaceActive + oder PlugIn wird TRUE, sondt FALSE zur"uckgegeben. + + [Querverweise] + + <SvEmbeddedClient::CanPlugIn()> +*/ +{ + CLASS_INVARIANT + + if( !aClient.Is() || !aObj.Is() ) + return ERRCODE_SO_GENERALERROR; + + ErrCode nRet = ERRCODE_NONE; + + if( !bIPActive && !bEmbed && !bPlugIn && aObj->Owner() ) + { + BOOL bCanPlugIn = aClient->CanPlugIn(); + if( bCanPlugIn ) + { + if( !bOpen ) + { + nRet = aObj->DoOpen( TRUE ); + if( ERRCODE_TOERROR( nRet ) ) + // Abbrechen, wenn nicht geoeffnet werden kann + return nRet; + } + else + // in den offen-Status zurueck + Reset2Open(); + + if( !bIPActive && !bEmbed && !bPlugIn ) + { // der Status in dem wir nach PlugIn wechseln koennen + nRet = aObj->DoPlugIn( TRUE ); + } + } + else + return EmbedProtocol(); + } + + // IPProtocol ist TRUE, wenn eines der drei Protokolle + // gefahren werden konnte + if( !bIPActive && !bEmbed && !bPlugIn && !ERRCODE_TOERROR( nRet ) ) + nRet = ERRCODE_SO_NOT_INPLACEACTIVE; + return nRet; +} + +ErrCode SvEditObjectProtocol::PlugInProtocol() +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + return pImp->PlugInProtocol(); +} + +/************************************************************************ +|* SvEditObjectProtocol::InPlaceProtocol() +|* +|* Beschreibung +*************************************************************************/ +ErrCode ImplSvEditObjectProtocol::IPProtocol() +{ + CLASS_INVARIANT + + if( !aIPClient.Is() || !aIPObj.Is() ) + return PlugInProtocol(); + + ErrCode nRet = ERRCODE_NONE; + if( !bIPActive && !bEmbed && !bPlugIn && aObj->Owner() ) + { + // auf beiden Seiten IP-Service + BOOL bIP = aIPClient->CanInPlaceActivate(); + nRet = aIPObj->DoOpen( TRUE ); + if( ERRCODE_TOERROR( nRet ) ) + // Abbrechen, wenn nicht geoeffnet werden kann + return nRet; + + if( bIP ) + { + if( !bIPActive ) + nRet = aIPObj->DoInPlaceActivate( TRUE ); + //MakeVisible(); + } + else + // auf PlugIn Protokoll umsteigen + nRet = PlugInProtocol(); + } + + CLASS_INVARIANT + + // IPProtocol ist TRUE, wenn eines der drei Protokolle + // gefahren werden konnte + if( !bIPActive && !bEmbed && !bPlugIn && !ERRCODE_TOERROR( nRet ) ) + nRet = ERRCODE_SO_NOT_INPLACEACTIVE; + return nRet; +} + +ErrCode SvEditObjectProtocol::IPProtocol() +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + return pImp->IPProtocol(); +} + +/************************************************************************ +|* SvEditObjectProtocol::UIProtocol() +|* +|* Beschreibung +*************************************************************************/ +ErrCode ImplSvEditObjectProtocol::UIProtocol() +{ + CLASS_INVARIANT + + if( !aIPClient.Is() || !aIPObj.Is() ) + return PlugInProtocol(); + + ErrCode nRet = ERRCODE_NONE; + if( !bUIActive && !bEmbed && !bPlugIn && aObj->Owner() ) + { + nRet = IPProtocol(); + if( !bUIActive && bIPActive ) + nRet = aIPObj->DoUIActivate( TRUE ); + } + else + MakeVisible(); + + CLASS_INVARIANT + // UIProtocol ist TRUE, wenn eine der drei Protokolle + // gefahren werden konnte + if( !bIPActive && !bEmbed && !bPlugIn && !ERRCODE_TOERROR( nRet ) ) + nRet = ERRCODE_SO_NOT_INPLACEACTIVE; + return nRet; +} + +ErrCode SvEditObjectProtocol::UIProtocol() +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + return pImp->UIProtocol(); +} + +/************************************************************************ +|* SvEditObjectProtocol::Reset() +|* +|* Beschreibung +*************************************************************************/ +BOOL ImplSvEditObjectProtocol::Reset() +{ + CLASS_INVARIANT + DBG_PROTREC( "Reset" ); + + if( bInClosed || (aObj.Is() && aObj->IsInClose()) ) + { + if( bConnect ) + Reset2Connect(); // bis auf Connect runter + if( bCliConnect || bSvrConnect ) + // falls nur Client oder nur Server Disconnect bekam + Connected( FALSE ); + } + else if( bConnect ) + Connected( FALSE ); + + DBG_ASSERT( !IS_CONNECT() && !IS_OPEN() + && !IS_EMBED() && !IS_PLUGIN() + && !IS_UIACTIVE() && !IS_IPACTIVE(), + "cannot Reset()" ); + CLASS_INVARIANT + return !bConnect; +} + +BOOL SvEditObjectProtocol::Reset() +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + return pImp->Reset(); +} + +/************************************************************************ +|* SvEditObjectProtocol::Reset2Connect() +|* +|* Beschreibung +*************************************************************************/ +BOOL ImplSvEditObjectProtocol::Reset2Connect() +{ + CLASS_INVARIANT + DBG_PROTREC( "Reset2Connect" ); + if( bOpen ) + { + Reset2Open(); + if( bOpen ) + aObj->DoOpen( FALSE ); + } + if( bCliOpen || bSvrOpen ) + // falls nur Client oder nur Server Close bekam + Opened( FALSE ); + DBG_ASSERT( !IS_OPEN() && !IS_EMBED() && !IS_PLUGIN() + && !IS_UIACTIVE() && !IS_IPACTIVE(), + "cannot Reset2Connect()" ); + CLASS_INVARIANT + return bConnect; +} + +BOOL SvEditObjectProtocol::Reset2Connect() +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + return pImp->Reset2Connect(); +} + +/************************************************************************ +|* SvEditObjectProtocol::Reset2Open() +|* +|* Beschreibung +*************************************************************************/ +BOOL ImplSvEditObjectProtocol::Reset2Open() +{ + CLASS_INVARIANT + DBG_PROTREC( "Reset2Open" ); + if( bEmbed ) + aObj->DoEmbed( FALSE ); + else if( bPlugIn ) + aObj->DoPlugIn( FALSE ); + else if( bIPActive ) + { + Reset2InPlaceActive(); + if( bIPActive ) + aIPObj->DoInPlaceActivate( FALSE ); + } + if( bCliEmbed || bSvrEmbed ) + // falls nur Client oder nur Server Embed bekam + Embedded( FALSE ); + if( bCliPlugIn || bSvrPlugIn ) + // falls nur Client oder nur Server PlugIn bekam + PlugIn( FALSE ); + if( bCliIPActive || bSvrIPActive ) + // falls nur Client oder nur Server IPActive bekam + InPlaceActivate( FALSE ); + DBG_ASSERT( !IS_EMBED() && !IS_PLUGIN() + && !IS_UIACTIVE() && !IS_IPACTIVE(), + "cannot Reset2Open()" ); + CLASS_INVARIANT + return bOpen; +} + +BOOL SvEditObjectProtocol::Reset2Open() +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + return pImp->Reset2Open(); +} + +//========================================================================= +BOOL SvEditObjectProtocol::Reset2Embed() +{ + return IsEmbed(); +} + +//========================================================================= +BOOL SvEditObjectProtocol::Reset2PlugIn() +/* [Beschreibung] + + Ist das Protocol im PlugIn Status, dann wird TRUE zur"uckgegeben. + + [R"uckgabewert] + + BOOL + + [Querverweise] +*/ +{ + return IsPlugIn(); +} + +/************************************************************************ +|* SvEditObjectProtocol::Reset2InPlaceActive() +|* +|* Beschreibung +*************************************************************************/ +BOOL ImplSvEditObjectProtocol::Reset2InPlaceActive() +{ + CLASS_INVARIANT + DBG_PROTREC( "Reset2InPlaceActive" ); + if( bUIActive && aIPObj.Is() ) + aIPObj->DoUIActivate( FALSE ); + if( bCliUIActive || bSvrUIActive ) + // falls nur Client oder nur Server UIActive bekam + UIActivate( FALSE ); + DBG_ASSERT( !IS_UIACTIVE(), + "cannot Reset2InPlaceActive()" ); + CLASS_INVARIANT + return bIPActive; +} + +BOOL SvEditObjectProtocol::Reset2InPlaceActive() +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + return pImp->Reset2InPlaceActive(); +} + +/************************************************************************ +|* SvEditObjectProtocol::Reset2UIActive() +|* +|* Beschreibung +*************************************************************************/ +BOOL SvEditObjectProtocol::Reset2UIActive() +{ + return IsUIActive(); +} + +/************************************************************************ +|* SvEditObjectProtocol::Connected() +|* +|* Beschreibung +*************************************************************************/ +void ImplSvEditObjectProtocol::Connected( BOOL bConnectP ) +{ + CLASS_INVARIANT + DBG_PROTREC( "Connected" ); + if( bCliConnect == bConnectP && bSvrConnect == bConnectP ) + { + DBG_ASSERT( bConnect == bConnectP, "connect assert" ); + return; // nichts zu tun + } + + if( !aClient.Is() || !aObj.Is() ) + return; //keine Kommunikationspartner + + bLastActionConnect = bConnectP; + if( !bConnectP ) + Reset2Connect(); + + if( bLastActionConnect != bConnectP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + DBG_ASSERT( !bOpen, "connect assert failed" ); + bConnect = bConnectP; // vor der Aktion den Status setzen + if( bLastActionConnect && !bCliConnect ) + { // Ich darf verbinden und zuerst an den Client + DBG_ASSERT( bConnect && bConnectP && bLastActionConnect && !bCliConnect, + "connect assert failed" ); + DBG_ASSERT( aClient.Is(), "connect assert failed" ); + bCliConnect = TRUE; + aClient->Connected( TRUE ); + } + + if( bLastActionConnect != bConnectP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + // nach dem ClientConnect darf alles passieren, bis auf loeschen von this + if( (bLastActionConnect && !bSvrConnect) || (!bLastActionConnect && bSvrConnect) ) + { // Object verbinden Ich darf verbinden + DBG_ASSERT( (bConnect && bConnectP && bLastActionConnect && !bSvrConnect) + || (!bConnect && !bConnectP && !bLastActionConnect && bSvrConnect), + "connect assert failed" ); + bSvrConnect = bConnect; + aObj->Connect( bConnect ); + } + + if( bLastActionConnect != bConnectP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + if( !bLastActionConnect && bCliConnect ) + { // Ich darf die Verbindund abbrechen. Zuletzt an den Client + DBG_ASSERT( !bConnect && !bConnectP && !bLastActionConnect && bCliConnect, + "connect assert failed" ); + DBG_ASSERT( aClient.Is(), "connect assert failed" ); + bCliConnect = FALSE; + aClient->Connected( FALSE ); + } + + if( !bLastActionConnect ) + { + aObj.Clear(); + aIPObj.Clear(); + aClient.Clear(); + aIPClient.Clear(); + } + CLASS_INVARIANT +} + +/************************************************************************ +|* SvEditObjectProtocol::Opened() +|* +|* Beschreibung +*************************************************************************/ +void ImplSvEditObjectProtocol::Opened( BOOL bOpenP ) +{ + CLASS_INVARIANT + DBG_PROTREC( "Opened" ); + + // Letzte Aktion war 'runterfahren, aktuelle Aktion is hochfahren + // und auf dieser Seite noch nicht komplett 'runtergefahren + if( bOpenP && !bLastActionOpen && (bCliOpen || bSvrOpen)) + return; + + if( bCliOpen == bOpenP && bSvrOpen == bOpenP ) + { + DBG_ASSERT( bOpen == bOpenP, "open assert" ); + return; // nichts zu tun + } + bLastActionOpen = bOpenP; + + if( bOpenP ) + Connected( bOpenP ); + else + Reset2Open(); + + if( bLastActionOpen != bOpenP ) + return; // irgendeiner hat Rekursiv protokoll geaendert + + DBG_ASSERT( !bEmbed && !bPlugIn && !bIPActive, "open assert failed" ); + bOpen = bOpenP; // vor der Aktion den Status setzen + if( bLastActionOpen && !bCliOpen ) + { // Ich darf oeffnen und zuerst an den Client + DBG_ASSERT( bOpen && bOpenP && bLastActionOpen && !bCliOpen, + "open assert failed" ); + bCliOpen = TRUE; + aClient->Opened( TRUE ); + } + + if( bLastActionOpen != bOpenP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + // nach dem ClientOpen darf alles passieren, bis auf loeschen von this + if( (bLastActionOpen && !bSvrOpen) || (!bLastActionOpen && bSvrOpen) ) + { // Object oeffnen + DBG_ASSERT( (bOpen && bOpenP && bLastActionOpen && !bSvrOpen) + || (!bOpen && !bOpenP && !bLastActionOpen && bSvrOpen), + "open assert failed" ); + bSvrOpen = bOpen; + aObj->Open( bOpen ); + } + + if( bLastActionOpen != bOpenP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + if( !bLastActionOpen && bCliOpen ) + { // Ich darf schliessen. Zuletzt an den Client + DBG_ASSERT( !bOpen && !bOpenP && !bLastActionOpen && bCliOpen, + "open assert failed" ); + DBG_ASSERT( aClient.Is(), "open assert failed" ); + bCliOpen = FALSE; + aClient->Opened( FALSE ); + } + CLASS_INVARIANT +} + +void SvEditObjectProtocol::Opened( BOOL bOpen ) +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + pImp->Opened( bOpen ); +} + +/************************************************************************ +|* SvEditObjectProtocol::Embedded() +|* +|* Beschreibung +*************************************************************************/ +void ImplSvEditObjectProtocol::Embedded( BOOL bEmbedP ) +{ + CLASS_INVARIANT + DBG_PROTREC( "Embedded" ); + if( bCliEmbed == bEmbedP && bSvrEmbed == bEmbedP ) + { + DBG_ASSERT( bEmbed == bEmbedP, "Embedded assert" ); + return; // nichts zu tun + } + bLastActionEmbed = bEmbedP; + + if( bEmbedP ) + Opened( bEmbedP ); + + if( bLastActionEmbed != bEmbedP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + DBG_ASSERT( !bIPActive, "embed assert failed" ); + bEmbed = bEmbedP; // vor der Aktion den Status setzen + if( bLastActionEmbed && !bCliEmbed ) + { // Ich darf oeffnen und zuerst an den Client + DBG_ASSERT( bEmbed && bEmbedP && bLastActionEmbed && !bCliEmbed, + "embed assert failed" ); + bCliEmbed = TRUE; + aClient->Embedded( TRUE ); + } + + if( bLastActionEmbed != bEmbedP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + // nach dem ClientEmbed darf alles passieren, bis auf loeschen von this + if( (bLastActionEmbed && !bSvrEmbed) || (!bLastActionEmbed && bSvrEmbed) ) + { // Object oeffnen + DBG_ASSERT( (bEmbed && bEmbedP && bLastActionEmbed && !bSvrEmbed) + || (!bEmbed && !bEmbedP && !bLastActionEmbed && bSvrEmbed), + "embed assert failed" ); + bSvrEmbed = bEmbed; + aObj->Embed( bEmbed ); + if( bEmbed && aObj->GetDocumentName().Len() ) + aObj->DocumentNameChanged( aObj->GetDocumentName() ); + } + + if( bLastActionEmbed != bEmbedP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + if( !bLastActionEmbed && bCliEmbed ) + { // Ich darf schliessen. Zuletzt an den Client + DBG_ASSERT( !bEmbed && !bEmbedP && !bLastActionEmbed && bCliEmbed, + "embed assert failed" ); + bCliEmbed = FALSE; + aClient->Embedded( FALSE ); + } + CLASS_INVARIANT +} + +void SvEditObjectProtocol::Embedded( BOOL bEmbed ) +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + pImp->Embedded( bEmbed ); +} + +//========================================================================= +void ImplSvEditObjectProtocol::PlugIn +( + BOOL bPlugInP +) +/* [Beschreibung] + + [R"uckgabewert] + + [Querverweise] +*/ +{ + CLASS_INVARIANT + DBG_PROTREC( "PlugIn" ); + if( bCliPlugIn == bPlugInP && bSvrPlugIn == bPlugInP ) + { + DBG_ASSERT( bPlugIn == bPlugInP, "PlugIn assert" ); + return; // nichts zu tun + } + bLastActionPlugIn = bPlugInP; + + if( bPlugInP ) + Opened( bPlugInP ); + + if( bLastActionPlugIn != bPlugInP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + DBG_ASSERT( !bIPActive, "PlugIn assert failed" ); + bPlugIn = bPlugInP; // vor der Aktion den Status setzen + if( bLastActionPlugIn && !bCliPlugIn ) + { // Ich darf oeffnen und zuerst an den Client + DBG_ASSERT( bPlugIn && bPlugInP && bLastActionPlugIn && !bCliPlugIn, + "PlugIn assert failed" ); + bCliPlugIn = TRUE; + aClient->PlugIn( TRUE ); + } + + if( bLastActionPlugIn != bPlugInP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + // nach dem ClientPlugIn darf alles passieren, bis auf loeschen von this + if( (bLastActionPlugIn && !bSvrPlugIn) || (!bLastActionPlugIn && bSvrPlugIn) ) + { // Object oeffnen + DBG_ASSERT( (bPlugIn && bPlugInP && bLastActionPlugIn && !bSvrPlugIn) + || (!bPlugIn && !bPlugInP && !bLastActionPlugIn && bSvrPlugIn), + "PlugIn assert failed" ); + bSvrPlugIn = bPlugIn; + aObj->PlugIn( bPlugIn ); + if( bPlugIn && aObj->GetDocumentName().Len() ) + aObj->DocumentNameChanged( aObj->GetDocumentName() ); + } + + if( bLastActionPlugIn != bPlugInP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + if( !bLastActionPlugIn && bCliPlugIn ) + { // Ich darf schliessen. Zuletzt an den Client + DBG_ASSERT( !bPlugIn && !bPlugInP && !bLastActionPlugIn && bCliPlugIn, + "PlugIn assert failed" ); + bCliPlugIn = FALSE; + aClient->PlugIn( FALSE ); + } + CLASS_INVARIANT +} + +//========================================================================= +void SvEditObjectProtocol::PlugIn( BOOL bPlugIn ) +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + pImp->PlugIn( bPlugIn ); +} + +/************************************************************************ +|* SvEditObjectProtocol::InPlaceActivate(); +|* +|* Beschreibung +*************************************************************************/ +void ImplSvEditObjectProtocol::InPlaceActivate( BOOL bIPActiveP ) +{ + CLASS_INVARIANT + DBG_PROTREC( "InPlaceActivate" ); + if( bCliIPActive == bIPActiveP && bSvrIPActive == bIPActiveP ) + { + DBG_ASSERT( bIPActive == bIPActiveP, "IPActive assert" ); + return; // nichts zu tun + } + bLastActionIPActive = bIPActiveP; + if( bIPActiveP ) + Opened( bIPActiveP ); + else + Reset2InPlaceActive(); + + if( bLastActionIPActive != bIPActiveP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + DBG_ASSERT( !bEmbed && !bPlugIn, "inplace assert failed" ); + bIPActive = bIPActiveP; // vor der Aktion den Status setzen + if( bLastActionIPActive && !bCliIPActive ) + { // Ich darf oeffnen und zuerst an den Client + DBG_ASSERT( bIPActive && bIPActiveP && bLastActionIPActive && !bCliIPActive, + "inplace assert failed" ); + DBG_ASSERT( aIPClient.Is(), "inplace assert failed" ); + bCliIPActive = TRUE; + if( aIPClient->Owner() ) + SvInPlaceClient::GetIPActiveClientList().Insert( aIPClient, LIST_APPEND ); + aIPClient->InPlaceActivate( TRUE ); + } + + if( bLastActionIPActive != bIPActiveP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + // nach dem ClientIPActive darf alles passieren, bis auf loeschen von this + if( (bLastActionIPActive && !bSvrIPActive) || (!bLastActionIPActive && bSvrIPActive) ) + { // Object oeffnen + DBG_ASSERT( (bIPActive && bIPActiveP && bLastActionIPActive && !bSvrIPActive) + || (!bIPActive && !bIPActiveP && !bLastActionIPActive && bSvrIPActive), + "inplace assert failed" ); + DBG_ASSERT( aIPObj.Is(), "inplace assert failed" ); + bSvrIPActive = bIPActive; + if( bIPActive ) + { + aIPObj->InPlaceActivate( bIPActive ); + if( aIPObj.Is() && bIPActive ) + TopWinActivate( bIPActive ); + if( aIPObj.Is() && bIPActive ) + DocWinActivate( bIPActive ); + } + else + { + DocWinActivate( bIPActive ); + TopWinActivate( bIPActive ); + aIPObj->InPlaceActivate( bIPActive ); + } + } + + if( bLastActionIPActive != bIPActiveP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + if( !bLastActionIPActive && bCliIPActive ) + { // Ich darf schliessen. Zuletzt an den Client + DBG_ASSERT( !bIPActive && !bIPActiveP && !bLastActionIPActive && bCliIPActive, + "open assert failed" ); + bCliIPActive = FALSE; + DBG_ASSERT( aIPClient.Is(), "inplace assert failed" ); + if( aIPClient->Owner() ) + SvInPlaceClient::GetIPActiveClientList().Remove( aIPClient ); + aIPClient->InPlaceActivate( FALSE ); + } + CLASS_INVARIANT +} + +void SvEditObjectProtocol::InPlaceActivate( BOOL bIPActive ) +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + pImp->InPlaceActivate( bIPActive ); +} + +/************************************************************************ +|* SvEditObjectProtocol::UIActivate(); +|* +|* Beschreibung +*************************************************************************/ +void ImplSvEditObjectProtocol::UIActivate( BOOL bUIActiveP ) +{ + CLASS_INVARIANT + DBG_PROTREC( "UIActivate" ); + if( bCliUIActive == bUIActiveP && bSvrUIActive == bUIActiveP ) + { + DBG_ASSERT( bUIActive == bUIActiveP, "UIActive assert" ); + return; // nichts zu tun + } + bLastActionUIActive = bUIActiveP; + if( bUIActiveP ) + InPlaceActivate( bUIActiveP ); + DBG_ASSERT( !bEmbed && !bPlugIn, "ui assert failed" ); + bUIActive = bUIActiveP; // vor der Aktion den Status setzen + if( bLastActionUIActive && !bCliUIActive ) + { // Ich darf ui aktivieren und zuerst an den Client + DBG_ASSERT( bUIActive && bUIActiveP && bLastActionUIActive && !bCliUIActive, + "ui assert failed" ); + DBG_ASSERT( aIPClient.Is(), "inplace assert failed" ); + SvContainerEnvironment * pFrm = aIPClient->GetEnv(); + + // falls es einen Parent gibt, diesen UI-Deaktivieren + SvContainerEnvironment * pParentFrm = pFrm->GetParent(); + if( pParentFrm && pParentFrm->GetIPClient() ) + pParentFrm->GetIPClient()->GetProtocol().Reset2InPlaceActive(); + + // Alle UI-Aktiven Clients im Dokument suchen und UI-Deaktivieren + SvInPlaceClientList * pCList = SOAPP->pIPActiveClientList; + if( pCList ) + { + ULONG i = 0; + while( i < pCList->Count() ) + { + SvInPlaceClient * pCl = pCList->GetObject( i ); + SvContainerEnvironment * pClEnv = pCl->GetEnv(); + if( pCl->Owner() && pCl != &aIPClient + && pCl->GetProtocol().IsUIActive() + && pClEnv->GetTopWin() == pFrm->GetTopWin() + && pClEnv->GetDocWin() == pFrm->GetDocWin() ) + { + pCl->GetProtocol().Reset2InPlaceActive(); + // wer weis wie die Liste veraendert wurde + i = 0; + } + else + i++; + } + } + + + if( bLastActionUIActive && !bCliUIActive ) + { // wer weis was DoInPlaceActivate getan hat + bCliUIActive = TRUE; + aIPClient->UIActivate( TRUE ); + if( aIPObj.Is() && aIPObj->Owner() ) + { // Tools anordnen anstossen, aber nur wenn selbst + aIPObj->GetIPEnv()->DoTopWinResize(); + } + } + } + + if( bLastActionUIActive != bUIActiveP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + // nach dem ClientUIActive darf alles passieren, bis auf loeschen von this + if( (bLastActionUIActive && !bSvrUIActive) || (!bLastActionUIActive && bSvrUIActive) ) + { // Object oeffnen + DBG_ASSERT( (bUIActive && bUIActiveP && bLastActionUIActive && !bSvrUIActive) + || (!bUIActive && !bUIActiveP && !bLastActionUIActive && bSvrUIActive), + "ui assert failed" ); + DBG_ASSERT( aIPObj.Is(), "inplace assert failed" ); + bSvrUIActive = bUIActive; + if( aIPClient->Owner() ) + { + if( aIPClient->GetEnv()->GetDocWin() ) + SetTopUIActiveClient( bDocWinActive, bUIActive ); + else + SetTopUIActiveClient( bTopWinActive, bUIActive ); + } + aIPObj->UIActivate( bUIActive ); + } + + if( bLastActionUIActive != bUIActiveP ) + return; // irgend einer hat rekursiv das Protokoll geaendert + + if( !bLastActionUIActive && bCliUIActive ) + { // Ich darf schliessen. Zuletzt an den Client + DBG_ASSERT( !bUIActive && !bUIActiveP && !bLastActionUIActive && bCliUIActive, + "open assert failed" ); + bCliUIActive = FALSE; + DBG_ASSERT( aIPClient.Is(), "inplace assert failed" ); + aIPClient->UIActivate( FALSE ); + } + + CLASS_INVARIANT +} + +void SvEditObjectProtocol::UIActivate( BOOL bUIActive ) +{ + // Schutz gegen Zuweisungsoperator und delete + SvEditObjectProtocol aThis( *this ); + pImp->UIActivate( bUIActive ); +} + +void ImplSvEditObjectProtocol::TopWinActivate( BOOL bActive ) +{ + CLASS_INVARIANT + if( aIPObj.Is() && bActive != bTopWinActive ) + { + bTopWinActive = bActive; + SvContainerEnvironment * pEnv = aIPClient->GetEnv(); + if( aIPClient.Is() && pEnv && !pEnv->GetDocWin() ) + SetTopUIActiveClient( bTopWinActive, bUIActive ); + aIPObj->TopWinActivate( bActive ); + } + CLASS_INVARIANT +} + +/************************************************************************ +|* ImpSvEditObjectProtocol::SetTopUIActiveClient() +|* +|* Beschreibung +*************************************************************************/ +void ImplSvEditObjectProtocol::SetTopUIActiveClient( BOOL /*bTopWinActive*/, + BOOL /*bUIActive*/ ) +{ +} + +void ImplSvEditObjectProtocol::DocWinActivate( BOOL bActive ) +{ + CLASS_INVARIANT + if( aIPObj.Is() && aIPClient.Is() && bActive != bDocWinActive ) + { + SvContainerEnvironment * pEnv = aIPClient->GetEnv(); + if( !aIPClient->Owner() || (pEnv && pEnv->GetDocWin()) ) + {// eventuell kann das DocWin nicht geholt werden (Send in Send) + bDocWinActive = bActive; + SetTopUIActiveClient( bDocWinActive, bUIActive ); + aIPObj->DocWinActivate( bActive ); + } + } + CLASS_INVARIANT +} + +/************************************************************************ +|* SvEditObjectProtocol::SetInClosed() +|* +|* Beschreibung +*************************************************************************/ +void SvEditObjectProtocol::SetInClosed( BOOL bInClosed ) +{ + DBG_ASSERT( bInClosed != pImp->bInClosed, "bInClosed == pImp->bInClosed" ); + pImp->bInClosed = bInClosed; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/rmapplet.cxx b/bf_so3/source/inplace/rmapplet.cxx new file mode 100644 index 000000000..777e8cdda --- /dev/null +++ b/bf_so3/source/inplace/rmapplet.cxx @@ -0,0 +1,404 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifdef REMOTE_VERSION + +#include <svgen.hxx> +#include <thread.hxx> + +#include <dcca/object.hxx> +#include <dcca/message.hxx> +#include <dcca/broker.hxx> + +#include <string.h> + +#include <owncont.hxx> +#include <tlgen.hxx> + +#include <rsvstrm.hxx> + +#include <RmApplet.hxx> + +namespace binfilter { + +// Attention : MT_LINK should be here temporarily only for testing +// and is supposed to be moved into SV ! + +#if !defined WNT +// caution: faster but be aware of deadlocks +// todo: someone in the main thread must call Lock()/Unlock() +#define MT_LINK +#endif + +// Example: +// MT_Link aLink = LINK( Instance, Class, Method ); +// long n = aLink.Call( (void*)pData ); +// Caution: +// Never call MT_Link::Call() in the main thread + +#if !defined MT_LINK +class MT_Link +{ + Link rLink_; + long nReturn_; + ULONG nEvent_; + SignaledEvent *aOut_; + static int count; + DECL_LINK( Call_Impl, void* ); +public: + long Call( void *p ); + MT_Link( Link r ); + ~MT_Link(); +}; + +IMPL_LINK( MT_Link, Call_Impl, void*, p ) +{ + nEvent_ = 0; + nReturn_ = rLink_.Call( p ); + aOut_->Set(); + return nReturn_; +} +int MT_Link::count = 0; + +long MT_Link::Call( void *p ) +{ + Link aLink = LINK( this, MT_Link, Call_Impl ); + + nEvent_ = GetpApp()->PostUserEvent( aLink, p ); + aOut_->Wait(); + return nReturn_; +} + +MT_Link::MT_Link( Link r ) : rLink_( r ) +{ + nEvent_ = 0; + String name1 = "Event"; + + name1 += count++; + aOut_ = new SignaledEvent(name1, FALSE); +} + +MT_Link::~MT_Link() +{ + if( nEvent_ ) GetpApp()->RemoveUserEvent( nEvent_ ); + if (aOut_) + delete aOut_; +} + +#else +class MT_Link +{ + Link rLink_; + + static Mutex aMtx__; +public: + static void Lock() { aMtx__.Lock(); } + static void Unlock() { aMtx__.Unlock(); } + + long Call( void *p ); + + MT_Link( Link r ) : rLink_( r ) {} +}; + +Mutex MT_Link::aMtx__; + +long MT_Link::Call( void *p ) +{ + Lock(); + long nReturn = rLink_.Call( p ); + Unlock(); + return nReturn; +} +#endif + + +// Link Deklarationen + + +INetURLObject *getURL(String& rStr) +{ + if( rStr.Len() >= 8 && rStr.Compare( "file:/", 6 ) == COMPARE_EQUAL + && rStr[(USHORT)7] == ':' ) + { + // Verkehrte JavaURL von file:/?: auf file:///?| bringen; + String aNew = "file:///"; + aNew += rStr[(USHORT)6]; + aNew += '|'; + aNew += rStr.Erase( 0, 8 ); + rStr = aNew; + //aStr = "file:///" + aStr[(USHORT)6] + '|' + aStr.Erase( 0, 7 ); + } + + INetURLObject *aDocURL = new INetURLObject(); + aDocURL->SetURL( rStr ); + return aDocURL; +} +/** + macht aus C++ URL eine JAVA kompatible URL +*/ +String getJavaURL(const INetURLObject & rDocBase) +{ + String aURL = rDocBase.GetMainURL(NetURLObject::DECODE_TO_IURI); + if( aURL.Len() ) + { + //WorkAround, weil Java mit dem | nicht zurecht kommt + if( rDocBase.GetProtocol() == INET_PROT_FILE + && aURL[ (USHORT)9 ] == INET_ENC_DELIM_TOKEN ) + aURL[ (USHORT)9 ] = INET_DELIM_TOKEN; + } + return aURL; +} + +RmAppletStub::RmAppletStub( ) : + RmBasisObject() +{ + pClassName = "ApOAppletStub"; +} + +void RmAppletStub::Create(RmAppletContext* pContext, const INetURLObject& rURL1, const SvCommandList & rList,const INetURLObject& rURL2 , BOOL bMayScript ) +{ + OSL_TRACE( "Rm: AppletStub::Create() - Befor createObject() - %s", pClassName ); + + char * aBuf + = new char[ strlen( RMAPPLET_PACKAGE ) + strlen( pClassName ) + 1 ]; + strcpy( aBuf, RMAPPLET_PACKAGE ); // #100211# - checked + strcat( aBuf, pClassName ); // #100211# - checked + createObject( DCA_NAMESPACE(OObjectBroker, dca)::getBroker("dcabroker"), aBuf ); + delete[] aBuf; + + OSL_TRACE( "Rm: Window::Create() - After createObject()" ); + + DCA_NAMESPACE(OCallMethodMsg, dca) aMsg(this, MSG_APPLET_CREATE); + DCA_NAMESPACE(OObjStream , dca)& s = aMsg.getData(); + + s << getJavaURL(rURL1); + s << getJavaURL(rURL2); + + s << pContext; + + long size = rList.Count(); + s << size; + for( long i = 0; i < size; i++ ) + { + const SvCommand & rCmd = rList[i]; + s << rCmd.GetCommand().Lower() ; + s << rCmd.GetArgument(); + + } + + s << bMayScript; + aMsg.post(); +} + + +// ----------------------------------------------------------------------- + +RmAppletContext::RmAppletContext( ) : + RmBasisObject() +{ + pClassName = "ApOAppletContainer"; +} + +// ----------------------------------------------------------------------- + +void RmAppletContext::Create( ) +{ + OSL_TRACE( "Rm: AppletContext::Create() - Befor createObject() - %s", pClassName ); + + char * aBuf + = new char[ strlen( RMAPPLET_PACKAGE ) + strlen( pClassName ) + 1 ]; + strcpy( aBuf, RMAPPLET_PACKAGE ); // #100211# - checked + strcat( aBuf, pClassName ); // #100211# - checked + createObject( DCA_NAMESPACE(OObjectBroker, dca)::getBroker("dcabroker"), aBuf ); + delete[] aBuf; + + OSL_TRACE( "Rm: Window::Create() - After createObject()" ); + +} + +// ----------------------------------------------------------------------- + +RmAppletObject::RmAppletObject( ) : + RmBasisObject() +{ + pClassName = "ApOAppletPanel"; +} + +void RmAppletObject::Create(const String& sClassName, const String& sName, const RmAppletStub& stub, const Window& parent ) +{ + OSL_TRACE( "Rm: AppletObject::Create() - Befor createObject() - %s", pClassName ); + + char * aBuf + = new char[ strlen( RMAPPLET_PACKAGE ) + strlen( pClassName ) + 1 ]; + strcpy( aBuf, RMAPPLET_PACKAGE ); // #100211# - checked + strcat( aBuf, pClassName ); // #100211# - checked + createObject( DCA_NAMESPACE(OObjectBroker, dca)::getBroker("dcabroker"), aBuf ); + delete[] aBuf; + + OSL_TRACE( "Rm: Window::Create() - After createObject()" ); + DCA_NAMESPACE(OCallMethodMsg, dca) aMsg( this, MSG_APPLET_CREATE ); + DCA_NAMESPACE(OObjStream , dca)& s = aMsg.getData(); + + s << sClassName; + s << sName; + s << (RmAppletStub*)&stub; + void *dummy = (void *)parent.ImpGetRemoteObject(); + s << (DCA_NAMESPACE(OObj , dca)*)dummy; + + aMsg.post(); +} + +void RmAppletObject::Start( const Size & rSize) +{ + DCA_NAMESPACE(OCallMethodMsg, dca) aMsg( this, MSG_APPLET_START ); + DCA_NAMESPACE(OObjStream , dca)& s = aMsg.getData(); + + s << rSize.Width(); + s << rSize.Height(); + + aMsg.post(); + +} + +void RmAppletObject::Stop() +{ + DCA_NAMESPACE(OCallMethodMsg, dca) aMsg( this, MSG_APPLET_STOP ); + aMsg.post(); + +} + +void RmAppletObject::SetSizePixel( const Size & rSize) +{ + DCA_NAMESPACE(OCallMethodMsg, dca) aMsg( this, MSG_APPLET_SETSIZE ); + DCA_NAMESPACE(OObjStream , dca)& s = aMsg.getData(); + s << rSize.Width(); + s << rSize.Height(); + aMsg.post(); + +} + + +/* -------- Basis Object ---------------- */ + +RmBasisObject::RmBasisObject( ) +{ +} + + +Boolean RmBasisObject::dispatchMessage(DCA_NAMESPACE(OCallMethodMsg , dca)& rMsg) +{ + // we have to switch to the main Thread + MT_Link aLink (LINK((RmBasisObject*) this, RmBasisObject,executeMessage )); + aLink.Call(&rMsg); + return 1; +} + +IMPL_LINK( RmBasisObject, executeMessage, DCA_NAMESPACE(OCallMethodMsg , dca) *, pMsg ) +{ + int nType = pMsg->getType(); + + switch ( nType ) + { + case MSG_SHOWSTATUS: + { + OSL_TRACE( "Rm: ShowStatus" ); + DCA_NAMESPACE(OObjStream , dca)& s = pMsg->getData(); + String statusText; + s >> statusText; + ((RmAppletContext*)this) -> showStatus(statusText); + } + break; + case MSG_GETAPPLET : + { + OSL_TRACE( "Rm: GetApplet" ); + DCA_NAMESPACE(OObjStream , dca)& s = pMsg->getData(); + String sName; + s >> sName; + RmAppletObject * pObj = ((RmAppletContext *)this) -> getApplet(sName ); + DCA_NAMESPACE(OObjStream , dca)& rStream = pMsg->getData(); + rStream << pObj; + pMsg->post(); + } + break; + case MSG_GETAPPLETS : + { + OSL_TRACE( "Rm: GetApplets" ); + DCA_NAMESPACE(OObjStream , dca)& s = pMsg->getData(); + List rList; + ((RmAppletContext *) this) -> fillApplets(rList ); + DCA_NAMESPACE(OObjStream , dca)& rStream = pMsg->getData(); + rStream << (long)rList.Count(); + for (int i = 0; i < (int)rList.Count(); i++) + rStream << (RmAppletObject*)rList.GetObject(i); + pMsg->post(); + } + break; + case MSG_SHOWDOCUMENT : + { + OSL_TRACE( "Rm: ShowDocument" ); + DCA_NAMESPACE(OObjStream , dca)& s = pMsg->getData(); + String sURL; + String sDest; + INetURLObject *pURL; + s >> sURL; + s >> sDest; + pURL = getURL(sURL); + ((RmAppletContext*) this) -> showDocument((*pURL), sDest ); + } + break; + case MSG_APPLETRESIZE : + { + OSL_TRACE( "Rm: AppletResize" ); + long width; + long height; + DCA_NAMESPACE(OObjStream , dca)& s = pMsg->getData(); + s >> width; + s >> height; + ((RmAppletStub *) this) -> appletResize(width, height); + } + break; + case MSG_APPLETSTARTED: + { + OSL_TRACE( "Rm: AppletStarted" ); + ((RmAppletStub *) this) -> appletStarted(); + } + break; + case MSG_APPLETABORT: + { + OSL_TRACE( "Rm: AppletAbort" ); + ((RmAppletStub *) this) -> onAppletAbort(); + } + break; + + + default: + OSL_TRACE( "Rm: Unknown dispatchMessage (%d)", nType ); + //OObj::dispatchMessage( rMsg ); + break; + } + + return 1; +} + + +} + +#endif // REMOTE_VERSION + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/soconv.cxx b/bf_so3/source/inplace/soconv.cxx new file mode 100644 index 000000000..3b88915e7 --- /dev/null +++ b/bf_so3/source/inplace/soconv.cxx @@ -0,0 +1,406 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + + +#include <vcl/graph.hxx> +#include <bf_so3/svstor.hxx> +#include <bf_so3/embobj.hxx> +#include <bf_so3/ipobj.hxx> +#include <sot/exchange.hxx> + +namespace binfilter { + +// Vordefinierte OLE-1-IDs +// Unter Windows koennen wir uns noch auf die RegDB stuerzen, sonst +// nehmen wir eben diese IDs +// Standardformat: + +// 0003xxxx-0000-0000-C000-000000000046 + +struct ClsIDs { + UINT32 nId; + const sal_Char* pSvrName; + const sal_Char* pDspName; +} aClsIDs[] = { + + { 0x000212F0, "MSWordArt", "Microsoft Word Art" }, + { 0x000212F0, "MSWordArt.2", "Microsoft Word Art 2.0" }, + + // MS Apps + { 0x00030000, "ExcelWorksheet", "Microsoft Excel Worksheet" }, + { 0x00030001, "ExcelChart", "Microsoft Excel Chart" }, + { 0x00030002, "ExcelMacrosheet", "Microsoft Excel Macro" }, + { 0x00030003, "WordDocument", "Microsoft Word Document" }, + { 0x00030004, "MSPowerPoint", "Microsoft PowerPoint" }, + { 0x00030005, "MSPowerPointSho", "Microsoft PowerPoint Slide Show"}, + { 0x00030006, "MSGraph", "Microsoft Graph" }, + { 0x00030007, "MSDraw", "Microsoft Draw" }, + { 0x00030008, "Note-It", "Microsoft Note-It" }, + { 0x00030009, "WordArt", "Microsoft Word Art" }, + { 0x0003000a, "PBrush", "Microsoft PaintBrush Picture" }, + { 0x0003000b, "Equation", "Microsoft Equation Editor" }, + { 0x0003000c, "Package", "Package" }, + { 0x0003000d, "SoundRec", "Sound" }, + { 0x0003000e, "MPlayer", "Media Player" }, + // MS Demos + { 0x0003000f, "ServerDemo", "OLE 1.0 Server Demo" }, + { 0x00030010, "Srtest", "OLE 1.0 Test Demo" }, + { 0x00030011, "SrtInv", "OLE 1.0 Inv Demo" }, + { 0x00030012, "OleDemo", "OLE 1.0 Demo" }, + + // Coromandel / Dorai Swamy / 718-793-7963 + { 0x00030013, "CoromandelIntegra", "Coromandel Integra" }, + { 0x00030014, "CoromandelObjServer","Coromandel Object Server" }, + + // 3-d Visions Corp / Peter Hirsch / 310-325-1339 + { 0x00030015, "StanfordGraphics", "Stanford Graphics" }, + + // Deltapoint / Nigel Hearne / 408-648-4000 + { 0x00030016, "DGraphCHART", "DeltaPoint Graph Chart" }, + { 0x00030017, "DGraphDATA", "DeltaPoint Graph Data" }, + + // Corel / Richard V. Woodend / 613-728-8200 x1153 + { 0x00030018, "PhotoPaint", "Corel PhotoPaint" }, + { 0x00030019, "CShow", "Corel Show" }, + { 0x0003001a, "CorelChart", "Corel Chart" }, + { 0x0003001b, "CDraw", "Corel Draw" }, + + // Inset Systems / Mark Skiba / 203-740-2400 + { 0x0003001c, "HJWIN1.0", "Inset Systems" }, + + // Mark V Systems / Mark McGraw / 818-995-7671 + { 0x0003001d, "ObjMakerOLE", "MarkV Systems Object Maker" }, + + // IdentiTech / Mike Gilger / 407-951-9503 + { 0x0003001e, "FYI", "IdentiTech FYI" }, + { 0x0003001f, "FYIView", "IdentiTech FYI Viewer" }, + + // Inventa Corporation / Balaji Varadarajan / 408-987-0220 + { 0x00030020, "Stickynote", "Inventa Sticky Note" }, + + // ShapeWare Corp. / Lori Pearce / 206-467-6723 + { 0x00030021, "ShapewareVISIO10", "Shapeware Visio 1.0" }, + { 0x00030022, "ImportServer", "Spaheware Import Server" }, + + // test app SrTest + { 0x00030023, "SrvrTest", "OLE 1.0 Server Test" }, + + // test app ClTest. Doesn't really work as a server but is in reg db + { 0x00030025, "Cltest", "OLE 1.0 Client Test" }, + + // Microsoft ClipArt Gallery Sherry Larsen-Holmes + { 0x00030026, "MS_ClipArt_Gallery", "Microsoft ClipArt Gallery" }, + // Microsoft Project Cory Reina + { 0x00030027, "MSProject", "Microsoft Project" }, + + // Microsoft Works Chart + { 0x00030028, "MSWorksChart", "Microsoft Works Chart" }, + + // Microsoft Works Spreadsheet + { 0x00030029, "MSWorksSpreadsheet", "Microsoft Works Spreadsheet" }, + + // AFX apps - Dean McCrory + { 0x0003002A, "MinSvr", "AFX Mini Server" }, + { 0x0003002B, "HierarchyList", "AFX Hierarchy List" }, + { 0x0003002C, "BibRef", "AFX BibRef" }, + { 0x0003002D, "MinSvrMI", "AFX Mini Server MI" }, + { 0x0003002E, "TestServ", "AFX Test Server" }, + + // Ami Pro + { 0x0003002F, "AmiProDocument", "Ami Pro Document" }, + + // WordPerfect Presentations For Windows + { 0x00030030, "WPGraphics", "WordPerfect Presentation" }, + { 0x00030031, "WPCharts", "WordPerfect Chart" }, + + // MicroGrafx Charisma + { 0x00030032, "Charisma", "MicroGrafx Charisma" }, + { 0x00030033, "Charisma_30", "MicroGrafx Charisma 3.0" }, + { 0x00030034, "CharPres_30", "MicroGrafx Charisma 3.0 Pres" }, + // MicroGrafx Draw + { 0x00030035, "Draw", "MicroGrafx Draw" }, + // MicroGrafx Designer + { 0x00030036, "Designer_40", "MicroGrafx Designer 4.0" }, + + // STAR DIVISION +// { 0x000424CA, "StarMath", "StarMath 1.0" }, + { 0x00043AD2, "FontWork", "Star FontWork" }, +// { 0x000456EE, "StarMath2", "StarMath 2.0" }, + + { 0, "", "" } }; + +// Da wir nicht die gesamte SO-Lib inklusive OLE1 dran haben wollen, +// sei hier die Leseroutine fuer ein StarObject noch mit drin. + +#define SO_SIGNATURE 0x534F6D64 // Signatur ('mdSO' im INTEL-Format) +#define SO_VERSION 0x00000002 + +struct StarObjectFileHdr +{ + UINT32 nSize; // Groesse der Struktur + UINT32 nSignature; // Signatur + UINT32 nVersion; // Version + UINT32 nWidth; // Breite in 1/100 mm + UINT32 nHeight; // Hoehe in 1/100 mm + UINT32 nObjName; // Laenge Objektname + UINT32 nServerName; // Laenge Servername + UINT32 nPrivData; // Laenge private Daten + UINT32 nPicData; // Laenge GDIMetafile +}; + +// Laden eines StarObjects. Die Daten werden in den Parametern +// uebergeben, der Returnwert ist der Stream-Fehlercode. +#define PIC_READ 1 +#define DATA_READ 2 +static ULONG LoadStarObject + ( SvStream& rSrc, String& rSvrName, String& rObjName, + GDIMetaFile & rPic, SvStream & rDataStm ) +{ + ULONG nRet = 0; + StarObjectFileHdr aHdr; + long pos = rSrc.Tell(); + aHdr.nSize = 0L; + rSrc >> aHdr.nSize; + rSrc.Seek( pos ); + + if ( aHdr.nSize != sizeof( aHdr ) ) + { + rSrc.SetError( SVSTREAM_GENERALERROR ); + return 0; + } + + rSrc >> aHdr.nSize + >> aHdr.nSignature + >> aHdr.nVersion + >> aHdr.nWidth + >> aHdr.nHeight + >> aHdr.nObjName + >> aHdr.nServerName + >> aHdr.nPrivData + >> aHdr.nPicData; + + if ( aHdr.nSignature != SO_SIGNATURE || aHdr.nVersion > SO_VERSION ) + { + rSrc.SetError( SVSTREAM_GENERALERROR ); + return 0; + } + + sal_Char cBuf[ 128 ]; + rSrc.Read( cBuf, aHdr.nObjName ); + if ( rSrc.GetError() ) + return 0; + rObjName = String( + cBuf, sal::static_int_cast< xub_StrLen >( aHdr.nObjName ), + osl_getThreadTextEncoding() ); + + rSrc.Read( cBuf, aHdr.nServerName ); + if ( rSrc.GetError() ) + return 0; + rSvrName = String( + cBuf, sal::static_int_cast< xub_StrLen >( aHdr.nServerName ), + osl_getThreadTextEncoding() ); + if ( aHdr.nPrivData ) + { + UINT32 nLen; + rSrc >> nLen; + if ( rSrc.GetError() ) + return 0; + + BYTE * pData = new BYTE[ nLen ]; + rDataStm << nLen; + rSrc.Read( pData, nLen ); + rDataStm.Write( pData, nLen ); + delete [] pData; + if ( rDataStm.GetError() ) + { + rSrc.SetError( rDataStm.GetError() ); + return 0; + } + nRet = DATA_READ; + } + if ( aHdr.nPicData ) + { + if( aHdr.nVersion < SO_VERSION ) + { + // Alte Grafiken + rSrc >> rPic; + } + else + { + // neue, portable oder nicht portable Grafiken + Graphic aGrf; + aGrf.ReadEmbedded( rSrc ); + rPic = aGrf.GetGDIMetaFile(); + } + nRet |= PIC_READ; + } + if ( rSrc.GetError() ) + return 0; + return nRet; +} + +BOOL SvEmbeddedObject::InsertStarObject + ( const String &rObjName, const String& rStgName, + SvStream& rSrc, SvPersist* pPersist ) +{ + ULONG nRead; + SvStorageRef rpDst( pPersist->GetStorage() ); + String aObjName, aSvrName; + GDIMetaFile aPic; + SvMemoryStream aDataStm; + + nRead = LoadStarObject( rSrc, aSvrName, aObjName, aPic, aDataStm ); + if( rSrc.GetError() != SVSTREAM_OK ) + return FALSE; + + // Es kann losgehen! + // Erstmal den ClassID sowie die Bschreibung suchen + ClsIDs* pIds; + for( pIds = aClsIDs; pIds->nId; pIds++ ) + { + if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) ) + break; + } + SvGlobalName* pClsId = NULL; + String aShort, aFull; + if( pIds->nId ) + { + // gefunden! + pClsId = new SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ); + aFull = String( pIds->pDspName, osl_getThreadTextEncoding() ); + aShort = aSvrName; + } + else if( (COMPARE_EQUAL == aSvrName.CompareToAscii( "StarMath2" )) + || (COMPARE_EQUAL == aSvrName.CompareToAscii( "StarMath" )) ) + { + // Sonderfall: In StarMath 3 umwandeln + pClsId = new SvGlobalName; + pClsId->MakeId( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "D4590460-35FD-101C-B12A-04021C007002" ) ) ); + aFull = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "StarMath 3.0" ) ); + aShort = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "StarMath" ) ); + } + + if( !pClsId ) + { + rpDst->SetError( SVSTREAM_GENERALERROR ); + return FALSE; + } + + // Class-ID und Daten sind vorhanden. Nun muss noch der Storage + // aufgebaut werden. + // Main Storage einrichten + if( rpDst->IsContained( rStgName ) ) + rpDst->Remove( rStgName ); + SvStorageRef rpObj = rpDst->OpenOLEStorage( rStgName, + STREAM_READWRITE| STREAM_SHARE_DENYALL ); +// SvStorageRef rpObj = rpDst->OpenStorage( rStgName, +// STREAM_READWRITE| STREAM_SHARE_DENYALL ); + if( rpObj.Is() && rpObj->GetError() ) + { + rpDst->SetError( rpObj->GetError() ); rpObj.Clear(); + } + if( rpObj.Is() ) + { + // 1. die OLE-Daten + ULONG nCbFmt = SotExchange::RegisterFormatName( aShort ); + rpObj->SetClass( *pClsId, nCbFmt, aFull ); + } + delete pClsId; + + // 2. Den Daten-Stream aufsetzen + if( rpObj.Is() && (nRead & DATA_READ) ) + { + SvStorageStreamRef rpStrm = + rpObj->OpenStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ), + STREAM_WRITE| STREAM_SHARE_DENYALL ); + if( rpStrm.Is() && rpStrm->GetError() ) + { + rpDst->SetError( rpStrm->GetError() ); rpStrm.Clear(); + } + if( rpStrm.Is() ) + { + aDataStm.Seek( 0 ); + *rpStrm << aDataStm; + rpDst->SetError( rpObj->GetError() ); + if( rpDst->GetError() ) + rpObj.Clear(); + } + } + + // 3. Den Picture-Stream aufsetzen + if( rpObj.Is() && (nRead & PIC_READ) ) + { + ULONG nErr = SVSTREAM_OK; + if( !SvEmbeddedObject::MakeContentStream( rpObj, aPic ) ) + nErr = SVSTREAM_WRITE_ERROR; + else + nErr = rpObj->GetError(); + rpDst->SetError( nErr ); + if( nErr != SVSTREAM_OK ) + rpObj.Clear(); + } + + // 4. Alles committen + if( rpObj.Is() ) + { + rpObj->Commit(); + rpDst->SetError( rpObj->GetError() ); + } + // Sonst evtl. den (defekten) Storage weg + else if( rpDst->IsContained( rStgName ) ) + rpDst->Remove( rStgName ); + rpDst->Commit(); + if( rpDst->GetError() == SVSTREAM_OK ) + { + SvObjectRef rpOleObj = + ((SvFactory*)SvInPlaceObject::ClassFactory())->CreateAndLoad( rpObj ); + SvInPlaceObjectRef rpInplaceObj( &rpOleObj ); + if( rpInplaceObj.Is() ) + { + SvInfoObjectRef rpInfo = + new SvEmbeddedInfoObject( rpInplaceObj, rObjName ); + return pPersist->Insert( rpInfo ); + } + } + return FALSE; +} + +// Laden des Pictures eines StarObjects +// (falls es nicht als OLE-Objekt ladbar ist) + +BOOL SvEmbeddedObject::LoadStarObjectPicture( SvStream& rSrc, GDIMetaFile& rMTF ) +{ + String aObjName, aSvrName; + GDIMetaFile aPic; + SvMemoryStream aDataStm; + + ULONG nErr = LoadStarObject( rSrc, aSvrName, aObjName, aPic, aDataStm ); + (void)nErr; + if( rSrc.GetError() != SVSTREAM_OK ) + return FALSE; + + rMTF = aPic; + return TRUE; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/inplace/viscache.hxx b/bf_so3/source/inplace/viscache.hxx new file mode 100644 index 000000000..a981b4313 --- /dev/null +++ b/bf_so3/source/inplace/viscache.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <tools/stream.hxx> +#include <vcl/gdimtf.hxx> +#include <vcl/bitmap.hxx> + +namespace binfilter { + +/************************************************************************ +|* Impl_CacheElement +|* Impl_Cache +|* +|* Beschreibung +*************************************************************************/ +class Impl_OlePres +{ + ULONG nFormat; + USHORT nAspect; + Bitmap * pBmp; + GDIMetaFile * pMtf; + + UINT32 nAdvFlags; + INT32 nJobLen; + BYTE* pJob; + Size aSize; // Groesse in 100TH_MM +public: + Impl_OlePres( ULONG nF ) + : nFormat( nF ) + , pBmp( NULL ) + , pMtf( NULL ) + , nAdvFlags( 0x2 ) // in Dokument gefunden + , nJobLen( 0 ) + , pJob( NULL ) + {} + ~Impl_OlePres() + { + delete [] pJob; + delete pBmp; + delete pMtf; + } + void SetMtf( const GDIMetaFile & rMtf ) + { + if( pMtf ) + delete pMtf; + pMtf = new GDIMetaFile( rMtf ); + } + Bitmap *GetBitmap() const { return pBmp; } + GDIMetaFile *GetMetaFile() const { return pMtf; } + ULONG GetFormat() const { return nFormat; } + void SetAspect( USHORT nAsp ) { nAspect = nAsp; } + ULONG GetAdviseFlags() const { return nAdvFlags; } + void SetAdviseFlags( ULONG nAdv ) { nAdvFlags = nAdv; } + void SetSize( const Size & rSize ) { aSize = rSize; } + /// return FALSE => unknown format + BOOL Read( SvStream & rStm ); + void Write( SvStream & rStm ); +}; + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/misc/factory.cxx b/bf_so3/source/misc/factory.cxx new file mode 100644 index 000000000..bb3a3df2b --- /dev/null +++ b/bf_so3/source/misc/factory.cxx @@ -0,0 +1,712 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <string.h> +#include <stdio.h> + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <comphelper/processfactory.hxx> + + +#include <tools/config.hxx> + +#include <bf_so3/factory.hxx> + +#include <vcl/timer.hxx> +#include <vcl/svapp.hxx> +#include <basic/sbxfac.hxx> +#include <basic/sbxprop.hxx> +#include <basic/sbxmeth.hxx> +#include <bf_svtools/solar.hrc> +#include <tools/resmgr.hxx> + +#include <binddata.hxx> + +#include <soimpl.hxx> +#include <bf_so3/svstor.hxx> +#include <bf_so3/embobj.hxx> +#include "bf_so3/ipclient.hxx" +#include <bf_so3/ipobj.hxx> +#include "bf_so3/outplace.hxx" +#include <bf_so3/ipenv.hxx> +#include <bf_so3/protocol.hxx> +#include "bf_so3/plugin.hxx" +#include "bf_so3/soerr.hxx" +#include <comphelper/classids.hxx> +#include "insdlg.hxx" + +#include <sot/formats.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::datatransfer; + +namespace binfilter { + +/************** class SoDll *********************************************/ +/************************************************************************* +|* SoDll::SoDll +|* +|* Beschreibung +*************************************************************************/ +static SoDll* pDll=NULL; + +SoDll* SoDll::GetOrCreate() +{ + if ( !pDll ) + pDll = new SoDll; + return pDll; +} + +SoDll::SoDll() + : bInit( FALSE ) + , bSelfInit( FALSE ) + , pResMgr( NULL ) + , pSvObjectFactory( NULL ) + , pSvStorageStreamFactory( NULL ) + , pSvStorageFactory( NULL ) + , pSvEmbeddedObjectFactory( NULL ) + , pSvEmbeddedClientFactory( NULL ) + , pSvInPlaceObjectFactory( NULL ) + , pSvPlugInObjectFactory( NULL ) + , pSvAppletObjectFactory( NULL ) + , pSvInPlaceClientFactory( NULL ) + , pSvPersistFactory( NULL ) + , pSvPseudoObjectFactory( NULL ) + , pSvSimplePersistFactory( NULL ) + , pSvObjectContainerFactory( NULL ) + , pSvFactory_ImplFactory( NULL ) + , pDfltPlugInFactory( NULL ) + , pDfltAppletFactory( NULL ) + , pSoBindingFactory( NULL ) + , pContEnvList( NULL ) + , pIPActiveClientList( NULL ) + , pUIShowIPEnv( NULL ) + , pIEOPDflt( NULL ) + , aSvInterface( 0xB34BB240L, 0x4BD8, 0x101C, 0x8D, 0x86, + 0x4A, 0x04, 0x12, 0x94, 0x26, 0x0D ) + , pPlugInVerbList( NULL ) + , nPlugInDocFormat( 0 ) + , pAppletVerbList( NULL ) + , nAppletDocFormat( 0 ) + , pDeathTimer( NULL ) + , pBindingData( 0 ) + , pConvTable( NULL ) + , nConvTableEntries( 0 ) +{ +} + + +SoDll::~SoDll() +{ + delete pResMgr; + delete pIPActiveClientList; + delete pContEnvList; + SvEditObjectProtocol::Imp_DeleteDefault(); + delete pDeathTimer; + delete pPlugInVerbList; + delete pAppletVerbList; + + SvBindingData::Delete(); + delete [] pConvTable; +} + + +ResMgr * SoDll::GetResMgr() +{ + // resources are in the OFA res mgr + if ( !pResMgr ) + { + ByteString aMgrName = ByteString( "bf_ofa" ); + pResMgr = ResMgr::CreateResMgr( aMgrName.GetBuffer() ); + } + return pResMgr; +} + +/************** class SvFactory *****************************************/ +/************************************************************************* +|* SvFactory::SvFactory() +|* +|* Beschreibung +*************************************************************************/ +TYPEINIT0(SvFactory); + +SvFactory::SvFactory( const SvGlobalName & rName, + const String & rClassName, + CreateInstanceType pCreateFuncP ) + : SotFactory( rName, rClassName, pCreateFuncP ) + , nRegisterId ( 0 ) +{ +} + + +//========================================================================= +SvFactory::~SvFactory() +{ +} + +/************************************************************************* +|* SvFactory::Init() +|* +|* Beschreibung +*************************************************************************/ + +BOOL SvFactory::Init() +{ + SoDll* pSoApp = SOAPP; + pSoApp->bInit = TRUE; + pSoApp->bSelfInit = TRUE; + if( pSoApp->bSelfInit ) + { + // Lokal anmelden + pSoApp->aInfoClassMgr.SV_CLASS_REGISTER( SvEmbeddedInfoObject ); + pSoApp->aInfoClassMgr.SV_CLASS_REGISTER( SvInfoObject ); + SvPlugInObject::ClassFactory(); + // SvAppletObject::ClassFactory(); + SvOutPlaceObject::ClassFactory(); + } + + return pSoApp->bInit; +} + +String SvFactory::GetServiceName( const SvGlobalName& rClassName ) +{ + ::rtl::OUString aServiceName; + if( SvGlobalName(SO3_SC_CLASSID_60) == rClassName ) + { + aServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.SpreadsheetDocument" )); + } + else if( SvGlobalName(SO3_SW_CLASSID_60) == rClassName ) + { + aServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Writer.TextDocument" )); + } + else if( SvGlobalName(SO3_SWWEB_CLASSID_60) == rClassName ) + { + aServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Writer.WebDocument" )); + } + else if( SvGlobalName(SO3_SWGLOB_CLASSID_60) == rClassName ) + { + aServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Writer.GlobalDocument" )); + } + else if( SvGlobalName(SO3_SIMPRESS_CLASSID_60) == rClassName ) + { + aServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Draw.PresentationDocument" )); + } + else if( SvGlobalName(SO3_SDRAW_CLASSID_60) == rClassName ) + { + aServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Draw.DrawingDocument" )); + } + else if( SvGlobalName(SO3_SCH_CLASSID_60) == rClassName ) + { + aServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.ChartDocument" )); + } + else if( SvGlobalName(SO3_SM_CLASSID_60) == rClassName ) + { + aServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.FormulaDocument" )); + } + + return aServiceName; +} + +SvObject* TryCreate( const SvGlobalName& rClassName ) +{ + ::rtl::OUString aServiceName = SvFactory::GetServiceName( rClassName ); + if ( aServiceName.getLength() ) + { + ::com::sun::star::uno::Reference < ::com::sun::star::frame::XModel > xDoc( + ::comphelper::getProcessServiceFactory()->createInstance( aServiceName ), UNO_QUERY ); + if ( xDoc.is() ) + { + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aProps( 1 ); + aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SetEmbedded" )); + aProps[0].Value <<= sal_True; + xDoc->attachResource( ::rtl::OUString(), aProps ); + + ::com::sun::star::uno::Reference < ::com::sun::star::lang::XUnoTunnel > xObj( xDoc, UNO_QUERY ); + ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( (sal_Int8*) SvGlobalName( SO3_GLOBAL_CLASSID ).GetBytes(), 16 ); + sal_Int64 nHandle = xObj->getSomething( aSeq ); + if ( nHandle ) + return reinterpret_cast<SvObject*>(sal::static_int_cast<sal_IntPtr>(nHandle)); + // return (SvObject*) (sal_Int32*) nHandle; + } + } + + return 0; +} + +/************************************************************************* +|* SvFactory::Create() +|* +|* Beschreibung +*************************************************************************/ +SvObjectRef SvFactory::Create( const SvGlobalName & rClassName ) const +{ + SotObject *pBasicObj=NULL; + pBasicObj = TryCreate( rClassName ); + if ( pBasicObj ) + return SvObjectRef( pBasicObj ); + + const SvFactory * pFact = this; + if ( !pFact || rClassName != *this ) + pFact = PTR_CAST( SvFactory, Find( rClassName ) ); + + if( pFact ) + { + pFact->CreateInstance( &pBasicObj ); + } + else if( !this || (SotFactory *)this == SvEmbeddedObject::ClassFactory() + || (SotFactory *)this == (SotFactory *)SvInPlaceObject::ClassFactory() ) + { + SvOutPlaceObject::ClassFactory()->CreateInstance( &pBasicObj ); + } + else + { + CreateInstance( &pBasicObj ); + } + + SvObjectRef aObj( pBasicObj ); + return aObj; +} + + +/************************************************************************* +|* SvFactory::Create() +|* +|* Beschreibung +*************************************************************************/ +SvObjectRef SvFactory::CreateAndLoad( SvStorage * pStor, BOOL ) const +{ + // Storage sichern + SvStorageRef aStor = pStor; + SvGlobalName aClassName_ = pStor->GetClassName(); + aClassName_ = GetAutoConvertTo( aClassName_ ); + + const ::binfilter::SvObjectServer* pInternalServer = SvOutPlaceObject::GetInternalServer_Impl( aClassName_ ); + if ( pInternalServer ) + { + // this is a StarOffice 6.1 embedded object + SotStorageStreamRef xEmbStm = pStor->OpenSotStream( + String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "package_stream" ) ), + STREAM_STD_READ ); + + if( !xEmbStm->GetError() ) + { + SvStorageRef xEmbStor = new SvStorage( *xEmbStm ); + if( !xEmbStor->GetError() ) + { + SvPersistRef aPObj( &Create( pInternalServer->GetClassName() ) ); + if( aPObj.Is() && aPObj->DoLoad( xEmbStor ) ) + return &aPObj; + } + } + } + else + { + SvPersistRef aPObj( &Create( aClassName_ ) ); + if( aPObj.Is() && aPObj->DoLoad( pStor ) ) + return &aPObj; + } + + return SvObjectRef(); +} + +/************************************************************************* +|* SvFactory::CreateAndInit() +|* +|* Beschreibung +*************************************************************************/ +SvObjectRef SvFactory::CreateAndInit( const SvGlobalName & rClassName, + SvStorage * pStor ) const +{ + // Storage sichern + SvStorageRef aStor = pStor; + SvEmbeddedObjectRef aEObj( &Create( rClassName ) ); + if( aEObj.Is() && aEObj->DoInitNew( pStor ) ) + return &aEObj; + + return SvObjectRef(); +} + +/************************************************************************* +|* SvFactory::Register() +|* +|* Beschreibung +*************************************************************************/ +void SvFactory::Register() +{ + DBG_ASSERT( !IsRegistered(), "SvFactory::Register: register twice" ); + if( !IsRegistered() ) + { + nRegisterId = 1; // Wert ist unwichtig, aber != 0 + DBG_ASSERT( IsRegistered(), "SvFactory::Register: cannot register" ); + } +} + +//========================================================================= +ConvertTo_Impl (* SetupConvertTable_Impl( USHORT * pCount )) [SO3_OFFICE_VERSIONS] +{ + // Die alten Eintr"age m"ussen vor den neueren stehen, damit der + // Algorithmus besser "uber mehrere Konvertierungsstufen laufen kann. + // Neue Eintr"age d"urfen nur angeh"angt werden. Sonst m"ussen alle + // Vorg"anger und Nachfolger Indizes "uberarbeitet werden. + SoDll * pSoApp = SOAPP; + if( !pSoApp->pConvTable ) + { + pSoApp->nConvTableEntries = 8; + pSoApp->pConvTable = new ConvertTo_Impl[8][SO3_OFFICE_VERSIONS]; + + pSoApp->pConvTable[0][0] = ConvertTo_Impl + (// StarWiter 3.0 + SvGlobalName( 0xDC5C7E40L, 0xB35C, 0x101B, 0x99, 0x61, 0x04, 0x02, 0x1C, 0x00, 0x70,0x02 ), + *SvInPlaceObject::ClassFactory(), + SOT_FORMATSTR_ID_STARWRITER_30 + ); + pSoApp->pConvTable[0][1] = ConvertTo_Impl + (// StarWiter 4.0 + SvGlobalName( 0x8b04e9b0L, 0x420e, 0x11d0, 0xa4, 0x5e, 0x0, 0xa0, 0x24, 0x9d, 0x57, 0xb1 ), + SOT_FORMATSTR_ID_STARWRITER_40 + ); + pSoApp->pConvTable[0][2] = ConvertTo_Impl + (// StarWiter 5.0 + SvGlobalName( SO3_SW_CLASSID_50 ), + SOT_FORMATSTR_ID_STARWRITER_50 + ); + pSoApp->pConvTable[0][3] = ConvertTo_Impl + (// StarWiter + SvGlobalName( SO3_SW_CLASSID_60 ), + SOT_FORMATSTR_ID_STARWRITER_60 + ); + pSoApp->pConvTable[0][4] = ConvertTo_Impl + (// StarWiter + SvGlobalName( SO3_SW_CLASSID ), + SOT_FORMATSTR_ID_STARWRITER_60 + ); + + pSoApp->pConvTable[1][0] = ConvertTo_Impl + (// StarDraw 3.0 + SvGlobalName( 0xAF10AAE0L, 0xB36D, 0x101B, 0x99, 0x61, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02 ), + *SvInPlaceObject::ClassFactory(), + SOT_FORMATSTR_ID_STARDRAW + ); + pSoApp->pConvTable[1][1] = ConvertTo_Impl + (// StarDraw 4.0 + SvGlobalName( 0x012d3cc0L, 0x4216, 0x11d0, 0x89, 0xcb, 0x00, 0x80, 0x29, 0xe4, 0xb0, 0xb1 ), + SOT_FORMATSTR_ID_STARDRAW_40 + ); + pSoApp->pConvTable[1][2] = ConvertTo_Impl + (// StarImpress 5.0 + SvGlobalName( SO3_SIMPRESS_CLASSID_50 ), + SOT_FORMATSTR_ID_STARIMPRESS_50 + ); + pSoApp->pConvTable[1][3] = ConvertTo_Impl + (// StarImpress + SvGlobalName( SO3_SIMPRESS_CLASSID_60 ), + SOT_FORMATSTR_ID_STARIMPRESS_60 + ); + pSoApp->pConvTable[1][4] = ConvertTo_Impl + (// StarImpress + SvGlobalName( SO3_SIMPRESS_CLASSID ), + SOT_FORMATSTR_ID_STARIMPRESS_60 + ); + + pSoApp->pConvTable[2][0] = ConvertTo_Impl + (// StarChart 3.0 + SvGlobalName( 0xFB9C99E0L, 0x2C6D, 0x101C, 0x8E, 0x2C, 0x00, 0x00, 0x1B, 0x4C, 0xC7, 0x11 ), + SOT_FORMATSTR_ID_STARCHART + ); + pSoApp->pConvTable[2][1] = ConvertTo_Impl + (// StarChart 4.0 + SvGlobalName( 0x02b3b7e0L, 0x4225, 0x11d0, 0x89, 0xca, 0x00, 0x80, 0x29, 0xe4, 0xb0, 0xb1 ), + SOT_FORMATSTR_ID_STARCHART_40 + ); + pSoApp->pConvTable[2][2] = ConvertTo_Impl + (// StarChart 5.0 + SvGlobalName( SO3_SCH_CLASSID_50 ), + SOT_FORMATSTR_ID_STARCHART_50 + ); + pSoApp->pConvTable[2][3] = ConvertTo_Impl + (// StarChart + SvGlobalName( SO3_SCH_CLASSID_60 ), + SOT_FORMATSTR_ID_STARCHART_60 + ); + pSoApp->pConvTable[2][4] = ConvertTo_Impl + (// StarChart + SvGlobalName( SO3_SCH_CLASSID ), + SOT_FORMATSTR_ID_STARCHART_60 + ); + + pSoApp->pConvTable[3][0] = ConvertTo_Impl + (// StarMath 3.0 + SvGlobalName( 0xD4590460L, 0x35FD, 0x101C, 0xB1, 0x2A, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02 ), + SOT_FORMATSTR_ID_STARMATH + ); + pSoApp->pConvTable[3][1] = ConvertTo_Impl + (// StarMath 4.0 + SvGlobalName( 0x02b3b7e1L, 0x4225, 0x11d0, 0x89, 0xca, 0x00, 0x80, 0x29, 0xe4, 0xb0, 0xb1 ), + SOT_FORMATSTR_ID_STARMATH_40 + ); + pSoApp->pConvTable[3][2] = ConvertTo_Impl + (// StarMath 5.0 + SvGlobalName( SO3_SM_CLASSID_50 ), + SOT_FORMATSTR_ID_STARMATH_50 + ); + pSoApp->pConvTable[3][3] = ConvertTo_Impl + (// StarMath + SvGlobalName( SO3_SM_CLASSID_60 ), + SOT_FORMATSTR_ID_STARMATH_60 + ); + pSoApp->pConvTable[3][4] = ConvertTo_Impl + (// StarMath + SvGlobalName( SO3_SM_CLASSID ), + SOT_FORMATSTR_ID_STARMATH_60 + ); + + pSoApp->pConvTable[4][0] = ConvertTo_Impl + (// StarCalc 3.0 + SvGlobalName( 0x3F543FA0L, 0xB6A6, 0x101B, 0x99, 0x61, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02 ), + *SvInPlaceObject::ClassFactory(), + SOT_FORMATSTR_ID_STARCALC + ); + pSoApp->pConvTable[4][1] = ConvertTo_Impl + (// StarCalc 4.0 + SvGlobalName( 0x6361d441L, 0x4235, 0x11d0, 0x89, 0xcb, 0x00, 0x80, 0x29, 0xe4, 0xb0, 0xb1 ), + SOT_FORMATSTR_ID_STARCALC_40 + ); + pSoApp->pConvTable[4][2] = ConvertTo_Impl + (// StarCalc 5.0 + SvGlobalName( SO3_SC_CLASSID_50 ), + SOT_FORMATSTR_ID_STARCALC_50 + ); + pSoApp->pConvTable[4][3] = ConvertTo_Impl + (// StarCalc + SvGlobalName( SO3_SC_CLASSID_60 ), + SOT_FORMATSTR_ID_STARCALC_60 + ); + pSoApp->pConvTable[4][4] = ConvertTo_Impl + (// StarCalc + SvGlobalName( SO3_SC_CLASSID ), + SOT_FORMATSTR_ID_STARCALC_60 + ); + + pSoApp->pConvTable[5][0] = ConvertTo_Impl + (// StarDraw 3.0 + SvGlobalName( 0xAF10AAE0L, 0xB36D, 0x101B, 0x99, 0x61, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02 ), + *SvInPlaceObject::ClassFactory(), + SOT_FORMATSTR_ID_STARDRAW + ); + pSoApp->pConvTable[5][1] = ConvertTo_Impl + (// StarDraw 4.0 + SvGlobalName( 0x012d3cc0L, 0x4216, 0x11d0, 0x89, 0xcb, 0x00, 0x80, 0x29, 0xe4, 0xb0, 0xb1 ), + SOT_FORMATSTR_ID_STARDRAW_40 + ); + pSoApp->pConvTable[5][2] = ConvertTo_Impl + (// StarDraw 5.0 + SvGlobalName( SO3_SDRAW_CLASSID_50 ), + SOT_FORMATSTR_ID_STARDRAW_50 + ); + pSoApp->pConvTable[5][3] = ConvertTo_Impl + (// StarDraw + SvGlobalName( SO3_SDRAW_CLASSID_60 ), + SOT_FORMATSTR_ID_STARDRAW_60 + ); + pSoApp->pConvTable[5][4] = ConvertTo_Impl + (// StarDraw + SvGlobalName( SO3_SDRAW_CLASSID ), + SOT_FORMATSTR_ID_STARDRAW_60 + ); + + pSoApp->pConvTable[6][0] = ConvertTo_Impl + (// StarWiter 3.0 + SvGlobalName( 0xDC5C7E40L, 0xB35C, 0x101B, 0x99, 0x61, 0x04, 0x02, 0x1C, 0x00, 0x70,0x02 ), + *SvInPlaceObject::ClassFactory(), + SOT_FORMATSTR_ID_STARWRITER_30 + ); + pSoApp->pConvTable[6][1] = ConvertTo_Impl + (// StarWiter 4.0 + SvGlobalName( SO3_SWWEB_CLASSID_40 ), + SOT_FORMATSTR_ID_STARWRITERWEB_40 + ); + pSoApp->pConvTable[6][2] = ConvertTo_Impl + (// StarWiter 5.0 + SvGlobalName( SO3_SWWEB_CLASSID_50 ), + SOT_FORMATSTR_ID_STARWRITERWEB_50 + ); + pSoApp->pConvTable[6][3] = ConvertTo_Impl + (// StarWiter + SvGlobalName( SO3_SWWEB_CLASSID_60 ), + SOT_FORMATSTR_ID_STARWRITERWEB_60 + ); + pSoApp->pConvTable[6][4] = ConvertTo_Impl + (// StarWiter + SvGlobalName( SO3_SWWEB_CLASSID ), + SOT_FORMATSTR_ID_STARWRITERWEB_60 + ); + + pSoApp->pConvTable[7][0] = ConvertTo_Impl + (// StarWiter 3.0 + SvGlobalName( 0xDC5C7E40L, 0xB35C, 0x101B, 0x99, 0x61, 0x04, 0x02, 0x1C, 0x00, 0x70,0x02 ), + *SvInPlaceObject::ClassFactory(), + SOT_FORMATSTR_ID_STARWRITER_30 + ); + pSoApp->pConvTable[7][1] = ConvertTo_Impl + (// StarWiter 4.0 + SvGlobalName( SO3_SWGLOB_CLASSID_40 ), + SOT_FORMATSTR_ID_STARWRITERGLOB_40 + ); + pSoApp->pConvTable[7][2] = ConvertTo_Impl + (// StarWiter 5.0 + SvGlobalName( SO3_SWGLOB_CLASSID_50 ), + SOT_FORMATSTR_ID_STARWRITERGLOB_50 + ); + pSoApp->pConvTable[7][3] = ConvertTo_Impl + (// StarWiter + SvGlobalName( SO3_SWGLOB_CLASSID_60 ), + SOT_FORMATSTR_ID_STARWRITERGLOB_60 + ); + pSoApp->pConvTable[7][4] = ConvertTo_Impl + (// StarWiter + SvGlobalName( SO3_SWGLOB_CLASSID ), + SOT_FORMATSTR_ID_STARWRITERGLOB_60 + ); + + } + *pCount = pSoApp->nConvTableEntries; + return pSoApp->pConvTable; +} + +//========================================================================= +SvGlobalName SvFactory::GetAutoConvertTo +( + const SvGlobalName & rClass +) +/* [Beschreibung] + + Ist f"ur diese KlassenId eine Konvertierung installiert, dann wird + die Klasse, in die Konvertiert werden soll, zur"uckgegeben. + Ansonsten wird rClass zur"ueckgegeben. + + [R"uckgabewert] + + SvGlobalName Die KlassenId, die statt der "ubergebenen benutzt + werden soll. + + [Querverweise] + + <SvFactory::SetAutoConvertTo>, +*/ +{ + SvGlobalName aRet = rClass; + + USHORT nCount; + ConvertTo_Impl (* pTable)[SO3_OFFICE_VERSIONS] = SetupConvertTable_Impl( &nCount ); + for( USHORT i = 0; i < nCount; i++ ) + { + for( USHORT n = 0; n < SO3_OFFICE_VERSIONS; n++ ) + { + if( pTable[i][n].aName == aRet ) + { + // #110743# + // return pTable[i][SO3_OFFICE_VERSIONS -1].aName; + if (n < SO3_OFFICE_VERSIONS-2) + { + return pTable[i][SO3_OFFICE_VERSIONS -3].aName; + } + else + { + return pTable[i][SO3_OFFICE_VERSIONS -1].aName; + } + } + } + } + + return aRet; +} + +//========================================================================= +BOOL SvFactory::IsIntern +( + const SvGlobalName & rClass, + long *pFileFormat +) +/* [Description] + + Is it an internal object + + [Return Value] + + BOOL TRUE, if it is an internal object + + [Cross reference] + +*/ +{ + SvGlobalName aRet = rClass; + + USHORT nCount; + ConvertTo_Impl (*pTable)[SO3_OFFICE_VERSIONS] = SetupConvertTable_Impl( &nCount ); + for( USHORT i = 0; i < nCount; i++ ) + { + for( USHORT n = 0; n < SO3_OFFICE_VERSIONS; n++ ) + { + if( pTable[i][n].aName == aRet ) + { + if( pFileFormat ) + { + switch( n ) + { + case 0: *pFileFormat = SOFFICE_FILEFORMAT_31; break; + case 1: *pFileFormat = SOFFICE_FILEFORMAT_40; break; + case 2: *pFileFormat = SOFFICE_FILEFORMAT_50; break; + case 3: *pFileFormat = SOFFICE_FILEFORMAT_60; break; + default: + OSL_FAIL( "unexepected class id" ); + break; + } + } + return TRUE; + } + } + } + return FALSE; +} + +SvGlobalName SvFactory::GetServerName( long nStorageFormat ) +{ + SvGlobalName aRet; + + USHORT nCount; + ConvertTo_Impl (*pTable)[SO3_OFFICE_VERSIONS] = SetupConvertTable_Impl( &nCount ); + for( USHORT i = 0; i < nCount; i++ ) + { + for( USHORT n = 0; n < SO3_OFFICE_VERSIONS; n++ ) + { + if( pTable[i][n].aFormat == nStorageFormat ) + return pTable[i][n].aName; + } + } + return aRet; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/misc/iface.cxx b/bf_so3/source/misc/iface.cxx new file mode 100644 index 000000000..53420eebf --- /dev/null +++ b/bf_so3/source/misc/iface.cxx @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <string.h> +#include <stdio.h> + + +#include <bf_so3/iface.hxx> +#include <bf_svtools/ownlist.hxx> + +#include "bf_so3/soerr.hxx" + +#include <tools/debug.hxx> + +namespace binfilter { + +/************** class SvObject ******************************************/ +SV_IMPL_FACTORY(SvObjectFactory) + { + } +}; +TYPEINIT1(SvObjectFactory,SvFactory); + + +SO2_IMPL_CLASS1_DLL(SvObject,SvObjectFactory,SotObject, + SvGlobalName( 0x7F7E0E60L, 0xC32D, 0x101B, + 0x80, 0x4C, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02 ) ) + +/************************************************************************* +|* SvObject::GetMemberInterface() +|* +|* Beschreibung: +*************************************************************************/ +::IUnknown * SvObject::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +/************************************************************************* +|* SvObject::SvObject() +|* +|* Beschreibung +*************************************************************************/ +SvObject::SvObject() + : pObj ( NULL ) // union mit pClient, pService + , nExtCount ( 0 ) +{ +} + +/************************************************************************* +|* +|* SvObject::~SvObject() +|* +*************************************************************************/ +SvObject::~SvObject() +{ +} + +/************************************************************************* +|* +|* SvObject::ReleaseRef() +|* +*************************************************************************/ +UINT32 SvObject::ReleaseRef() +{ + return SotObject::ReleaseRef(); +} + +//======================================================================== +void SvObject::MakeUnknown() +/* [Beschreibung] + + Klassen, die immer extern sind, aber nicht sofort <SvObject::Init> + rufen, m"ussen diese Methode "uberladen. + Darin muss das externe Objekt erzeugt und mit Init eingesetzt werden. + Im Konstruktor muss das Objekt als extern gekennzeichnet werden. + + [Beispiel] + + void MyClass::MyClass() + { + SetExtern(); + } + + void MyClass::MakeUnknown() + { + CreateBindCtx( 0, &pObjI ); + Init( pObjI ); + } +*/ +{ +} + + + +#if defined (_INC_WINDOWS) || defined (_WINDOWS_) +RECT GetSysRect( const Rectangle & rRect ) +{ + RECT aRect; + aRect.top = (int)rRect.Top(); + aRect.left = (int)rRect.Left(); + if( rRect.Right() == RECT_EMPTY ) + aRect.right = aRect.left; + else + aRect.right = (int)(rRect.Right() +1); + if( rRect.Bottom() == RECT_EMPTY ) + aRect.bottom = aRect.top; + else + aRect.bottom = (int)(rRect.Bottom() +1); + return aRect; +} +Rectangle GetSvRect( const RECT & rRect ) +{ + Rectangle aRect; + aRect.Top() = rRect.top; + aRect.Left() = rRect.left; + if( rRect.right != rRect.left ) + aRect.Right() = rRect.right -1; + if( rRect.bottom != rRect.top ) + aRect.Bottom() = rRect.bottom -1; + return aRect; +} +#endif + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/misc/makefile.mk b/bf_so3/source/misc/makefile.mk new file mode 100644 index 000000000..4876a4a06 --- /dev/null +++ b/bf_so3/source/misc/makefile.mk @@ -0,0 +1,55 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. +SUBPRJ=..$/.. + +PRJINC=$(SUBPRJ) + +PRJNAME=binfilter +TARGET=so3_misc + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk +.INCLUDE : $(SUBPRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +CXXFILES= factory.cxx \ + iface.cxx \ + +.IF "$(GUI)"!="UNX" +CXXFILES+= so2dll.cxx +.ENDIF + + +SLOFILES= \ + $(SLO)$/factory.obj \ + $(SLO)$/iface.obj + +.IF "$(GUI)"!="UNX" +SLOFILES+= $(SLO)$/so2dll.obj +.ENDIF + +EXCEPTIONSFILES= \ + $(SLO)$/factory.obj + + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/bf_so3/source/misc/so2dll.cxx b/bf_so3/source/misc/so2dll.cxx new file mode 100644 index 000000000..330c990bb --- /dev/null +++ b/bf_so3/source/misc/so2dll.cxx @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifdef WIN + +#include <svwin.h> + +#include <sysdep.hxx> + +#endif + +#ifdef WIN +// Statische DLL-Verwaltungs-Variablen +static HINSTANCE hDLLInst = 0; // HANDLE der DLL + +/*************************************************************************** +|* LibMain() +|* +|* Beschreibung Initialisierungsfunktion der DLL +***************************************************************************/ +extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR ) +{ +#ifndef WNT + if ( nHeap ) + UnlockData( 0 ); +#endif + + hDLLInst = hDLL; + + return TRUE; +} + +/*************************************************************************** +|* WEP() +|* +|* Beschreibung DLL-Deinitialisierung +***************************************************************************/ +extern "C" int CALLBACK WEP( int ) +{ + return 1; +} + +#endif + +#ifdef WNT +void ResourceDummy (void ) +{ + +} +#endif + +#ifdef OS2 + +#include <svpm.h> + +// Statische DLL-Verwaltungs-Variablen +static ULONG hDLLInst = 0; // HANDLE der DLL + + +/*************************************************************************** +|* LibMain() +|* +|* Beschreibung Initialisierungsfunktion der DLL +***************************************************************************/ +extern "C" int LibDummy() +{ + return TRUE; +} + +/*************************************************************************** +|* WEP() +|* +|* Beschreibung DLL-Deinitialisierung +***************************************************************************/ +extern "C" int WEPDummy( int ) +{ + return 1; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/ole/ansi.cxx b/bf_so3/source/ole/ansi.cxx new file mode 100644 index 000000000..f4b93c6bf --- /dev/null +++ b/bf_so3/source/ole/ansi.cxx @@ -0,0 +1,405 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#define NOMACROREDIRECT +#include "soole.h" + +namespace binfilter { + +#ifdef WIN32ANSI + + +/* + * ConvertStringAlloc + * + * Purpose: + * Allocates memory using the task allocator. Used internally + * in this file. + */ + +HRESULT ConvertStringAlloc(ULONG ulSize, void **ppv) + { + HRESULT hr; + IMalloc *pIMalloc; + + if (NULL==ppv) + return ResultFromScode(E_INVALIDARG); + + hr=CoGetMalloc(MEMCTX_TASK, &pIMalloc); + + if (FAILED(hr)) + return hr; + + *ppv=pIMalloc->Alloc(ulSize); + pIMalloc->Release(); + + return (NULL==*ppv) ? ResultFromScode(E_OUTOFMEMORY) : NOERROR; + } + + + +/* + * StarObject_ConvertStringToANSI + * + * Purpose: + * Converts the string in pszW to ANSI, allocating the + * output buffer pointed to by *ppszA on output. The + * string is allocated with COM's task allocator. + * + */ + +STDAPI StarObject_ConvertStringToANSI(LPCWSTR pszW, LPSTR *ppszA) + { + ULONG cch; + HRESULT hr; + + //If input is NULL then just return the same + if (NULL==pszW) + { + *ppszA=NULL; + return NOERROR; + } + + cch=wcslen(pszW)+1; + + hr=ConvertStringAlloc(cch, (void **)ppszA); + + if (FAILED(hr)) + return hr; + + WideCharToMultiByte(CP_ACP, 0, pszW, -1, *ppszA, cch, NULL, NULL); + return NOERROR; + } + + + + +/* + * StarObject_StringFromCLSID + */ + +STDAPI StarObject_StringFromCLSID(REFCLSID clsID, LPSTR *ppszCLSID) + { + LPWSTR psz; + HRESULT hr; + + if (NULL==ppszCLSID) + return ResultFromScode(E_INVALIDARG); + + hr=StringFromCLSID(clsID, &psz); + + if (FAILED(hr)) + return hr; + + hr=StarObject_ConvertStringToANSI(psz, ppszCLSID); + CoTaskMemFree((void *)psz); + return hr; + } + + + +/* + * StarObject_StringFromGUID2 + */ + +STDAPI StarObject_StringFromGUID2(REFGUID guid, LPSTR pszGUID, int cch) + { + LPSTR psz; + HRESULT hr; + + if (NULL==pszGUID) + return ResultFromScode(E_INVALIDARG); + + hr=StarObject_StringFromCLSID(guid, &psz); + + if (FAILED(hr)) + return hr; + + lstrcpyn(pszGUID, psz, cch); + CoTaskMemFree((void *)psz); + return hr; + } + + + + + +/* + * StarObject_ProgIDFromCLSID + */ + +STDAPI StarObject_ProgIDFromCLSID(REFCLSID clsID, LPSTR *ppszProgID) + { + LPWSTR psz; + HRESULT hr; + + if (NULL==ppszProgID) + return ResultFromScode(E_INVALIDARG); + + hr=ProgIDFromCLSID(clsID, &psz); + + if (FAILED(hr)) + return hr; + + hr=StarObject_ConvertStringToANSI(psz, ppszProgID); + CoTaskMemFree(psz); + return hr; + } + + + + +/* + * StarObject_ReadFmtUserTypeStg + * StarObject_WriteFmtUserTypeStg + */ + +STDAPI StarObject_ReadFmtUserTypeStg(IStorage *pIStorage + , CLIPFORMAT *pcf, LPSTR *ppszUserType) + { + HRESULT hr; + LPOLESTR pszUserType; + + if (NULL==ppszUserType) + return ResultFromScode(E_INVALIDARG); + + hr=ReadFmtUserTypeStg(pIStorage, pcf, &pszUserType); + + if (FAILED(hr)) + return hr; + + if (ppszUserType) + { + hr=StarObject_ConvertStringToANSI(pszUserType, ppszUserType); + CoTaskMemFree(pszUserType); + } + + return hr; + } + + +STDAPI StarObject_WriteFmtUserTypeStg(IStorage *pIStorage, CLIPFORMAT cf + , LPSTR pszUserType) + { + OLECHAR szType[512]; + HRESULT hr; + + if (NULL==pszUserType) + return ResultFromScode(E_INVALIDARG); + + MultiByteToWideChar(CP_ACP, 0, pszUserType, -1, szType, 512); + hr=WriteFmtUserTypeStg(pIStorage, cf, szType); + + return hr; + } + + + +/* + * StarObject_StgIsStorageFile + * StarObject_StgCreateDocfile + * StarObject_StgOpenStorage + */ + +STDAPI StarObject_StgIsStorageFile(LPCSTR pszName) + { + OLECHAR szTemp[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, pszName, -1 + , szTemp, MAX_PATH); + return StgIsStorageFile(szTemp); + } + + + +STDAPI StarObject_StgCreateDocfile(LPCSTR pszNameA, DWORD grfMode + , DWORD reserved, IStorage **ppIStorage) + { + OLECHAR szTemp[MAX_PATH]; + LPOLESTR pszName; + + *ppIStorage=NULL; + + if (NULL!=pszNameA) + { + MultiByteToWideChar(CP_ACP, 0, pszNameA, -1 + , szTemp, MAX_PATH); + pszName=szTemp; + } + else + pszName=NULL; + + return StgCreateDocfile(pszName, grfMode, reserved + , ppIStorage); + } + + + +STDAPI StarObject_StgOpenStorage(LPCSTR pszNameA, IStorage *pStgPri + , DWORD grfMode, SNB snbEx, DWORD reserved + , IStorage * *ppIStorage) + { + OLECHAR szTemp[MAX_PATH]; + LPOLESTR pszName; + + *ppIStorage=NULL; + + if (NULL!=pszNameA) + { + MultiByteToWideChar(CP_ACP, 0, pszNameA, -1 + , szTemp, MAX_PATH); + pszName= szTemp; + } + else + pszName=NULL; + + return StgOpenStorage(pszName, pStgPri, grfMode, snbEx + , reserved, ppIStorage); + } + + + + +/* + * StarObject_CreateFileMoniker + * StarObject_CreateItemMoniker + * StarObject_MkParseDisplayName + */ + +STDAPI StarObject_CreateFileMoniker(LPCSTR pszPathNameA, LPMONIKER *ppmk) + { + OLECHAR szTemp[MAX_PATH]; + + if (NULL==ppmk) + return ResultFromScode(E_INVALIDARG); + + *ppmk=NULL; + + MultiByteToWideChar(CP_ACP, 0, pszPathNameA, -1 + , szTemp, MAX_PATH); + + return CreateFileMoniker(szTemp, ppmk); + } + + +STDAPI StarObject_CreateItemMoniker(LPCSTR pszDelimA, LPCSTR pszItemA + , LPMONIKER *ppmk) + { + OLECHAR szItem[MAX_PATH]; //Some assumptions about string length + OLECHAR szDelim[20]; + + if (NULL==ppmk) + return ResultFromScode(E_INVALIDARG); + + *ppmk=NULL; + + MultiByteToWideChar(CP_ACP, 0, pszItemA, -1 + , szItem, MAX_PATH); + MultiByteToWideChar(CP_ACP, 0, pszDelimA, -1 + , szDelim, 20); + + return CreateItemMoniker(szDelim, szItem, ppmk); + } + + +STDAPI StarObject_MkParseDisplayName(LPBC pbc, LPCSTR pszUserNameA + , ULONG *pchEaten, LPMONIKER *ppmk) + { + OLECHAR szTemp[512]; //Assumption on string length + + if (NULL==ppmk) + return ResultFromScode(E_INVALIDARG); + + *ppmk=NULL; + + MultiByteToWideChar(CP_ACP, 0, pszUserNameA, -1 + , szTemp, 512); + + return MkParseDisplayName(pbc, szTemp, pchEaten, ppmk); + } + + + +/* + * StarObject_OleCreateLinkToFile + * StarObject_OleCreateFromFile + */ + +STDAPI StarObject_OleCreateLinkToFile(LPCSTR lpszFileName, REFIID riid + , DWORD renderopt, LPFORMATETC lpFormatEtc + , LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID *ppvObj) + { + OLECHAR szFile[512]; //Assumption on string length + + MultiByteToWideChar(CP_ACP, 0, lpszFileName, -1, szFile, 512); + return OleCreateLinkToFile(szFile, riid, renderopt, lpFormatEtc + , pClientSite, pStg, ppvObj); + } + + + +STDAPI StarObject_OleCreateFromFile(REFCLSID rclsid, LPCSTR lpszFileName + , REFIID riid, DWORD renderopt, LPFORMATETC lpFormatEtc + , LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID *ppvObj) + { + OLECHAR szFile[512]; //Assumption on string length + + MultiByteToWideChar(CP_ACP, 0, lpszFileName, -1, szFile, 512); + return OleCreateFromFile(rclsid, szFile, riid, renderopt, lpFormatEtc + , pClientSite, pStg, ppvObj); + } + +#else + +//Do-nothing functions so we can at least export them. + +#ifndef WIN32 +STDAPI StarObject_ConvertStringToANSI(LPCSTR a, LPSTR *b) {return NOERROR;} +#else +STDAPI StarObject_ConvertStringToANSI(LPCWSTR a, LPSTR *b) {return NOERROR;} +#endif +STDAPI StarObject_StringFromCLSID(REFCLSID a, LPSTR *b) {return NOERROR;} +STDAPI StarObject_StringFromGUID2(REFGUID a, LPSTR b, int c) {return NOERROR;} +STDAPI StarObject_ProgIDFromCLSID(REFCLSID a, LPSTR *b) {return NOERROR;} + +STDAPI StarObject_ReadFmtUserTypeStg(IStorage *a, CLIPFORMAT *b, LPSTR *c) {return NOERROR;} +STDAPI StarObject_WriteFmtUserTypeStg(IStorage *a, CLIPFORMAT b, LPSTR c) {return NOERROR;} + +STDAPI StarObject_StgIsStorageFile(LPCSTR a) {return NOERROR;} +STDAPI StarObject_StgCreateDocfile(LPCSTR a, DWORD b, DWORD c, IStorage ** d) {return NOERROR;} +STDAPI StarObject_StgOpenStorage(LPCSTR a, IStorage *b, DWORD c, SNB d + , DWORD e, IStorage **f) {return NOERROR;} + +STDAPI StarObject_CreateFileMoniker(LPCSTR, LPMONIKER *) {return NOERROR;} +STDAPI StarObject_CreateItemMoniker(LPCSTR, LPCSTR, LPMONIKER *) {return NOERROR;} +STDAPI StarObject_MkParseDisplayName(LPBC, LPCSTR, ULONG *, LPMONIKER *) {return NOERROR;} + +STDAPI StarObject_OleCreateLinkToFile(LPCOLESTR, REFIID, DWORD, LPFORMATETC + , LPOLECLIENTSITE, LPSTORAGE, LPVOID *) {return NOERROR;} + +STDAPI StarObject_OleCreateFromFile(REFCLSID, LPCOLESTR, REFIID + , DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, LPVOID *) {return NOERROR;} + + +#endif + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/ole/helpers.cxx b/bf_so3/source/ole/helpers.cxx new file mode 100644 index 000000000..b6cc21a17 --- /dev/null +++ b/bf_so3/source/ole/helpers.cxx @@ -0,0 +1,917 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "soole.h" + +#include <systools/win32/snprintf.h> + +#include <sal/macros.h> + +namespace binfilter { +static BOOL GetFileTimes(LPTSTR pszFileName, FILETIME *pft); + +/* + * StarObject_MetafilePictIconFree + * + * Purpose: + * Deletes the metafile contained in a METAFILEPICT structure and + * frees the memory for the structure itself. + * + * Parameters: + * hMetaPict HGLOBAL metafilepict structure created in + * OleMetafilePictFromIconAndLabel + * + * Return Value: + * None + */ + +STDAPI_(void) StarObject_MetafilePictIconFree(HGLOBAL hMetaPict) + { + LPMETAFILEPICT pMF; + + if (NULL==hMetaPict) + return; + + pMF=(LPMETAFILEPICT)GlobalLock(hMetaPict); + + if (NULL!=pMF) + { + if (NULL!=pMF->hMF) + DeleteMetaFile(pMF->hMF); + } + + GlobalUnlock(hMetaPict); + GlobalFree(hMetaPict); + return; + } + + + + + +/* + * StarObject_SwitchDisplayAspect + * + * Purpose: + * Switch the currently cached display aspect between DVASPECT_ICON + * and DVASPECT_CONTENT. When setting up icon aspect, any currently + * cached content cache is discarded and any advise connections for + * content aspect are broken. + * + * Parameters: + * pObj IUnknown * to the object in question + * pdwCurAspect DWORD * containing the current aspect which + * will contain the new aspect on output. + * dwNewAspect DWORD with the aspect to switch to. + * hMetaPict HGLOBAL containing the CF_METAFILEPICT with + * the icon. + * fDeleteOld BOOL indicating if we're to delete the old + * aspect from the cache. + * fViewAdvise BOOL indicating if we're to establish an + * advise with the object for this new aspect. + * pSink IAdviseSink * to the notification sink. + * pfMustUpdate BOOL * in which to return whether or not + * an update from a running server is necessary. + * + * Return Value: + * HRESULT NOERROR or an error code in which case the cache + * remains unchanged. + */ + +STDAPI StarObject_SwitchDisplayAspect(IUnknown *pObj, LPDWORD pdwCurAspect + , DWORD dwNewAspect, HGLOBAL hMetaPict, BOOL fDeleteOld + , BOOL fViewAdvise, IAdviseSink *pSink, BOOL *pfMustUpdate) + { + IOleCache *pCache=NULL; + FORMATETC fe; + STGMEDIUM stm; + DWORD dwAdvf; + DWORD dwNewConnection; + DWORD dwOldAspect=*pdwCurAspect; + HRESULT hr; + + if (pfMustUpdate) + *pfMustUpdate=FALSE; + + hr=pObj->QueryInterface(IID_IOleCache, (void **)&pCache); + + if (FAILED(hr)) + return ResultFromScode(E_FAIL); + + //Establish new cache with the new aspect + SETFormatEtc(fe, 0, dwNewAspect, NULL, TYMED_NULL, -1); + + /* + * If we are using a custom icon for the display aspect then + * we won't want to establish notifications with the data + * source, that is, we don't want to change the icon. Otherwise + * we link up the given advise sink. + */ + if (DVASPECT_ICON==dwNewAspect && NULL!=hMetaPict) + dwAdvf=ADVF_NODATA; + else + dwAdvf=ADVF_PRIMEFIRST; + + hr=pCache->Cache(&fe, dwAdvf, &dwNewConnection); + + if (FAILED(hr)) + { + pCache->Release(); + return hr; + } + + *pdwCurAspect=dwNewAspect; + + /* + * Stuff the custom icon into the cache, or force an update + * from the server. + */ + if (DVASPECT_ICON==dwNewAspect && NULL!=hMetaPict) + { + SETFormatEtc(fe, CF_METAFILEPICT, DVASPECT_ICON, NULL + , TYMED_MFPICT, -1); + + stm.tymed=TYMED_MFPICT; + stm.hGlobal=hMetaPict; + stm.pUnkForRelease=NULL; + + hr=pCache->SetData(&fe, &stm, FALSE); + } + else + { + if (pfMustUpdate) + *pfMustUpdate=TRUE; + } + + if (fViewAdvise && pSink) + { + IViewObject *pView=NULL; + + hr=pObj->QueryInterface(IID_IViewObject, (void **)&pView); + + if (SUCCEEDED(hr)) + { + pView->SetAdvise(dwNewAspect, 0, pSink); + pView->Release(); + } + } + + /* + * Remove existing caches for the old display aspect to cut + * down on needless storage overhead. If you want to switch + * frequently between icon and content aspects, then it is + * best to actually keep both presentations in the cache. + */ + if (fDeleteOld) + { + IEnumSTATDATA *pEnum=NULL; + STATDATA sd; + + hr=pCache->EnumCache(&pEnum); + + while(NOERROR==hr) + { + hr=pEnum->Next(1, &sd, NULL); + + if (NOERROR==hr) + { + //Remove old aspect caches + if (sd.formatetc.dwAspect==dwOldAspect) + pCache->Uncache(sd.dwConnection); + } + } + + if (NULL!=pEnum) + pEnum->Release(); + } + + pCache->Release(); + return NOERROR; + } + + + +/* + * StarObject_SetIconInCache + * + * Purpose: + * Stores an iconic presentation metafile in the cache. + * + * Parameters: + * pObj IUnknown * of the object. + * hMetaPict HGLOBAL containing the presentation. + * + * Return Value: + * HRESULT From IOleCache::SetData. + */ + +STDAPI StarObject_SetIconInCache(IUnknown *pObj, HGLOBAL hMetaPict) + { + IOleCache *pCache; + FORMATETC fe; + STGMEDIUM stm; + HRESULT hr; + + if (NULL==hMetaPict) + return ResultFromScode(E_INVALIDARG); + + if (FAILED(pObj->QueryInterface(IID_IOleCache, (void **)&pCache))) + return ResultFromScode(E_NOINTERFACE); + + SETFormatEtc(fe, CF_METAFILEPICT, DVASPECT_ICON, NULL + , TYMED_MFPICT, -1); + + stm.tymed=TYMED_MFPICT; + stm.hGlobal=hMetaPict; + stm.pUnkForRelease=NULL; + + hr=pCache->SetData(&fe, &stm, FALSE); + pCache->Release(); + + return hr; + } + + + + + +/* + * StarObject_GetUserTypeOfClass + * + * Purpose: + * Returns the user type (human readable class name) of the + * specified class as stored in the registry. + * + * Parameters: + * clsID CLSID in question + * iName UINT index to the name to retrieve, where + * zero is the name found as the value of + * of the CLSID, anything else tries + * AuxUserType\iName. + * pszUserType LPTSTR in which to return the type + * cch UINT length of pszUserType + * + * Return Value: + * UINT Number of characters in returned string. + * 0 on error. + */ + +STDAPI_(UINT) StarObject_GetUserTypeOfClass(REFCLSID clsID, UINT iName + , LPTSTR pszUserType, UINT cch) + { + LPTSTR pszCLSID; + LPTSTR pszProgID; + TCHAR szKey[300]; + LONG dw; + LONG lRet; + + if (!pszUserType) + return 0; + + *pszUserType='\0'; + + //Get a string containing the class name + StarObject_StringFromCLSID(clsID, &pszCLSID); + + if (0==iName) + sntprintf(szKey, SAL_N_ELEMENTS(szKey), TEXT("CLSID\\%s"), pszCLSID); + else + { + sntprintf(szKey, SAL_N_ELEMENTS(szKey), TEXT("CLSID\\%s\\AuxUserType\\%u") + , pszCLSID, iName); + } + + CoTaskMemFree(pszCLSID); + + dw=cch; + lRet=RegQueryValue(HKEY_CLASSES_ROOT, szKey, pszUserType, &dw); + + if (ERROR_SUCCESS!=lRet) + { + lstrcpyn(pszUserType, TEXT("Unknown"), cch); + + if (CoIsOle1Class(clsID)) + { + //Try to get ProgID value for OLE 1 class + StarObject_ProgIDFromCLSID(clsID, &pszProgID); + + dw=cch; + lRet=RegQueryValue(HKEY_CLASSES_ROOT, pszProgID + , pszUserType, &dw); + + CoTaskMemFree(pszProgID); + + if (ERROR_SUCCESS!=lRet) + dw=0; + } + } + + return (UINT)dw; + } + + + + + +/* + * StarObject_DoConvert + * + * Purpose: + * Convert an embedded or linked object to another type, working + * in conjunection with OleUIConvert. + * + * Parameters: + * pIStorage IStorage * to the object's data. + * clsID CLSID to which we convert the object. + * + * Return Value: + * HRESULT The usual. + */ + +STDAPI StarObject_DoConvert(IStorage *pIStorage, REFCLSID clsID) + { + HRESULT hr; + CLSID clsIDOrg; + CLIPFORMAT cfOrg; + LPTSTR pszOrg=NULL; + TCHAR szNew[256]; + + if (FAILED(ReadClassStg(pIStorage, &clsIDOrg))) + return ResultFromScode(E_FAIL); + + //Read original format/user type + hr=StarObject_ReadFmtUserTypeStg(pIStorage, &cfOrg, &pszOrg); + + //Get new user type + if (0==StarObject_GetUserTypeOfClass(clsID, 0, szNew, 256)) + lstrcpyn(szNew, TEXT(""), SAL_N_ELEMENTS(szNew)); + + //Write new class into the storage + if (SUCCEEDED(WriteClassStg(pIStorage, clsID))) + { + if (SUCCEEDED(StarObject_WriteFmtUserTypeStg(pIStorage, cfOrg + , szNew))) + { + SetConvertStg(pIStorage, TRUE); + CoTaskMemFree((void *)pszOrg); + return NOERROR; + } + + //Failed to write new type, restore the old class + WriteClassStg(pIStorage, clsIDOrg); + } + + CoTaskMemFree((void *)pszOrg); + return ResultFromScode(E_FAIL); + } + + + + +/* + * StarObject_CopyString + * + * Purpose: + * Copies a string allocated with CoTaskMemAlloc. + * + * Parameters: + * pszSrc LPTSTR to the string to copy. + * + * Return Value: + * LPTSTR New string or a NULL. + */ + +STDAPI_(LPTSTR) StarObject_CopyString(LPTSTR pszSrc) + { + IMalloc *pIMalloc; + LPTSTR pszDst; + UINT cch; + + cch=lstrlen(pszSrc); + + if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc))) + return NULL; + + pszDst=(LPTSTR)pIMalloc->Alloc((cch+1)*sizeof(TCHAR)); + + if (NULL!=pszDst) + lstrcpyn(pszDst, pszSrc, cch+1); + + pIMalloc->Release(); + return pszDst; + } + + + + +/* + * StarObject_ObjectDescriptorFromOleObject + * + * Purpose: + * Fills and returns an OBJECTDESCRIPTOR structure. Information + * for the structure is obtained from an IOleObject instance. + * + * Parameters: + * pObj IOleObject * from which to retrieve information. + * dwAspect DWORD with the display aspect + * ptl POINTL from upper-left corner of object where + * mouse went down for use with Drag & Drop. + * pszl LPSIZEL (optional) if the object is being scaled in + * its container, then the container should pass the + * extents that it is using to display the object. + * + * Return Value: + * HBGLOBAL Handle to OBJECTDESCRIPTOR structure. + */ + +STDAPI_(HGLOBAL) StarObject_ObjectDescriptorFromOleObject + (IOleObject *pObj, DWORD dwAspect, POINTL ptl, LPSIZEL pszl) + { + CLSID clsID; + LPTSTR pszName=NULL; + LPTSTR pszSrc=NULL; + BOOL fLink=FALSE; + IOleLink *pLink; + TCHAR szName[512]; + DWORD dwMisc=0; + HGLOBAL hMem; + HRESULT hr; + #ifdef WIN32ANSI + //#ifndef UNICODE + LPWSTR pszw; + char szTemp[512]; + #endif + + if (SUCCEEDED(pObj->QueryInterface(IID_IOleLink + , (void **)&pLink))) + fLink=TRUE; + + if (FAILED(pObj->GetUserClassID(&clsID))) + clsID=CLSID_NULL; + + //Get user string, expand to "Linked %s" if this is link + #ifndef WIN32ANSI + //#ifdef UNICODE + pObj->GetUserType(USERCLASSTYPE_FULL, &pszName); + #else + pObj->GetUserType(USERCLASSTYPE_FULL, &pszw); + WideCharToMultiByte(CP_ACP, 0, pszw, -1, szTemp + , sizeof(szTemp), NULL, NULL); + pszName=szTemp; + #endif + + if (fLink && NULL!=pszName) + sntprintf(szName, SAL_N_ELEMENTS(szName), TEXT("Linked %s"), pszName); + else + lstrcpyn(szName, pszName, SAL_N_ELEMENTS(szName)); + + #ifndef WIN32ANSI + //#ifdef UNICODE + CoTaskMemFree(pszName); + #else + CoTaskMemFree(pszw); + #endif + + /* + * Get the source name of this object using either the + * link display name (for link) or a moniker display + * name. + */ + + if (fLink) + { + #ifndef WIN32ANSI + //#ifdef UNICODE + hr=pLink->GetSourceDisplayName(&pszSrc); + #else + hr=pLink->GetSourceDisplayName(&pszw); + WideCharToMultiByte(CP_ACP, 0, pszw, -1, szTemp + , sizeof(szTemp), NULL, NULL); + pszSrc=szTemp; + #endif + } + else + { + IMoniker *pmk; + + hr=pObj->GetMoniker(OLEGETMONIKER_TEMPFORUSER + , OLEWHICHMK_OBJFULL, &pmk); + + if (SUCCEEDED(hr)) + { + IBindCtx *pbc; + CreateBindCtx(0, &pbc); + + #ifndef WIN32ANSI + //#ifdef UNICODE + pmk->GetDisplayName(pbc, NULL, &pszSrc); + #else + pmk->GetDisplayName(pbc, NULL, &pszw); + WideCharToMultiByte(CP_ACP, 0, pszw, -1, szTemp + , sizeof(szTemp), NULL, NULL); + pszSrc=szTemp; + #endif + + pbc->Release(); + + pmk->Release(); + } + } + + if (fLink) + pLink->Release(); + + //Get MiscStatus bits + hr=pObj->GetMiscStatus(dwAspect, &dwMisc); + + //Get OBJECTDESCRIPTOR + hMem=StarObject_AllocObjectDescriptor(clsID, dwAspect, *pszl, ptl + , dwMisc, szName, pszSrc); + + #ifndef WIN32ANSI + //#ifdef UNICODE + CoTaskMemFree(pszSrc); + #else + CoTaskMemFree(pszw); + #endif + + return hMem; + } + + + + + +/* + * StarObject_AllocObjectDescriptor + * + * Purpose: + * Allocated and fills an OBJECTDESCRIPTOR structure. + * + * Parameters: + * clsID CLSID to store. + * dwAspect DWORD with the display aspect + * pszl LPSIZEL (optional) if the object is being scaled in + * its container, then the container should pass the + * extents that it is using to display the object. + * ptl POINTL from upper-left corner of object where + * mouse went down for use with Drag & Drop. + * dwMisc DWORD containing MiscStatus flags + * pszName LPTSTR naming the object to copy + * pszSrc LPTSTR identifying the source of the object. + * + * Return Value: + * HBGLOBAL Handle to OBJECTDESCRIPTOR structure. + */ + +STDAPI_(HGLOBAL) StarObject_AllocObjectDescriptor(CLSID clsID + , DWORD dwAspect, SIZEL szl, POINTL ptl, DWORD dwMisc + , LPTSTR pszName, LPTSTR pszSrc) + { + HGLOBAL hMem=NULL; + LPOBJECTDESCRIPTOR pOD; + DWORD cb, cbStruct; + DWORD cchName, cchSrc; + + cchName=lstrlen(pszName)+1; + + if (NULL!=pszSrc) + cchSrc=lstrlen(pszSrc)+1; + else + { + cchSrc=cchName; + pszSrc=pszName; + } + + /* + * Note: CFSTR_OBJECTDESCRIPTOR is an ANSI structure. + * That means strings in it must be ANSI. OLE will do + * internal conversions back to Unicode as necessary, + * but we have to put ANSI strings in it ourselves. + */ + cbStruct=sizeof(OBJECTDESCRIPTOR); + cb=cbStruct+(sizeof(WCHAR)*(cchName+cchSrc)); //HACK + + hMem=GlobalAlloc(GHND, cb); + + if (NULL==hMem) + return NULL; + + pOD=(LPOBJECTDESCRIPTOR)GlobalLock(hMem); + + pOD->cbSize=cb; + pOD->clsid=clsID; + pOD->dwDrawAspect=dwAspect; + pOD->sizel=szl; + pOD->pointl=ptl; + pOD->dwStatus=dwMisc; + + if (pszName) + { + pOD->dwFullUserTypeName=cbStruct; + #ifdef WIN32ANSI + MultiByteToWideChar(CP_ACP, 0, pszName, -1 + , (LPWSTR)((LPBYTE)pOD+pOD->dwFullUserTypeName), cchName); + #else + lstrcpyn((LPTSTR)((LPBYTE)pOD+pOD->dwFullUserTypeName) + , pszName, cchName); + #endif + } + else + pOD->dwFullUserTypeName=0; //No string + + if (pszSrc) + { + pOD->dwSrcOfCopy=cbStruct+(cchName*sizeof(WCHAR)); + + #ifdef WIN32ANSI + MultiByteToWideChar(CP_ACP, 0, pszSrc, -1 + , (LPWSTR)((LPBYTE)pOD+pOD->dwSrcOfCopy), cchSrc); + #else + lstrcpyn((LPTSTR)((LPBYTE)pOD+pOD->dwSrcOfCopy), pszSrc, cchSrc); + #endif + } + else + pOD->dwSrcOfCopy=0; //No string + + GlobalUnlock(hMem); + return hMem; + } + + + + + +/* + * StarObject_CreateStorageOnHGlobal + * + * Purpose: + * Create a memory based storage object on an memory lockbytes. + * + * Parameters: + * grfMode -- flags passed to StgCreateDocfileOnILockBytes + * + * NOTE: if hGlobal is NULL, then a new IStorage is created and + * STGM_CREATE flag is passed to StgCreateDocfileOnILockBytes. + * if hGlobal is non-NULL, then it is assumed that the hGlobal already + * has an IStorage inside it and STGM_CONVERT flag is passed + * to StgCreateDocfileOnILockBytes. + * + * Return Value: + * IStorage * Pointer to the storage we create. + */ + +STDAPI_(IStorage *) StarObject_CreateStorageOnHGlobal(DWORD grfMode) + { + DWORD grfCreate=grfMode | STGM_CREATE; + HRESULT hr; + ILockBytes *pLB=NULL; + IStorage *pIStorage=NULL; + + hr=CreateILockBytesOnHGlobal(NULL, TRUE, &pLB); + + if (FAILED(hr)) + return NULL; + + hr=StgCreateDocfileOnILockBytes(pLB, grfCreate, 0, &pIStorage); + + pLB->Release(); + + return SUCCEEDED(hr) ? pIStorage : NULL; + } + + + + + + + + +/* + * StarObject_GetLinkSourceData + * + * Purpose: + * Creates a CFSTR_LINKSOURCE data format, that is, a serialized + * moniker in a stream. + * + * Parameters: + * pmk IMoniker * of the link. + * pClsID CLSID * to write into the stream. + * pFE FORMATETC * describing the data which + * should have TYMED_ISTREAM in it. + * pSTM STGMEDIUM in which to return the data. + * If this has TYMED_NULL, then this function + * allocates the stream, otherwise it writes + * into the stream in pSTM->pstm. + */ + +STDAPI StarObject_GetLinkSourceData(IMoniker *pmk, LPCLSID pClsID + , LPFORMATETC pFE, LPSTGMEDIUM pSTM) + { + LPSTREAM pIStream = NULL; + HRESULT hr; + + pSTM->pUnkForRelease=NULL; + + if (TYMED_NULL==pSTM->tymed) + { + if (pFE->tymed & TYMED_ISTREAM) + { + hr=CreateStreamOnHGlobal(NULL, TRUE, &pIStream); + + if (FAILED(hr)) + return ResultFromScode(E_OUTOFMEMORY); + + pSTM->pstm=pIStream; + pSTM->tymed=TYMED_ISTREAM; + } + else + return ResultFromScode(DATA_E_FORMATETC); + } + else + { + if (TYMED_ISTREAM==pSTM->tymed) + { + pSTM->tymed=TYMED_ISTREAM; + pSTM->pstm=pSTM->pstm; + } + else + return ResultFromScode(DATA_E_FORMATETC); + } + + hr=OleSaveToStream(pmk, pSTM->pstm); + + if (FAILED(hr)) + return hr; + + return WriteClassStm(pSTM->pstm, *pClsID); + } + + + + + +/* + * StarObject_RegisterAsRunning + * + * Purpose: + * Registers a moniker as running in the running object + * table, revoking any existing registration. + * + * Parameters: + * pUnk IUnknown * of the object. + * pmk IMoniker * naming the object. + * dwFlags DWORD flags to pass to IROT::Register + * pdwReg LPDWORD in which to store the registration key. + * + * Return Value: + * None + */ + +STDAPI_(void) StarObject_RegisterAsRunning(IUnknown *pUnk + , IMoniker *pmk, DWORD dwFlags, LPDWORD pdwReg) + { + IRunningObjectTable *pROT; + HRESULT hr; + DWORD dwReg=*pdwReg; + + if (NULL==pmk || NULL==pUnk || NULL==pdwReg) + return; + + dwReg=*pdwReg; + + if (FAILED(GetRunningObjectTable(0, &pROT))) + return; + + hr=pROT->Register(dwFlags, pUnk, pmk, pdwReg); + + if (MK_S_MONIKERALREADYREGISTERED==GetScode(hr)) + { + if (0!=dwReg) + pROT->Revoke(dwReg); + } + + pROT->Release(); + return; + } + + + +/* + * StarObject_RevokeAsRunning + * + * Purpose: + * Wrapper for IRunningObjectTable::Revoke + * + * Parameters: + * pdwReg LPDWORD containing the key on input, zeroed + * on output. + * + * Return Value: + * None + */ + +STDAPI_(void) StarObject_RevokeAsRunning(LPDWORD pdwReg) + { + IRunningObjectTable *pROT; + + if (0==*pdwReg) + return; + + if (FAILED(GetRunningObjectTable(0, &pROT))) + return; + + pROT->Revoke(*pdwReg); + pROT->Release(); + + *pdwReg=0; + return; + } + + + +/* + * StarObject_NoteChangeTime + * + * Purpose: + * Wrapper for IRunningObjectTable::NoteChangeTime + * + * Parameters: + * dwReg DWORD identifying the running object to note. + * pft FILETIME * containing the new time. If NULL, + * then we'll get it from CoFileTimeNow. + * pszFile LPTSTR to a filename. If pft is NULL, we'll + * retrieve times from this file. + * + * Return Value: + * None + */ + +STDAPI_(void) StarObject_NoteChangeTime(DWORD dwReg, FILETIME *pft + , LPTSTR pszFile) + { + IRunningObjectTable *pROT; + FILETIME ft; + + if (NULL==pft) + { + CoFileTimeNow(&ft); + pft=&ft; + } + + if (NULL!=pszFile) + GetFileTimes(pszFile, pft); + + if (FAILED(GetRunningObjectTable(0, &pROT))) + return; + + pROT->NoteChangeTime(dwReg, pft); + pROT->Release(); + return; + } + + + + +/* + * GetFileTimes + * (Internal) + * + * Purpose: + * Retrieve the FILETIME structure for a given file. + */ + +static BOOL GetFileTimes(LPTSTR pszFileName, FILETIME *pft) +{ + WIN32_FIND_DATA fd; + HANDLE hFind; + + hFind=FindFirstFile(pszFileName, &fd); + + if (NULL==hFind || INVALID_HANDLE_VALUE==hFind) + return FALSE; + + FindClose(hFind); + *pft=fd.ftLastWriteTime; + return TRUE; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/ole/makefile.mk b/bf_so3/source/ole/makefile.mk new file mode 100644 index 000000000..21d7f2994 --- /dev/null +++ b/bf_so3/source/ole/makefile.mk @@ -0,0 +1,55 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. +SUBPRJ=..$/.. + +PRJINC=$(SUBPRJ) + +PRJNAME=binfilter +TARGET=so3_ole + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk +.INCLUDE : $(SUBPRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +CXXFILES= \ + sosink.cxx \ + socli.cxx \ + socont.cxx \ + ansi.cxx \ + helpers.cxx \ + uieffect.cxx \ + +.IF "$(GUI)" == "WNT" +SLOFILES= \ + $(SLO)$/sosink.obj \ + $(SLO)$/socli.obj \ + $(SLO)$/socont.obj \ + $(SLO)$/ansi.obj \ + $(SLO)$/helpers.obj \ + $(SLO)$/uieffect.obj +.ENDIF + + +# --- Tagets ------------------------------------------------------- + + +.INCLUDE : target.mk diff --git a/bf_so3/source/ole/socli.cxx b/bf_so3/source/ole/socli.cxx new file mode 100644 index 000000000..2c1eebd65 --- /dev/null +++ b/bf_so3/source/ole/socli.cxx @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <osl/mutex.hxx> +#include <vcl/svapp.hxx> + +#include "socont.h" + + +namespace binfilter { + +/* + * CImpIOleClientSite::CImpIOleClientSite + * CImpIOleClientSite::~CImpIOleClientSite + * + * Parameters (Constructor): + * pSO_Cont PCSO_Cont of the tenant we're in. + * pUnkOuter LPUNKNOWN to which we delegate. + */ + +CImpIOleClientSite::CImpIOleClientSite(PCSO_Cont pSO_Cont + , LPUNKNOWN pUnkOuter) + { + m_cRef=0; + m_pTen=pSO_Cont; + m_pUnkOuter=pUnkOuter; + return; + } + +CImpIOleClientSite::~CImpIOleClientSite(void) + { + return; + } + + + + +/* + * CImpIOleClientSite::QueryInterface + * CImpIOleClientSite::AddRef + * CImpIOleClientSite::Release + * + * Purpose: + * IUnknown members for CImpIOleClientSite object. + */ + +STDMETHODIMP CImpIOleClientSite::QueryInterface(REFIID riid + , PPVOID ppv) + { + return m_pUnkOuter->QueryInterface(riid, ppv); + } + + +STDMETHODIMP_(ULONG) CImpIOleClientSite::AddRef(void) + { + ++m_cRef; + return m_pUnkOuter->AddRef(); + } + +STDMETHODIMP_(ULONG) CImpIOleClientSite::Release(void) + { + --m_cRef; + return m_pUnkOuter->Release(); + } + + + + +/* + * CImpIOleClientSite::SaveObject + * + * Purpose: + * Requests that the container call OleSave for the object that + * lives here. Typically this happens on server shutdown. + * + * Parameters: + * None + * + * Return Value: + * HRESULT Standard. + */ + +STDMETHODIMP CImpIOleClientSite::SaveObject(void) +{ + ::SolarMutexGuard aGuard; + + m_pTen->Update(); + + return NOERROR; +} + + + + + +/* + * CImpIOleClientSite::GetMoniker + * + * Purpose: + * Retrieves the moniker for the site in which this object lives, + * either the moniker relative to the container or the full + * moniker. + * + * Parameters: + * dwAssign DWORD specifying that the object wants moniker + * assignment. Yeah. Right. Got any bridges to + * sell? + * dwWhich DWORD identifying which moniker the object + * wants, either the container's moniker, the + * moniker relative to this client site, or the + * full moniker. + * + * Return Value: + * HRESULT Standard. + */ + +STDMETHODIMP CImpIOleClientSite::GetMoniker(DWORD + , DWORD, LPMONIKER *ppmk) + { + *ppmk=NULL; + + /* + * We don't yet want to allow for linking to embedded objects + * within us, so we just fail for now. If you are only a simple + * container you never have to implement this function. + */ + return ResultFromScode(E_NOTIMPL); + } + + + + + + +/* + * CImpIOleClientSite::GetContainer + * + * Purpose: + * Returns a pointer to the document's IOleContainer interface. + * + * Parameters: + * ppContainer LPOLECONTAINER * in which to return the + * interface. + * + * Return Value: + * HRESULT Standard. + */ + +STDMETHODIMP CImpIOleClientSite::GetContainer(LPOLECONTAINER + * ppContainer) + { + //Only necessary if you allow linking to embeddings + *ppContainer=NULL; + return ResultFromScode(E_NOTIMPL); + } + + + + + + +/* + * CImpIOleClientSite::ShowObject + * + * Purpose: + * Tells the container to bring the object fully into view as much + * as possible, that is, scroll the document. + * + * Parameters: + * None + * + * Return Value: + * HRESULT Standard. + */ + +STDMETHODIMP CImpIOleClientSite::ShowObject(void) + { + /* + * We let the tenant do this, since it can access the current + * scroll position as a friend of CPages whereas we cannot. + */ + m_pTen->ShowYourself(); + return NOERROR; + } + + + + + + +/* + * CImpIOleClientSite::OnShowWindow + * + * Purpose: + * Informs the container if the object is showing itself or + * hiding itself. This is done only in the opening mode and allows + * the container to know when to shade or unshade the object. + * + * Parameters: + * fShow BOOL indiciating that the object is being shown + * (TRUE) or hidden (FALSE). + * Return Value: + * HRESULT Standard. + */ + +STDMETHODIMP CImpIOleClientSite::OnShowWindow(WIN_BOOL fShow) + { + //All we have to do is tell the tenant of the open state change. + m_pTen->ShowAsOpen(fShow); + return NOERROR; + } + + + + + + +/* + * CImpIOleClientSite::RequestNewObjectLayout + * + * Purpose: + * Called when the object needs more room in the container. + * + * Parameters: + * None + * + * Return Value: + * HRESULT Standard. + */ + +STDMETHODIMP CImpIOleClientSite::RequestNewObjectLayout(void) + { + return ResultFromScode(E_NOTIMPL); + } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/ole/socont.cxx b/bf_so3/source/ole/socont.cxx new file mode 100644 index 000000000..8bf817c98 --- /dev/null +++ b/bf_so3/source/ole/socont.cxx @@ -0,0 +1,2045 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "socont.h" +#include <bf_so3/svstor.hxx> +#include <sal/macros.h> + +#define LOMETRIC_PER_INCH 254 + +#define HIMETRIC_PER_INCH 2540 //Number HIMETRIC units per inch +#define PTS_PER_INCH 72 //Number points (font size) per inch + +#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli)) +#define MAP_LOGHIM_TO_PIX(x,ppli) MulDiv((ppli), (x), HIMETRIC_PER_INCH) + +namespace binfilter { + +void SO_MetricRectInPixelsToHimetric( LPRECT prcPix, LPRECT prcHiMetric) + { + int iXppli; //Pixels per logical inch along width + int iYppli; //Pixels per logical inch along height + int iXextInPix=(prcPix->right-prcPix->left); + int iYextInPix=(prcPix->bottom-prcPix->top); + BOOL fSystemDC=FALSE; + + HDC hDC = GetDC(NULL); + fSystemDC=TRUE; + + iXppli=GetDeviceCaps (hDC, LOGPIXELSX); + iYppli=GetDeviceCaps (hDC, LOGPIXELSY); + + //We got pixel units, convert them to logical HIMETRIC along the display + prcHiMetric->right=MAP_PIX_TO_LOGHIM(iXextInPix, iXppli); + prcHiMetric->top =MAP_PIX_TO_LOGHIM(iYextInPix, iYppli); + + prcHiMetric->left =0; + prcHiMetric->bottom =0; + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return; + } + +void SO_MetricSizeInPixelsToHimetric( LPSIZEL pSizeInPix, LPSIZEL pSizeInHiMetric) + { + int iXppli; //Pixels per logical inch along width + int iYppli; //Pixels per logical inch along height + BOOL fSystemDC=FALSE; + + HDC hDC=GetDC(NULL); + fSystemDC=TRUE; + + iXppli=GetDeviceCaps (hDC, LOGPIXELSX); + iYppli=GetDeviceCaps (hDC, LOGPIXELSY); + + //We got pixel units, convert them to logical HIMETRIC along the display + pSizeInHiMetric->cx=(long)MAP_PIX_TO_LOGHIM((int)pSizeInPix->cx, iXppli); + pSizeInHiMetric->cy=(long)MAP_PIX_TO_LOGHIM((int)pSizeInPix->cy, iYppli); + + if (fSystemDC) + ReleaseDC(NULL, hDC); + + return; + } + +/* + * RectConvertMappings + * + * Purpose: + * Converts the contents of a rectangle from device to logical + * coordinates where the hDC defines the logical coordinates. + * + * Parameters: + * pRect LPRECT containing the rectangle to convert. + * hDC HDC describing the logical coordinate system. + * if NULL, uses a screen DC in MM_LOMETRIC. + * fToDevice WIN_BOOL TRUE to convert from uConv to device, + * FALSE to convert device to uConv. + * + * Return Value: + * None + */ + +void RectConvertMappings(LPRECT pRect, HDC hDC, WIN_BOOL fToDevice) + { + POINT rgpt[2]; + WIN_BOOL fSysDC=FALSE; + + if (NULL==pRect) + return; + + rgpt[0].x=pRect->left; + rgpt[0].y=pRect->top; + rgpt[1].x=pRect->right; + rgpt[1].y=pRect->bottom; + + if (NULL==hDC) + { + hDC=GetDC(NULL); + SetMapMode(hDC, MM_HIMETRIC); + fSysDC=TRUE; + } + + if (fToDevice) + LPtoDP(hDC, rgpt, 2); + else + DPtoLP(hDC, rgpt, 2); + + if (fSysDC) + ReleaseDC(NULL, hDC); + + pRect->left=rgpt[0].x; + pRect->top=rgpt[0].y; + pRect->right=rgpt[1].x; + pRect->bottom=rgpt[1].y; + + return; + } + +/* + * CSO_Cont::CSO_Cont + * CSO_Cont::~CSO_Cont + * + * Constructor Parameters: + * dwID DWORD identifier for this page. + * hWnd HWND of the pages window. + * pPG PCPages to the parent structure. + */ + +CSO_Cont::CSO_Cont(DWORD dwID, HWND hWnd, SvOutPlaceObject * pPG) + { + m_hWnd=hWnd; + m_dwID=dwID; + + m_fInitialized=0; + m_pIStorage=NULL; + pTmpStorage=NULL; + m_cOpens=0; + + m_pObj=NULL; + m_pPG =pPG; + m_clsID=CLSID_NULL; + m_fSetExtent=FALSE; + + m_cRef=0; + m_pIOleObject=NULL; + m_pIViewObject2=NULL; + m_grfMisc=0; + + m_pImpIOleClientSite=NULL; + m_pImpIAdviseSink=NULL; + + m_fRepaintEnabled=TRUE; + + return; + } + + +CSO_Cont::~CSO_Cont(void) + { + //Object pointers cleaned up in Close. + DeleteInterfaceImp(m_pImpIAdviseSink); + DeleteInterfaceImp(m_pImpIOleClientSite); + + return; + } + + + +/* + * CSO_Cont::QueryInterface + * CSO_Cont::AddRef + * CSO_Cont::Release + * + * Purpose: + * IUnknown members for CSO_Cont object. + */ + +STDMETHODIMP CSO_Cont::QueryInterface(REFIID riid, PPVOID ppv) + { + *ppv=NULL; + + if (IID_IUnknown==riid) + *ppv=this; + + if (IID_IOleClientSite==riid) + *ppv=m_pImpIOleClientSite; + + if (IID_IAdviseSink==riid) + *ppv=m_pImpIAdviseSink; + + if (NULL!=*ppv) + { + ((LPUNKNOWN)*ppv)->AddRef(); + return NOERROR; + } + + return ResultFromScode(E_NOINTERFACE); + } + + +STDMETHODIMP_(ULONG) CSO_Cont::AddRef(void) + { + return ++m_cRef; + } + +STDMETHODIMP_(ULONG) CSO_Cont::Release(void) + { + if (0!=--m_cRef) + return m_cRef; + + delete this; + return 0; + } + + + +/* + * CSO_Cont::GetID + * + * Return Value: + * DWORD dwID field in this tenant. + */ + +DWORD CSO_Cont::GetID(void) + { + return m_dwID; + } + + + +/* + * CSO_Cont::GetStorageName + * + * Parameters: + * pszName LPOLESTR to a buffer in which to store the storage + * name for this tenant. + * + * Return Value: + * UINT Number of characters stored. + */ + +String CSO_Cont::GetStorageName() +{ + // used in SvOutPlaceObject too, don't change name + return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ); +} + + +/* + * CSO_Cont::Create + * + * Purpose: + * Creates a new tenant of the given CLSID, which can be either a + * static bitmap or metafile or any compound document object. + * + * Parameters: + * tType TENANTTYPE to create, either a static metafile, + * bitmap, or some kind of compound document object + * This determines which OleCreate* call we use. + * pvType LPVOID providing the relevant pointer from which + * to create the tenant, depending on iType. + * pFE LPFORMATETC specifying the type of renderings + * to use. + * pptl PPOINTL in which we store offset coordinates. + * pszl LPSIZEL where this object should store its + * lometric extents. + * pIStorage LPSTORAGE of the page we live in. We have to + * create another storage in this for the tenant. + * ppo PPATRONOBJECT containing placement data. + * dwData DWORD with extra data, sensitive to iType. + * + * Return Value: + * UINT A CREATE_* value depending on what we + * actually do. + */ + +UINT CSO_Cont::Create(TENANTTYPE tType, LPVOID pvType + , LPFORMATETC pFE, PPOINTL pptl, LPSIZEL pszl + , SotStorage * pIStorage, PPATRONOBJECT ppo, DWORD dwData) + { + HRESULT hr; + LPUNKNOWN pObj = NULL; + UINT uRet=CREATE_GRAPHICONLY; + + if (NULL==pvType || NULL==pIStorage) + return CREATE_FAILED; + + //Fail if this is called for an already living tenant. + if (m_fInitialized) + return CREATE_FAILED; + + m_fInitialized=TRUE; + + //Create a new storage for this tenant. + if (!Open(pIStorage)) + return CREATE_FAILED; + + /* + * Get the placement info if it's here. We either have a non- + * NULL PPATRONOBJECT in ppo or we have to use default + * placement and retrieve the size from the object itself. + */ + pszl->cx=0; + pszl->cy=0; + + if (NULL!=ppo) + { + *pFE=ppo->fe; + *pptl=ppo->ptl; + *pszl=ppo->szl; //Could be 0,0 , so we ask object + + uRet=CREATE_PLACEDOBJECT; + } + + hr=ResultFromScode(E_FAIL); + + //Now create an object based specifically for the type. + switch (tType) + { + case TENANTTYPE_NULL: + break; + + case TENANTTYPE_STATIC: + /* + * We could use OleCreateStaticFromData here which does + * pretty much what we're doing below. However, it does + * not allow us to control whether we paste a bitmap or + * a metafile--it uses metafile first, bitmap second. + * For this reason we'll use code developed in Chapter + * 11's FreeLoader to affect the paste. + */ + hr=CreateStatic((LPDATAOBJECT)pvType, pFE, &pObj); + break; + + //CHAPTER17MOD + case TENANTTYPE_EMBEDDEDOBJECT: + hr=OleCreate(*((LPCLSID)pvType), IID_IUnknown + , OLERENDER_DRAW, NULL, NULL, m_pIStorage + , (PPVOID)&pObj); + break; + + case TENANTTYPE_EMBEDDEDFILE: + hr=StarObject_OleCreateFromFile(CLSID_NULL, (LPTSTR)pvType + , IID_IUnknown, OLERENDER_DRAW, NULL, NULL + , m_pIStorage, (PPVOID)&pObj); + break; + + case TENANTTYPE_EMBEDDEDOBJECTFROMDATA: + hr=OleCreateFromData((LPDATAOBJECT)pvType, IID_IUnknown + , OLERENDER_DRAW, NULL, NULL, m_pIStorage + , (PPVOID)&pObj); + break; + //End CHAPTER17MOD + + default: + break; + } + + //If creation didn't work, get rid of the element Open created. + if (FAILED(hr)) + { + Destroy(pIStorage); + return CREATE_FAILED; + } + + //CHAPTER17MOD + //We don't get the size if PatronObject data was seen already. + if (!ObjectInitialize(pObj, pFE->dwAspect, dwData)) + //if (!ObjectInitialize(pObj, pFE, dwData)) + { + Destroy(pIStorage); + return CREATE_FAILED; + } + + if (0==pszl->cx && 0==pszl->cy) + { + GetExtent( pszl ); + } + //End CHAPTER17MOD + + return uRet; + } + + +/* + * CSO_Cont::Load + * + * Purpose: + * Recreates the object living in this tenant in place of calling + * FCreate. This is used in loading as opposed to new creation. + * + * Parameters: + * pIStorage LPSTORAGE of the page we live in. + * pti PTENTANTINFO containing persistent information. + * The ID value in this structure is ignored. + * + * Return Value: + * WIN_BOOL TRUE if successful, FALSE otherwise. + */ + +//WIN_BOOL CSO_Cont::Load(LPSTORAGE pIStorage, PTENANTINFO pti) +WIN_BOOL CSO_Cont::Load(SotStorage *pIStorage, DWORD dwAspect, WIN_BOOL fSetExtent, RECTL & rcl ) + { + HRESULT hr; + LPUNKNOWN pObj; + //CHAPTER17MOD + DWORD dwState=TENANTSTATE_DEFAULT; + //End CHAPTER17MOD + + /* + if (NULL==pIStorage || NULL==pti) + return FALSE; + */ + + //CHAPTER17MOD + /* + * If we already initialized once, clean up, releasing + * everything before we attempt to reload. This happens + * when using the Convert Dialog. + */ + if (m_fInitialized) + { + //Preserve all states except open + dwState=(m_dwState & ~TENANTSTATE_OPEN); + m_cRef++; //Prevent accidental closure + + //This should release all holds on our IStorage as well. + if (NULL!=m_pIViewObject2) + { + m_pIViewObject2->SetAdvise(dwAspect, 0, NULL); + ReleaseInterface(m_pIViewObject2); + } + + ReleaseInterface(m_pIOleObject); + ReleaseInterface(m_pObj); + + m_pIStorage=NULL; //We'll have already released this. + pTmpStorage=NULL; //We'll have already released this. + m_cRef--; //Match safety increment above. + } + //End CHAPTER14MOD + + m_fInitialized=TRUE; + + //Open the storage for this tenant. + if (!Open(pIStorage)) + return FALSE; + + hr=OleLoad(m_pIStorage, IID_IUnknown, NULL, (PPVOID)&pObj); + + if (FAILED(hr)) + { + Destroy(pIStorage); + return FALSE; + } + + m_fSetExtent=fSetExtent; + ObjectInitialize(pObj, dwAspect, NULL); + + //Restore the original state before reloading. + m_dwState=dwState; + + RectSet(&rcl, FALSE, FALSE); + return TRUE; + } + + + + +/* + * CSO_Cont::GetInfo + * + * Purpose: + * Retrieved a TENANTINFO structure for this tenant. + * + * Parameters: + * pti PTENANTINFO structure to fill + * + * Return Value: + * None + */ + +void CSO_Cont::GetInfo(DWORD& rAspect, WIN_BOOL & rSetExtend ) +{ + rAspect = dwAspect; + rSetExtend = m_fSetExtent; +} + +/* + * CSO_Cont::ObjectInitialize + * (Protected) + * + * Purpose: + * Performs operations necessary after creating an object or + * reloading one from storage. + * + * Parameters: + * pObj LPUNKNOWN of the object in this tenant. + * pFE LPFORMATETC describing the graphic here. + * dwData DWORD extra data. If pFE->dwAspect== + * DVASPECT_ICON then this is the iconic metafile. + * + * Return Value: + * WIN_BOOL TRUE if the function succeeded, FALSE otherwise. + */ + +WIN_BOOL CSO_Cont::ObjectInitialize(LPUNKNOWN pObj, DWORD dwAspect_, DWORD dwData) + { + HRESULT hr; + LPPERSIST pIPersist=NULL; + DWORD dw; + TCHAR szFile[CCHPATHMAX]; + + m_pObj=pObj; + dwAspect = dwAspect_; + m_dwState=TENANTSTATE_DEFAULT; + + /* + * Determine the type: Static or Embedded. If Static, + * this will have CLSID_Picture_Metafile or CLSID_Picture_Dib. + * Otherwise it's embedded. Later we'll add a case for links. + */ + m_tType=TENANTTYPE_EMBEDDEDOBJECT; + + if (SUCCEEDED(pObj->QueryInterface(IID_IPersist + , (PPVOID)&pIPersist))) + { + CLSID clsid=CLSID_NULL; + + hr=pIPersist->GetClassID(&clsid); + + //If we don't have a CLSID, default to static + if (FAILED(hr) || CLSID_Picture_Metafile==clsid + || CLSID_Picture_Dib==clsid) + m_tType=TENANTTYPE_STATIC; + + pIPersist->Release(); + } + + + m_pIViewObject2=NULL; + hr=pObj->QueryInterface(IID_IViewObject2 + , (PPVOID)&m_pIViewObject2); + + if (FAILED(hr)) + return FALSE; + + m_pIViewObject2->SetAdvise(dwAspect, 0, m_pImpIAdviseSink); + + IOleCache* pIOleCache = NULL; + if ( SUCCEEDED(m_pIViewObject2->QueryInterface(IID_IOleCache, (PPVOID)&pIOleCache)) && pIOleCache ) + { + IEnumSTATDATA* pEnumSD = NULL; + HRESULT hr = pIOleCache->EnumCache( &pEnumSD ); + + sal_Bool bRegister = sal_True; + if ( SUCCEEDED( hr ) && pEnumSD ) + { + pEnumSD->Reset(); + STATDATA aSD; + DWORD nNum; + while( SUCCEEDED( pEnumSD->Next( 1, &aSD, &nNum ) ) && nNum == 1 ) + { + if ( aSD.formatetc.cfFormat == 0 ) + { + bRegister = sal_False; + break; + } + } + } + + if ( bRegister ) + { + DWORD nConn; + FORMATETC aFormat = { 0, 0, ASPECT_CONTENT, -1, TYMED_MFPICT }; + hr = pIOleCache->Cache( &aFormat, /*ADVFCACHE_FORCEBUILTIN*/ /*ADVF_PRIMEFIRST*/ ADVFCACHE_ONSAVE, &nConn ); + } + + pIOleCache->Release(); + pIOleCache = NULL; + } + + + //We need an IOleObject most of the time, so get one here. + m_pIOleObject=NULL; + hr=pObj->QueryInterface(IID_IOleObject + , (PPVOID)&m_pIOleObject); + + /* + * Follow up object creation with advises and so forth. If + * we cannot get IOleObject here, then we know we can't do + * any IOleObject actions from here on--object is static. + */ + if (FAILED(hr)) + return TRUE; + + /* + * Get the MiscStatus bits and check for OLEMISC_ONLYICONIC. + * If set, force dwAspect in m_fe to DVASPECT_ICON so we + * remember to draw it properly and do extents right. + */ + m_pIOleObject->GetMiscStatus(dwAspect, &m_grfMisc); + + if (OLEMISC_ONLYICONIC & m_grfMisc) + dwAspect=DVASPECT_ICON; + + /* + * We could pass m_pImpIOleClientSite in an OleCreate* call, but + * since this function could be called after OleLoad, we still + * need to do this here, so it's always done here... + */ + m_pIOleObject->SetClientSite(m_pImpIOleClientSite); + m_pIOleObject->Advise(m_pImpIAdviseSink, &dw); + + OleSetContainedObject(m_pIOleObject, TRUE); + + /* + * For IOleObject::SetHostNames we need the application name + * and the document name (which is passed in the object + * parameter). The design of Patron doesn't give us nice + * structured access to the name of the document we're in, so + * I grab the parent of the Pages window (the document) and + * send it DOCM_PDOCUMENT which returns us the pointer. + * Roundabout, but it works. + */ + + szFile[0]=0; + + NotifyOfRename(szFile, NULL); + + + /* + * If we're creating an iconic aspect object and we have + * an object from the Insert Object dialog, then we need to + * store that iconic presentation in the cache, handled + * with the utility function StarObject_SwitchDisplayAspect. In + * this case dwData is a handle to the metafile containing + * the icon. If dwData is NULL then we depend on the + * server to provide the aspect, in which case we need + * a view advise. + */ + + if (DVASPECT_ICON & dwAspect) + { + DWORD dw=DVASPECT_CONTENT; + IAdviseSink *pSink; + + pSink=(NULL==dwData) ? NULL : m_pImpIAdviseSink; + + StarObject_SwitchDisplayAspect(m_pIOleObject, &dw + , DVASPECT_ICON, (HGLOBAL)(UINT)dwData, FALSE + , (NULL!=dwData), pSink, NULL); + } + + return TRUE; + } + + +/* + * CSO_Cont::Open + * + * Purpose: + * Retrieves the IStorage associated with this tenant. The + * IStorage is owned by the tenant and thus the tenant always + * holds a reference count. + * + * If the storage is already open for this tenant, then this + * function will AddRef it; therefore the caller must always + * match an Open with a Close. + * + * Parameters: + * pIStorage LPSTORAGE above this tenant (which has its + * own storage). + * + * Return Value: + * WIN_BOOL TRUE if opening succeeds, FALSE otherwise. + */ + +WIN_BOOL CSO_Cont::Open(SotStorage * pIStorage) + { + if (NULL==m_pIStorage) + { + if (NULL==pIStorage) + return FALSE; + + /* + * Attempt to open the storage under this ID. If there is + * none, then create it. In either case we end up with an + * IStorage that we either save in pPage or release. + */ + + SotStorageStreamRef xStm; + String szTemp = GetStorageName(); + if( pIStorage->IsContained( szTemp ) ) + { + xStm = pIStorage->OpenSotStream( szTemp, STREAM_STD_READ ); + if( xStm->GetError() ) + return FALSE; + xStm->Seek( STREAM_SEEK_TO_END ); + UINT32 nLen = xStm->Tell(); + xStm->Seek( 0 ); + HGLOBAL hMem = GlobalAlloc( GMEM_MOVEABLE | GMEM_SHARE, nLen ); + void * pMem = GlobalLock( hMem ); + if( pMem ) + xStm->Read( pMem, nLen ); + else + return FALSE; + GlobalUnlock( hMem ); + xStm = NULL; + + CreateILockBytesOnHGlobal( + hMem, //Memory handle for the byte array object + TRUE, //Whether to free memory when the object is released + &pTmpStorage //Indirect pointer to the new byte array object + ); + if( !pTmpStorage ) + return FALSE; + + HRESULT hr = StgOpenStorageOnILockBytes( + pTmpStorage, //Pointer to the byte array object + NULL, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, //Access mode + NULL, + 0, //Reserved; must be zero + &m_pIStorage //Indirect pointer to the new storage object + ); + if( FAILED( hr ) ) + return FALSE; + } + else + { + CreateILockBytesOnHGlobal( + NULL, //Memory handle for the byte array object + TRUE, //Whether to free memory when the object is released + &pTmpStorage //Indirect pointer to the new byte array object + ); + if( !pTmpStorage ) + return FALSE; + + StgCreateDocfileOnILockBytes( + pTmpStorage, //Pointer to the byte array object + STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, //Access mode + 0, //Reserved; must be zero + &m_pIStorage //Indirect pointer to the new storage object + ); + } + } + else + { + m_pIStorage->AddRef(); + pTmpStorage->AddRef(); + } + + + m_cOpens++; + + //Create these if we don't have them already. + if (NULL==m_pImpIOleClientSite && NULL==m_pImpIAdviseSink) + { + m_pImpIOleClientSite=new CImpIOleClientSite(this, this); + m_pImpIAdviseSink=new CImpIAdviseSink(this, this); + + if (NULL==m_pImpIOleClientSite || NULL==m_pImpIAdviseSink) + return FALSE; + } + + return TRUE; + } + + + + +/* + * CSO_Cont::Close + * + * Purpose: + * Possibly commits the storage, then releases it reversing the + * reference count from Open. If the reference on the storage + * goes to zero, the storage is forgotten. However, the object we + * contain is still held and as long as it's active the storage + * remains alive. + * + * Parameters: + * fCommit WIN_BOOL indicating if we're to commit. + * + * Return Value: + * None + */ + +//void CSO_Cont::Close(WIN_BOOL fCommit) +void CSO_Cont::Close(WIN_BOOL fCommit) + { + if (fCommit) + Update(); + + if (NULL!=m_pIStorage) + { + m_pIStorage->Release(); + pTmpStorage->Release(); + + /* + * We can't use a zero reference count to know when to NULL + * this since other things might have AddRef'd the storage. + */ + if (0==--m_cOpens) + { + m_pIStorage=NULL; + pTmpStorage=NULL; + + //Close the object saving if necessary + if (NULL!=m_pIOleObject) + { + m_pIOleObject->Close( fCommit ? OLECLOSE_SAVEIFDIRTY : OLECLOSE_NOSAVE ); + ReleaseInterface(m_pIOleObject); + } + + //Release all other held pointers + if (NULL!=m_pIViewObject2) + { + m_pIViewObject2->SetAdvise(dwAspect, 0, NULL); + ReleaseInterface(m_pIViewObject2); + } + + ReleaseInterface(m_pObj); + } + } + + return; + } + + + + +/* + * CSO_Cont::Update + * + * Purpose: + * Forces a common on the page if it's open. + * + * Parameters: + * None + * + * Return Value: + * WIN_BOOL TRUE if the object is open, FALSE otherwise. + */ + +WIN_BOOL CSO_Cont::Update() + { + Save( m_pPG->GetWorkingStorage()); + m_pPG->ClearCache(); + m_pPG->ViewChanged( (UINT16)dwAspect ); + m_pPG->SendViewChanged(); + + return FALSE; + } + + + + + +/* + * CSO_Cont::Destroy + * + * Purpose: + * Removes this page from the given storage. The caller should + * eventually delete this CSO_Cont object to free the object herein. + * Nothing is committed when being destroyed. + * + * Parameters: + * pIStorage LPSTORAGE contianing this page on which to call + * DestroyElement + * + * Return Value: + * None + */ + +void CSO_Cont::Destroy(SotStorage * pIStorage) + { + if (NULL!=pIStorage) + { + if (NULL!=m_pIOleObject) + m_pIOleObject->Close(OLECLOSE_NOSAVE); + + if (NULL!=m_pIStorage) + { + //Remove all reference/open counts on this storage. + while (0!=m_cOpens) + { + m_pIStorage->Release(); + pTmpStorage->Release(); + m_cOpens--; + } + } + + String szTemp = GetStorageName(); + pIStorage->Remove(szTemp); + + m_pIStorage=NULL; + pTmpStorage = NULL; + } + + return; + } + + + + +/* + * CSO_Cont::Select + * + * Purpose: + * Selects or deselects the tenant. + * + * Parameters: + * fSelect WIN_BOOL indicating the new state of the tenant. + * + * Return Value: + * None + */ + +void CSO_Cont::Select(WIN_BOOL fSelect) + { + WIN_BOOL fWasSelected; + DWORD dwState; + RECT rc; + + fWasSelected=(WIN_BOOL)(TENANTSTATE_SELECTED & m_dwState); + + //Nothing to do when there's no change. + if (fWasSelected==fSelect) + return; + + dwState=m_dwState & ~TENANTSTATE_SELECTED; + m_dwState=dwState | ((fSelect) ? TENANTSTATE_SELECTED : 0); + + /* + * Draw sizing handles to show the selection state. We convert + * things to MM_TEXT since that's what this function expects. + */ + + RECTFROMRECTL(rc, m_rcl); + RectConvertMappings(&rc, NULL, TRUE); + + if (fSelect) + m_pPG->SetModified(); + + return; + } + + + + +/* + * CSO_Cont::ShowAsOpen + * + * Purpose: + * Draws or removes the hatch pattern over an object. + * + * Parameters: + * fOpen WIN_BOOL indicating the open state of this tenant. + * + * Return Value: + * None + */ + +void CSO_Cont::ShowAsOpen(WIN_BOOL fOpen) + { + WIN_BOOL fWasOpen; + DWORD dwState; + RECT rc; + + fWasOpen=(WIN_BOOL)(TENANTSTATE_OPEN & m_dwState); + + dwState=m_dwState & ~TENANTSTATE_OPEN; + m_dwState=dwState | ((fOpen) ? TENANTSTATE_OPEN : 0); + + //If this was not open, then just hatch, otherwise repaint. + if (!fWasOpen && fOpen) + { + RECTFROMRECTL(rc, m_rcl); + RectConvertMappings(&rc, NULL, TRUE); + } + + if (fWasOpen && !fOpen) + { + m_pPG->GetProtocol().Reset2Open(); + + Repaint(); + } + else if (!fWasOpen && fOpen) + { + m_pPG->GetProtocol().EmbedProtocol(); + } + + return; + } + + + + + +/* + * CSO_Cont::ShowYourself + * + * Purpose: + * Function that really just implements IOleClientSite::ShowObject. + * Here we first check if the tenant is fully visible, and if so, + * then nothing needs to happen. Otherwise, if the upper left + * corner of the tenant is in the upper left visible quadrant of + * the window, we'll also consider ourselves done. Otherwise + * we'll put the upper left corner of the object at the upper left + * corner of the window. + * + * Parameters: + * None + * + * Return Value: + * None + */ + +void CSO_Cont::ShowYourself(void) + { + RECTL rcl; + RECT rc; + + //Scrolling deals in device units; get our rectangle in those. + RectGet(&rcl, TRUE); + + //Get the window rectangle offset for the current scroll pos. + GetClientRect(m_hWnd, &rc); + return; + } + + + +/* + * CSO_Cont::AddVerbMenu + * + * Purpose: + * Creates the variable verb menu item for the object in this + * tenant. + * + * Parmeters: + * hMenu HMENU on which to add items. + * iPos UINT position on that menu to add items. + * + * Return Value: + * None + */ + +void CSO_Cont::AddVerbMenu(HMENU, UINT) + { + } + + + + +/* + * CSO_Cont::TypeGet + * + * Purpose: + * Returns the type of this tenant + * + * Parameters: + * None + * + * Return Value: + * TENANTTYPE Type of the tenant. + */ + +TENANTTYPE CSO_Cont::TypeGet(void) + { + return m_tType; + } + + + + + + +/* + * CSO_Cont::CopyEmbeddedObject + * + * Purpose: + * Copies an embedded object to the given data object (via SetData, + * assuming this is a data transfer object for clipboard/drag-drop) + * if that's what we're holding. + * + * Parameters: + * pIDataObject LPDATAOBJECT in which to store the copy. + * pFE LPFORMATETC into which to copy CFSTR_EMBEDDEDOBJECT + * if we put that in the data object. + * pptl PPOINTL to the pick point (NULL outside of + * drag-drop); + * + * Return Value: + * None + */ + +void CSO_Cont::CopyEmbeddedObject(LPDATAOBJECT pIDataObject + , LPFORMATETC pFE, PPOINTL pptl) + { + LPPERSISTSTORAGE pIPS; + STGMEDIUM stm; + FORMATETC fe; + HRESULT hr; + UINT cf; + POINTL ptl; + SIZEL szl; + + //Can only copy embeddings. + if (TENANTTYPE_EMBEDDEDOBJECT!=m_tType || NULL==m_pIOleObject) + return; + + if (NULL==pptl) + { + SETPOINTL(ptl, 0, 0); + pptl=&ptl; + } + + /* + * Create CFSTR_EMBEDDEDOBJECT. This is simply an IStorage with + * a copy of the embedded object in it. The not-so-simple part + * is getting an IStorage to stuff it in. For this operation + * we'll use a temporary compound file. + */ + + stm.pUnkForRelease=NULL; + stm.tymed=TYMED_ISTORAGE; + hr=StgCreateDocfile(NULL, STGM_TRANSACTED | STGM_READWRITE + | STGM_CREATE| STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE + , 0, &stm.pstg); + + if (FAILED(hr)) + return; + + m_pObj->QueryInterface(IID_IPersistStorage, (PPVOID)&pIPS); + + if (NOERROR==pIPS->IsDirty()) + { + OleSave(pIPS, stm.pstg, FALSE); + pIPS->SaveCompleted(NULL); + } + else + m_pIStorage->CopyTo(0, NULL, NULL, stm.pstg); + + pIPS->Release(); + + //stm.pstg now has a copy, so stuff it away. + cf=RegisterClipboardFormat(CFSTR_EMBEDDEDOBJECT); + SETDefFormatEtc(fe, sal::static_int_cast< CLIPFORMAT >(cf), TYMED_ISTORAGE); + + if (SUCCEEDED(pIDataObject->SetData(&fe, &stm, TRUE))) + *pFE=fe; + else + ReleaseStgMedium(&stm); + + stm.tymed=TYMED_HGLOBAL; + + /* + * You want to make sure that if this object is iconic, that you + * create the object descriptor with DVASPECT_ICON instead of + * the more typical DVASPECT_CONTENT. Also remember that + * the pick point is in HIMETRIC. + */ + SO_MetricSizeInPixelsToHimetric( (LPSIZEL)pptl, (LPSIZEL)&ptl); + + //SETSIZEL(szl, (10*(m_rcl.right-m_rcl.left)) + // , (10 * (m_rcl.bottom-m_rcl.top))); + SETSIZEL(szl, m_rcl.right-m_rcl.left, m_rcl.bottom-m_rcl.top ); + + stm.hGlobal=StarObject_ObjectDescriptorFromOleObject(m_pIOleObject, dwAspect, ptl, &szl); + //stm.hGlobal=StarObject_ObjectDescriptorFromOleObject(m_pIOleObject, m_fe.dwAspect, ptl, &szl); + + cf=RegisterClipboardFormat(CFSTR_OBJECTDESCRIPTOR); + SETDefFormatEtc(fe, sal::static_int_cast< CLIPFORMAT >(cf), TYMED_HGLOBAL); + + if (FAILED(pIDataObject->SetData(&fe, &stm, TRUE))) + ReleaseStgMedium(&stm); + + return; + } + + + + + +/* + * CSO_Cont::NotifyOfRename + * + * Purpose: + * Instructs the tenant that the document was saved under a + * different name. In order to keep the right compound document + * user interface, this tenant needs to tell its object through + * IOleObject::SetHostNames. + * + * Parameters: + * pszFile LPTSTR of filename. + * pvReserved LPVOID reserved for future use. + * + * Return Value: + * None + */ + +void CSO_Cont::NotifyOfRename(LPTSTR pszFile, LPVOID) + { + TCHAR szObj[40]; + TCHAR szApp[40]; + + if (NULL==m_pIOleObject) + return; + + if (TEXT('\0')==*pszFile) + { + // MM ??? + lstrcpyn( szObj, "untitled", SAL_N_ELEMENTS(szObj) ); + } + else + { + // MM ??? + lstrcpyn( szObj, "untitled", SAL_N_ELEMENTS(szObj) ); + + #ifndef WIN32 + //Force filenames to uppercase in DOS versions. + AnsiUpper(szObj); + #endif + } + + // MM ??? + lstrcpyn( szApp, "app name", SAL_N_ELEMENTS(szApp) ); + #ifdef WIN32ANSI + OLECHAR szObjW[40], szAppW[40]; + + MultiByteToWideChar(CP_ACP, 0, szObj, -1, szObjW, 40); + MultiByteToWideChar(CP_ACP, 0, szApp, -1, szAppW, 40); + m_pIOleObject->SetHostNames(szAppW, szObjW); + #else + m_pIOleObject->SetHostNames(szApp, szObj); + #endif + return; + } + + +/* + * CSO_Cont::Activate + * + * Purpose: + * Activates a verb on the object living in the tenant. Does + * nothing for static objects. + * + * Parameters: + * iVerb LONG of the verb to execute. + * + * Return Value: + * WIN_BOOL TRUE if the object changed due to this verb + * execution. + */ + +WIN_BOOL CSO_Cont::Activate(LONG iVerb, HWND hParent ) + { + RECT rc, rcH; + SIZEL szl; + + //Can't activate statics. + if (TENANTTYPE_STATIC==m_tType || NULL==m_pIOleObject) + { + MessageBeep(0); + return FALSE; + } + + RECTFROMRECTL(rc, m_rcl); + RectConvertMappings(&rc, NULL, TRUE); + SO_MetricRectInPixelsToHimetric( &rc, &rcH); + + //Get the server running first, then do a SetExtent, then show it + OleRun(m_pIOleObject); + + if (m_fSetExtent) + { + SETSIZEL(szl, rcH.right-rcH.left, rcH.top-rcH.bottom); + m_pIOleObject->SetExtent(dwAspect, &szl); + m_fSetExtent=FALSE; + } + + if( !hParent ) + hParent = m_hWnd; + HRESULT hr = m_pIOleObject->DoVerb(iVerb, NULL, m_pImpIOleClientSite, 0 + , hParent, &rcH); + + //delete pHour; + + //If object changes, IAdviseSink::OnViewChange will see it. + return SUCCEEDED( hr ); + } + + +BOOL CSO_Cont::GetMetaFile( long& nMapMode, Size& rSize, HMETAFILE& hMet ) +{ + if ( !m_pObj ) + return FALSE; + + HRESULT hr; + LPDATAOBJECT pIDataObject; + FORMATETC fe; + STGMEDIUM stm; + hr=m_pObj->QueryInterface(IID_IDataObject, (PPVOID)&pIDataObject); + if ( SUCCEEDED(hr) ) + { + if ( !OleIsRunning( m_pIOleObject ) ) + OleRun( m_pObj ); + + SETFormatEtc(fe, CF_METAFILEPICT, DVASPECT_CONTENT, NULL, TYMED_MFPICT, -1); + hr=pIDataObject->GetData(&fe, &stm); + pIDataObject->Release(); + METAFILEPICT* pMem = (METAFILEPICT*) GlobalLock( stm.hGlobal ); + if( !pMem ) + return FALSE; + nMapMode = pMem->mm; + rSize.Width() = pMem->xExt; + rSize.Height() = pMem->yExt; + hMet = pMem->hMF; + GlobalUnlock( stm.hGlobal ); + } + + return TRUE; +} + +/* + * CSO_Cont::Draw + * + * Purpose: + * Draws the tenant in its rectangle on the given hDC. We assume + * the DC is already set up for the mapping mode in which our + * rectangle is expressed, since the Page we're in tells us both + * the rect and the hDC. + * + * Parameters: + * hDC HDC in which to draw. Could be a metafile, + * memory DC, screen, or printer. + * ptd DVTARGETDEVICE * describing the device. + * hIC HDC holding an information context (printing). + * xOff, yOff int offsets for the page in lometric + * fNoColor WIN_BOOL indicating if we should do B & W + * fPrinter WIN_BOOL indicating if we should render for a + * printer. + * + * Return Value: + * None + */ + +void CSO_Cont::Draw(HDC hDC, DVTARGETDEVICE *ptd, HDC hIC + , int xOff, int yOff, WIN_BOOL fNoColor, WIN_BOOL fPrinter) + { + HRESULT hr; + RECT rc = { 0, 0, xOff, -yOff }; + RECTL rcl = { 0, 0, xOff, -yOff }; + UINT uMM; + + //Repaint erases the rectangle to insure full object cleanup + + if (!fNoColor && !fPrinter) + { + COLORREF cr; + cr=SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); + ExtTextOut(hDC, rc.left, rc.top, ETO_OPAQUE, &rc, NULL + , 0, NULL); + SetBkColor(hDC, cr); + } + + //We have to use Draw since we have a target device and IC. + hr=m_pIViewObject2->Draw(dwAspect, -1, NULL, ptd, hIC, hDC, NULL, &rcl, NULL, 0); + + /* + * If Draw failed, then perhaps it couldn't work for the device, + * so try good old OleDraw as a last resort. The code will + * generally be OLE_E_BLANK. + */ + if (FAILED(hr)) + OleDraw(m_pObj, dwAspect, hDC, &rc); + + if (!fPrinter + && (TENANTSTATE_SELECTED | TENANTSTATE_OPEN) & m_dwState) + { + /* + * Draw sizing handles to show the selection state. We + * convert things to MM_TEXT since that's what this + * function expects. + */ + RectConvertMappings(&rc, NULL, TRUE); + uMM=SetMapMode(hDC, MM_TEXT); + + if (TENANTSTATE_SELECTED & m_dwState) + { + UIDrawHandles(&rc, hDC, UI_HANDLES_INSIDE + | UI_HANDLES_NOBORDER | UI_HANDLES_USEINVERSE + , CXYHANDLE, TRUE); + } + + if (TENANTSTATE_OPEN & m_dwState) + UIDrawShading(&rc, hDC, UI_SHADE_FULLRECT, 0); + + uMM=SetMapMode(hDC, uMM); + } + + return; + } + + + + + +/* + * CSO_Cont::Repaint + * CSO_Cont::Invalidate + * + * Purpose: + * Repaints the tenant where it lies or invalidates its area + * for later repainting. + * + * Parameters: + * None + * + * Return Value: + * None + */ + +void CSO_Cont::Repaint(void) + { + + /* + * We might be asked to repaint from + * IOleClientSite::OnShowWindow after we've switched pages if + * our server was running. This check on m_cOpens prevents that. + */ + if (0==m_cOpens || !m_fRepaintEnabled) + return; + + return; + } + + +void CSO_Cont::Invalidate(void) + { + RECTL rcl; + RECT rc; + + RectGet(&rcl, TRUE); + RECTFROMRECTL(rc, rcl); + + return; + } + + + + +/* + * CSO_Cont::ObjectClassFormatAndIcon + * + * Purpose: + * Helper function for CPage::ConvertObject to retrieve necessary + * information about the object. + * + * Parameters: + * pClsID LPCLSID in which to store the CLSID. + * pwFormat LPWORD in which to store the clipboard format + * used. + * ppszType LPTSTR * in which to return a pointer to a + * type string. + * phMetaIcon HGLOBAL * in which to return the metafile + * icon currently in use. + * + * Return Value: + * None + */ + +void CSO_Cont::ObjectClassFormatAndIcon(LPCLSID pClsID + , LPWORD pwFormat, LPTSTR *ppszType, HGLOBAL *phMetaIcon + , LPTSTR *ppszLabel) + { + HRESULT hr; + TCHAR szType[128]; + LPDATAOBJECT pIDataObject; + FORMATETC fe; + STGMEDIUM stm; + + if (TENANTTYPE_EMBEDDEDOBJECT!=m_tType || NULL==m_pIOleObject) + return; + + if (NULL==pClsID || NULL==pwFormat || NULL==ppszType + || NULL==phMetaIcon) + return; + + + /* + * For embedded objects get the real CLSID of the object and + * its format string. If this fails then we can try to ask + * the object, or we can look in the registry. + */ + + hr=ReadClassStg(m_pIStorage, pClsID); + + if (FAILED(hr)) + { + hr=m_pIOleObject->GetUserClassID(pClsID); + + if (FAILED(hr)) + *pClsID=CLSID_NULL; + } + + + hr=StarObject_ReadFmtUserTypeStg(m_pIStorage, pwFormat, ppszType); + + if (FAILED(hr)) + { + *pwFormat=0; + *ppszType=NULL; + + if (StarObject_GetUserTypeOfClass(*pClsID, 0, szType + , sizeof(szType))) + { + *ppszType=StarObject_CopyString(szType); + } + } + + /* + * Try to get the AuxUserType from the registry, using + * the short version (registered under AuxUserType\2). + * If that fails, just copy *ppszType. + */ + *ppszLabel=NULL; + + if (StarObject_GetUserTypeOfClass(*pClsID, 2, szType + , sizeof(szType))) + { + *ppszLabel=StarObject_CopyString(szType); + } + else + *ppszLabel=StarObject_CopyString(*ppszType); + + //Get the icon for this thing, if we're iconic. + *phMetaIcon=NULL; + + hr=m_pObj->QueryInterface(IID_IDataObject + , (PPVOID)&pIDataObject); + + if (SUCCEEDED(hr)) + { + SETFormatEtc(fe, CF_METAFILEPICT, DVASPECT_ICON, NULL + , TYMED_MFPICT, -1); + hr=pIDataObject->GetData(&fe, &stm); + pIDataObject->Release(); + + if (SUCCEEDED(hr)) + *phMetaIcon=stm.hGlobal; + else + *phMetaIcon=OleGetIconOfClass(*pClsID, NULL, TRUE); + } + + return; + } + + + + +/* + * CSO_Cont::SwitchOrUpdateAspect + * + * Purpose: + * Switches between DVASPECT_CONTENT and DVASPECT_ICON + * + * Parameters: + * hMetaIcon HGLOBAL to the new icon if we're changing the + * icon or switching to DVASPECT_ICON. NULL to + * change back to content. + * fPreserve WIN_BOOL indicating if we're to preserve the old + * aspect after changing. + * + * Return Value: + * WIN_BOOL TRUE if anything changed, FALSE otherwise. + */ + +WIN_BOOL CSO_Cont::SwitchOrUpdateAspect(HGLOBAL hMetaIcon + , WIN_BOOL fPreserve) + { + HRESULT hr; + WIN_BOOL fUpdate=FALSE; + + //Nothing to do if we're content already and there's no icon. + if (NULL==hMetaIcon && DVASPECT_CONTENT==dwAspect) + return FALSE; + + //If we're iconic already, just cache the new icon + if (NULL!=hMetaIcon && DVASPECT_ICON==dwAspect) + hr=StarObject_SetIconInCache(m_pIOleObject, hMetaIcon); + else + { + //Otherwise, switch between iconic and content. + dwAspect=(NULL==hMetaIcon) ? DVASPECT_CONTENT : DVASPECT_ICON; + + /* + * Switch between aspects, where dwAspect has the new one + * and m_fe.dwAspect will be changed in the process. + */ + hr=StarObject_SwitchDisplayAspect(m_pIOleObject + , &dwAspect, dwAspect, hMetaIcon, !fPreserve + , TRUE, m_pImpIAdviseSink, &fUpdate); + + if (SUCCEEDED(hr)) + { + //Update MiscStatus for the new aspect + m_pIOleObject->GetMiscStatus(dwAspect, &m_grfMisc); + + if (fUpdate) + m_pIOleObject->Update(); //This repaints. + } + } + + //If we switched, update our extents. + if (SUCCEEDED(hr)) + { + SIZEL szl; + + m_pIOleObject->GetExtent(dwAspect, &szl); + + if (0 > szl.cy) + szl.cy=-szl.cy; + + //Convert HIMETRIC absolute units to our LOMETRIC mapping + Invalidate(); //Remove old aspect + SizeSet(&szl, FALSE, FALSE); //Change size + Repaint(); //Paint the new one + } + + return SUCCEEDED(hr); + } + + + +/* + * CSO_Cont::EnableRepaint + * + * Purpose: + * Toggles whether the Repaint function does anything. This + * is used during conversion/emulation of an object to disable + * repaints until the new object can be given the proper extents. + * + * Parameters: + * fEnable TRUE to enable repaints, FALSE to disable. + * + * Return Value: + * None + */ + +void CSO_Cont::EnableRepaint(WIN_BOOL fEnable) + { + m_fRepaintEnabled=fEnable; + return; + } + + +/* + * CSO_Cont::ObjectGet + * + * Purpose: + * Retrieves the LPUNKNOWN of the object in use by this tenant + * + * Parameters: + * ppUnk LPUNKNOWN * in which to return the object + * pointer. + * + * Return Value: + * None + */ + +void CSO_Cont::ObjectGet(LPUNKNOWN *ppUnk) + { + if (NULL!=ppUnk) + { + *ppUnk=m_pObj; + m_pObj->AddRef(); + } + + return; + } + + + + + +/* + * CSO_Cont::FormatEtcGet + * + * Purpose: + * Retrieves the FORMATETC in use by this tenant + * + * Parameters: + * pFE LPFORMATETC in which to store the information. + * fPresentation WIN_BOOL indicating if we want the real format or + * that of the presentation. + * + * Return Value: + * None + */ + +void CSO_Cont::FormatEtcGet(LPFORMATETC pFE, WIN_BOOL fPresentation) + { + if (NULL!=pFE) + { + SETDefFormatEtc(*pFE, 0, TYMED_NULL); + + //If there is no format, use metafile (for embedded objects) + if (fPresentation || 0==pFE->cfFormat) + { + //Don't mess with dwAspect; might be icon or content. + pFE->cfFormat=CF_METAFILEPICT; + pFE->tymed=TYMED_MFPICT; + } + } + + return; + } + + + + +WIN_BOOL CSO_Cont::GetExtent(LPSIZEL pszl) +{ + SETSIZEL((*pszl), 2*HIMETRIC_PER_INCH, 2*HIMETRIC_PER_INCH); + SIZEL szl = SIZEL(); + HRESULT hr=ResultFromScode(E_FAIL); + + //Try IViewObject2 first, then IOleObject as a backup. + if (NULL!=m_pIViewObject2) + { + hr = m_pIViewObject2->GetExtent(dwAspect, -1, NULL, &szl); + } + else + { + if (NULL!=m_pIOleObject) + hr = m_pIOleObject->GetExtent(dwAspect, &szl); + } + if (SUCCEEDED(hr)) + { + *pszl = szl; + } + + return SUCCEEDED( hr ); +} + +/* + * CSO_Cont::SizeGet + * CSO_Cont::SizeSet + * CSO_Cont::RectGet + * CSO_Cont::RectSet + * + * Purpose: + * Returns or sets the size/position of the object contained here. + * + * Parameters: + * pszl/prcl LPSIZEL (Size) or LPRECTL (Rect) with the + * extents of interest. In Get situations, + * this will receive the extents; in Set it + * contains the extents. + * fDevice WIN_BOOL indicating that pszl/prcl is expressed + * in device units. Otherwise it's LOMETRIC. + * fInformObj (Set Only) WIN_BOOL indicating if we need to inform + * the object all. + * + * Return Value: + * None + */ + +void CSO_Cont::SizeGet(LPSIZEL pszl, WIN_BOOL fDevice) + { + if (!fDevice) + { + pszl->cx=m_rcl.right-m_rcl.left; + pszl->cy=m_rcl.bottom-m_rcl.top; + } + else + { + RECT rc; + + SetRect(&rc, (int)(m_rcl.right-m_rcl.left) + , (int)(m_rcl.bottom-m_rcl.top), 0, 0); + + RectConvertMappings(&rc, NULL, TRUE); + + pszl->cx=(long)rc.left; + pszl->cy=(long)rc.top; + } + + return; + } + +void CSO_Cont::SizeSet(LPSIZEL pszl, WIN_BOOL fDevice, WIN_BOOL fInformObj) + { + SIZEL szl; + + if (!fDevice) + { + szl=*pszl; + m_rcl.right =pszl->cx+m_rcl.left; + m_rcl.bottom=pszl->cy+m_rcl.top; + } + else + { + RECT rc; + + SetRect(&rc, (int)pszl->cx, (int)pszl->cy, 0, 0); + RectConvertMappings(&rc, NULL, FALSE); + + m_rcl.right =(long)rc.left+m_rcl.left; + m_rcl.bottom=(long)rc.top+m_rcl.top; + + SETSIZEL(szl, (long)rc.left, (long)rc.top); + } + + + //Tell OLE that this object was resized. + if (NULL!=m_pIOleObject && fInformObj) + { + HRESULT hr; + WIN_BOOL fRun=FALSE; + + if( szl.cy < 0 ) + szl.cy *= -1; + + /* + * If the MiscStatus bit of OLEMISC_RECOMPOSEONRESIZE + * is set, then we need to run the object before calling + * SetExtent to make sure it has a real chance to + * re-render the object. We have to update and close + * the object as well after this happens. + */ + + if (OLEMISC_RECOMPOSEONRESIZE & m_grfMisc) + { + if (!OleIsRunning(m_pIOleObject)) + { + OleRun(m_pIOleObject); + fRun=TRUE; + } + } + + hr=m_pIOleObject->SetExtent(dwAspect, &szl); + + /* + * If the object is not running and it does not have + * RECOMPOSEONRESIZE, then SetExtent fails. Make + * sure that we call SetExtent again (by just calling + * SizeSet here again) when we next run the object. + */ + if (SUCCEEDED(hr)) + { + m_fSetExtent=FALSE; + + if (fRun) + { + m_pIOleObject->Update(); + m_pIOleObject->Close(OLECLOSE_SAVEIFDIRTY); + } + } + else + { + if (OLE_E_NOTRUNNING==GetScode(hr)) + m_fSetExtent=TRUE; + } + } + + return; + } + + +void CSO_Cont::RectGet(LPRECTL prcl, WIN_BOOL fDevice) + { + if (!fDevice) + *prcl=m_rcl; + else + { + RECT rc; + + RECTFROMRECTL(rc, m_rcl); + RectConvertMappings(&rc, NULL, TRUE); + RECTLFROMRECT(*prcl, rc); + } + + return; + } + + +void CSO_Cont::RectSet(LPRECTL prcl, WIN_BOOL fDevice, WIN_BOOL fInformObj) + { + SIZEL szl; + LONG cx, cy; + + cx=m_rcl.right-m_rcl.left; + cy=m_rcl.bottom-m_rcl.top; + + if (!fDevice) + m_rcl=*prcl; + else + { + RECT rc; + + RECTFROMRECTL(rc, *prcl); + RectConvertMappings(&rc, NULL, FALSE); + RECTLFROMRECT(m_rcl, rc); + } + + /* + * Tell ourselves that the size changed, if it did. SizeSet + * will call IOleObject::SetExtent for us. + */ + if ((m_rcl.right-m_rcl.left)!=cx || (m_rcl.bottom-m_rcl.top)!=cy) + { + SETSIZEL(szl, m_rcl.right-m_rcl.left, m_rcl.bottom-m_rcl.top); + SizeSet(&szl, FALSE, fInformObj); + } + + return; + } + + + + + + + +/* + * CSO_Cont::CreateStatic + * (Protected) + * + * Purpose: + * Creates a new static bitmap or metafile object for this tenant + * using a freeloading method allowing us to specify exactly which + * type of data we want to paste since OleCreateStaticFromData + * doesn't. + * + * Parameters: + * pIDataObject LPDATAOBJECT from which to paste. + * pFE LPFORMATETC describing the format to paste. + * ppObj LPUNKNOWN * into which we store the + * object pointer. + * + * Return Value: + * HRESULT NOERROR on success, error code otherwise. + */ + +HRESULT CSO_Cont::CreateStatic(LPDATAOBJECT pIDataObject + , LPFORMATETC pFE, LPUNKNOWN *ppObj) + { + HRESULT hr; + STGMEDIUM stm; + LPUNKNOWN pIUnknown; + LPOLECACHE pIOleCache; + LPPERSISTSTORAGE pIPersistStorage; + CLSID clsID; + + *ppObj=NULL; + + //Try to get the data desired as specified in pFE->cfFormat + hr=pIDataObject->GetData(pFE, &stm); + + if (FAILED(hr)) + return hr; + + //Create the object to handle this data. + if (CF_METAFILEPICT==pFE->cfFormat) + clsID=CLSID_Picture_Metafile; + else + clsID=CLSID_Picture_Dib; + + hr=CreateDataCache(NULL, clsID, IID_IUnknown + , (PPVOID)&pIUnknown); + + if (FAILED(hr)) + { + ReleaseStgMedium(&stm); + return hr; + } + + m_clsID=clsID; + + //Stuff the data into the object + pIUnknown->QueryInterface(IID_IPersistStorage + , (PPVOID)&pIPersistStorage); + pIPersistStorage->InitNew(m_pIStorage); + + //Now that we have the cache object, shove the data into it. + pIUnknown->QueryInterface(IID_IOleCache, (PPVOID)&pIOleCache); + pIOleCache->Cache(pFE, ADVF_PRIMEFIRST, NULL); + + hr=pIOleCache->SetData(pFE, &stm, TRUE); + pIOleCache->Release(); + + //Insure there is a persistent copy on the disk + WriteClassStg(m_pIStorage, m_clsID); + pIPersistStorage->Save(m_pIStorage, TRUE); + pIPersistStorage->SaveCompleted(NULL); + pIPersistStorage->Release(); + + //The cache owns this now. + ReleaseStgMedium(&stm); + + if (FAILED(hr)) + pIUnknown->Release(); + else + *ppObj=pIUnknown; + + return hr; + } + +CLSID CSO_Cont::GetCLSID() +{ + if ( m_clsID == GUID_NULL ) + { + LPPERSIST pIPS; + m_pObj->QueryInterface(IID_IPersist, (PPVOID)&pIPS); + pIPS->GetClassID( &m_clsID ); + } + + return m_clsID; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/ole/socont.h b/bf_so3/source/ole/socont.h new file mode 100644 index 000000000..ed2313780 --- /dev/null +++ b/bf_so3/source/ole/socont.h @@ -0,0 +1,292 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#ifndef _TENANT_H_ +#define _TENANT_H_ + +#include <bf_svtools/bf_prewin.h> +#include "soole.h" +#include <bf_svtools/bf_postwin.h> +#include "bf_so3/outplace.hxx" + +#define HIMETRIC_PER_INCH 2540 +#define LOMETRIC_PER_INCH 254 + +#ifndef PPVOID +typedef LPVOID * PPVOID; +#endif //PPVOID + + +namespace binfilter { + +//CHAPTER17MOD + +class CImpIOleClientSite : public IOleClientSite + { + protected: + ULONG m_cRef; + class CSO_Cont *m_pTen; + LPUNKNOWN m_pUnkOuter; + + public: + CImpIOleClientSite(class CSO_Cont *, LPUNKNOWN); + virtual ~CImpIOleClientSite(void); + + STDMETHODIMP QueryInterface(REFIID, PPVOID); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + STDMETHODIMP SaveObject(void); + STDMETHODIMP GetMoniker(DWORD, DWORD, LPMONIKER *); + STDMETHODIMP GetContainer(LPOLECONTAINER *); + STDMETHODIMP ShowObject(void); + STDMETHODIMP OnShowWindow(WIN_BOOL); + STDMETHODIMP RequestNewObjectLayout(void); + }; + +typedef CImpIOleClientSite *PCImpIOleClientSite; + + + +class CImpIAdviseSink : public IAdviseSink + { + protected: + ULONG m_cRef; + class CSO_Cont *m_pTen; + LPUNKNOWN m_pUnkOuter; + + public: + CImpIAdviseSink(class CSO_Cont *, LPUNKNOWN); + virtual ~CImpIAdviseSink(void); + + STDMETHODIMP QueryInterface(REFIID, PPVOID); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + STDMETHODIMP_(void) OnDataChange(LPFORMATETC, LPSTGMEDIUM); + STDMETHODIMP_(void) OnViewChange(DWORD, LONG); + STDMETHODIMP_(void) OnRename(LPMONIKER); + STDMETHODIMP_(void) OnSave(void); + STDMETHODIMP_(void) OnClose(void); + }; + + +typedef CImpIAdviseSink *PCImpIAdviseSink; + +//End CHAPTER17MOD + + +/* + * SO_Cont class describing an individual piece of data in a page. + * It knows where it sits, what object is inside of it, and what + * its idenitifer is such that it can find it's storage within a + * page. + */ + +//Patron Objects clipboard format +typedef struct tagPATRONOBJECT + { + POINTL ptl; //Location of object + POINTL ptlPick; //Pick point from drag-drop operation + SIZEL szl; //Extents of object (absolute) + FORMATETC fe; //Actual object format + } PATRONOBJECT, *PPATRONOBJECT; + + + +//Values for hit-testing, drawing, and resize-tracking tenants +#define CXYHANDLE 5 + +//SO_Cont types (not persistent, but determined at load time) +typedef enum + { + TENANTTYPE_NULL=0, + TENANTTYPE_STATIC, + //CHAPTER17MOD + TENANTTYPE_EMBEDDEDOBJECT, + TENANTTYPE_EMBEDDEDFILE, + TENANTTYPE_EMBEDDEDOBJECTFROMDATA + //End CHAPTER17MOD + } TENANTTYPE, *PTENANTTYPE; + + +//State flags +#define TENANTSTATE_DEFAULT 0x00000000 +#define TENANTSTATE_SELECTED 0x00000001 + +//CHAPTER17MOD +#define TENANTSTATE_OPEN 0x00000002 +//End CHAPTER17MOD + + +/* + * Persistent information we need to save for each tenant, which is + * done in the tenant list instead of with each tenant. Since this + * is a small structure it's best not to blow another stream for it + * (overhead). + */ +/* +#pragma pack( push, 8 ) +typedef struct tagTENANTINFO + { + DWORD dwID; + RECTL rcl; + FORMATETC fe; //Excludes ptd + short fSetExtent; //Call IOleObject::SetExtent on Run + } TENANTINFO, *PTENANTINFO; +#pragma pack( pop, 8 ) +*/ + +class CSO_Cont : public IUnknown + { + //CHAPTER17MOD + friend class CImpIOleClientSite; + friend class CImpIAdviseSink; + //End CHAPTER17MOD + + private: + HWND m_hWnd; //Pages window + DWORD m_dwID; //Persistent DWORD ID + DWORD m_cOpens; //Count calls to Open + + WIN_BOOL m_fInitialized; //Something here? + LPUNKNOWN m_pObj; //The object here + LPSTORAGE m_pIStorage; //Sub-storage for tenant + ILockBytes * pTmpStorage; // temporary storage + + DWORD dwAspect; // new MM + //FORMATETC m_fe; //Used to create the object + DWORD m_dwState; //State flags + RECTL m_rcl; //Space of this object + CLSID m_clsID; //Object class (for statics) + WIN_BOOL m_fSetExtent; //Call SetExtent on next run + + class SvOutPlaceObject *m_pPG; //Pages window +// class CPages *m_pPG; //Pages window + + //CHAPTER17MOD + TENANTTYPE m_tType; //Type identifier + ULONG m_cRef; //We're an object now + LPOLEOBJECT m_pIOleObject; //IOleObject on m_pObj + LPVIEWOBJECT2 m_pIViewObject2; //IViewObject2 on m_pObj + ULONG m_grfMisc; //OLEMISC flags + WIN_BOOL m_fRepaintEnabled; //No redundant paints + + //Our interfaces + PCImpIOleClientSite m_pImpIOleClientSite; + PCImpIAdviseSink m_pImpIAdviseSink; + //End CHAPTER17MOD + + protected: + //CHAPTER17MOD + WIN_BOOL ObjectInitialize(LPUNKNOWN, DWORD, DWORD); + //WIN_BOOL ObjectInitialize(LPUNKNOWN, LPFORMATETC, DWORD); + //End CHAPTER17MOD + HRESULT CreateStatic(LPDATAOBJECT, LPFORMATETC + , LPUNKNOWN *); + + public: + CSO_Cont(DWORD, HWND, SvOutPlaceObject *); +// CSO_Cont(DWORD, HWND, CPages *); + virtual ~CSO_Cont(void); + + //CHAPTER17MOD + //Gotta have an IUnknown for delegation + STDMETHODIMP QueryInterface(REFIID, PPVOID); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + //End CHAPTER17MOD + + LPOLEOBJECT GetOleObj() const { return m_pIOleObject; } + CLSID GetCLSID(); + DWORD GetID(void); + String GetStorageName(); + //UINT GetStorageName(LPOLESTR); + //CHAPTER17MOD + //void StorageGet(LPSTORAGE *); + //End CHAPTER17MOD + UINT Create(TENANTTYPE, LPVOID, LPFORMATETC, PPOINTL + , LPSIZEL, SotStorage *, PPATRONOBJECT, DWORD); +// UINT Create(TENANTTYPE, LPVOID, LPFORMATETC, PPOINTL +// , LPSIZEL, LPSTORAGE, PPATRONOBJECT, DWORD); + WIN_BOOL Save(SotStorage * ) {return false;} + WIN_BOOL Load(SotStorage *, DWORD dwAspect, WIN_BOOL fSetExtend, RECTL & rcl ); +// WIN_BOOL Load(LPSTORAGE, PTENANTINFO); + void GetInfo(DWORD& rAspect, WIN_BOOL & rSetExtend ); +// void GetInfo(PTENANTINFO); + WIN_BOOL Open(SotStorage *); +// WIN_BOOL Open(LPSTORAGE); + void Close(WIN_BOOL); + WIN_BOOL Update(void); + void Destroy(SotStorage *); +// void Destroy(LPSTORAGE); + + void Select(WIN_BOOL); + //CHAPTER17MOD + void ShowAsOpen(WIN_BOOL); + void ShowYourself(void); + void AddVerbMenu(HMENU, UINT); + TENANTTYPE TypeGet(void); + void CopyEmbeddedObject(LPDATAOBJECT, LPFORMATETC + , PPOINTL); + void NotifyOfRename(LPTSTR, LPVOID); + //End CHAPTER17MOD + + WIN_BOOL Activate(LONG, HWND); + void Draw(HDC, DVTARGETDEVICE *, HDC, int, int + , WIN_BOOL, WIN_BOOL); + void Repaint(void); + void Invalidate(void); + + //CHAPTER17MOD + void ObjectClassFormatAndIcon(LPCLSID, LPWORD + , LPTSTR *, HGLOBAL *, LPTSTR *); + WIN_BOOL SwitchOrUpdateAspect(HGLOBAL, WIN_BOOL); + void EnableRepaint(WIN_BOOL); + //End CHAPTER17MOD + + void ObjectGet(LPUNKNOWN *); + void FormatEtcGet(LPFORMATETC, WIN_BOOL); + WIN_BOOL GetExtent(LPSIZEL); + void SizeGet(LPSIZEL, WIN_BOOL); + //CHAPTER17MOD + void SizeSet(LPSIZEL, WIN_BOOL, WIN_BOOL); + //End CHAPTER17MOD + void RectGet(LPRECTL, WIN_BOOL); + //CHAPTER17MOD + void RectSet(LPRECTL, WIN_BOOL, WIN_BOOL); + //End CHAPTER17MOD + BOOL GetMetaFile( long& nMapMode, Size& rSize, HMETAFILE& hMet ); + }; + + +typedef CSO_Cont *PCSO_Cont; + +//Return codes for Create +#define CREATE_FAILED 0 +#define CREATE_GRAPHICONLY 1 +#define CREATE_PLACEDOBJECT 2 + +} + + +#endif //_TENANT_H_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/ole/soole.h b/bf_so3/source/ole/soole.h new file mode 100644 index 000000000..ca20fb86c --- /dev/null +++ b/bf_so3/source/ole/soole.h @@ -0,0 +1,455 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#ifndef _SOOLE_H_ +#define _SOOLE_H_ + +#define INC_OLE2 +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <ole2.h> +#include <ole2ver.h> + +#ifdef WNT +#define WIN32ANSI +#endif + +#ifdef WIN32 +#include <oledlg.h> +#else +#include <ole2ui.h> +#endif + +#ifdef INC_CONTROLS +#define INC_AUTOMATION +#endif + +#ifdef INC_AUTOMATION +#ifndef WIN32 +#include <dispatch.h> +#include <olenls.h> +#else +#include <oleauto.h> +#endif +#endif + +#ifdef INC_CONTROLS +#include <olectl.h> +#ifndef INITGUIDS +#include <olectlid.h> +#endif +#endif + +#ifdef WIN32 +#include <tchar.h> +#ifdef UNICODE +#include <wchar.h> +#endif +#endif + +#ifndef WIN32 +#include <shellapi.h> +#include <malloc.h> +#endif + +#ifdef INC_CLASSLIB +extern "C" + { + #include <commdlg.h> + #ifndef WIN32 + #include <print.h> + #include <dlgs.h> + #endif + } + +#endif + + +namespace binfilter { +//Types that OLE2.H et. al. leave out + +#ifndef PPVOID +typedef LPVOID * PPVOID; +#endif //PPVOID +#define CCHPATHMAX 256 + + +#if defined(_OLE2_H_) || defined(_OLE2_H) //May not include ole2.h at all times. + +#ifndef PPOINTL +typedef POINTL * PPOINTL; +#endif //PPOINTL + + +#ifndef _WIN32 +#ifndef OLECHAR +typedef sal_Char OLECHAR; +typedef OLECHAR FAR* LPOLESTR; +typedef const OLECHAR FAR* LPCOLESTR; +#endif //OLECHAR +#endif //_WIN32 + + +//Useful macros. +#define SETFormatEtc(fe, cf, asp, td, med, li) \ + {\ + (fe).cfFormat=cf;\ + (fe).dwAspect=asp;\ + (fe).ptd=td;\ + (fe).tymed=med;\ + (fe).lindex=li;\ + } + +#define SETDefFormatEtc(fe, cf, med) \ + {\ + (fe).cfFormat=cf;\ + (fe).dwAspect=DVASPECT_CONTENT;\ + (fe).ptd=NULL;\ + (fe).tymed=med;\ + (fe).lindex=-1;\ + } + + +#define SETRECTL(rcl, l, t, r, b) \ + {\ + (rcl).left=l;\ + (rcl).top=t;\ + (rcl).right=r;\ + (rcl).bottom=b;\ + } + +#define SETSIZEL(szl, h, v) \ + {\ + (szl).cx=h;\ + (szl).cy=v;\ + } + + +#define RECTLFROMRECT(rcl, rc)\ + {\ + (rcl).left=(long)(rc).left;\ + (rcl).top=(long)(rc).top;\ + (rcl).right=(long)(rc).right;\ + (rcl).bottom=(long)(rc).bottom;\ + } + + +#define RECTFROMRECTL(rc, rcl)\ + {\ + (rc).left=(int)(rcl).left;\ + (rc).top=(int)(rcl).top;\ + (rc).right=(int)(rcl).right;\ + (rc).bottom=(int)(rcl).bottom;\ + } + + +#define POINTLFROMPOINT(ptl, pt) \ + { \ + (ptl).x=(long)(pt).x; \ + (ptl).y=(long)(pt).y; \ + } + + +#define POINTFROMPOINTL(pt, ptl) \ + { \ + (pt).x=(int)(ptl).x; \ + (pt).y=(int)(ptl).y; \ + } + +//Here's one that should be in windows.h +#define SETPOINT(pt, h, v) \ + {\ + (pt).x=h;\ + (pt).y=v;\ + } + +#define SETPOINTL(ptl, h, v) \ + {\ + (ptl).x=h;\ + (ptl).y=v;\ + } + +#endif //_OLE2_H_ + +#ifdef INC_AUTOMATION + +//Macros for setting DISPPARAMS structures +#define SETDISPPARAMS(dp, numArgs, pvArgs, numNamed, pNamed) \ + {\ + (dp).cArgs=numArgs;\ + (dp).rgvarg=pvArgs;\ + (dp).cNamedArgs=numNamed;\ + (dp).rgdispidNamedArgs=pNamed;\ + } + +#define SETNOPARAMS(dp) SETDISPPARAMS(dp, 0, NULL, 0, NULL) + +//Macros for setting EXCEPINFO structures +#define SETEXCEPINFO(ei, excode, src, desc, file, ctx, func, scd) \ + {\ + (ei).wCode=excode;\ + (ei).wReserved=0;\ + (ei).bstrSource=src;\ + (ei).bstrDescription=desc;\ + (ei).bstrHelpFile=file;\ + (ei).dwHelpContext=ctx;\ + (ei).pvReserved=NULL;\ + (ei).pfnDeferredFillIn=func;\ + (ei).scode=scd;\ + } + + +#define INITEXCEPINFO(ei) \ + SETEXCEPINFO(ei,0,NULL,NULL,NULL,0L,NULL,S_OK) + +#endif + + +/* + * State flags for IPersistStorage implementations. These + * are kept here to avoid repeating the code in all samples. + */ + +typedef enum + { + PSSTATE_UNINIT, //Uninitialized + PSSTATE_SCRIBBLE, //Scribble + PSSTATE_ZOMBIE, //No scribble + PSSTATE_HANDSOFF //Hand-off + } PSSTATE; + + +/* + * Identifers to describe which persistence model an object + * is using, along with a union type that holds on the the + * appropriate pointers that a client may need. + */ +typedef enum + { + PERSIST_UNKNOWN=0, + PERSIST_STORAGE, + PERSIST_STREAM, + PERSIST_STREAMINIT, + PERSIST_FILE + } PERSIST_MODEL; + +typedef struct + { + PERSIST_MODEL psModel; + union + { + IPersistStorage *pIPersistStorage; + IPersistStream *pIPersistStream; + #ifdef INC_CONTROLS + IPersistStreamInit *pIPersistStreamInit; + #endif + IPersistFile *pIPersistFile; + } pIP; + + } PERSISTPOINTER, *PPERSISTPOINTER; + + +//To identify a storage in which to save, load, or create. +typedef struct + { + PERSIST_MODEL psModel; + union + { + IStorage *pIStorage; + IStream *pIStream; + } pIS; + + } STGPOINTER, *PSTGPOINTER; + + + +//Type for an object-destroyed callback +typedef void (*PFNDESTROYED)(void); + + +//DeleteInterfaceImp calls 'delete' and NULLs the pointer +#define DeleteInterfaceImp(p)\ + {\ + if (NULL!=p)\ + {\ + delete p;\ + p=NULL;\ + }\ + } + + +//ReleaseInterface calls 'Release' and NULLs the pointer +#define ReleaseInterface(p)\ + {\ + if (NULL!=p)\ + {\ + p->Release();\ + p=NULL;\ + }\ + } + + +//OLE Documents Clipboard Formats + +#define CFSTR_EMBEDSOURCE TEXT("Embed Source") +#define CFSTR_EMBEDDEDOBJECT TEXT("Embedded Object") +#define CFSTR_LINKSOURCE TEXT("Link Source") +#define CFSTR_CUSTOMLINKSOURCE TEXT("Custom Link Source") +#define CFSTR_OBJECTDESCRIPTOR TEXT("Object Descriptor") +#define CFSTR_LINKSRCDESCRIPTOR TEXT("Link Source Descriptor") + + + +//Functions in the helper DLL, SOOLE.DLL + +//UI Effects +STDAPI_(void) UIDrawHandles(LPRECT, HDC, DWORD, UINT, BOOL); +STDAPI_(void) UIDrawShading(LPRECT, HDC, DWORD, UINT); +STDAPI_(void) UIShowObject(LPCRECT, HDC, BOOL); + +//For UIDrawHandles +#define UI_HANDLES_USEINVERSE 0x00000001L +#define UI_HANDLES_NOBORDER 0x00000002L +#define UI_HANDLES_INSIDE 0x00000004L +#define UI_HANDLES_OUTSIDE 0x00000008L + +//For UIDrawShading +#define UI_SHADE_FULLRECT 1 +#define UI_SHADE_BORDERIN 2 +#define UI_SHADE_BORDEROUT 3 + +//Coordinate Munging +STDAPI_(int) XformWidthInHimetricToPixels(HDC, int); +STDAPI_(int) XformWidthInPixelsToHimetric(HDC, int); +STDAPI_(int) XformHeightInHimetricToPixels(HDC, int); +STDAPI_(int) XformHeightInPixelsToHimetric(HDC, int); + +STDAPI_(void) XformRectInPixelsToHimetric(HDC, LPRECT, LPRECT); +STDAPI_(void) XformRectInHimetricToPixels(HDC, LPRECT, LPRECT); +STDAPI_(void) XformSizeInPixelsToHimetric(HDC, LPSIZEL, LPSIZEL); +STDAPI_(void) XformSizeInHimetricToPixels(HDC, LPSIZEL, LPSIZEL); + + +//Helpers +STDAPI_(void) StarObject_MetafilePictIconFree(HGLOBAL); +STDAPI StarObject_SwitchDisplayAspect(IUnknown *, LPDWORD, DWORD + , HGLOBAL, BOOL, BOOL, IAdviseSink *, BOOL *); +STDAPI StarObject_SetIconInCache(IUnknown *, HGLOBAL); +STDAPI_(UINT) StarObject_GetUserTypeOfClass(REFCLSID, UINT, LPTSTR + , UINT); +STDAPI StarObject_DoConvert(IStorage *, REFCLSID); +STDAPI_(LPTSTR) StarObject_CopyString(LPTSTR); +STDAPI_(HGLOBAL) StarObject_ObjectDescriptorFromOleObject(IOleObject * + , DWORD, POINTL, LPSIZEL); +STDAPI_(HGLOBAL) StarObject_AllocObjectDescriptor(CLSID, DWORD + , SIZEL, POINTL, DWORD, LPTSTR, LPTSTR); +STDAPI_(IStorage *) StarObject_CreateStorageOnHGlobal(DWORD); +STDAPI StarObject_GetLinkSourceData(IMoniker *, LPCLSID + , LPFORMATETC, LPSTGMEDIUM); +STDAPI_(void) StarObject_RegisterAsRunning(IUnknown *, IMoniker * + , DWORD, LPDWORD); +STDAPI_(void) StarObject_RevokeAsRunning(LPDWORD); +STDAPI_(void) StarObject_NoteChangeTime(DWORD, FILETIME *, LPTSTR); + + + +/* + * These are for ANSI compilations on Win32. Source code assumes + * a Win32 Unicode environment (or Win16 Ansi). These macros + * route Win32 ANSI compiled functions to wrappers which do the + * proper Unicode conversion. + */ + + +#ifdef WIN32ANSI +STDAPI StarObject_ConvertStringToANSI(LPCWSTR, LPSTR *); +STDAPI StarObject_StringFromCLSID(REFCLSID, LPSTR *); +STDAPI StarObject_StringFromGUID2(REFGUID, LPSTR, int); +STDAPI StarObject_ProgIDFromCLSID(REFCLSID, LPSTR *); + +STDAPI StarObject_ReadFmtUserTypeStg(IStorage *, CLIPFORMAT *, LPSTR *); +STDAPI StarObject_WriteFmtUserTypeStg(IStorage *, CLIPFORMAT, LPSTR); + +STDAPI StarObject_StgIsStorageFile(LPCSTR); +STDAPI StarObject_StgCreateDocfile(LPCSTR, DWORD, DWORD, IStorage **); +STDAPI StarObject_StgOpenStorage(LPCSTR, IStorage *, DWORD, SNB + , DWORD, IStorage **); + + +STDAPI StarObject_CreateFileMoniker(LPCSTR, LPMONIKER *); +STDAPI StarObject_CreateItemMoniker(LPCSTR, LPCSTR, LPMONIKER *); +STDAPI StarObject_MkParseDisplayName(LPBC, LPCSTR, ULONG *, LPMONIKER *); + +STDAPI StarObject_OleCreateLinkToFile(LPCSTR, REFIID, DWORD, LPFORMATETC + , LPOLECLIENTSITE, LPSTORAGE, LPVOID *); +STDAPI StarObject_OleCreateFromFile(REFCLSID, LPCSTR, REFIID + , DWORD, LPFORMATETC, LPOLECLIENTSITE, LPSTORAGE, LPVOID *); + +#ifdef skbdkbasdfbasbjdas +#undef StringFromCLSID +#define StringFromCLSID(c, pp) StarObject_StringFromCLSID(c, pp) + +#undef StringFromGUID2 +#define StringFromGUID2(r, p, i) StarObject_StringFromGUID2(r, p, i) + +#undef ProgIDFromCLSID +#define ProgIDFromCLSID(c, pp) StarObject_ProgIDFromCLSID(c, pp) + +#undef ReadFmtUserTypeStg +#define ReadFmtUserTypeStg(p, c, s) StarObject_ReadFmtUserTypeStg(p, c, s) + +#undef WriteFmtUserTypeStg +#define WriteFmtUserTypeStg(p, c, s) StarObject_WriteFmtUserTypeStg(p, c, s) + +#undef StgIsStorageFile +#define StgIsStorageFile(s) StarObject_StgIsStorageFile(s) + +#undef StgCreateDocfile +#define StgCreateDocfile(a, b, c, d) StarObject_StgCreateDocfile(a, b, c, d) + +#undef StgOpenStorage +#define StgOpenStorage(a,b,c,d,e,f) StarObject_StgOpenStorage(a,b,c,d,e,f) + +#undef CreateFileMoniker +#define CreateFileMoniker(p, i) StarObject_CreateFileMoniker(p, i) + +#undef MkParseDisplayName +#define MkParseDisplayName(b, p, u, i) StarObject_MkParseDisplayName(b, p, u, i) + +#undef OleCreateLinkToFile +#define OleCreateLinkToFile(s, i, d, fe, cs, st, pv) StarObject_OleCreateLinkToFile(s, i, d, fe, cs, st, pv) + +#undef OleCreateFromFile +#define OleCreateFromFile(c, s, i, d, fe, cs, st, pv) StarObject_OleCreateFromFile(c, s, i, d, fe, cs, st, pv) + +#endif + +#endif + +} + +#endif //_StarObject_H_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/ole/sosink.cxx b/bf_so3/source/ole/sosink.cxx new file mode 100644 index 000000000..fd64f5272 --- /dev/null +++ b/bf_so3/source/ole/sosink.cxx @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "socont.h" + + +namespace binfilter { + +/* + * CImpIAdviseSink::CImpIAdviseSink + * CImpIAdviseSink::~CImpIAdviseSink + * + * Parameters (Constructor): + * pSO_Cont PCSO_Cont of the tenant we're in. + * pUnkOuter LPUNKNOWN to which we delegate. + */ + +CImpIAdviseSink::CImpIAdviseSink(PCSO_Cont pSO_Cont + , LPUNKNOWN pUnkOuter) + { + m_cRef=0; + m_pTen=pSO_Cont; + m_pUnkOuter=pUnkOuter; + return; + } + +CImpIAdviseSink::~CImpIAdviseSink(void) + { + return; + } + + + + +/* + * CImpIAdviseSink::QueryInterface + * CImpIAdviseSink::AddRef + * CImpIAdviseSink::Release + * + * Purpose: + * IUnknown members for CImpIAdviseSink object. + */ + +STDMETHODIMP CImpIAdviseSink::QueryInterface(REFIID riid, PPVOID ppv) + { + return m_pUnkOuter->QueryInterface(riid, ppv); + } + + +STDMETHODIMP_(ULONG) CImpIAdviseSink::AddRef(void) + { + ++m_cRef; + return m_pUnkOuter->AddRef(); + } + +STDMETHODIMP_(ULONG) CImpIAdviseSink::Release(void) + { + --m_cRef; + return m_pUnkOuter->Release(); + } + + + + +/* + * CImpIAdviseSink::OnDataChange + * + * Unused since we don't IDataObject::Advise. + */ + +STDMETHODIMP_(void) CImpIAdviseSink::OnDataChange(LPFORMATETC + , LPSTGMEDIUM) + { + return; + } + + + + + + + +/* + * CImpIAdviseSink::OnViewChange + * + * Purpose: + * Notifes the advise sink that presentation data changed in the + * data object to which we're connected providing the right time + * to update displays using such presentations. + * + * Parameters: + * dwAspect DWORD indicating which aspect has changed. + * lindex LONG indicating the piece that changed. + * + * Return Value: + * None + */ + +STDMETHODIMP_(void) CImpIAdviseSink::OnViewChange(DWORD dwAspect + , LONG) + { + //Repaint only if this is the right aspect + //if (dwAspect==m_pTen->m_fe.dwAspect) + if (dwAspect==m_pTen->dwAspect) + { + m_pTen->m_pPG->SetModified(); + // VCL and OLE aspects have the same values + //m_pTen->m_pPG->ViewChanged( dwAspect ); + //m_pTen->m_pPG->m_fDirty=TRUE; + //m_pTen->Repaint(); + } + + return; + } + + + + + +/* + * CImpIAdviseSink::OnRename + * + * Purpose: + * Informs the advise sink that a linked object has been renamed. + * Generally only the OLE default handler cares about this. + * + * Parameters: + * pmk LPMONIKER providing the new name of the object + * + * Return Value: + * None + */ + +STDMETHODIMP_(void) CImpIAdviseSink::OnRename(LPMONIKER) + { + /* + * As a container this is unimportant to us since it really + * tells the handler's implementation of IOleLink that the + * object's moniker has changed. Since we get this call + * from the handler, we don't have to do anything ourselves. + */ + return; + } + + + + + + +/* + * CImpIAdviseSink::OnSave + * + * Purpose: + * Informs the advise sink that the OLE object has been saved + * persistently. The primary purpose of this is for containers + * that want to make optimizations for objects that are not in a + * saved state, so on this you have to disable such optimizations. + * + * Parameters: + * None + * + * Return Value: + * None + */ + +STDMETHODIMP_(void) CImpIAdviseSink::OnSave(void) + { + /* + * A Container has nothing to do here as this notification is + * only useful when we have an ADVFCACHE_ONSAVE advise set up, + * which we don't. So we ignore it. + */ + return; + } + + + + + +/* + * CImpIAdviseSink::OnClose + * + * Purpose: + * Informs the advise sink that the OLE object has closed and is + * no longer bound in any way. + * + * Parameters: + * None + * + * Return Value: + * None + */ + +STDMETHODIMP_(void) CImpIAdviseSink::OnClose(void) + { + /* + * This doesn't have much to do with us again as it's only + * used to notify the handler's IOleLink implementation of the + * change in the object. We don't have to do anything since + * we'll also get an IOleClientSite::OnShowWindow(FALSE) to + * tell us to repaint. + */ + + /* + * If we are dealing with an OLE 1.0 server it may not call + * IOleClientSite::OnShowWindow(FALSE) properly, so to protect + * ourselves we make sure the object is drawn as closed on + * this notification. + */ + m_pTen->ShowAsOpen(FALSE); + return; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/ole/uieffect.cxx b/bf_so3/source/ole/uieffect.cxx new file mode 100644 index 000000000..dadf23d46 --- /dev/null +++ b/bf_so3/source/ole/uieffect.cxx @@ -0,0 +1,267 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "soole.h" + +namespace binfilter { + + void DrawHandle(HDC hDC, int x, int y, UINT cSize, BOOL fInvert + , BOOL fDraw); + +//Hatch pattern brush bits +static WORD g_wHatchBmp[]={0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88}; + + +/* + * UIDrawHandles + * + * Purpose: + * Draw handles or/and boundary around Container Object when selected + * + * Parameters: + * pRect Dimensions of Container Object + * hDC HDC of the site + * dwFlags DWORD specifying how to draw the handles. + * cSize UINT size of handle box + * fDraw BOOL draw if TRUE, erase if FALSE + * + * Return Value: + * None + */ + +STDAPI_(void) UIDrawHandles(LPRECT pRect, HDC hDC, DWORD dwFlags, UINT cSize + , BOOL fDraw) + { + HBRUSH hBR; + RECT rc; + int bkmodeOld; + BOOL fInvert=(BOOL)(dwFlags & UI_HANDLES_USEINVERSE); + + CopyRect((LPRECT)&rc, pRect); + + bkmodeOld=SetBkMode(hDC, TRANSPARENT); + + if (dwFlags & UI_HANDLES_OUTSIDE) + InflateRect((LPRECT)&rc, cSize - 1, cSize - 1); + + //Draw the handles inside the rectangle boundary + DrawHandle(hDC, rc.left, rc.top, cSize, fInvert, fDraw); + DrawHandle(hDC, rc.left, rc.top+(rc.bottom-rc.top-cSize)/2, cSize, fInvert, fDraw); + DrawHandle(hDC, rc.left, rc.bottom-cSize, cSize, fInvert, fDraw); + DrawHandle(hDC, rc.left+(rc.right-rc.left-cSize)/2, rc.top, cSize, fInvert, fDraw); + DrawHandle(hDC, rc.left+(rc.right-rc.left-cSize)/2, rc.bottom-cSize, cSize, fInvert, fDraw); + DrawHandle(hDC, rc.right-cSize, rc.top, cSize, fInvert, fDraw); + DrawHandle(hDC, rc.right-cSize, rc.top+(rc.bottom-rc.top-cSize)/2, cSize, fInvert, fDraw); + DrawHandle(hDC, rc.right-cSize, rc.bottom-cSize, cSize, fInvert, fDraw); + + if (!(dwFlags & UI_HANDLES_NOBORDER)) + { + if (fDraw) + hBR=(HBRUSH)GetStockObject(BLACK_BRUSH); + else + hBR=(HBRUSH)GetStockObject(WHITE_BRUSH); + + FrameRect(hDC, pRect, hBR); + } + + SetBkMode(hDC, bkmodeOld); + } + + + +/* + * DrawHandle + * + * Purpose: + * Draw a handle box at the specified coordinate + * + * Parameters: + * hDC HDC to be drawn into + * x, y int upper left corner coordinate of the handle box + * cSize UINT size of handle box + * fInvert BOOL indicating to invert the rect or fill it + * fDraw BOOL draw if TRUE, erase if FALSE, + * ignored if fInvert is TRUE + * + * Return Value: + * None + */ + +void DrawHandle(HDC hDC, int x, int y, UINT cSize, BOOL fInvert + , BOOL fDraw) + { + HBRUSH hBR; + HBRUSH hBROld; + HPEN hPen; + HPEN hPenOld; + RECT rc; + + if (!fInvert) + { + if (fDraw) + { + hPen=(HPEN)GetStockObject(BLACK_PEN); + hBR=(HBRUSH)GetStockObject(BLACK_BRUSH); + } + else + { + hPen=(HPEN)GetStockObject(WHITE_PEN); + hBR=(HBRUSH)GetStockObject(WHITE_PEN); + } + + hPenOld=(HPEN)SelectObject(hDC, hPen); + hBROld=(HBRUSH)SelectObject(hDC, hBR); + Rectangle(hDC, x, y, x+cSize, y+cSize); + SelectObject(hDC, hPenOld); + SelectObject(hDC, hBROld); + } + else + { + rc.left=x; + rc.top=y; + rc.right=x + cSize; + rc.bottom=y + cSize; + InvertRect(hDC, (LPRECT)&rc); + } + + return; + } + + + +/* + * UIDrawShading + * + * Purpose: + * Draw a hatching across a rectangle, inside a rectangle, or + * outside a rectangle. + * + * Parameters: + * prc LPRECT containing the rectangle. + * hDC HDC on which to draw. + * dwFlags DWORD specifying how to draw the shading. + * cWidth UINT width of the border to draw. Ignored + * if dwFlags has UI_SHADE_FULLRECT. + * + * Return Value: + * None + */ + +STDAPI_(void) UIDrawShading(LPRECT prc, HDC hDC, DWORD dwFlags, UINT cWidth) + { + HBRUSH hBR; + HBRUSH hBROld; + HBITMAP hBM; + RECT rc; + UINT cx, cy; + COLORREF crText; + COLORREF crBk; + const DWORD dwROP=0x00A000C9L; //DPa + + if (NULL==prc || NULL==hDC) + return; + + hBM=CreateBitmap(8, 8, 1, 1, g_wHatchBmp); + hBR=CreatePatternBrush(hBM); + hBROld=(HBRUSH)SelectObject(hDC, hBR); + + rc=*prc; + cx=rc.right-rc.left; + cy=rc.bottom-rc.top; + + if (UI_SHADE_FULLRECT==dwFlags) + { + crText=SetTextColor(hDC, RGB(255, 255, 255)); + crBk=SetBkColor(hDC, RGB(0, 0, 0)); + PatBlt(hDC, rc.left, rc.top, cx, cy, dwROP); + } + else + { + if (UI_SHADE_BORDEROUT==dwFlags) + InflateRect((LPRECT)&rc, cWidth-1, cWidth-1); + + crText=SetTextColor(hDC, RGB(255, 255, 255)); + crBk=SetBkColor(hDC, RGB(0, 0, 0)); + PatBlt(hDC, rc.left, rc.top, cx, cWidth, dwROP); + PatBlt(hDC, rc.left, rc.top, cWidth, cy, dwROP); + PatBlt(hDC, rc.right-cWidth, rc.top, cWidth, cy, dwROP); + PatBlt(hDC, rc.left, rc.bottom-cWidth, cx, cWidth, dwROP); + } + + SetTextColor(hDC, crText); + SetBkColor(hDC, crBk); + SelectObject(hDC, hBROld); + DeleteObject(hBR); + DeleteObject(hBM); + + return; + } + + + + +/* + * UIShowObject + * + * Purpose: + * Draw the ShowObject effect around an embedded or linked + * object. + * + * Parameters: + * prc LPRECT to draw around. + * hDC HDC on which to draw. + * fLink BOOL specifying a linked (TRUE) or + * embedded (FALSE) object + * + * Return Value: + * None + */ + +STDAPI_(void) UIShowObject(LPCRECT prc, HDC hDC, BOOL fLink) + { + HPEN hPen; + HPEN hPenOld; + HBRUSH hBROld; + + if (NULL==prc || NULL==hDC) + return; + + hPen=fLink ? CreatePen(PS_DASH, 1, RGB(0,0,0)) + : (HPEN)GetStockObject(BLACK_PEN); + + if (!hPen) + return; + + hPenOld=(HPEN)SelectObject(hDC, hPen); + hBROld=(HBRUSH)SelectObject(hDC, GetStockObject(NULL_BRUSH)); + + Rectangle(hDC, prc->left, prc->top, prc->right, prc->bottom); + + SelectObject(hDC, hPenOld); + SelectObject(hDC, hBROld); + + if (fLink) + DeleteObject(hPen); + + return; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/persist/binddata.cxx b/bf_so3/source/persist/binddata.cxx new file mode 100644 index 000000000..044875f3a --- /dev/null +++ b/bf_so3/source/persist/binddata.cxx @@ -0,0 +1,558 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define _BINDDATA_CXX + +#include <bf_svtools/bf_solar.h> +#include <tools/shl.hxx> +#include <tools/urlobj.hxx> +#include <tools/wldcrd.hxx> + +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> + +#include <com/sun/star/frame/XConfigManager.hpp> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> + +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> + +#include <com/sun/star/uno/XInterface.hpp> + +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Reference.h> + +#include <cppuhelper/weak.hxx> + +#include <binddata.hxx> +#include <bf_so3/transprt.hxx> +#include <transuno.hxx> +#include <bf_so3/so2dll.hxx> + +using namespace com::sun::star::beans; +using namespace com::sun::star::frame; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; +using namespace cppu; + +using rtl::OUString; + +namespace binfilter { + +typedef com::sun::star::uno::XInterface ifc_type; + +#define SOAPP() SoDll::GetOrCreate() + +/*======================================================================== + * + * SvBindingData_Impl interface. + * + *======================================================================*/ +class SvBindingData_Impl : + public OWeakObject, + public XPropertyChangeListener +{ +public: + SvBindingData_Impl ( + const Reference<XMultiServiceFactory> &rxFactory); + + void dispose (void); + + sal_Bool hasHttpCache (void); + sal_Bool hasFtpProxy (void); + sal_Bool shouldUseFtpProxy (const String &rUrl); + + /** XInterface. + */ + virtual Any SAL_CALL queryInterface ( + const Type &rType) throw(RuntimeException); + + virtual void SAL_CALL acquire (void) throw(); + + virtual void SAL_CALL release (void) throw(); + + /** XEventEventListener. + */ + void SAL_CALL disposing ( + const EventObject &rEvent) throw(RuntimeException); + + /** XPropertyChangeListener. + */ + virtual void SAL_CALL propertyChange ( + const PropertyChangeEvent &rEvent) throw(RuntimeException); + +protected: + virtual ~SvBindingData_Impl (void); + + Reference<ifc_type> getConfigManager_Impl (void); + +private: + /** Representation. + */ + Reference<XMultiServiceFactory> m_xFactory; + Reference<ifc_type> m_xManager; + Reference<XContent> m_xCache; + + String m_aNoProxyList; + String m_aFtpProxyName; + sal_uInt16 m_nFtpProxyPort; + sal_uInt16 m_nProxyType; + + /** Initialization. + */ + String readConfigKey_Impl ( + const Reference<XRegistryKey> &rxRootKey, + const String &rKeyName); + + void readConfigManager_Impl (void); + void initConfigManager_Impl (void); + + /** Not implemented. + */ + SvBindingData_Impl (const SvBindingData_Impl&); + SvBindingData_Impl& operator= (const SvBindingData_Impl&); +}; + +/*======================================================================== + * + * SvBindingData implementation. + * + *======================================================================*/ +/* + * SvBindingData. + */ +SvBindingData::SvBindingData (void) + : m_pImpl (NULL) +{ + Reference<XMultiServiceFactory> xFactory ( + SvBindingTransport_Impl::getProcessServiceFactory(), UNO_QUERY); + if (xFactory.is()) + { + m_pImpl = new SvBindingData_Impl (xFactory); + m_pImpl->acquire(); + } +} + +/* + * ~SvBindingData. + */ +SvBindingData::~SvBindingData (void) +{ + if (m_pImpl) + { + m_pImpl->dispose(); + m_pImpl->release(); + } +} + +/* + * Get. + */ +SvBindingData* SvBindingData::Get (void) +{ + SvBindingData *&rpData = SOAPP()->pBindingData; + if (rpData == NULL) + { + // Allocate data. + rpData = new SvBindingData(); + + // Register transport factories. + new SvLockBytesTransportFactory; + new CntTransportFactory; + } + return rpData; +} + +/* + * Delete. + */ +void SvBindingData::Delete (void) +{ + SvBindingData *&rpData = SOAPP()->pBindingData; + DELETEZ (rpData); +} + +/* + * HasHttpCache. + */ +BOOL SvBindingData::HasHttpCache (void) +{ + if (m_pImpl) + return m_pImpl->hasHttpCache(); + else + return FALSE; +} + +/* + * ShouldUseFtpProxy. + */ +BOOL SvBindingData::ShouldUseFtpProxy (const String &rUrl) +{ + if (m_pImpl) + return m_pImpl->shouldUseFtpProxy (rUrl); + else + return FALSE; +} + +/*======================================================================== + * + * SvBindingData_Impl internals. + * + *======================================================================*/ +#define U2S(u) OUStringToString((u), CHARSET_SYSTEM) + +#define STR_KEY_INET_PROXYTYPE "INet/ProxyType" +#define STR_KEY_INET_NOPROXY "INet/NoProxy" +#define STR_KEY_INET_FTPPROXYNAME "INet/FTPProxyName" +#define STR_KEY_INET_FTPPROXYPORT "INet/FTPProxyPort" + +#define STRL_KEY_INET_PROXYTYPE "inet/proxytype" +#define STRL_KEY_INET_NOPROXY "inet/noproxy" +#define STRL_KEY_INET_FTPPROXYNAME "inet/ftpproxyname" +#define STRL_KEY_INET_FTPPROXYPORT "inet/ftpproxyport" + +#define INIMANAGER_SERVICE_NAME \ + "com.sun.star.config.SpecialConfigManager" + +/*======================================================================== + * + * SvBindingData_Impl implementation. + * + *======================================================================*/ +/* + * SvBindingData_Impl. + */ +SvBindingData_Impl::SvBindingData_Impl ( + const Reference<XMultiServiceFactory> &rxFactory) + : m_xFactory (rxFactory), + m_xCache (NULL), + m_nFtpProxyPort (0), + m_nProxyType (0) +{ +} + +/* + * ~SvBindingData_Impl. + */ +SvBindingData_Impl::~SvBindingData_Impl (void) +{ +} + +/* + * hasHttpCache. + */ +sal_Bool SvBindingData_Impl::hasHttpCache (void) +{ + if (!m_xCache.is()) + { + m_xCache = SvBindingTransport_Impl::createContent ( + OUString( RTL_CONSTASCII_USTRINGPARAM( "private:httpcache" ))); + + Reference<XCommandProcessor> xProcessor (m_xCache, UNO_QUERY); + if (xProcessor.is()) + { + Sequence<Property> aProps(3); + aProps[0].Handle = aProps[1].Handle = aProps[2].Handle = -1; + + aProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ConnectionLimit" )); + aProps[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SizeLimit" )); + aProps[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" )); + + SvBindingTransport_Impl::getProperties (xProcessor, aProps); + } + } + return m_xCache.is(); +} + +/* + * hasFtpProxy. + */ +sal_Bool SvBindingData_Impl::hasFtpProxy (void) +{ + Reference<XConfigManager> xManager (getConfigManager_Impl(), UNO_QUERY); + if (!xManager.is()) + return sal_False; + + if (!((m_aFtpProxyName.Len() > 0) && (m_nFtpProxyPort > 0))) + return sal_False; + + return (m_nProxyType > 0); +} + +/* + * shouldUseFtpProxy. + */ +sal_Bool SvBindingData_Impl::shouldUseFtpProxy (const String &rUrl) +{ + // Check URL. + INetURLObject aURL (rUrl); + if (!(aURL.GetProtocol() == INET_PROT_FTP)) + return sal_False; + + if (!hasFtpProxy()) + return sal_False; + + if (m_aNoProxyList.Len()) + { + // Setup Endpoint. + String aEndpoint (aURL.GetHost()); + if (!aEndpoint.Len()) + return sal_False; + + aEndpoint += ':'; + if (aURL.HasPort()) + aEndpoint += String::CreateFromInt64(aURL.GetPort()); + else + aEndpoint.AppendAscii( "21" ); + + // Match NoProxyList. + USHORT i, n = m_aNoProxyList.GetTokenCount (';'); + for (i = 0; i < n; i++) + { + String aWildToken (m_aNoProxyList.GetToken (i, ';')); + if (aWildToken.Search(':') == STRING_NOTFOUND) + aWildToken.AppendAscii( ":*" ); + + WildCard aWildCard (aWildToken); + if (aWildCard.Matches (aEndpoint)) + return sal_False; + } + } + return sal_True; +} + +/* + * XInterface: queryInterface. + */ +Any SAL_CALL SvBindingData_Impl::queryInterface ( + const Type &rType) throw(RuntimeException) +{ + Any aRet (cppu::queryInterface ( + rType, + (static_cast< XEventListener* >(this)), + (static_cast< XPropertyChangeListener* >(this)))); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface (rType); +} + +/* + * XInterface: acquire. + */ +void SAL_CALL SvBindingData_Impl::acquire (void) throw() +{ + OWeakObject::acquire(); +} + +/* + * XInterface: release. + */ +void SAL_CALL SvBindingData_Impl::release (void) throw() +{ + OWeakObject::release(); +} + +/* + * XEventEventListener: disposing. + */ +void SAL_CALL SvBindingData_Impl::disposing ( + const EventObject & ) throw(RuntimeException) +{ + m_xManager = NULL; +} + +/* + * XPropertyChangeListener: propertyChange. + */ +void SAL_CALL SvBindingData_Impl::propertyChange ( + const PropertyChangeEvent &rEvent) throw(RuntimeException) +{ + OUString aKey (rEvent.PropertyName.toAsciiLowerCase()); + if (aKey.compareToAscii (STRL_KEY_INET_PROXYTYPE) == 0) + { + OUString aNewValue; + if (rEvent.NewValue >>= aNewValue) + m_nProxyType = (USHORT)aNewValue.toInt32(); + return; + } + if (aKey.compareToAscii (STRL_KEY_INET_NOPROXY) == 0) + { + OUString aNewValue; + if (rEvent.NewValue >>= aNewValue) + m_aNoProxyList = String( aNewValue ); + return; + } + if (aKey.compareToAscii (STRL_KEY_INET_FTPPROXYNAME) == 0) + { + OUString aNewValue; + if (rEvent.NewValue >>= aNewValue) + m_aFtpProxyName = String( aNewValue ); + return; + } + if (aKey.compareToAscii (STRL_KEY_INET_FTPPROXYPORT) == 0) + { + OUString aNewValue; + if (rEvent.NewValue >>= aNewValue) + m_nFtpProxyPort = (USHORT)aNewValue.toInt32(); + return; + } +} + +/* + * getConfigManager_Impl. + */ +Reference<ifc_type> SvBindingData_Impl::getConfigManager_Impl (void) +{ + if (!m_xManager.is() && m_xFactory.is()) + { + try + { + m_xManager = m_xFactory->createInstance ( + OUString(RTL_CONSTASCII_USTRINGPARAM (INIMANAGER_SERVICE_NAME))); + if (m_xManager.is()) + { + readConfigManager_Impl(); + initConfigManager_Impl(); + } + } + catch (Exception) + { + } + } + return m_xManager; +} + +/* + * readConfigKey_Impl. + */ +String SvBindingData_Impl::readConfigKey_Impl ( + const Reference<XRegistryKey> &rxRootKey, + const String &rKeyName) +{ + if (rxRootKey.is()) + { + try + { + Reference<XRegistryKey> xKey ( + rxRootKey->openKey (rKeyName)); + if (xKey.is()) + return xKey->getStringValue(); + } + catch (InvalidValueException) + { + } + } + return String(); +} + +/* + * readConfigManager_Impl. + */ +void SvBindingData_Impl::readConfigManager_Impl (void) +{ + Reference<XSimpleRegistry> xRegistry (m_xManager, UNO_QUERY); + if (xRegistry.is()) + { + try + { + Reference<XRegistryKey> xRootKey (xRegistry->getRootKey()); + if (xRootKey.is()) + { + m_aNoProxyList = readConfigKey_Impl ( + xRootKey, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( STR_KEY_INET_NOPROXY ) ) ); + m_aFtpProxyName = readConfigKey_Impl ( + xRootKey, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( STR_KEY_INET_FTPPROXYNAME ) ) ); + m_nFtpProxyPort = (USHORT)readConfigKey_Impl ( + xRootKey, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( STR_KEY_INET_FTPPROXYPORT ) ) ).ToInt32(); + m_nProxyType = (USHORT)readConfigKey_Impl ( + xRootKey, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( STR_KEY_INET_PROXYTYPE ) ) ).ToInt32(); + } + } + catch (InvalidRegistryException) + { + } + } +} + +/* + * initConfigManager_Impl. + */ +void SvBindingData_Impl::initConfigManager_Impl (void) +{ + Reference<XConfigManager> xConfig (m_xManager, UNO_QUERY); + if (xConfig.is()) + { + try + { + xConfig->addPropertyChangeListener ( + OUString(RTL_CONSTASCII_USTRINGPARAM (STR_KEY_INET_PROXYTYPE)), this); + xConfig->addPropertyChangeListener ( + OUString(RTL_CONSTASCII_USTRINGPARAM (STR_KEY_INET_NOPROXY)), this); + xConfig->addPropertyChangeListener ( + OUString(RTL_CONSTASCII_USTRINGPARAM (STR_KEY_INET_FTPPROXYNAME)), this); + xConfig->addPropertyChangeListener ( + OUString(RTL_CONSTASCII_USTRINGPARAM (STR_KEY_INET_FTPPROXYPORT)), this); + } + catch (Exception) + { + } + } +} + +/* + * dispose. + */ +void SvBindingData_Impl::dispose (void) +{ + Reference<XConfigManager> xConfig (m_xManager, UNO_QUERY); + if (xConfig.is()) + { + try + { + xConfig->removePropertyChangeListener ( + OUString(RTL_CONSTASCII_USTRINGPARAM (STR_KEY_INET_PROXYTYPE)), this); + xConfig->removePropertyChangeListener ( + OUString(RTL_CONSTASCII_USTRINGPARAM (STR_KEY_INET_NOPROXY)), this); + xConfig->removePropertyChangeListener ( + OUString(RTL_CONSTASCII_USTRINGPARAM (STR_KEY_INET_FTPPROXYNAME)), this); + xConfig->removePropertyChangeListener ( + OUString(RTL_CONSTASCII_USTRINGPARAM (STR_KEY_INET_FTPPROXYPORT)), this); + } + catch (Exception) + { + } + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/persist/makefile.mk b/bf_so3/source/persist/makefile.mk new file mode 100644 index 000000000..a6c15578b --- /dev/null +++ b/bf_so3/source/persist/makefile.mk @@ -0,0 +1,56 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. +SUBPRJ=..$/.. + +PRJINC=$(SUBPRJ) + +PRJNAME=binfilter +TARGET=so3_persist + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(SUBPRJ)$/util$/makefile.pmk + +.IF "$(NO_DLL)" == "NO_DLL" +SLO=$(OBJ) +.ENDIF + + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/binddata.obj \ + $(SLO)$/persist.obj \ + $(SLO)$/svstor.obj \ + $(SLO)$/transbnd.obj \ + $(SLO)$/transprt.obj \ + $(SLO)$/transuno.obj + +.IF "$(NO_DLL)" == "NO_DLL" +OBJFILES=$(SLOFILES) +SLOFILES= +.ENDIF + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/bf_so3/source/persist/persist.cxx b/bf_so3/source/persist/persist.cxx new file mode 100644 index 000000000..641b12692 --- /dev/null +++ b/bf_so3/source/persist/persist.cxx @@ -0,0 +1,1356 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + +#include <bf_so3/persist.hxx> +#include <bf_so3/svstor.hxx> +#include <bf_so3/embobj.hxx> +#include <bf_so3/pseudo.hxx> // fuer Hack +#include "bf_so3/soerr.hxx" // fuer Hack +#include "bf_so3/outplace.hxx" // im- export + +#include <sot/storinfo.hxx> +#include <sot/formats.hxx> + +#include <rtl/strbuf.hxx> + +#include <tools/debug.hxx> +#include <bf_tools/string.hxx> + +#include <unotools/ucbhelper.hxx> +#include <unotools/tempfile.hxx> + +namespace binfilter { + +/************** class SvInfoObject ***************************************/ +SV_IMPL_PERSIST1(SvInfoObject,SvPersistBase) + +class SvInfoObject_Impl +{ +public: + String aRealStorageName; + const String& GetRealStorageName() {return aRealStorageName;} + void SetRealStorageName( const String& rName ) + { + if ( aRealStorageName.Len() ) + ::utl::UCBContentHelper::Kill( aRealStorageName ); + aRealStorageName=rName; + } +}; + +SvInfoObject::SvInfoObject() + : pImp( new SvInfoObject_Impl ) + , bDeleted( FALSE ) +{ +} + +SvInfoObject::SvInfoObject( SvPersist * pObj, const String & rName ) + : pImp( new SvInfoObject_Impl ) + , bDeleted( FALSE ) +{ + SetObj( pObj ); + aObjName = rName; +} + +SvInfoObject::SvInfoObject( const String& rObjName, + const SvGlobalName& rClassName ) + : pImp( new SvInfoObject_Impl ) + , bDeleted( FALSE ) +{ + aObjName = rObjName; + aSvClassName = rClassName; +} + +SvInfoObject::~SvInfoObject() +{ + pImp->SetRealStorageName( String() ); + delete pImp; +} + +SvInfoObjectRef SvInfoObject::CreateCopy() const +{ + SvCreateInstancePersist pFunc = SOAPP->aInfoClassMgr.Get( GetClassId() ); + SvInfoObject* pI; + SvPersistBase* pB; + (*pFunc)(&pB); + + pI = PTR_CAST(SvInfoObject,pB); + DBG_ASSERT( pI, "cannot cast" ); + SvInfoObjectRef xI( pI ); + xI->Assign( this ); + return xI; +} + +void SvInfoObject::Assign( const SvInfoObject * pObj ) +{ + aObjName = pObj->GetObjName(); + aStorName = pObj->GetStorageName(); + pImp->SetRealStorageName( pObj->pImp->GetRealStorageName() ); + aSvClassName = pObj->GetClassName(); +} + +#define INFO_OBJECT_VER_MIN (BYTE)0 +#define INFO_OBJECT_VER_AKT (BYTE)1 + +void SvInfoObject::Load( SvPersistStream & rStm ) +{ + BYTE nVers = 0; + rStm >> nVers; + // wegen Warning unter OS2 auskommentiert + DBG_ASSERT( /*nVers >= INFO_OBJECT_VER_MIN &&*/ + nVers <= INFO_OBJECT_VER_AKT, + "SvInfoObject version conflict" ); + if( nVers > INFO_OBJECT_VER_AKT ) + rStm.SetError( SVSTREAM_WRONGVERSION ); + else + { + aStorName = rStm.ReadUniOrByteString( osl_getThreadTextEncoding() ); + aObjName = rStm.ReadUniOrByteString( osl_getThreadTextEncoding() ); + if( !aObjName.Len() ) + aObjName = aStorName; + rStm >> aSvClassName; + if( aSvClassName == *SvInPlaceObject::ClassFactory() + || aSvClassName == *SvEmbeddedObject::ClassFactory() ) + { + // use SvOutPlaceObject class as ole wrapper + aSvClassName = *SvOutPlaceObject::ClassFactory(); + } + if(nVers > 0) + rStm >> bDeleted; + } +} + +void SvInfoObject::Save( SvPersistStream & ) {} + +void SvInfoObject::SetObj( SvPersist * pObj ) +{ + aObj = pObj; + if( pObj ) + aSvClassName = *pObj->GetSvFactory(); +} + +String SvInfoObject::GetObjName() const +{ + return aObjName; +} + +String SvInfoObject::GetStorageName() const +{ + if( aStorName.Len() ) + return aStorName; + return aObjName; +} + +SvGlobalName SvInfoObject::GetClassName() const +{ + if( GetPersist() ) + ((SvInfoObject *)this)->aSvClassName = *GetPersist()->GetSvFactory(); + return aSvClassName; +} + +void SvInfoObject::SetDeleted( BOOL bDel ) +{ + if( bDel == bDeleted ) + return; + + bDeleted = bDel; + + if( aObj.Is() ) + { + if ( bDel && !pImp->GetRealStorageName().Len() && !aObj->IsHandsOff() ) + { + SvStorageRef aStor = aObj->GetStorage(); + String aRealName = ::utl::TempFile().GetURL(); + BOOL bKill = TRUE; + SvStorageRef aNewStor = new SvStorage( !aStor->IsOLEStorage(), aRealName, STREAM_STD_READWRITE, 0 ); + if( aNewStor->GetError() == SVSTREAM_OK ) + { + bool bRet; + if( aObj->IsModified() ) + { + bRet = false; + } + else + { + bRet = aStor->CopyTo( aNewStor ); + } + + if( bRet ) + { + aObj->DoHandsOff(); + if(false) + { + pImp->SetRealStorageName( aNewStor->GetName() ); + bKill = FALSE; + } + else + { + // was aObj->DoSaveCompleted(); but return value is not checked + } + } + } + + if ( bKill ) + ::utl::UCBContentHelper::Kill( aRealName ); + + } + + if( aObj->IsEnableSetModified() == bDel ) + { + aObj->EnableSetModified( !bDel ); + } + } +} + +//==================class SvObjectContainer================================ +SV_IMPL_FACTORY(SvObjectContainerFactory) + { + } +}; +TYPEINIT1(SvObjectContainerFactory,SvFactory); + +SO2_IMPL_STANDARD_CLASS1_DLL(SvObjectContainer,SvObjectContainerFactory,SvObject, + 0x96dee2a1, 0x62f6, 0x11cf, + 0x89, 0xca, 0x0, 0x80, 0x29, 0xe4, 0xb0, 0xb1 ) + +::IUnknown * SvObjectContainer::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +SvObjectContainer::SvObjectContainer() +/* [Beschreibung] + + Konstruktor der Klasse SvObjectContainer. +*/ +{ +} + +SvObjectContainer::~SvObjectContainer() +/* [Beschreibung] + + Destruktor der Klasse SvObjectContainer. +*/ +{ + // Parent haelt immer Referenz, deswegen muss der das Objekt + // schon Removed sein +} + +//==============class SvPersist============================================ +SV_IMPL_FACTORY(SvPersistFactory) + { + } +}; +TYPEINIT1(SvPersistFactory,SvFactory); + +SO2_IMPL_STANDARD_CLASS1_DLL(SvPersist,SvPersistFactory,SvObjectContainer, + 0xC24CC4E0L, 0x73DF, 0x101B, + 0x80,0x4C,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD ) + +::IUnknown * SvPersist::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +SvPersist::SvPersist() + : bIsModified ( FALSE ) + , bIsInit ( FALSE ) + , bOpSave ( FALSE ) + , bOpSaveAs ( FALSE ) + , bSaveExtern ( FALSE ) + , bOpHandsOff ( FALSE ) + , bCreateTempStor ( FALSE ) + , bSaveFailed ( FALSE ) + , bEnableSetModified( TRUE ) + , bIsObjectShell ( FALSE ) + , nModifyCount ( 0 ) // Anzahl der modifizierten Childs und sich selbst + , pParent ( NULL ) // kein zusaetzlicher RefCount + , pChildList ( NULL ) + , aModifiedTime ( Time::EMPTY ) +{ +} + +SvPersist::~SvPersist() +{ + // Parent haelt immer Referenz, deswegen muss der das Objekt + // schon Removed sein + dtorClear(); +} + +#ifdef DBG_UTIL +void SvPersist::AssertInit() const +{ + DBG_ASSERT( bIsInit, "super class SvPersist: call InitNew or Load bevor other calls" ); +} +#endif + +void SvPersist::FillClass +( + SvGlobalName * pClassName, /* Der Typ der Klasse */ + ULONG * pFormat, /* Das Dateiformat in dem geschrieben wird */ + String * pAppName, /* Der Applikationsname */ + String * pFullTypeName, /* Der genaue Name des Typs */ + String * pShortTypeName, /* Der kurze Name des Typs */ + long /*nFileFormat */ /* F"ur dieses Office-Format sollen die + Parameter gef"ullt werden */ +) const +/* [Beschreibung] + + Diese Methode liefert Informationen "uber den Typ und das Dateiformat + des Objektes. Alle Parameter werden von der Methode gefuellt. + + [R"uckgabewert] + + *pClassName Liefert den Typ-Identifier des Objektes. + *pFormat Die FormatId des Storages. + *pAppName Den sprachabh"angigen Applikationsnamen. + *pFullTypeName Den sprachabh"angigen Namen des Typs. + *pShortTypeName Den kurzen sprachabh"angigen Namen des Typs. Er darf + nicht l"anger als 15 Zeichen sein. + + [Anmerkung] + + F"uer externe Objekte ist pAppName und pShortName leer. + + [Beispiel] + + MyClass::FillClass( ... ) + { + *pClassName = *SvFactory::GetSvFactory(); // keine emulation + *pFormat = nMyDocFormat; + *pAppName = "StarDivison Calc 3.0"; + *pFullTypeName = "StarDivison Calc 3.0 Tabelle"; + *pShortTypeName = "Tabelle"; + } +*/ +{ + *pFormat = 0; + *pFullTypeName = *pShortTypeName = *pAppName = String(); + *pClassName = SvGlobalName(); + + if( Owner() ) + *pClassName = *GetSvFactory(); +} + +void SvPersist::SetupStorage( SvStorage * pStor ) const +{ + SvUniqueName aName; + String aFullTypeName, aShortTypeName, aAppName; + ULONG nClipFormat; + + // this code is used in the binfilter module only + // this module will not be made aware of any new file formats + ULONG nVersion = pStor->GetVersion(); + if ( nVersion > SOFFICE_FILEFORMAT_60 ) + { + nVersion = SOFFICE_FILEFORMAT_60; + pStor->SetVersion( nVersion ); + } + + FillClass( &aName, &nClipFormat, &aAppName, + &aFullTypeName, &aShortTypeName, pStor->GetVersion() ); + pStor->SetClass( aName, nClipFormat, aShortTypeName ); +} + +SvInfoObjectMemberList * SvPersist::GetInfoList() +{ + if( !pChildList ) + pChildList = new SvInfoObjectMemberList(); + return pChildList; +} + +#ifdef _NO_MODIFY_ADVISE +void SvPersist::SetModifiedFormat( ULONG nFormat ) +{ + if( !Owner() ) + { // sonst wird das durch die Baumstruktur erledigt + if( aAdvSink.Is() ) + { + DBG_ASSERT( !nFormat, "SvPersist::SetModifiedFormat: double set" ); + SvAdviseRef aAdv( this ); + aAdv->RemoveAdvise( &aAdvSink, ADVISE_DATA ); + aAdvSink.Clear(); + } + if( nFormat ) + { + SvAdviseRef aAdv( this ); + if( aAdv.Is() ) + { // Es kann ein Link gesetzt werden + aAdvSink = new SvPersistAdviseSink( this ); + aAdv->AddDataAdvise( &aAdvSink, SvDataType( nFormat ), + ADVISEMODE_NODATA ); + return; + } + DBG_ASSERT( aAdv.Is(), " cannot install data advise" ); + } + } +} +#endif + +BOOL SvPersist::Insert( SvInfoObject * pInfoObj ) +{ + ASSERT_INIT() + SvInfoObjectRef aRef( pInfoObj ); + + DBG_ASSERT( pInfoObj->GetObjName().Len(), + "Try to Insert Object without name" ); + + if( !GetInfoList() ) + return FALSE; // es konnte keine Liste erstellt werden + + SvPersist * pChild = pInfoObj->GetPersist(); + + if( pChild ) + { + // als erstes, wegen Patch in IsModified + if( pChild->Owner() && pChild->IsModified() ) + // modify-Zaehler fuer Child raufzaehlen + CountModified( TRUE ); + + if( pChild->pParent ) + // Aus altem Parent entfernen + pChild->pParent->Remove( pChild ); + + pChild->pParent = this; // kein zusaetzlicher RefCount + } + + pChildList->Append( pInfoObj ); + SetModified( TRUE ); + + return TRUE; +} + +BOOL SvPersist::Move( SvInfoObject * pInfoObj, const String & rStorName, BOOL bCopyStorage ) +{ + ASSERT_INIT() + SvInfoObjectRef aRef( pInfoObj ); + DBG_ASSERT( pInfoObj->GetObjName().Len(), "Try to Move Object without name" ); + + BOOL bRet = TRUE; + if( !GetInfoList() ) + bRet = FALSE; + + SvPersist * pChild = pInfoObj->GetPersist(); + if( !pChild ) + bRet = FALSE; + + if( bRet && ( this != pChild->pParent || !GetStorage()->IsStorage( rStorName ) ) ) + { + bRet = FALSE; + String aRealName; + SvPseudoObjectRef xPO( pChild ); + if ( !GetStorage()->IsOLEStorage() && xPO.Is() && ( xPO->GetMiscStatus() & SVOBJ_MISCSTATUS_SPECIALOBJECT ) ) + { + (void)bCopyStorage; + // save in binary format - there is no other format ! + DBG_ASSERT( !bCopyStorage, "Impossible to copy storage!" ); + aRealName = ::utl::TempFile().GetURL(); + SvStorageRef aNewStor( new SvStorage( FALSE, aRealName, STREAM_STD_READWRITE, 0 ) ); + } + else + { + bRet = ImplCopy( pChild, rStorName, TRUE ); + } + + if( bRet ) + { + pInfoObj->pImp->SetRealStorageName( aRealName ); + bRet = Insert( pInfoObj ); + } + else if ( aRealName.Len() ) + ::utl::UCBContentHelper::Kill( aRealName ); + } + + return bRet; +} + +SvPersistRef SvPersist::CopyObject( const String& rObjName, const String& rNewName, SvPersist * pSrc ) +{ + SvPersistRef xNewObject; + SvPersist *pSrcPersist = ( pSrc ? pSrc : this ); + SvInfoObject *pOld = pSrcPersist->Find( rObjName ); + if( pOld ) + { + SvInfoObjectRef xNewInfo( pOld->CreateCopy() ); + + if ( pOld->GetPersist() ) + { + SvEmbeddedInfoObject* pI = PTR_CAST( SvEmbeddedInfoObject, pOld ); + SvEmbeddedObjectRef xEmbObj( pOld->GetPersist() ); + if ( pI && xEmbObj.Is() ) + pI->SetInfoVisArea( xEmbObj->GetVisArea() ); + } + + SvPersistRef xOldObject( pSrcPersist->GetObject( rObjName ) ); + SvPseudoObjectRef xPO( xOldObject ); + if ( !GetStorage()->IsOLEStorage() && xPO.Is() && ( xPO->GetMiscStatus() & SVOBJ_MISCSTATUS_SPECIALOBJECT ) ) + { + // save in binary format - there is no other format ! + String aRealName = ::utl::TempFile().GetURL(); + SvStorageRef xNewStor( new SvStorage( FALSE, aRealName, STREAM_STD_READWRITE, 0 ) ); + if ( false) + { + } + else + ::utl::UCBContentHelper::Kill( aRealName ); + } + else + { + Copy( rNewName, rNewName, pOld, pSrcPersist ); + xNewObject = GetObject( rNewName ); + } + } + + return xNewObject; +} + +/************************************************************************* +|* SvPersist::Copy() +|* +|* Beschreibung: Kopiert ein Objekt von der einen in die andere +|* Persist Instanz +*************************************************************************/ +BOOL SvPersist::Copy( const String & rNewObjName, const String & rNewStorName, + SvInfoObject * pSrcI, SvPersist * pSrc ) +{ + BOOL bRet = TRUE; + if( !GetInfoList() ) + bRet = FALSE; // es konnte keine Liste erstellt werden + + SvInfoObjectRef xI( pSrcI->CreateCopy() ); + xI->SetObjName( rNewObjName ); + xI->SetStorageName( rNewStorName ); + xI->pImp->aRealStorageName.Erase(); + + DBG_ASSERT( rNewStorName == rNewObjName || !rNewStorName.Len(), "Can't set storage name in this context!" ); + + if( pSrcI->GetPersist() ) + { + bRet = ImplCopy( pSrcI->GetPersist(), xI->GetStorageName(), FALSE ); + } + else + { + // copy storage of new element into my storage + bRet = pSrc->GetStorage()->CopyTo( pSrcI->GetStorageName(), GetStorage(), xI->GetStorageName() ); + } + + if( bRet ) + { + pChildList->Append( xI ); + SetModified( TRUE ); + } + + return bRet; +} + +BOOL SvPersist::ImplCopy( SvPersist* pSrc, const String& rStorageName, BOOL bMoving ) +{ + BOOL bRet = FALSE; + SvStorageRef aSrcEleStor = pSrc->GetStorage(); + SvStorage* pStor = GetStorage(); + + long nObjVersion = aSrcEleStor->GetVersion(); + BOOL bIntern = SvFactory::IsIntern( aSrcEleStor->GetClassName(), &nObjVersion ); + if( nObjVersion >= SOFFICE_FILEFORMAT_60 ) + { + ULONG nFormat = aSrcEleStor->GetFormat(); + switch( nFormat ) + { + 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: + nObjVersion = SOFFICE_FILEFORMAT_8; + break; + default: + break; + } + } + + SvPseudoObjectRef xPO( pSrc ); + if ( !pStor->IsOLEStorage() && xPO.Is() && ( xPO->GetMiscStatus() & SVOBJ_MISCSTATUS_SPECIALOBJECT ) ) + { + // these object are saved into the document stream + bRet = FALSE; + OSL_FAIL("Can't copy special objects into XML format!"); + } + else + { + SvStorageRef aNewStor; + if( !bIntern || pStor->IsOLEStorage() ) + aNewStor = pStor->OpenOLEStorage( rStorageName, STREAM_STD_READWRITE | STREAM_TRUNC, 0 ); + else + aNewStor = pStor->OpenUCBStorage( rStorageName, STREAM_STD_READWRITE | STREAM_TRUNC, 0 ); + + if( aNewStor->GetError() == SVSTREAM_OK ) + { + BOOL bSave = pSrc->IsModified(); + if ( !bSave ) + { + SvStorageInfoList aList; + aSrcEleStor->FillInfoList( &aList ); + bSave = aList.empty(); + if ( !bSave ) + { + if( pStor->GetVersion() <= SOFFICE_FILEFORMAT_50 ) + { + // If we store into the old binary format, objects + // that have a newer file format version than the + // destination storage have to be saved. + bSave = bIntern && nObjVersion > pStor->GetVersion(); + } + else + { + // If we store into an XML format, all internal objects that + // aren't stored in the XML format or that are stored in + // a newer XML format have to be saved. + bSave = + ( nObjVersion < SOFFICE_FILEFORMAT_60 || + nObjVersion > pStor->GetVersion() ); + } + } + } + + aNewStor->SetVersion( pStor->GetVersion() ); + + if( bSave ) + { + bRet = false; + } + else + { + SvStorageRef xEleStor = pSrc->GetStorage(); + pSrc->DoHandsOff(); + bRet = xEleStor->CopyTo( aNewStor ); + if ( !bRet || !bMoving ) + { + // was pSrc->DoSaveCompleted( xEleStor ); but return value is not checked + } + } + + if ( bRet && bMoving ) + { + // was pSrc->DoSaveCompleted( aNewStor ); but return value is not checked + } + } + } + + return bRet; +} + +BOOL SvPersist::Unload( SvInfoObject *pInfoObj) +{ + if( bOpSaveAs || bOpHandsOff || bOpSave ) + return FALSE; + + DBG_ASSERT(pInfoObj,"Kein InfoObj"); + SvPersistRef xChild = pInfoObj->GetPersist(); + DBG_ASSERT(xChild->pParent == this,"wrong parent"); + if( xChild.Is() ) + { + if( xChild->Owner() ) + { + DBG_ASSERT(!xChild->IsModified(),"unload modified object"); + if( xChild->IsModified() ) + // modified, do not unload + return FALSE; + } + + // update info object before unload + SvEmbeddedInfoObject * pI = PTR_CAST(SvEmbeddedInfoObject, pInfoObj ); + if( pI ) + { + pI->GetVisArea(); + pI->IsLink(); + } + + SvPersistRef x; + pInfoObj->SetObj( x ); + + // Ein Hack, da ueber den RefCount keine Logik implementiert werden daerf + if ( (xChild->bIsObjectShell && xChild->GetRefCount() == 2) + || (!xChild->bIsObjectShell && xChild->GetRefCount() == 1) ) + { + xChild->DoClose(); + xChild->pParent = NULL; + return TRUE; + } + else + pInfoObj->SetObj( xChild ); + } + + return FALSE; +} + +BOOL SvPersist::Unload( SvPersist * pChild ) +{ + DBG_ASSERT( pChild, "SvPersist::Unload(): pChild == NULL" ); + if( pChildList ) + { + SvInfoObjectRef pEle = pChildList->First(); + while( pEle.Is() ) + { + if( pEle->GetPersist() == pChild ) + return Unload( pEle ); + pEle = pChildList->Next(); + } + } + return FALSE; +} + +void SvPersist::Remove( SvInfoObject *pInfoObj) +{ + DBG_ASSERT(pInfoObj,"Kein InfoObj"); + SvPersist * pChild = pInfoObj->GetPersist(); + if( pChild ) + { + if( pChild->Owner() && pChild->IsModified() ) + // modify-Zaehler fuer Child runterzaehlen + CountModified( FALSE ); + if( pChild->pParent == this ) + pChild->pParent = NULL; // kein zusaetzlicher RefCount + } + pChildList->Remove( pInfoObj ); + SetModified( TRUE ); +} + + +void SvPersist::Remove( const String & rName ) +{ + SvInfoObjectRef pInfo = Find( rName ); + if( pInfo.Is() ) + Remove(pInfo); +} + +void SvPersist::Remove( SvPersist * pChild ) +{ + DBG_ASSERT( pChild, "SvPersist::Remove(): pChild == NULL" ); + if( pChildList ) + { + SvInfoObjectRef pEle = pChildList->First(); + while( pEle.Is() ) + { + if( pEle->GetPersist() == pChild ) + { + Remove(pEle); + break; + } + pEle = pChildList->Next(); + } + } +} + +void SvPersist::dtorClear() +{ + if( pChildList ) + { + SvInfoObjectMemberList * pList = pChildList; + pChildList = NULL; //Schutz vor Remove bei Destruktor + SvInfoObjectRef pEle = pList->Last(); + pList->Remove(); + while( pEle.Is() ) + { + if( pEle->GetPersist() ) + { + //pEle->GetPersist()->SetModifiedFormat( 0 ); + pEle->GetPersist()->pParent = NULL; // kein zusaetzlicher RefCount + } + pEle = pList->Last(); + pList->Remove(); + } + delete pList; + } +} + +SvInfoObject * SvPersist::Find( const String & rName ) const +{ + if( pChildList ) + { // Befindet sich das Objekt in der aktuellen Liste + SvInfoObjectRef pEle = pChildList->First(); + while( pEle.Is() ) + { + if( pEle->GetObjName() == rName ) + return pEle; + pEle = pChildList->Next(); + } + } + return NULL; +} + +SvInfoObject * SvPersist::Find( const SvPersist * pObj_ ) const +{ + if( pChildList ) + { // Befindet sich das Objekt in der aktuellen Liste + SvInfoObject* pEle = pChildList->First(); + while( pEle ) + { + if( pEle->GetPersist() == pObj_ ) + return pEle; + pEle = pChildList->Next(); + } + } + return NULL; +} + +BOOL SvPersist::HasObject( const String & rObjName ) +{ + if( Owner() ) + { + // Befindet sich das Objekt in der aktuellen Liste + if( Find( rObjName ) ) + return TRUE; + } + return FALSE; +} + +SvPersistRef SvPersist::CreateObjectFromStorage( SvInfoObject* pEle, const SvStorageRef& xStor ) +{ + // Es gibt einen Storage zum Child + // entsprechende Sv-Klasse erzeugen + SvFactory* pFact=NULL; + SvPersistRef xPer = &pFact->CreateAndLoad( xStor ); + if( xPer.Is() ) + { + // Parent einsetzten + xPer->pParent = this; + + // ist ein persistentes Objekt + // muss initialisiert sein + pEle->SetObj( xPer ); + } + + SvEmbeddedInfoObject* pI = PTR_CAST( SvEmbeddedInfoObject, pEle ); + SvEmbeddedObjectRef xEmbObj( xPer ); + if ( pI && xEmbObj.Is() ) + { + BOOL bOld = xEmbObj->IsEnableSetModified(); + xEmbObj->EnableSetModified(FALSE); + xEmbObj->SetVisArea( pI->GetVisArea() ); + xEmbObj->EnableSetModified(bOld); + } + + return xPer; +} + +SvPersistRef SvPersist::GetObject( const String & rObjName ) +{ + SvPersistRef xReturn; + if( Owner() ) + { + SvInfoObject * pEle = Find( rObjName ); + if( !pEle ) + return SvPersistRef(); + if( pEle->GetPersist() ) + return pEle->GetPersist(); + + SvStorageRef xSt = GetObjectStorage( pEle ); + if( xSt.Is() && xSt->SotStorage::GetError() == SVSTREAM_OK ) + { + xReturn = CreateObjectFromStorage( pEle, xSt ); + } + else + GetStorage()->ResetError(); + } + + return xReturn; +} + +SvStorageRef SvPersist::GetObjectStorage( SvInfoObject* pEle ) +{ + SvStorageRef xRet; + SvPersist* pP = pEle->GetPersist(); + if( pP ) + xRet = pP->GetStorage(); + else + { + if ( pEle->pImp->GetRealStorageName().Len() ) + xRet = new SvStorage( pEle->pImp->GetRealStorageName() ); + else + xRet = GetStorage()->OpenStorage( pEle->GetStorageName() ); + } + + return xRet; +} + +void SvPersist::SetModified( BOOL bModifiedP ) +{ + ASSERT_INIT() + DBG_ASSERT( bModifiedP || IsEnableSetModified(), + "SetModified( FALSE ), obwohl IsEnableSetModified() == FALSE" ); + + if( !IsEnableSetModified() ) + return; + + if( bIsModified != bModifiedP ) + { // der Status hat sich geaendert + // Hilfsflag setzen + bIsModified = bModifiedP; + // Hierarchisch ModifyCount setzen + CountModified( bModifiedP ); + } + + aModifiedTime = Time( Time::SYSTEM ); +} + +void SvPersist::CountModified( BOOL bMod ) +{ + DBG_ASSERT( bMod || nModifyCount != 0, "modifiy count underflow" ); + nModifyCount += bMod ? 1 : -1; + if( pParent ) + { + /* Den ModifyCount des Parent nur einmal rauf oder runter + zaehlen. Bei den Insert und Move Methoden muss dieser + Zaehler dann nur einmal erhoeht oder erniedrigt werden + */ + if( (bMod && nModifyCount == 1) + || (!bMod && nModifyCount == 0) ) + pParent->CountModified( bMod ); + } + if ( ( nModifyCount == 1 && bMod ) || + ( nModifyCount == 0 ) ) + ModifyChanged(); +} + +void SvPersist::EnableSetModified( BOOL bEnable ) +{ + DBG_ASSERT( bEnable != bEnableSetModified, + "EnableSetModified 2x mit dem gleichen Wert gerufen" ); + bEnableSetModified = bEnable; +} + +void SvPersist::ModifyChanged() +{ +} + +BOOL SvPersist::IsModified() +{ + ASSERT_INIT() + if( nModifyCount ) + // Wenn Count gesetzt, auf jeden Fall modifiziert + return TRUE; + if( Owner() ) + { + if( pChildList ) + { + SvInfoObject * pObj_ = pChildList->First(); + while( pObj_ ) + { + if( pObj_->GetPersist() && pObj_->GetPersist()->IsModified() ) + return TRUE; + pObj_ = pChildList->Next(); + } + } + } + return FALSE; +} + +void SvPersist::InitMembers( SvStorage * pStor ) +{ + bIsInit = TRUE; + if ( pStor ) + aStorage = pStor; + else + bCreateTempStor = TRUE; +} + +BOOL SvPersist::DoInitNew( SvStorage * pStor ) +{ + EnableSetModified( FALSE ); + BOOL bRet = InitNew( pStor ); + EnableSetModified( TRUE ); + return bRet; +} + +BOOL SvPersist::DoLoad( SvStorage * pStor ) +{ + EnableSetModified( FALSE ); + BOOL bRet = Load( pStor ); + EnableSetModified( TRUE ); + return bRet; +} + +BOOL SvPersist::DoLoad +( + const String & rFileName, /* Name der Datei, aus der das Objekt + geladen werden soll. */ + StreamMode nStreamMode, /* Attribute f"ur um die Datei zu "offnen */ + StorageMode nStorageMode /* Attribute f"ur um die Datei zu "offnen */ +) +/* [Beschreibung] + + Das Objekt soll aus der angegebenen Datei geladen werden. + + [Anmerkung] + + Aufgrund fehlerhafter Ole funktionalitaet, wird der Stream auch + schreibend geoeffnet, wenn nur READ angegeben ist und er nicht + schreibgeschuetzt ist. + + [Querverweise] + + <SvPseudoObject::DoSave> +*/ +{ + SvStorageRef xStg; + SvGlobalName aGN; + // Es wird nur die IPersistStorage-Schnittstelle angeboten + xStg = new SvStorage( rFileName, nStreamMode | STREAM_WRITE, nStorageMode ); + if( !xStg.Is() ) + xStg = new SvStorage( rFileName, nStreamMode, nStorageMode ); + aGN = xStg->GetClassName(); + if( !xStg.Is() && aGN == *GetSvFactory() ) + { + xStg = new SvStorage( rFileName, nStreamMode | STREAM_WRITE, nStorageMode ); + if( !xStg.Is() ) + xStg = new SvStorage( rFileName, nStreamMode, nStorageMode ); + } + if( xStg.Is() && SVSTREAM_OK != xStg->GetError() ) + return FALSE; + + SetFileName( rFileName ); + return DoLoad( xStg ); +} + +void SvPersist::DoHandsOff() +{ + HandsOff(); +} + + + +SvStorage * SvPersist::GetStorage() const +{ + ASSERT_INIT() + DBG_ASSERT( !bOpHandsOff, "in hands off state, no accessible storage" ); + if( bCreateTempStor ) + { + SvPersist *pThis = (SvPersist*) this; + DBG_ASSERT( !aStorage.Is(), "bCreateTempStorage && aStorage.Is()" ); + pThis->aStorage = new SvStorage( FALSE, String() ); + pThis->bCreateTempStor = FALSE; + SetupStorage( pThis->aStorage ); + } + + return aStorage; +} + +BOOL SvPersist::InitNew( SvStorage * pStor ) +{ + InitMembers( pStor ); + BOOL bRet = FALSE; + + if( pStor ) + SetupStorage( pStor ); + + if( Owner() ) + bRet = TRUE; + return bRet; +} + +BOOL SvPersist::DoOwnerLoad( SvStorage * pStor ) +{ + InitMembers( pStor ); + + return DoLoadContent( pStor, TRUE ); +} + +BOOL SvPersist::Load( SvStorage * pStor ) +{ + dtorClear(); + InitMembers( pStor ); + + SvGlobalName aActualClassName = + SvFactory::GetAutoConvertTo( GetStorage()->GetClassName() ); + + if( aActualClassName == *GetSvFactory() && SOFFICE_FILEFORMAT_60 > pStor->GetVersion() ) + return DoLoadContent( pStor, TRUE ); + + return TRUE; +} + +void SvPersist::HandsOff() +{ + ASSERT_INIT() + + if ( bOpHandsOff ) + return; + + if( pChildList ) + { + for( ULONG i = 0; i < pChildList->Count(); i++ ) + { + SvInfoObject * pEle = pChildList->GetObject( i ); + if( pEle->GetPersist() && !pEle->IsDeleted() ) + { + // deleted objects don't need to take their hands off! + ULONG nVersion = GetStorage()->GetVersion(); + SvEmbeddedObjectRef xEmb( pEle->GetPersist() ); + if ( xEmb.Is() && nVersion >= SOFFICE_FILEFORMAT_60 && ( xEmb->GetMiscStatus() & SVOBJ_MISCSTATUS_SPECIALOBJECT ) ) + continue; + // Im HandsOff darf nicht mehr auf Persist zugegriffen werden + // deswegen alten Namen sichern + pEle->GetPersist()->DoHandsOff(); + } + pEle = pChildList->Next(); + } + } + + bOpHandsOff = TRUE; + aStorage.Clear(); +} + +#define PERSIST_STREAM "persist elements" +BOOL SvPersist::DoLoadContent( SvStorage * pStor, BOOL bOwner_ ) +{ + SvStorageStreamRef aContStm; + if( bOwner_ ) + aContStm = pStor->OpenStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( PERSIST_STREAM ) ), + STREAM_READ | STREAM_NOCREATE ); + else + { + + aContStm = pStor->OpenStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ), + STREAM_READ | STREAM_NOCREATE ); + if( aContStm->GetError() == SVSTREAM_FILE_NOT_FOUND ) + // Stream nicht vorhanden, Ole10Native probieren + aContStm = pStor->OpenStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ), + STREAM_READ | STREAM_NOCREATE ); + } + + // nicht vorhandener Stream ist kein Fehler + if( aContStm->GetError() == SVSTREAM_FILE_NOT_FOUND ) + return TRUE; + + aContStm->SetVersion( pStor->GetVersion() ); + if( aContStm->GetError() == SVSTREAM_OK ) + { + aContStm->SetBufferSize( 8192 ); +#if defined( SOLARIS ) && defined( C40 ) + // patch to work around Sparc-Compiler bug + SvEmbeddedObjectRef xSvEmbeddedObjectRef = this; + if( xSvEmbeddedObjectRef.Is() ) + xSvEmbeddedObjectRef->LoadContent( *aContStm, bOwner_ ); + else +#else + LoadContent( *aContStm, bOwner_ ); +#endif + aContStm->SetBufferSize( 0 ); + return aContStm->GetError() == SVSTREAM_OK; + } + return FALSE; +} + +#define CHILD_LIST_VER (BYTE)2 +void SvPersist::LoadContent( SvStream & rStm, BOOL bOwner_ ) +{ + if( bOwner_ ) + { + BYTE nVers; + rStm >> nVers; + DBG_ASSERT( nVers == CHILD_LIST_VER, "version conflict" ); + + if( nVers != CHILD_LIST_VER ) + rStm.SetError( SVSTREAM_WRONGVERSION ); + else + { + BOOL bList; + rStm >> bList; + if( bList ) + { + SvPersistStream aPStm( SOAPP->aInfoClassMgr, &rStm ); + aPStm >> *GetInfoList(); + } + } + } + // nichts tun bei Fremd-Format +} + +void SvPersist::SaveContent( SvStream & rStm, BOOL bOwner_ ) +{ + if( bOwner_ ) + { + rStm << (BYTE)CHILD_LIST_VER; + const SvInfoObjectMemberList * pList = GetObjectList(); + if( pList && pList->Count() ) + { + rStm << (BOOL)TRUE; + SvPersistStream aPStm( SOAPP->aInfoClassMgr, &rStm ); + aPStm << *pList; + } + else + rStm << (BOOL)FALSE; + } + // nichts tun bei Fremd-Format +} + +/************************************************************************* +|* SvPersist::CleanUp() +|* +|* Beschreibung +|* +|* Loescht Storages, die im SvInfoObject dafuer geflagt wurden +*************************************************************************/ + +void SvPersist::CleanUp( BOOL bRecurse) +{ + if( pChildList && pChildList->Count() ) + { + for(ULONG i=0;i<pChildList->Count();) + { + SvInfoObjectRef pEle = pChildList->GetObject(i); + if( bRecurse ) + { + SvPersistRef xPer = pEle->GetPersist(); + if(!xPer.Is()) + { + SvStorageRef aEleStor; + aEleStor = GetStorage()->OpenStorage( pEle->GetStorageName() ); + if( !aEleStor.Is() ) + continue; + + xPer=new SvPersist; + xPer->DoOwnerLoad( aEleStor); + pEle->SetObj(xPer); + xPer->CleanUp(); + } + } + + if( pEle->IsDeleted() ) + { + DBG_ASSERT( pEle->GetRefCount()==2, "Loeschen von referenziertem Storage" ); + String aStorName(pEle->GetStorageName()); + Remove(pEle); + GetStorage()->Remove(aStorName); + } + else + i++; + } + } +} + +SvPersistBaseMemberList::SvPersistBaseMemberList(){} + +#define PERSIST_LIST_VER (sal_uInt8)0 +#define PERSIST_LIST_DBGUTIL (sal_uInt8)0x80 + +/************************************************************************ +|* SvPersistBaseMemberList::WriteOnlyStreamedObjects() +*************************************************************************/ +void SvPersistBaseMemberList::WriteObjects( SvPersistStream & rStm, + sal_Bool bOnlyStreamed ) const +{ +#ifdef STOR_NO_OPTIMIZE + rStm << (sal_uInt8)(PERSIST_LIST_VER | PERSIST_LIST_DBGUTIL); + sal_uInt32 nObjPos = rStm.WriteDummyLen(); +#else + sal_uInt8 bTmp = PERSIST_LIST_VER; + rStm << bTmp; +#endif + sal_uInt32 nCountMember = Count(); + sal_uIntPtr nCountPos = rStm.Tell(); + sal_uInt32 nWriteCount = 0; + rStm << nCountMember; + //bloss die Liste nicht veraendern, + //wegen Seiteneffekten beim Save + for( sal_uIntPtr n = 0; n < nCountMember; n++ ) + { + SvPersistBase * pObj = GetObject( n ); + if( !bOnlyStreamed || rStm.IsStreamed( pObj ) ) + { // Objekt soll geschrieben werden + rStm << GetObject( n ); + nWriteCount++; + } + } + if( nWriteCount != nCountMember ) + { + // nicht alle Objekte geschrieben, Count anpassen + sal_uIntPtr nPos = rStm.Tell(); + rStm.Seek( nCountPos ); + rStm << nWriteCount; + rStm.Seek( nPos ); + } +#ifdef STOR_NO_OPTIMIZE + rStm.WriteLen( nObjPos ); +#endif +} + +/************************************************************************ +|* operator << () +*************************************************************************/ +SvPersistStream& operator << ( SvPersistStream & rStm, + const SvPersistBaseMemberList & rLst ) +{ + rLst.WriteObjects( rStm ); + return rStm; +} + +/************************************************************************ +|* operator >> () +*************************************************************************/ +SvPersistStream& operator >> ( SvPersistStream & rStm, + SvPersistBaseMemberList & rLst ) +{ + sal_uInt8 nVer; + rStm >> nVer; + + if( (nVer & ~PERSIST_LIST_DBGUTIL) != PERSIST_LIST_VER ) + { + rStm.SetError( SVSTREAM_GENERALERROR ); + OSL_FAIL( "persist list, false version" ); + } + + sal_uInt32 nObjLen(0), nObjPos(0); + if( nVer & PERSIST_LIST_DBGUTIL ) + nObjLen = rStm.ReadLen( &nObjPos ); + + sal_uInt32 nCount; + rStm >> nCount; + for( sal_uIntPtr n = 0; n < nCount && rStm.GetError() == SVSTREAM_OK; n++ ) + { + SvPersistBase * pObj; + rStm >> pObj; + if( pObj ) + rLst.Append( pObj ); + } +#ifdef DBG_UTIL + if( nObjLen + nObjPos != rStm.Tell() ) + { + rtl::OStringBuffer aStr( + RTL_CONSTASCII_STRINGPARAM("false list len: read = ")); + aStr.append(static_cast<sal_Int64>(rStm.Tell() - nObjPos)); + aStr.append(RTL_CONSTASCII_STRINGPARAM(", should = ")); + aStr.append(static_cast<sal_Int64>(nObjLen)); + OSL_FAIL(aStr.getStr()); + } +#else + (void)nObjLen; +#endif + return rStm; +} + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/persist/svstor.cxx b/bf_so3/source/persist/svstor.cxx new file mode 100644 index 000000000..d4d1ffea2 --- /dev/null +++ b/bf_so3/source/persist/svstor.cxx @@ -0,0 +1,307 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + + +#include <bf_so3/svstor.hxx> +#include "bf_so3/soerr.hxx" +#include <sot/storinfo.hxx> +#include <sot/stg.hxx> + +#include <tools/debug.hxx> + +// Freigeben, wenn SD-Storages verwendet werden sollen +#define SDSTORAGES +#define SD_ERROR OSL_FAIL( "use ole2, while SDSTORAGES defined" ) + +// kein Profiling +#undef DBG_PROFSTART +#define DBG_PROFSTART(John) +#undef DBG_PROFSTOP +#define DBG_PROFSTOP(John) + +namespace binfilter { + +/************** class SvStorageStream ***********************************/ +SV_IMPL_FACTORY(SvStorageStreamFactory) + { + } +}; +TYPEINIT1(SvStorageStreamFactory,SvFactory); + +SO2_IMPL_STANDARD_CLASS2_DLL(SvStorageStream,SvStorageStreamFactory,SvObject,SotStorageStream, + 0x89F1CAA0L, 0x7010, 0x101B, + 0x80,0x4C,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD ) + +::IUnknown * SvStorageStream::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +/************************************************************************ +|* SvStorageStream::SvStorageStream() +|* +|* Beschreibung +*************************************************************************/ +SvStorageStream::SvStorageStream( BaseStorageStream * pStm ) + : SotStorageStream( pStm ) + , pObjI( NULL ) + , pRelease( NULL ) +{ +} + +SvStorageStream::SvStorageStream() + : pObjI( NULL ) + , pRelease( NULL ) +{ +} + +/************************************************************************ +|* SvStorageStream::~SvStorageStream() +|* +|* Beschreibung +*************************************************************************/ +SvStorageStream::~SvStorageStream() +{ + //SetBufferSize( 0 ); +} + +/************************************************************************* +|* SvStorageStream::GetStream() +|* +|* Beschreibung +*************************************************************************/ +USHORT SvStorageStream::IsA() const +{ + return ID_STORAGESTREAM; +} + +ULONG SvStorageStream::GetData( void* pData, ULONG nSize ) +{ + return SotStorageStream::GetData( pData, nSize ); +} + +ULONG SvStorageStream::PutData( const void* pData, ULONG nSize ) +{ + return SotStorageStream::PutData( pData, nSize ); +} + +ULONG SvStorageStream::SeekPos( ULONG nPos ) +{ + return SotStorageStream::SeekPos( nPos ); +} + +void SvStorageStream::FlushData() +{ + SotStorageStream::FlushData(); +} + +void SvStorageStream::SetSize( ULONG nNewSize ) +{ + SotStorageStream::SetSize( nNewSize ); +} + +BOOL SvStorageStream::Commit() +{ + return SotStorageStream::Commit(); +} + +BOOL SvStorageStream::Revert() +{ + return SotStorageStream::Revert(); +} + +/************** class SvStorage ****************************************** +*************************************************************************/ +SV_IMPL_FACTORY(SvStorageFactory) + { + } +}; +TYPEINIT1(SvStorageFactory,SvFactory); + +SO2_IMPL_STANDARD_CLASS2_DLL(SvStorage,SvStorageFactory,SvObject,SotStorage, + 0xCD956821L, 0x70B5, 0x101B, + 0x80,0x4C,0xFD,0xFD,0xFD,0xFD,0xFD,0xFD ) + +::IUnknown * SvStorage::GetMemberInterface( const SvGlobalName & ) +{ + return NULL; +} + +/************************************************************************ +|* +|* SvStorage::SvStorage() +|* +|* Beschreibung Es muss ein I... Objekt an SvObject uebergeben +|* werden, da es sonst selbst ein IUnknown anlegt und +|* festlegt, dass alle weiteren I... Objekte mit +|* delete zerstoert werden (Owner() == TRUE). +|* Es werden aber nur IStorage Objekte benutzt und nicht +|* selbst implementiert, deshalb wird so getan, als ob +|* das IStorage Objekt von aussen kam und es wird mit +|* Release() freigegeben. +|* Die CreateStorage Methoden werden benoetigt, um +|* ein IStorage Objekt vor dem Aufruf von SvObject +|* zu erzeugen (Own, !Own automatik). +|* Hat CreateStorage ein Objekt erzeugt, dann wurde +|* der RefCounter schon um 1 erhoet. +|* Die Uebergabe erfolgt in pStorageCTor. Die Variable +|* ist NULL, wenn es nicht geklappt hat. +|* +*************************************************************************/ +#define INIT_SVSTORAGE() \ + , pRelease( NULL ) \ + , pObjI( NULL ) + +SvStorage::SvStorage() + : SotStorage() + INIT_SVSTORAGE() +{ +} + + +#define ERASEMASK ( STREAM_TRUNC | STREAM_WRITE | STREAM_SHARE_DENYALL ) +SvStorage::SvStorage( const String & rName, StreamMode nMode, + StorageMode nStorageMode ) + : SotStorage( rName, nMode, nStorageMode ) + INIT_SVSTORAGE() +{ +} + +SvStorage::SvStorage( BOOL bUCBStorage, const String & rName, StreamMode nMode, + StorageMode nStorageMode ) + : SotStorage( bUCBStorage, rName, nMode, nStorageMode ) + INIT_SVSTORAGE() +{ +} + +SvStorage::SvStorage( BaseStorage * pStor ) + : SotStorage( pStor ) + INIT_SVSTORAGE() +{ +} + +SvStorage::SvStorage( SvStream & rStm ) + : SotStorage( rStm ) + INIT_SVSTORAGE() +{ +} + +SvStorage::SvStorage( BOOL bUCBStorage, SvStream & rStm ) + : SotStorage( bUCBStorage, rStm ) + INIT_SVSTORAGE() +{ +} + +SvStorage::SvStorage( SvStream * pStm, BOOL bDelete ) + : SotStorage( pStm, bDelete ) + INIT_SVSTORAGE() +{ +} + +/************************************************************************* +|* SvStorage::~SvStorage() +|* +|* Beschreibung +*************************************************************************/ +SvStorage::~SvStorage() +{ +} + +/************************************************************************* +|* SvStorage::OpenStream() +|* +|* Beschreibung +*************************************************************************/ +SotStorageStream * SvStorage::OpenSotStream( const String & rEleName, + StreamMode nMode, + StorageMode nStorageMode ) +{ + DBG_ASSERT( !nStorageMode, "StorageModes ignored" ); + + SvStorageStream * pStm = NULL; + DBG_ASSERT( Owner(), "must be owner" ); + // volle Ole-Patches einschalten + // egal was kommt, nur exclusiv gestattet + nMode |= STREAM_SHARE_DENYALL; + ULONG nE = m_pOwnStg->GetError(); + BaseStorageStream * p = m_pOwnStg->OpenStream( rEleName, nMode, + (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE ); + pStm = new SvStorageStream( p ); + if( !nE ) + m_pOwnStg->ResetError(); // kein Fehler setzen + return pStm; +} + +/************************************************************************* +|* SvStorage::OpenStorage() +|* +|* Beschreibung +*************************************************************************/ +SotStorage * SvStorage::OpenSotStorage( const String & rEleName, + StreamMode nMode, + StorageMode nStorageMode ) +{ + SvStorage * pStor = NULL; + DBG_ASSERT( Owner(), "must be owner" ); + nMode |= STREAM_SHARE_DENYALL; + ULONG nE = m_pOwnStg->GetError(); + BaseStorage * p = m_pOwnStg->OpenStorage( rEleName, nMode, + (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE ); + pStor = new SvStorage( p ); + if( !nE ) + m_pOwnStg->ResetError(); // kein Fehler setzen + return pStor; +} + +SvStorage * SvStorage::OpenUCBStorage( const String & rEleName, + StreamMode nMode, + StorageMode nStorageMode ) +{ + SvStorage * pStor = NULL; + DBG_ASSERT( Owner(), "must be owner" ); + nMode |= STREAM_SHARE_DENYALL; + ULONG nE = m_pOwnStg->GetError(); + BaseStorage * p = m_pOwnStg->OpenUCBStorage( rEleName, nMode, + (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE ); + pStor = new SvStorage( p ); + if( !nE ) + m_pOwnStg->ResetError(); // kein Fehler setzen + return pStor; +} + +SvStorage * SvStorage::OpenOLEStorage( const String & rEleName, + StreamMode nMode, + StorageMode nStorageMode ) +{ + SvStorage * pStor = NULL; + DBG_ASSERT( Owner(), "must be owner" ); + nMode |= STREAM_SHARE_DENYALL; + ULONG nE = m_pOwnStg->GetError(); + BaseStorage * p = m_pOwnStg->OpenOLEStorage( rEleName, nMode, + (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE ); + pStor = new SvStorage( p ); + if( !nE ) + m_pOwnStg->ResetError(); // kein Fehler setzen + return pStor; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/persist/transbnd.cxx b/bf_so3/source/persist/transbnd.cxx new file mode 100644 index 000000000..406db4927 --- /dev/null +++ b/bf_so3/source/persist/transbnd.cxx @@ -0,0 +1,417 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#define _TRANSBND_CXX + +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/container/XNameAccess.hpp> + +#ifndef _RTL_USTRING_ +#include <rtl/ustring.h> +#endif + +#include <osl/mutex.hxx> + +#include <bf_svtools/bf_solar.h> +#include <tools/debug.hxx> +#include <tools/datetime.hxx> +#include <tools/errcode.hxx> +#include <tools/link.hxx> +#include <tools/ref.hxx> +#include <tools/stream.hxx> +#include <bf_tools/string.hxx> +#include <tools/urlobj.hxx> + +#include <vcl/svapp.hxx> + +#include <bf_svtools/cancel.hxx> +#include <bf_svtools/inethist.hxx> +#include <bf_svtools/svarray.hxx> + +#include <bf_so3/binding.hxx> +#include <binddata.hxx> +#include <bf_so3/transbnd.hxx> +#include <bf_so3/transprt.hxx> +#include <transuno.hxx> +#include <bf_so3/so2defs.hxx> + +#include <algorithm> + +using namespace com::sun::star::sdbc; +using namespace com::sun::star::beans; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; +using namespace com::sun::star::container; + +namespace binfilter { + + +/*======================================================================== + * + * SvBinding implementation. + * + *======================================================================*/ +/* + * SvBinding. + */ +/* + * ~SvBinding. + */ +SvBinding::~SvBinding (void) +{ + delete m_pTransport; + delete m_pCancelable; +} + +/* + * OnStart. + */ +void SvBinding::OnStart (void) +{ + SvBindingRef xThis (this); + if (m_xCallback.Is()) + { + SolarMutexGuard aAppGuard; + if (m_xCallback.Is()) + m_xCallback->InitStartTime(); + } +} + +/* + * OnError. + */ +void SvBinding::OnError (ErrCode eErrCode) +{ + SvBindingRef xThis (this); + m_eErrCode = eErrCode; + + if (m_xCallback.Is()) + { + SolarMutexGuard aAppGuard; + if (m_xCallback.Is()) + m_xCallback->OnStopBinding (m_eErrCode, String()); + } + + DELETEZ (m_pTransport); + DELETEZ (m_pCancelable); +} + +/* + * OnMimeAvailable. + */ +void SvBinding::OnMimeAvailable (const String &rMime) +{ + m_aMime = rMime; + m_bMimeAvail = TRUE; +} + +/* + * OnExpiresAvailable. + */ +void SvBinding::OnExpiresAvailable (const DateTime &rExpires) +{ + m_aExpires = rExpires; +} + +/* + * OnHeaderAvailable. + */ +void SvBinding::OnHeaderAvailable (const String &rName, const String &rValue) +{ + if (!m_xHeadIter.Is()) + m_xHeadIter = new SvKeyValueIterator; + + m_xHeadIter->Append (SvKeyValue (rName, rValue)); +} + +/* + * OnDataAvailable. + */ +void SvBinding::OnDataAvailable ( + SvStatusCallbackType eType, ULONG nSize, SvLockBytes *pLockBytes) +{ + SvBindingRef xThis (this); + + if (!m_xLockBytes.Is()) + m_xLockBytes = pLockBytes; + + switch (eType) + { + case SVBSCF_FIRSTDATANOTIFICATION: + case SVBSCF_INTERMEDIATEDATANOTIFICATION: + if (m_bMimeAvail && m_xLockBytes.Is() && nSize) + { + osl::SolarMutex &rAppMutex = Application::GetSolarMutex(); + if (m_xCallback.Is() && rAppMutex.tryToAcquire()) + { + m_xCallback->OnDataAvailable ( + eType, nSize, *m_xLockBytes); + rAppMutex.release(); + } + } + break; + + case SVBSCF_LASTDATANOTIFICATION: + m_bComplete = TRUE; + OnError (ERRCODE_NONE); + break; + + default: // Ignored. + break; + } +} + +/* + * OnProgress. + */ +void SvBinding::OnProgress ( + ULONG nNow, ULONG nEnd, SvBindStatus eStat) +{ + SvBindingRef xThis (this); + if (m_xCallback.Is()) + { + osl::SolarMutex &rAppMutex = Application::GetSolarMutex(); + if (m_xCallback.Is() && rAppMutex.tryToAcquire()) + { + m_xCallback->OnProgress ( + nNow, nEnd, eStat, m_aUrlObj.GetMainURL( INetURLObject::DECODE_TO_IURI )); + rAppMutex.release(); + } + } +} + +/* + * OnRedirect. + */ +void SvBinding::OnRedirect (const String &rUrl) +{ + SvBindingRef xThis (this); + if (m_xCallback.Is()) + { + SolarMutexGuard aAppGuard; + + INetURLHistory::GetOrCreate()->PutUrl (m_aUrlObj); + m_aUrlObj.SetURL (rUrl); + + if (m_xCallback.Is()) + m_xCallback->OnProgress (0, 0, SVBINDSTATUS_REDIRECTING, rUrl); + } +} + +/* + * ShouldUseFtpProxy. + */ +BOOL SvBinding::ShouldUseFtpProxy (const String &rUrl) +{ + return BAPP()->ShouldUseFtpProxy (rUrl); +} + +/* + * ~SvBindStatusCallback. + */ +SvBindStatusCallback::~SvBindStatusCallback (void) +{ +} + +Link SvBindStatusCallback::m_aProgressCallback; + +/* + * InitStartTime. + */ +void SvBindStatusCallback::InitStartTime (void) +{ + m_nStartTicks = Time::GetSystemTicks(); +} + +/* + * OnProgress. + */ +void SvBindStatusCallback::OnProgress ( + ULONG nNow, ULONG nMax, SvBindStatus eStat, const String& rStatusText) +{ + ULONG nTicks = std::max((Time::GetSystemTicks() - m_nStartTicks), (ULONG) 1); + + SvProgressArg aArg (rStatusText); + aArg.nProgress = nNow; + aArg.nMax = nMax; + aArg.eStatus = eStat; + aArg.nRate = (float)((nNow * 1000.0) / nTicks); + + m_aProgressCallback.Call (&aArg); +} + +/* + * OnDataAvailable (SvLockBytes). + */ +void SvBindStatusCallback::OnDataAvailable ( + SvStatusCallbackType eType, ULONG, SvLockBytes&) +{ + SvBindStatusCallbackRef xThis (this); + + if (!m_bInAvailableCall) + { + do + { + m_bInAvailableCall = TRUE; + + m_bReloadPending |= + (eType == SVBSCF_RELOADAVAILABLENOTIFICATION); + if (m_bReloadPending) + { + m_bReloadPending = FALSE; + m_aReloadLink.Call (this); + } + + m_bPartPending |= + (eType == SVBSCF_NEWPARTAVAILABLENOTIFICATION); + if (m_bPartPending) + { + m_bPartPending = FALSE; + m_aPartLink.Call (this); + } + + m_bDataPending |= + ((eType == SVBSCF_FIRSTDATANOTIFICATION) || + (eType == SVBSCF_LASTDATANOTIFICATION ) || + (eType == SVBSCF_INTERMEDIATEDATANOTIFICATION)); + if (m_bDataPending) + { + m_bDataPending = FALSE; + m_aDataLink.Call (this); + } + + m_bInAvailableCall = FALSE; + } while (m_bDataPending || m_bPartPending || m_bReloadPending); + } + else + { + switch (eType) + { + case SVBSCF_RELOADAVAILABLENOTIFICATION: + m_bReloadPending = TRUE; + break; + + case SVBSCF_NEWPARTAVAILABLENOTIFICATION: + m_bPartPending = TRUE; + break; + + default: + m_bDataPending = TRUE; + break; + } + } + + if (m_bDonePending) + { + m_bDonePending = FALSE; + m_aDoneLink.Call (this); + } +} + +/* + * OnDataAvailable (SvStream). + */ +void SvBindStatusCallback::OnDataAvailable ( + SvStatusCallbackType eType, ULONG, SvStream&) +{ + SvLockBytes aLB(NULL); + OnDataAvailable (eType, 0, aLB); +} + +/* + * OnStopBinding. + */ +void SvBindStatusCallback::OnStopBinding ( + ErrCode eErrCode, const String &rStatusText) +{ + (void)eErrCode; + (void)rStatusText; + + if (!m_bInAvailableCall) + m_aDoneLink.Call (this); + else + m_bDonePending = TRUE; +} + +/*======================================================================== + * + * SvKeyValueIterator implementation. + * + *======================================================================*/ +SV_DECL_PTRARR_DEL(SvKeyValueList_Impl, SvKeyValue*, 0, 4) +SV_IMPL_PTRARR(SvKeyValueList_Impl, SvKeyValue*); + +/* + * SvKeyValueIterator. + */ +SvKeyValueIterator::SvKeyValueIterator (void) + : m_pList (new SvKeyValueList_Impl), + m_nPos (0) +{ +} + +/* + * ~SvKeyValueIterator. + */ +SvKeyValueIterator::~SvKeyValueIterator (void) +{ + delete m_pList; +} + +/* + * GetFirst. + */ +BOOL SvKeyValueIterator::GetFirst (SvKeyValue &rKeyVal) +{ + m_nPos = m_pList->Count(); + return GetNext (rKeyVal); +} + +/* + * GetNext. + */ +BOOL SvKeyValueIterator::GetNext (SvKeyValue &rKeyVal) +{ + if (m_nPos > 0) + { + rKeyVal = *m_pList->GetObject(--m_nPos); + return TRUE; + } + else + { + // Nothing to do. + return FALSE; + } +} + +/* + * Append. + */ +void SvKeyValueIterator::Append (const SvKeyValue &rKeyVal) +{ + SvKeyValue *pKeyVal = new SvKeyValue (rKeyVal); + m_pList->C40_INSERT(SvKeyValue, pKeyVal, m_pList->Count()); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/persist/transprt.cxx b/bf_so3/source/persist/transprt.cxx new file mode 100644 index 000000000..2fab1af00 --- /dev/null +++ b/bf_so3/source/persist/transprt.cxx @@ -0,0 +1,2162 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define _TRANSPRT_CXX + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertiesChangeListener.hpp> +#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp> + +#include <com/sun/star/container/XNameAccess.hpp> + +#include <com/sun/star/io/XActiveDataControl.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XStreamListener.hpp> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionApprove.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> + +#include <com/sun/star/ucb/CHAOSProgressStart.hpp> +#include <com/sun/star/ucb/Command.hpp> +#include <com/sun/star/ucb/DocumentHeaderField.hpp> +#include <com/sun/star/ucb/InteractiveCHAOSException.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/ucb/PostCommandArgument.hpp> +#include <com/sun/star/ucb/XContent.hpp> + +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Reference.h> + +#include <cppuhelper/weak.hxx> + +#include <sal/macros.h> +#include <osl/mutex.hxx> +#include <rtl/ref.hxx> + +#include <bf_svtools/bf_solar.h> +#include <tools/debug.hxx> +#include <tools/datetime.hxx> +#include <tools/errcode.hxx> +#include <tools/errinf.hxx> +#include <tools/inetmsg.hxx> +#include <tools/stream.hxx> +#include <bf_tools/string.hxx> +#include <tools/urlobj.hxx> +#include <tools/wldcrd.hxx> + +#include <vcl/svapp.hxx> + +#include <bf_svtools/inettype.hxx> + +#include <bf_so3/binding.hxx> +#include <binddata.hxx> +#include <bf_so3/transprt.hxx> +#include <transuno.hxx> +#include <bf_so3/so2defs.hxx> + +#ifndef CONTENT_TYPE_STR_APP_WWWFORM +#define CONTENT_TYPE_STR_APP_WWWFORM "application/x-www-form-urlencoded" +#endif + +#ifndef ERRCODE_CHAOS_SERVER_ERROR /* cntids.hrc */ +#define ERRCODE_CHAOS_SERVER_ERROR (ERRCODE_AREA_CHAOS + 5) +#endif + +using namespace com::sun::star::container; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::task; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; +using namespace com::sun::star::io; +using namespace cppu; +using rtl::OUString; + +namespace binfilter { + +/*======================================================================== + * + * TODO: + * + * - UcbHTTPTransport_Impl: + * - interaction handling (SVBIND_SUCCESSONERRORDOC). + * + *======================================================================*/ + +/*======================================================================== + * + * SvBindingTransport implementation. + * + *======================================================================*/ +/* + * SvBindingTransport. + */ +SvBindingTransport::SvBindingTransport (void) +{ +} + +/* + * ~SvBindingTransport. + */ +SvBindingTransport::~SvBindingTransport (void) +{ +} + +/*======================================================================== + * + * SvBindingTransportFactory implementation. + * + *======================================================================*/ +SvBindingTransportFactory::SvBindingTransportFactory (void) +{ + SvBindingTransportFactoryList &rList = BAPP()->m_aTransportFactories; + rList.push_back( this ); +} + +SvBindingTransportFactory::~SvBindingTransportFactory (void) +{ + SvBindingTransportFactoryList &rList = BAPP()->m_aTransportFactories; + for ( SvBindingTransportFactoryList::iterator it = rList.begin(); + it < rList.end(); + ++it + ) + { + if ( *it == this ) + { + rList.erase( it ); + break; + } + } +} + +SvBindingTransportContext::~SvBindingTransportContext (void) +{ +} + +/*======================================================================== + * + * SvLockBytesFactory implementation. + * + *======================================================================*/ + +/* + * ~SvLockBytesFactory. + */ +SvLockBytesFactory::~SvLockBytesFactory (void) +{ + SvLockBytesFactoryList &rList = BAPP()->m_aLockBytesFactories; + for ( SvLockBytesFactoryList::iterator it = rList.begin(); + it < rList.end(); + ++it + ) + { + if ( *it == this ) + { + rList.erase( it ); + break; + } + } +} + +/* + * GetFactory. + */ +SvLockBytesFactory* SvLockBytesFactory::GetFactory (const String &rUrl) +{ + SvLockBytesFactoryList &rList = BAPP()->m_aLockBytesFactories; + SvLockBytesFactory *pFactory = NULL; + + size_t i, n = rList.size(); + for (i = 0; i < n; i++) + { + pFactory = rList[ i ]; + if (pFactory) + { + WildCard aWild (pFactory->GetWildcard()); + if (aWild.Matches(rUrl)) + break; + } + pFactory = NULL; + } + return pFactory; +} + +/*======================================================================== + * + * SfxSimpleLockBytesFactory implementation. + * + *======================================================================*/ +USHORT SfxSimpleLockBytesFactory::m_nCounter = 0; + + +/* + * ~SfxSimpleLockBytesFactory. + */ +SfxSimpleLockBytesFactory::~SfxSimpleLockBytesFactory (void) +{ +} + +/* + * CreateLockBytes. + */ +SvLockBytesRef SfxSimpleLockBytesFactory::CreateLockBytes ( + const String &rUrl, String &rMime) +{ + (void)rUrl; + + rMime = m_aMime; + return m_xLockBytes; +} + +/*======================================================================== + * + * SvLockBytesTransport interface. + * + *======================================================================*/ +class SvLockBytesTransport : public SvBindingTransport +{ + /** Representation. + */ + String m_aUrl; + SvLockBytesFactory &m_rFactory; + SvBindingTransportCallback *m_pCallback; + + /** Not implemented. + */ + COPYCTOR_API(SvLockBytesTransport); + +public: + SvLockBytesTransport ( + const String &rUrl, + SvLockBytesFactory &rFactory, + SvBindingTransportCallback *pCB); + + virtual ~SvLockBytesTransport (void); + + virtual void Start (void); + virtual void Abort (void); +}; + +/*======================================================================== + * + * SvLockBytesTransport implementation. + * + *======================================================================*/ +/* + * SvLockBytesTransport. + */ +SvLockBytesTransport::SvLockBytesTransport ( + const String &rUrl, + SvLockBytesFactory &rFactory, + SvBindingTransportCallback *pCB) + : m_aUrl (rUrl), + m_rFactory (rFactory), + m_pCallback (pCB) +{ +} + +/* + * ~SvLockBytesTransport. + */ +SvLockBytesTransport::~SvLockBytesTransport (void) +{ +} + +/* + * Start. + */ +void SvLockBytesTransport::Start (void) +{ + DBG_ASSERT( + m_pCallback, "SvLockBytesTransport::Start(): No callback"); + if (m_pCallback == NULL) + return; + + String aMime; + SvLockBytesRef xLockBytes (m_rFactory.CreateLockBytes (m_aUrl, aMime)); + if (xLockBytes.Is()) + { + m_pCallback->OnMimeAvailable (aMime); + m_pCallback->OnDataAvailable ( + SVBSCF_LASTDATANOTIFICATION, 0, xLockBytes); + } + else + { + m_pCallback->OnError (ERRCODE_IO_ABORT); + } +} + +/* + * Abort. + */ +void SvLockBytesTransport::Abort (void) +{ +} + +/*======================================================================== + * + * SvLockBytesTransportFactory implementation. + * + *======================================================================*/ +/* + * SvLockBytesTransportFactory. + */ +SvLockBytesTransportFactory::SvLockBytesTransportFactory (void) + : SvBindingTransportFactory () +{ +} + +/* + * ~SvLockBytesTransportFactory. + */ +SvLockBytesTransportFactory::~SvLockBytesTransportFactory (void) +{ +} + +/* + * HasTransport. + */ +BOOL SvLockBytesTransportFactory::HasTransport (const String &rUrl) +{ + SvLockBytesFactory *pFactory = SvLockBytesFactory::GetFactory (rUrl); + if (pFactory) + return TRUE; + else + return FALSE; +} + +/* + * CreateTransport. + */ +SvBindingTransport* SvLockBytesTransportFactory::CreateTransport ( + const String &rUrl, + SvBindingTransportContext &rCtx, + SvBindingTransportCallback *pCB) +{ + (void)rCtx; + + SvLockBytesFactory *pFactory = SvLockBytesFactory::GetFactory (rUrl); + if (pFactory) + return new SvLockBytesTransport (rUrl, *pFactory, pCB); + else + return NULL; +} + +/*======================================================================== + * + * UcbTransportLockBytes. + * + *======================================================================*/ +class UcbTransportLockBytes : + public virtual SvLockBytes, + public virtual SvRefBase +{ +public: + inline UcbTransportLockBytes (void); + + inline Reference<XInputStream> getInputStream (void); + + inline sal_Bool hasInputStream (void) const; + + inline sal_Bool setInputStream ( + const Reference<XInputStream> &rxInputStream); + + inline void terminate (void); + + /** SvLockBytes. + */ + virtual void SetSynchronMode (BOOL bSynchron); + + virtual ErrCode ReadAt ( + ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const; + + virtual ErrCode WriteAt ( + ULONG, const void*, ULONG, ULONG *pWritten); + + virtual ErrCode Flush (void) const; + + virtual ErrCode SetSize (ULONG); + + virtual ErrCode Stat ( + SvLockBytesStat *pStat, SvLockBytesStatFlag) const; + +protected: + /** Destruction (SvRefBase). + */ + virtual ~UcbTransportLockBytes (void); + +private: + /** Representation. + */ + Reference<XInputStream> m_xInputStream; + sal_Bool m_bTerminated; + + sal_uInt32 m_nRead; + sal_uInt32 m_nSize; + + /** Not implemented. + */ + COPYCTOR_API(UcbTransportLockBytes); +}; + +/* + * UcbTransportLockBytesRef. + */ +SV_DECL_IMPL_REF(UcbTransportLockBytes); + +/* + * UcbTransportLockBytes. + */ +inline UcbTransportLockBytes::UcbTransportLockBytes (void) + : m_xInputStream (NULL), + m_bTerminated (sal_False), + m_nRead (0), + m_nSize (0) +{ +} + +/* + * UcbTransportLockBytes. + */ +UcbTransportLockBytes::~UcbTransportLockBytes (void) +{ + if (m_xInputStream.is()) + m_xInputStream->closeInput(); +} + +/* + * getInputStream. + */ +inline Reference<XInputStream> UcbTransportLockBytes::getInputStream (void) +{ + return m_xInputStream; +} + +/* + * hasInputStream. + */ +inline sal_Bool UcbTransportLockBytes::hasInputStream (void) const +{ + return m_xInputStream.is(); +} + +/* + * setInputStream. + */ +inline sal_Bool UcbTransportLockBytes::setInputStream ( + const Reference<XInputStream> &rxInputStream) +{ + if (m_xInputStream.is()) + m_xInputStream->closeInput(); + + m_xInputStream = rxInputStream; + return m_xInputStream.is(); +} + +/* + * terminate. + */ +/* inline */ void UcbTransportLockBytes::terminate (void) +{ + Reference<XSeekable> xSeekable (m_xInputStream, UNO_QUERY); + if (xSeekable.is()) + m_nSize = sal_uInt32(xSeekable->getLength()); + + m_bTerminated = sal_True; +} + +/* + * SetSynchronMode. + */ +void UcbTransportLockBytes::SetSynchronMode (BOOL bSynchron) +{ + SvLockBytes::SetSynchronMode (bSynchron); +} + +/* + * ReadAt. + */ +ErrCode UcbTransportLockBytes::ReadAt ( + ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const +{ + if (pRead) + *pRead = 0; + if (!m_xInputStream.is()) + return ERRCODE_IO_CANTREAD; + + Reference<XSeekable> xSeekable (m_xInputStream, UNO_QUERY); + if (!xSeekable.is()) + return ERRCODE_IO_CANTREAD; + + try + { + xSeekable->seek (nPos); + } + catch (IOException) + { + return ERRCODE_IO_CANTSEEK; + } + + Sequence<sal_Int8> aData; + sal_Int32 nSize; + + if(nCount > 0x7FFFFFFF) + { + nCount = 0x7FFFFFFF; + } + try + { + while (!m_bTerminated) + { + sal_uInt64 nLen = xSeekable->getLength(); + if (IsSynchronMode()) + { + if (nPos + nCount > nLen) + Application::Yield(); + else + break; + } + else + { + if (nPos + nCount > nLen) + return ERRCODE_IO_PENDING; + else + break; + } + } + nSize = m_xInputStream->readSomeBytes (aData, sal_Int32(nCount)); + } + catch (IOException) + { + return ERRCODE_IO_CANTREAD; + } + + rtl_copyMemory (pBuffer, aData.getConstArray(), nSize); + if (pRead) + *pRead = ULONG(nSize); + + if(m_nRead > nPos + nSize) + { + (const_cast< UcbTransportLockBytes* >(this))->m_nRead = m_nRead; + } + else + { + (const_cast< UcbTransportLockBytes* >(this))->m_nRead = nPos + nSize; + } + + return ERRCODE_NONE; +} + +/* + * WriteAt. + */ +ErrCode UcbTransportLockBytes::WriteAt ( + ULONG, const void*, ULONG, ULONG *pWritten) +{ + if (pWritten) + *pWritten = 0; + return ERRCODE_IO_CANTWRITE; +} + +/* + * Flush. + */ +ErrCode UcbTransportLockBytes::Flush (void) const +{ + return ERRCODE_NONE; +} + +/* + * SetSize. + */ +ErrCode UcbTransportLockBytes::SetSize (ULONG) +{ + return ERRCODE_IO_NOTSUPPORTED; +} + +/* + * Stat. + */ +ErrCode UcbTransportLockBytes::Stat ( + SvLockBytesStat *pStat, SvLockBytesStatFlag) const +{ + if (!pStat) + return ERRCODE_IO_INVALIDPARAMETER; + if (!m_xInputStream.is()) + return ERRCODE_IO_INVALIDACCESS; + + Reference<XSeekable> xSeekable (m_xInputStream, UNO_QUERY); + if (!xSeekable.is()) + return ERRCODE_IO_INVALIDACCESS; + + try + { + pStat->nSize = ULONG(xSeekable->getLength()); + } + catch (IOException) + { + return ERRCODE_IO_CANTTELL; + } + + if (!m_bTerminated) + return ERRCODE_IO_PENDING; + else + return ERRCODE_NONE; +} + +/*======================================================================== + * + * UcbTransportDataSink_Impl. + * + *======================================================================*/ +class UcbTransportDataSink_Impl : + public OWeakObject, + public XActiveDataControl, + public XActiveDataSink +{ +public: + inline UcbTransportDataSink_Impl (void); + + inline SvLockBytes* getLockBytes (void); + + /** XInterface. + */ + virtual Any SAL_CALL queryInterface ( + const Type &rType) throw(RuntimeException); + + virtual void SAL_CALL acquire (void) throw(); + + virtual void SAL_CALL release (void) throw(); + + /** XActiveDataControl. + */ + virtual void SAL_CALL addListener ( + const Reference<XStreamListener> &rxListener) + throw(RuntimeException); + + virtual void SAL_CALL removeListener ( + const Reference<XStreamListener> &rxListener) + throw(RuntimeException); + + virtual void SAL_CALL start (void) throw(RuntimeException); + + virtual void SAL_CALL terminate (void) throw(RuntimeException); + + /** XActiveDataSink. + */ + virtual void SAL_CALL setInputStream ( + const Reference<XInputStream> &rxInputStream) + throw(RuntimeException); + + virtual Reference<XInputStream> SAL_CALL getInputStream (void) + throw(RuntimeException); + +protected: + /** Destruction (OWeakObject). + */ + virtual ~UcbTransportDataSink_Impl (void); + +private: + /** Representation. + */ + UcbTransportLockBytesRef m_xLockBytes; + + /** Not implemented. + */ + COPYCTOR_API(UcbTransportDataSink_Impl); +}; + +/* + * UcbTransportDataSink_Impl. + */ +inline UcbTransportDataSink_Impl::UcbTransportDataSink_Impl (void) + : m_xLockBytes (new UcbTransportLockBytes()) +{ +} + +/* + * ~UcbTransportDataSink_Impl. + */ +UcbTransportDataSink_Impl::~UcbTransportDataSink_Impl (void) +{ +} + +/* + * getLockBytes. + */ +inline SvLockBytes* UcbTransportDataSink_Impl::getLockBytes (void) +{ + if (m_xLockBytes->hasInputStream()) + return m_xLockBytes; + else + return NULL; +} + +/* + * XInterface: queryInterface. + */ +Any SAL_CALL UcbTransportDataSink_Impl::queryInterface ( + const Type &rType) throw(RuntimeException) +{ + Any aRet (cppu::queryInterface ( + rType, + // (static_cast< XActiveDataControl* >(this)), + (static_cast< XActiveDataSink* >(this)))); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface (rType); +} + +/* + * XInterface: acquire. + */ +void SAL_CALL UcbTransportDataSink_Impl::acquire (void) throw() +{ + OWeakObject::acquire(); +} + +/* + * XInterface: release. + */ +void SAL_CALL UcbTransportDataSink_Impl::release (void) throw() +{ + OWeakObject::release(); +} + +/* + * XActiveDataControl: addListener (not supported). + */ +void SAL_CALL UcbTransportDataSink_Impl::addListener ( + const Reference<XStreamListener> & ) throw(RuntimeException) +{ +} + +/* + * XActiveDataControl: removeListener (not supported). + */ +void SAL_CALL UcbTransportDataSink_Impl::removeListener ( + const Reference<XStreamListener> & ) throw(RuntimeException) +{ +} + +/* + * XActiveDataControl: start (not supported). + */ +void SAL_CALL UcbTransportDataSink_Impl::start (void) throw(RuntimeException) +{ +} + +/* + * XActiveDataControl: terminate. + */ +void SAL_CALL UcbTransportDataSink_Impl::terminate (void) + throw(RuntimeException) +{ + m_xLockBytes->terminate(); +} + +/* + * XActiveDataSink: setInputStream. + */ +void SAL_CALL UcbTransportDataSink_Impl::setInputStream ( + const Reference<XInputStream> &rxInputStream) throw(RuntimeException) +{ + m_xLockBytes->setInputStream (rxInputStream); +} + +/* + * XActiveDataSink: getInputStream. + */ +Reference<XInputStream> SAL_CALL +UcbTransportDataSink_Impl::getInputStream (void) throw(RuntimeException) +{ + return m_xLockBytes->getInputStream(); +} + +/*======================================================================== + * + * UcbTransportInputStream_Impl. + * + *======================================================================*/ +class UcbTransportInputStream_Impl : + public OWeakObject, + public XInputStream, + public XSeekable +{ +public: + inline UcbTransportInputStream_Impl (SvLockBytes *pLockBytes); + + /** XInterface. + */ + virtual Any SAL_CALL queryInterface( + const Type &rType) throw (RuntimeException); + + virtual void SAL_CALL acquire (void) throw (); + + virtual void SAL_CALL release (void) throw (); + + /** XInputStream. + */ + virtual sal_Int32 SAL_CALL readBytes ( + Sequence<sal_Int8> &rData, sal_Int32 nBytesToRead) + throw (NotConnectedException, + BufferSizeExceededException, + IOException); + + virtual sal_Int32 SAL_CALL readSomeBytes ( + Sequence<sal_Int8> &rData, sal_Int32 nMaxBytesToRead) + throw (NotConnectedException, + BufferSizeExceededException, + IOException); + + virtual void SAL_CALL skipBytes (sal_Int32 nBytesToSkip) + throw (NotConnectedException, + BufferSizeExceededException, + IOException); + + virtual sal_Int32 SAL_CALL available (void) + throw (NotConnectedException, IOException); + + virtual void SAL_CALL closeInput (void) + throw (NotConnectedException, IOException); + + /** XSeekable. + */ + virtual void SAL_CALL seek (sal_Int64 nPosition) + throw (IllegalArgumentException, IOException); + + virtual sal_Int64 SAL_CALL getPosition (void) throw (IOException); + + virtual sal_Int64 SAL_CALL getLength (void) throw (IOException); + +protected: + /** Destruction (OWeakObject). + */ + virtual ~UcbTransportInputStream_Impl (void); + +private: + /** Representation. + */ + SvLockBytesRef m_xLockBytes; + sal_uInt32 m_nPosition; + + /** Not implemented. + */ + COPYCTOR_API(UcbTransportInputStream_Impl); +}; + +/* + * UcbTransportInputStream_Impl. + */ +inline UcbTransportInputStream_Impl::UcbTransportInputStream_Impl ( + SvLockBytes *pLockBytes) + : m_xLockBytes (pLockBytes), + m_nPosition (0) +{ +} + +/* + * ~UcbTransportInputStream_Impl. + */ +UcbTransportInputStream_Impl::~UcbTransportInputStream_Impl (void) +{ +} + +/* + * XInterface: queryInterface. + */ +Any SAL_CALL UcbTransportInputStream_Impl::queryInterface ( + const Type &rType) throw(RuntimeException) +{ + Any aRet (cppu::queryInterface ( + rType, + (static_cast< XInputStream* >(this)), + (static_cast< XSeekable* >(this)))); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface (rType); +} + +/* + * XInterface: acquire. + */ +void SAL_CALL UcbTransportInputStream_Impl::acquire (void) + throw () +{ + OWeakObject::acquire(); +} + +/* + * XInterface: release. + */ +void SAL_CALL UcbTransportInputStream_Impl::release (void) + throw () +{ + OWeakObject::release(); +} + +/* + * XInputStream: readBytes. + */ +sal_Int32 SAL_CALL UcbTransportInputStream_Impl::readBytes ( + Sequence<sal_Int8> &rData, sal_Int32 nBytesToRead) + throw(NotConnectedException, BufferSizeExceededException, IOException) +{ + if (!m_xLockBytes.Is()) + throw NotConnectedException(); + + rData.realloc(nBytesToRead); + sal_Int32 nSize = 0; + while (nSize < nBytesToRead) + { + ULONG nCount = 0; + ErrCode nError = m_xLockBytes->ReadAt ( + m_nPosition, + rData.getArray() + nSize, + nBytesToRead - nSize, + &nCount); + if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING) + throw IOException(); + m_nPosition += nCount; + nSize += nCount; + if (nError == ERRCODE_NONE && nCount == 0) + break; + } + + rData.realloc(nSize); + return nSize; +} + +/* + * XInputStream: readSomeBytes. + */ +sal_Int32 SAL_CALL UcbTransportInputStream_Impl::readSomeBytes ( + Sequence<sal_Int8> &rData, sal_Int32 nMaxBytesToRead) + throw(NotConnectedException, BufferSizeExceededException, IOException) +{ + if (!m_xLockBytes.Is()) + throw NotConnectedException(); + + rData.realloc(nMaxBytesToRead); + ULONG nCount; + ErrCode nError; + do + { + nError = m_xLockBytes->ReadAt ( + m_nPosition, + rData.getArray(), + nMaxBytesToRead < 0 ? 0 : nMaxBytesToRead, + &nCount); + if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING) + throw IOException(); + m_nPosition += nCount; + } + while (nCount == 0 && nError == ERRCODE_IO_PENDING); + + rData.realloc(sal_Int32(nCount)); + return sal_Int32(nCount); +} + +/* + * XInputStream: skipBytes. + */ +void SAL_CALL UcbTransportInputStream_Impl::skipBytes (sal_Int32 nBytesToSkip) + throw(NotConnectedException, BufferSizeExceededException, IOException) +{ + if (!m_xLockBytes.Is()) + throw NotConnectedException(); + if (nBytesToSkip < 0) + throw IOException(); + if (m_nPosition > 0xFFFFFFFF - nBytesToSkip) + throw BufferSizeExceededException(); + m_nPosition += nBytesToSkip; +} + +/* + * XInputStream: available. + */ +sal_Int32 SAL_CALL UcbTransportInputStream_Impl::available (void) + throw(NotConnectedException, IOException) +{ + if (!m_xLockBytes.Is()) + throw NotConnectedException(); + + SvLockBytesStat aStat; + if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE) + throw IOException(); + + return aStat.nSize <= m_nPosition ? 0 : + aStat.nSize - m_nPosition < 0x7FFFFFFF ? + sal_Int32(aStat.nSize - m_nPosition) : 0x7FFFFFFF; +} + +/* + * XInputStream: closeInput. + */ +void SAL_CALL UcbTransportInputStream_Impl::closeInput (void) + throw(NotConnectedException, IOException) +{ + if (!m_xLockBytes.Is()) + throw NotConnectedException(); + m_xLockBytes = 0; +} + +/* + * XSeekable: seek. + */ +void SAL_CALL UcbTransportInputStream_Impl::seek (sal_Int64 nPosition) + throw (IllegalArgumentException, IOException) +{ + if (nPosition < 0) + throw IllegalArgumentException(); + if (nPosition > 0x7FFFFFFF) + throw IOException(); + if (!m_xLockBytes.Is()) + throw IOException(); + m_nPosition = sal::static_int_cast<sal_uInt32>( nPosition ); +} + +/* + * XSeekable: getPosition. + */ +sal_Int64 SAL_CALL UcbTransportInputStream_Impl::getPosition (void) + throw (IOException) +{ + if (!m_xLockBytes.Is()) + throw IOException(); + return m_nPosition; +} + +/* + * XSeekable: getLength. + */ +sal_Int64 SAL_CALL UcbTransportInputStream_Impl::getLength (void) + throw (IOException) +{ + if (!m_xLockBytes.Is()) + throw IOException(); + + SvLockBytesStat aStat; + if (m_xLockBytes->Stat (&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE) + throw IOException(); + + return aStat.nSize; +} + +/*======================================================================== + * + * UcbTransport_Impl. + * + *======================================================================*/ + +class TransportThread_Impl : public ::osl::Thread +{ + Link m_aLink; +public: + TransportThread_Impl( const Link& rLink ) + : m_aLink( rLink ) + {} + + virtual void SAL_CALL run(); + void SAL_CALL onTerminated(); +}; + +void TransportThread_Impl::run() +{ + if( schedule() && m_aLink.IsSet() ) + m_aLink.Call(0); +} + +void TransportThread_Impl::onTerminated() +{ + delete this; +} + +class UcbTransport_Impl : + public OWeakObject, + public XCommandEnvironment, + public XInteractionHandler, + public XProgressHandler, + public XPropertiesChangeListener +{ +public: + inline UcbTransport_Impl ( + const String &rUrl, + SvBindingTransportContext &rCtx, + SvBindingTransportCallback *pCB); + + virtual void start (void); + virtual void abort (void); + + /** XInterface. + */ + virtual Any SAL_CALL queryInterface ( const Type &rType) throw(RuntimeException); + virtual void SAL_CALL acquire (void) throw(); + virtual void SAL_CALL release (void) throw(); + + virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler (void) throw(RuntimeException); + virtual Reference<XProgressHandler> SAL_CALL getProgressHandler (void) throw(RuntimeException); + + virtual void SAL_CALL disposing ( const EventObject &rEvent) throw(RuntimeException); + + /** XInteractionHandler. + */ + virtual void SAL_CALL handle ( const Reference<XInteractionRequest> &rxRequest) throw(RuntimeException); + + /** XProgressHandler. + */ + virtual void SAL_CALL push ( const Any &rStatus) throw(RuntimeException); + virtual void SAL_CALL update ( const Any &rStatus) throw(RuntimeException); + virtual void SAL_CALL pop (void) throw(RuntimeException); + + /** XPropertiesChangeListener. + */ + virtual void SAL_CALL propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException); + +protected: + /** Representation. + */ + Command m_aCommand; + String m_aUrl; + SvBindingTransportContext &m_rCtx; + SvBindingTransportCallback *m_pCallback; + rtl::Reference<UcbTransportDataSink_Impl> m_xSink; + SvLockBytesRef m_xLockBytes; + Reference<XContent> m_xContent; + OUString m_aContentType; + sal_Int32 m_nCommandId; + sal_Bool m_bMimeAvail : 1; + + /** Destruction (OWeakObject). + */ + virtual ~UcbTransport_Impl (void); + + /** dispose_Impl. + */ + void dispose_Impl (void); + + /** getCallback_Impl. + */ + inline sal_Bool getCallback_Impl ( + SvBindingTransportCallback *&rpCallback); + + /** getMutex_Impl. + */ + inline osl::Mutex& getMutex_Impl (void); + + /** createContent_Impl. + */ + inline Reference<XContent> createContent_Impl ( + const OUString &rUrl); + + /** getContentType_Impl. + */ + static OUString getContentType_Impl ( const Reference<XCommandProcessor> &rxProcessor); + DECL_LINK( ExecuteCallback, void* ); + +private: + /** Representation. + */ + osl::Mutex m_aMutex; + Reference<XInteractionHandler> m_xInteractionHdl; + oslInterlockedCount m_nProgressDepth; + sal_Int32 m_nProgressMin; + sal_Int32 m_nProgressMax; + + /** Not implemented. + */ + COPYCTOR_API(UcbTransport_Impl); +}; + +/* + * getCallback_Impl. + */ +inline sal_Bool UcbTransport_Impl::getCallback_Impl ( SvBindingTransportCallback *&rpCallback) +{ + osl::MutexGuard aGuard (m_aMutex); + rpCallback = m_pCallback; + return (!!rpCallback); +} + +/* + * getMutex_Impl. + */ +inline osl::Mutex& UcbTransport_Impl::getMutex_Impl (void) +{ + return m_aMutex; +} + +/* + * createContent_Impl. + */ +inline Reference<XContent> +UcbTransport_Impl::createContent_Impl (const OUString &rUrl) +{ + return SvBindingTransport_Impl::createContent (rUrl); +} + +/* + * UcbTransport_Impl. + */ +inline UcbTransport_Impl::UcbTransport_Impl ( + const String &rUrl, + SvBindingTransportContext &rCtx, + SvBindingTransportCallback *pCB) + : m_aUrl (rUrl), + m_rCtx (rCtx), + m_pCallback (pCB), + m_nCommandId (0), + m_bMimeAvail (sal_False), + m_nProgressDepth (0), + m_nProgressMin (0), + m_nProgressMax (0) +{ +} + +/* + * ~UcbTransport_Impl. + */ +UcbTransport_Impl::~UcbTransport_Impl (void) +{ +} + +IMPL_LINK( UcbTransport_Impl, ExecuteCallback, void*, pVoid ) +{ + (void)pVoid; + + // protect against destruction in dispose_impl + Reference < XCommandEnvironment > xEnv( this ); + + Reference<XCommandProcessor> xProcessor( m_xContent, UNO_QUERY ); + if ( xProcessor.is() && m_nCommandId ) + { + SvBindingTransportCallback *pCB=NULL; + if( getCallback_Impl( pCB ) ) + // notify that transport will start now + pCB->OnStart(); + + if ( m_bMimeAvail && getCallback_Impl(pCB) ) + // notify contenttype if available + pCB->OnMimeAvailable( m_aContentType ); + + Any aResult; + bool bException = false; + bool bAborted = false; + + try + { + // do it + aResult = xProcessor->execute( m_aCommand, m_nCommandId, xEnv ); + } + catch ( CommandAbortedException ) + { + bAborted = true; + } + catch ( Exception ) + { + bException = true; + } + + m_nCommandId = 0; + if ( bAborted || bException ) + { + // download aborted + if ( m_xSink.is() ) + { + m_xSink->terminate(); + m_xSink.clear(); + } + + if ( getCallback_Impl(pCB) ) + pCB->OnError( ERRCODE_ABORT ); + } + else + { + if ( !m_bMimeAvail ) + { + // contenttype was not detected until now, so get it + m_aContentType = getContentType_Impl(xProcessor); + } + + if ( m_xSink.is() ) + { + m_xSink->terminate(); + if( !m_xLockBytes.Is() ) + m_xLockBytes = m_xSink->getLockBytes(); + m_xSink.clear(); + } + + if ( !m_bMimeAvail ) + { + // contenttype was not notified until now + m_bMimeAvail = sal_True; + if( getCallback_Impl(pCB) ) + pCB->OnMimeAvailable( m_aContentType ); + } + + if( getCallback_Impl(pCB) ) + { + // last data notification. + pCB->OnDataAvailable( SVBSCF_LASTDATANOTIFICATION, m_nProgressMax, m_xLockBytes ); + } + } + } + + dispose_Impl(); + return 0; +} + +/* + * start. + */ +void UcbTransport_Impl::start (void) +{ + // Check context. + DBG_ASSERT( m_pCallback, "UcbTransport_Impl::start(): No callback"); + if (m_pCallback == NULL) + return; + + // Create content. + m_xContent = createContent_Impl (m_aUrl); + if (!m_xContent.is()) + { + m_pCallback->OnError (ERRCODE_IO_GENERAL); + return; + } + + Reference<XCommandProcessor> xProcessor (m_xContent, UNO_QUERY); + if (!xProcessor.is()) + { + m_pCallback->OnError (ERRCODE_IO_GENERAL); + return; + } + + // Check BindAction. + SvBindAction eAction = m_rCtx.GetBindAction(); + if( eAction == BINDACTION_GET ) + { + Reference<XPropertiesChangeNotifier> xProps (m_xContent, UNO_QUERY); + if (xProps.is()) + { + m_aContentType = getContentType_Impl (xProcessor); + if (m_aContentType.getLength() == 0) + m_aContentType = OUString(RTL_CONSTASCII_USTRINGPARAM( + CONTENT_TYPE_STR_APP_OCTSTREAM)); + m_bMimeAvail = sal_True; + xProps->addPropertiesChangeListener (Sequence<OUString>(), this); + } + + OpenCommandArgument2 aArgument; + aArgument.Mode = OpenMode::DOCUMENT; + aArgument.Priority = m_rCtx.GetPriority(); + + m_xSink = new UcbTransportDataSink_Impl(); + aArgument.Sink = (static_cast< OWeakObject* >(m_xSink.get())); + + if (m_rCtx.GetBindMode() & SVBIND_NEWESTVERSION) + m_aCommand.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "synchronize" )); + else + m_aCommand.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "open" )); + m_aCommand.Handle = -1; + m_aCommand.Argument <<= aArgument; + + m_nCommandId = xProcessor->createCommandIdentifier(); + TransportThread_Impl *pThread = new TransportThread_Impl( LINK( this, UcbTransport_Impl, ExecuteCallback ) ); + pThread->create(); + } + else if( eAction == BINDACTION_PUT ) + { + SvLockBytesRef xLockBytes (m_rCtx.GetPostLockBytes()); + if (!xLockBytes.Is()) + { + m_pCallback->OnError (ERRCODE_IO_INVALIDPARAMETER); + return; + } + + m_aCommand.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" )); + m_aCommand.Handle = -1; + m_aCommand.Argument <<= InsertCommandArgument( Reference<XInputStream> ( new UcbTransportInputStream_Impl(xLockBytes) ), + sal_False ); + + m_nCommandId = xProcessor->createCommandIdentifier(); + TransportThread_Impl *pThread = new TransportThread_Impl( LINK( this, UcbTransport_Impl, ExecuteCallback ) ); + pThread->create(); + } + else + { + // Unsupported. + m_pCallback->OnError (ERRCODE_IO_NOTSUPPORTED); + } +} + +/* + * abort. + */ +void UcbTransport_Impl::abort (void) +{ + m_aMutex.acquire(); + m_pCallback = NULL; + m_aMutex.release(); + + if ( m_nCommandId ) + { + Reference<XCommandProcessor> xProcessor( m_xContent, UNO_QUERY ); + xProcessor->abort( m_nCommandId ); + m_nCommandId = 0; + } +} + +/* + * XInterface: queryInterface. + */ +Any SAL_CALL UcbTransport_Impl::queryInterface ( const Type &rType) throw(RuntimeException ) +{ + Any aRet (cppu::queryInterface ( + rType, + (static_cast< XCommandEnvironment* >(this)), + (static_cast< XInteractionHandler* >(this)), + (static_cast< XProgressHandler* >(this)), + (static_cast< XPropertiesChangeListener* >(this)))); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface (rType); +} + +/* + * XInterface: acquire. + */ +void SAL_CALL UcbTransport_Impl::acquire (void) throw() +{ + OWeakObject::acquire(); +} + +/* + * XInterface: release. + */ +void SAL_CALL UcbTransport_Impl::release (void) throw() +{ + OWeakObject::release(); +} + +Reference<XInteractionHandler> SAL_CALL UcbTransport_Impl::getInteractionHandler (void) throw(RuntimeException) +{ + return this; +} + +Reference<XProgressHandler> SAL_CALL UcbTransport_Impl::getProgressHandler (void) throw(RuntimeException) +{ + return this; +} + +/* + * XEventListener: disposing. + */ +void SAL_CALL UcbTransport_Impl::disposing ( const EventObject & ) throw(RuntimeException) +{ + osl::MutexGuard aGuard (m_aMutex); + // m_xTask = NULL; +} + +/* + * XInteractionHandler: handle. + */ +void SAL_CALL UcbTransport_Impl::handle ( const Reference<XInteractionRequest> &rxRequest) throw(RuntimeException) +{ + if (!m_xInteractionHdl.is()) + { + Reference< XMultiServiceFactory > + xFactory(SvBindingTransport_Impl::getProcessServiceFactory(), + UNO_QUERY); + if (xFactory.is()) + m_xInteractionHdl + = Reference< XInteractionHandler >( + xFactory-> + createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ))), + UNO_QUERY); + } + DBG_ASSERT(m_xInteractionHdl.is(), + "UcbTransport_Impl::handle(): No handler"); + if (m_xInteractionHdl.is()) + m_xInteractionHdl->handle (rxRequest); +} + +/* + * XProgressHandler: push. + */ +void SAL_CALL UcbTransport_Impl::push ( const Any &rStatus) throw(RuntimeException) +{ + if (osl_incrementInterlockedCount (&m_nProgressDepth) == 1) + { + CHAOSProgressStart aStart; + if (rStatus >>= aStart) + { + m_nProgressMin = aStart.Minimum; + m_nProgressMax = aStart.Maximum; + } + + SvBindingTransportCallback *pCB = NULL; + if (getCallback_Impl (pCB)) + { + pCB->OnProgress ( m_nProgressMin, m_nProgressMax, SVBINDSTATUS_DOWNLOADINGDATA); + } + if (!m_xLockBytes.Is()) + { + if (m_xSink.is()) + m_xLockBytes = m_xSink->getLockBytes(); + } + if (m_bMimeAvail && m_xLockBytes.Is() && getCallback_Impl (pCB)) + { + // First data notification. + pCB->OnDataAvailable ( SVBSCF_FIRSTDATANOTIFICATION, m_nProgressMin, m_xLockBytes); + } + } +} + +/* + * XProgressHandler: update. + */ +void SAL_CALL UcbTransport_Impl::update ( const Any &rStatus) throw(RuntimeException) +{ + if (m_nProgressDepth == 1) + { + sal_Int32 nProgress = 0; + if ((rStatus >>= nProgress) && (nProgress > 0)) + { + SvBindingTransportCallback *pCB = NULL; + if (getCallback_Impl (pCB)) + { + pCB->OnProgress ( nProgress, m_nProgressMax, SVBINDSTATUS_DOWNLOADINGDATA); + } + if (!m_xLockBytes.Is()) + { + if (m_xSink.is()) + m_xLockBytes = m_xSink->getLockBytes(); + } + if (m_bMimeAvail && m_xLockBytes.Is() && getCallback_Impl (pCB)) + { + // Intermediate data notification. + pCB->OnDataAvailable ( SVBSCF_INTERMEDIATEDATANOTIFICATION, nProgress, m_xLockBytes); + } + } + } +} + +/* + * XProgressHandler: pop. + */ +void SAL_CALL UcbTransport_Impl::pop (void) throw(RuntimeException) +{ + if ( osl_decrementInterlockedCount (&m_nProgressDepth) == 0 ) + { + SvBindingTransportCallback *pCB = NULL; + if (getCallback_Impl (pCB)) + { + pCB->OnProgress ( m_nProgressMax, m_nProgressMax, SVBINDSTATUS_ENDDOWNLOADDATA); + } + } +} + +/* + * XPropertiesChangeListener: propertiesChange. + */ +void SAL_CALL UcbTransport_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException) +{ + SvBindingTransportCallback *pCB = NULL; + sal_Int32 i, n = rEvent.getLength(); + for (i = 0; i < n; i++) + { + PropertyChangeEvent evt (rEvent[i]); + if (evt.PropertyName == OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ))) + { + if (evt.NewValue >>= m_aContentType) + { + if (!m_bMimeAvail) + { + m_bMimeAvail = sal_True; + if (getCallback_Impl (pCB)) + pCB->OnMimeAvailable (m_aContentType); + } + } + continue; + } + if (evt.PropertyName == OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBody" ))) + { + if (m_xSink.is()) + m_xLockBytes = m_xSink->getLockBytes(); + continue; + } + } +} + +/* + * dispose_Impl. + */ +void UcbTransport_Impl::dispose_Impl (void) +{ + osl::MutexGuard aGuard (m_aMutex); + + Reference<XPropertiesChangeNotifier> xProps (m_xContent, UNO_QUERY); + if (xProps.is()) + xProps->removePropertiesChangeListener (Sequence<OUString>(), this); + m_xContent = NULL; + m_nProgressDepth = 0; +} + +/* + * getContentType_Impl. + */ +OUString UcbTransport_Impl::getContentType_Impl ( const Reference<XCommandProcessor> &rxProcessor) +{ + OUString aResult; + if (rxProcessor.is()) + { + OUString aName (OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ))); + Sequence<Property> aProps(1); + + aProps[0].Name = aName; + aProps[0].Handle = -1; + + Any aAny = SvBindingTransport_Impl::getProperties (rxProcessor, aProps); + Reference< XRow > xValues; + if ( aAny >>= xValues ) + { + Any aValue = xValues->getObject( 1, Reference< XNameAccess>() ); + aValue >>= aResult; + } + } + + return aResult; +} + +/*======================================================================== + * + * UcbHTTPTransport_Impl. + * + *======================================================================*/ +class UcbHTTPTransport_Impl : public UcbTransport_Impl +{ +public: + inline UcbHTTPTransport_Impl ( + const String &rUrl, + SvBindingTransportContext &rCtx, + SvBindingTransportCallback *pCB); + + /** UcbTransport_Impl. + */ + virtual void start (void); + + /** XInteractionHandler. + */ + virtual void SAL_CALL handle ( + const Reference<XInteractionRequest> &rxRequest) + throw(RuntimeException); + + /** XPropertiesChangeListener. + */ + virtual void SAL_CALL propertiesChange ( + const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException); + +protected: + /** Destruction (OWeakObject). + */ + virtual ~UcbHTTPTransport_Impl (void); + +private: + /** Representation. + */ + sal_Bool m_bNeedHead : 1; + sal_Bool m_bNeedMime : 1; + + /** analyzeHeader_Impl. + */ + void analyzeHeader_Impl ( + const Sequence<DocumentHeaderField> &rHdr); + + /** handleError_Impl. + */ + void handleError_Impl ( + const InteractiveCHAOSException &rException); + + /** Not implemented. + */ + COPYCTOR_API(UcbHTTPTransport_Impl); +}; + +/* + * UcbHTTPTransport_Impl. + */ +inline UcbHTTPTransport_Impl::UcbHTTPTransport_Impl ( + const String &rUrl, + SvBindingTransportContext &rCtx, + SvBindingTransportCallback *pCB) + : UcbTransport_Impl (rUrl, rCtx, pCB), + m_bNeedHead (sal_True), + m_bNeedMime (sal_True) +{ +} + +/* + * ~UcbHTTPTransport_Impl. + */ +UcbHTTPTransport_Impl::~UcbHTTPTransport_Impl (void) +{ +} + +/* + * UcbTransport_Impl: start. + */ +void UcbHTTPTransport_Impl::start (void) +{ + // Check context. + DBG_ASSERT( m_pCallback, "UcbHTTPTransport_Impl::start(): No callback"); + if (m_pCallback == NULL) + return; + + // Check HTTP initialization. + if (!BAPP()->HasHttpCache()) + { + m_pCallback->OnError (ERRCODE_IO_NOTSUPPORTED); + return; + } + + // Setup content URL. + String aOwnUrl (String::CreateFromAscii ( + RTL_CONSTASCII_STRINGPARAM ("private:httpcache#"))); + aOwnUrl += m_aUrl; + + // Create content. + m_xContent = createContent_Impl ( aOwnUrl ); + if (!m_xContent.is()) + { + m_pCallback->OnError (ERRCODE_IO_GENERAL); + return; + } + + Reference<XCommandProcessor> xProcessor (m_xContent, UNO_QUERY); + if (!xProcessor.is()) + { + m_pCallback->OnError (ERRCODE_IO_GENERAL); + return; + } + + Sequence<PropertyValue> aProps; + + // Check Referer URL. + String aUrl (m_rCtx.GetReferer()); + INetProtocol eProto = INetURLObject::CompareProtocolScheme (aUrl); + if ((eProto == INET_PROT_HTTPS) || + (eProto == INET_PROT_HTTP ) || + (eProto == INET_PROT_FTP ) ) + { + sal_Int32 n = aProps.getLength(); + aProps.realloc (n + 1); + + aProps[n].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" )); + aProps[n].Handle = -1; + aProps[n].Value <<= OUString(aUrl); + } + + // Check BindAction. + SvBindAction eAction = m_rCtx.GetBindAction(); + if (eAction == BINDACTION_GET) + { + Reference<XPropertiesChangeNotifier> xProps (m_xContent, UNO_QUERY); + if (xProps.is()) + { + SvBindingTransport_Impl::setProperties (xProcessor, aProps); + xProps->addPropertiesChangeListener (Sequence<OUString>(), this); + } + + m_xSink = new UcbTransportDataSink_Impl(); + + if (m_rCtx.GetBindMode() & SVBIND_NEWESTVERSION) + m_aCommand.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "synchronize" )); + else + m_aCommand.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "open" )); + m_aCommand.Handle = -1; + + OpenCommandArgument2 aArgument; + aArgument.Mode = OpenMode::DOCUMENT; + aArgument.Priority = m_rCtx.GetPriority(); + aArgument.Sink = (static_cast< OWeakObject* >(m_xSink.get())); + m_aCommand.Argument <<= aArgument; + + m_nCommandId = xProcessor->createCommandIdentifier(); + TransportThread_Impl *pThread = new TransportThread_Impl( LINK( this, UcbTransport_Impl, ExecuteCallback ) ); + pThread->create(); + } + else if ((eAction == BINDACTION_PUT) || (eAction == BINDACTION_POST)) + { + SvLockBytesRef xLockBytes (m_rCtx.GetPostLockBytes()); + if (!xLockBytes.Is()) + { + m_pCallback->OnError (ERRCODE_IO_INVALIDPARAMETER); + return; + } + + Reference<XPropertiesChangeNotifier > xProps (m_xContent, UNO_QUERY); + if (xProps.is()) + { + String aMimeType (m_rCtx.GetSendMimeType()); + if (!aMimeType.Len()) + { + if (eAction == BINDACTION_POST) + aMimeType.AppendAscii (CONTENT_TYPE_STR_APP_WWWFORM); + else + aMimeType.AppendAscii (CONTENT_TYPE_STR_APP_OCTSTREAM); + } + + sal_Int32 n = aProps.getLength(); + aProps.realloc (n + 1); + aProps[n].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" )); + aProps[n].Value <<= OUString(aMimeType); + + SvBindingTransport_Impl::setProperties (xProcessor, aProps); + xProps->addPropertiesChangeListener (Sequence<OUString>(), this); + } + + if (eAction == BINDACTION_PUT) + { + m_aCommand.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" )); + m_aCommand.Handle = -1; + m_aCommand.Argument <<= InsertCommandArgument( Reference<XInputStream> ( new UcbTransportInputStream_Impl(xLockBytes)), + sal_False ); + } + else + { + m_xSink = new UcbTransportDataSink_Impl(); + + m_aCommand.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "post" )); + m_aCommand.Handle = -1; + + PostCommandArgument aArgument; + aArgument.Source = new UcbTransportInputStream_Impl(xLockBytes); + aArgument.Sink = static_cast< OWeakObject* >(m_xSink.get()); + m_aCommand.Argument <<= aArgument; + } + + m_nCommandId = xProcessor->createCommandIdentifier(); + TransportThread_Impl *pThread = new TransportThread_Impl( LINK( this, UcbTransport_Impl, ExecuteCallback ) ); + pThread->create(); + } + else + { + // Unsupported. + m_pCallback->OnError (ERRCODE_IO_NOTSUPPORTED); + } +} + +/* + * XInteractionHandler: handle. + */ +void SAL_CALL UcbHTTPTransport_Impl::handle ( const Reference<XInteractionRequest> &rxRequest) throw(RuntimeException) +{ + if (rxRequest.is()) + { + Any aRequest (rxRequest->getRequest()); + InteractiveCHAOSException aException; + if (aRequest >>= aException) + { + if (aException.ID == ERRCODE_CHAOS_SERVER_ERROR) + { + typedef Reference<XInteractionContinuation> continue_type; + Sequence<continue_type> + aContinuations (rxRequest->getContinuations()); + + sal_Int32 i, n = aContinuations.getLength(); + for (i = 0; i < n; i++) + { + if (m_rCtx.GetBindMode() & SVBIND_SUCCESSONERRORDOC) + { + // Continue (and deliver error document). + Reference<XInteractionApprove> + xApprove (aContinuations[i], UNO_QUERY); + if (xApprove.is()) + { + xApprove->select(); + return; + } + + } + else + { + // Abort (and report error). + Reference<XInteractionAbort> + xAbort (aContinuations[i], UNO_QUERY); + if (xAbort.is()) + { + handleError_Impl (aException); + xAbort->select(); + return; + } + } + } + } + } + } + + UcbTransport_Impl::handle (rxRequest); +} + +/* + * XPropertiesChangeListener: propertiesChange. + */ +void SAL_CALL UcbHTTPTransport_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException) +{ + SvBindingTransportCallback *pCB = NULL; + sal_Int32 i, n = rEvent.getLength(); + for (i = 0; i < n; i++) + { + PropertyChangeEvent evt (rEvent[i]); + if (evt.PropertyName == OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentHeader" ))) + { + Sequence<DocumentHeaderField> aHead; + if (evt.NewValue >>= aHead) + { + if (m_bNeedHead) + { + m_bNeedHead = sal_False; + analyzeHeader_Impl (aHead); + } + + if (!m_bNeedMime && !m_bMimeAvail) + { + m_bMimeAvail = sal_True; + if (getCallback_Impl (pCB)) + pCB->OnMimeAvailable (m_aContentType); + } + } + continue; + } + if (evt.PropertyName == OUString( RTL_CONSTASCII_USTRINGPARAM( "PresentationURL" ))) + { + OUString aUrl; + if (evt.NewValue >>= aUrl) + { + OUString aBad (OUString( RTL_CONSTASCII_USTRINGPARAM( "private:" ))); + if (!(aUrl.compareTo (aBad, aBad.getLength()) == 0)) + { + // URL changed (Redirection). + m_aUrl = String( aUrl ); + + if (getCallback_Impl (pCB)) + pCB->OnRedirect (m_aUrl); + } + } + continue; + } + } + + UcbTransport_Impl::propertiesChange (rEvent); +} + +/* + * analyzeHeader_Impl. + */ +void UcbHTTPTransport_Impl::analyzeHeader_Impl ( + const Sequence<DocumentHeaderField> &rHdr) +{ + SvBindingTransportCallback *pCB = NULL; + sal_Int32 k, m = rHdr.getLength(); + for (k = 0; k < m; k++) + { + String aName( rHdr[k].Name ); + String aValue( rHdr[k].Value ); + + if (getCallback_Impl (pCB)) + pCB->OnHeaderAvailable (aName, aValue); + + if (aName.CompareIgnoreCaseToAscii("Content-Type") == COMPARE_EQUAL) + { + osl::MutexGuard aGuard (getMutex_Impl()); + + m_aContentType = aValue; + m_bNeedMime = sal_False; + + continue; + } + if (aName.CompareIgnoreCaseToAscii("Expires") == COMPARE_EQUAL) + { + DateTime aExpires (0, 0); + if (INetRFC822Message::ParseDateField (aValue, aExpires)) + { + aExpires.ConvertToLocalTime(); + if (getCallback_Impl (pCB)) + pCB->OnExpiresAvailable (aExpires); + } + continue; + } + } +} + +/* + * handleError_Impl. + */ +void UcbHTTPTransport_Impl::handleError_Impl ( + const InteractiveCHAOSException &rException) +{ + sal_uInt32 eErrCode = rException.ID; + + if (rException.Arguments.getLength() >= 2) + eErrCode = *new TwoStringErrorInfo ( + eErrCode, + String (rException.Arguments[0].getStr()), + String (rException.Arguments[1].getStr())); + + if (rException.Arguments.getLength() == 1) + eErrCode = *new StringErrorInfo ( + eErrCode, + String (rException.Arguments[0].getStr())); + + ErrorHandler::HandleError (eErrCode); +} + +/*======================================================================== + * + * UcbTransport. + * + *======================================================================*/ +class UcbTransport : public SvBindingTransport +{ +public: + UcbTransport (const rtl::Reference<UcbTransport_Impl> &rxImpl); + virtual ~UcbTransport (void); + + /** SvBindingTransport. + */ + virtual void Start (void); + virtual void Abort (void); + +private: + /** Representation. + */ + rtl::Reference<UcbTransport_Impl> m_xImpl; + + /** Not implemented. + */ + COPYCTOR_API(UcbTransport); +}; + +/* + * UcbTransport. + */ +UcbTransport::UcbTransport (const rtl::Reference<UcbTransport_Impl> &rxImpl) + : m_xImpl (rxImpl) +{ +} + +/* + * ~UcbTransport. + */ +UcbTransport::~UcbTransport (void) +{ +} + +/* + * Start. + */ +void UcbTransport::Start (void) +{ + if (m_xImpl.is()) + m_xImpl->start(); +} + +/* + * Abort. + */ +void UcbTransport::Abort (void) +{ + if (m_xImpl.is()) + m_xImpl->abort(); +} + +/*======================================================================== + * + * CntTransportFactory implementation. + * + *======================================================================*/ +/* + * CntTransportFactory. + */ +CntTransportFactory::CntTransportFactory (void) + : SvBindingTransportFactory () +{ +} + +/* + * ~CntTransportFactory. + */ +CntTransportFactory::~CntTransportFactory (void) +{ +} + +/* + * HasTransport. + */ +BOOL CntTransportFactory::HasTransport (const String &rUrl) +{ + INetProtocol eProto = INetURLObject::CompareProtocolScheme (rUrl); + return ((eProto == INET_PROT_HTTPS) || + (eProto == INET_PROT_HTTP ) || + (eProto == INET_PROT_FILE ) || + (eProto == INET_PROT_FTP ) ); +} + +/* + * CreateTransport. + */ +SvBindingTransport* CntTransportFactory::CreateTransport ( + const String &rUrl, + SvBindingTransportContext &rCtx, + SvBindingTransportCallback *pCB) +{ + INetProtocol eProto = INetURLObject::CompareProtocolScheme (rUrl); + if ((eProto == INET_PROT_HTTPS) || + (eProto == INET_PROT_HTTP ) || + (eProto == INET_PROT_FILE ) || + (eProto == INET_PROT_FTP ) ) + { + rtl::Reference<UcbTransport_Impl> xImpl; + if ((eProto == INET_PROT_HTTPS) || (eProto == INET_PROT_HTTP)) + xImpl = new UcbHTTPTransport_Impl (rUrl, rCtx, pCB); + else if ((eProto == INET_PROT_FTP) && BAPP()->ShouldUseFtpProxy (rUrl)) + xImpl = new UcbHTTPTransport_Impl (rUrl, rCtx, pCB); + else + xImpl = new UcbTransport_Impl (rUrl, rCtx, pCB); + return new UcbTransport (xImpl); + } + return NULL; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/persist/transuno.cxx b/bf_so3/source/persist/transuno.cxx new file mode 100644 index 000000000..292ff2679 --- /dev/null +++ b/bf_so3/source/persist/transuno.cxx @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef _RTL_WSTRING +#include <rtl/ustring.h> +#endif + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/XInterface.hpp> + +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <com/sun/star/ucb/UniversalContentBroker.hpp> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/XUniversalContentBroker.hpp> + +#include <comphelper/processfactory.hxx> + +#include <transuno.hxx> + +/*======================================================================== + * + * SvBindingTransport_Impl internals. + * + *======================================================================*/ +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; +using namespace com::sun::star::sdbc; + +namespace binfilter { + +typedef com::sun::star::lang::XMultiServiceFactory factory_type; + +/*======================================================================== + * + * SvBindingTransport_Impl implementation. + * + *======================================================================*/ +/* + * getProcessServiceFactory. + */ +com::sun::star::uno::Reference<com::sun::star::uno::XInterface> +SvBindingTransport_Impl::getProcessServiceFactory (void) +{ + return com::sun::star::uno::Reference<com::sun::star::uno::XInterface>( + comphelper::getProcessServiceFactory(), com::sun::star::uno::UNO_QUERY_THROW); +} + +/* + * createContent. + */ +com::sun::star::uno::Reference<XContent> +SvBindingTransport_Impl::createContent (const rtl::OUString &rUrl) +{ + com::sun::star::uno::Reference<XUniversalContentBroker> + xBroker (UniversalContentBroker::create(comphelper::getProcessComponentContext())); + return xBroker->queryContent (xBroker->createContentIdentifier (rUrl)); +} + +/* + * getProperties. + */ +Any SvBindingTransport_Impl::getProperties ( const Reference<XCommandProcessor> &rxProcessor, const Sequence<Property> &rProperties) +{ + Any aResult; + if (rxProcessor.is() && rProperties.getLength()) + { + try + { + com::sun::star::uno::Reference<XCommandEnvironment> xEnvironment; + Command aCommand; + aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" )); + aCommand.Handle = -1; /* unknown */ + aCommand.Argument <<= rProperties; + aResult = rxProcessor->execute( aCommand, 0, xEnvironment ); + } + catch (com::sun::star::uno::Exception &) + { + } + } + + return aResult; +} + +/* + * setProperties. + */ +void SvBindingTransport_Impl::setProperties ( const Reference<XCommandProcessor> &rxProcessor, const Sequence<PropertyValue> &rProperties) +{ + if (rxProcessor.is() && rProperties.getLength()) + { + try + { + Reference<XCommandEnvironment> xEnvironment; + Command aCommand; + aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" )); + aCommand.Handle = -1; /* unknown */ + aCommand.Argument <<= rProperties; + rxProcessor->execute( aCommand, 0, xEnvironment ); + } + catch (com::sun::star::uno::Exception &) + { + } + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/persist/transuno.hxx b/bf_so3/source/persist/transuno.hxx new file mode 100644 index 000000000..fe2fe2396 --- /dev/null +++ b/bf_so3/source/persist/transuno.hxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef _TRANSUNO_HXX +#define _TRANSUNO_HXX + +#ifndef _RTL_USTRING_ +#include <rtl/ustring.h> +#endif + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/ucb/PropertyValueInfo.hpp> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/sdbc/XRow.hpp> + +using com::sun::star::beans::PropertyValue; +using com::sun::star::beans::Property; +using com::sun::star::ucb::XContent; +using com::sun::star::ucb::XCommandProcessor; + +namespace binfilter { + +/*======================================================================== + * + * SvBindingTransport_Impl interface. + * + *======================================================================*/ +class SvBindingTransport_Impl +{ +public: + /** getProcessServiceFactory. + */ + static com::sun::star::uno::Reference<com::sun::star::uno::XInterface> + getProcessServiceFactory (void); + + /** createContent. + */ + static com::sun::star::uno::Reference<XContent> + createContent ( + const rtl::OUString &rUrl); + + /** getProperties. + */ + static com::sun::star::uno::Any + getProperties ( + const com::sun::star::uno::Reference<XCommandProcessor> &rxProc, + const com::sun::star::uno::Sequence<Property> &rxProp); + + /** setProperties. + */ + static void setProperties ( + const com::sun::star::uno::Reference<XCommandProcessor> &rxProc, + const com::sun::star::uno::Sequence<PropertyValue> &rxProp); +}; + +/*======================================================================== + * + * The End. + * + *======================================================================*/ + +} + +#endif /* !_TRANSUNO_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/solink/impldde.cxx b/bf_so3/source/solink/impldde.cxx new file mode 100644 index 000000000..cbac2722c --- /dev/null +++ b/bf_so3/source/solink/impldde.cxx @@ -0,0 +1,374 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#if defined WNT +#include <bf_svtools/bf_prewin.h> +#include <bf_svtools/bf_postwin.h> +#endif + +#include "impldde.hxx" + +#include <vcl/svapp.hxx> +#include <vcl/msgbox.hxx> +#include <sot/exchange.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/ustring.hxx> + +#include <bf_so3/iface.hxx> +#include "svuidlg.hrc" +#include "bf_so3/lnkbase.hxx" +#include "bf_so3/linkmgr.hxx" +#include "bf_so3/soerr.hxx" + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <bf_svtools/svdde.hxx> +#include <sot/formats.hxx> + +#define DDELINK_COLD 0 +#define DDELINK_HOT 1 + +#define DDELINK_ERROR_APP 1 +#define DDELINK_ERROR_DATA 2 +#define DDELINK_ERROR_LINK 3 + +using namespace ::com::sun::star::uno; + +namespace binfilter +{ + +SvDDEObject::SvDDEObject() + : pConnection( 0 ), pLink( 0 ), pRequest( 0 ), pGetData( 0 ), nError( 0 ) +{ + SetUpdateTimeout( 100 ); + bWaitForData = FALSE; +} + +SvDDEObject::~SvDDEObject() +{ + delete pLink; + delete pRequest; + delete pConnection; +} + +BOOL SvDDEObject::GetData( ::com::sun::star::uno::Any & rData /*out param*/, + const String & rMimeType, + BOOL bSynchron ) +{ + if( !pConnection ) + return FALSE; + + if( pConnection->GetError() ) // dann versuchen wir es nochmal + { + String sServer( pConnection->GetServiceName() ); + String sTopic( pConnection->GetTopicName() ); + + delete pConnection; + pConnection = new DdeConnection( sServer, sTopic ); + if( pConnection->GetError() ) + nError = DDELINK_ERROR_APP; + } + + if( bWaitForData ) // wir sind rekursiv drin, wieder raus + return FALSE; + + // Verriegeln gegen Reentrance + bWaitForData = TRUE; + + // falls gedruckt werden soll, warten wir bis die Daten vorhanden sind + if( bSynchron ) + { + DdeRequest aReq( *pConnection, sItem, 5000 ); + aReq.SetDataHdl( LINK( this, SvDDEObject, ImplGetDDEData ) ); + aReq.SetFormat( SotExchange::GetFormatIdFromMimeType( rMimeType )); + + pGetData = &rData; + + do { + aReq.Execute(); + } while( aReq.GetError() && ImplHasOtherFormat( aReq ) ); + + if( pConnection->GetError() ) + nError = DDELINK_ERROR_DATA; + + bWaitForData = FALSE; + } + else + { + // ansonsten wird es asynchron ausgefuehrt +// if( !pLink || !pLink->IsBusy() ) + { + if( pRequest ) + delete pRequest; + + pRequest = new DdeRequest( *pConnection, sItem ); + pRequest->SetDataHdl( LINK( this, SvDDEObject, ImplGetDDEData ) ); + pRequest->SetDoneHdl( LINK( this, SvDDEObject, ImplDoneDDEData ) ); + pRequest->SetFormat( SotExchange::GetFormatIdFromMimeType( + rMimeType ) ); + pRequest->Execute(); + } + + ::rtl::OUString aEmptyStr; + rData <<= aEmptyStr; + } + return 0 == pConnection->GetError(); +} + + +BOOL SvDDEObject::Connect( SvBaseLink * pSvLink ) +{ +#if defined(WIN) || defined(WNT) + static BOOL bInWinExec = FALSE; +#endif + + USHORT nLinkType = pSvLink->GetUpdateMode(); + if( pConnection ) // Verbindung steht ja schon + { + // tja, dann nur noch als Abhaengig eintragen + AddDataAdvise( pSvLink, + SotExchange::GetFormatMimeType( pSvLink->GetContentType()), + LINKUPDATE_ONCALL == nLinkType + ? ADVISEMODE_ONLYONCE + : 0 ); + AddConnectAdvise( pSvLink ); + + return TRUE; + } + + if( !pSvLink->GetLinkManager() ) + return FALSE; + + String sServer, sTopic; + pSvLink->GetLinkManager()->GetDisplayNames( pSvLink, &sServer, &sTopic, &sItem ); + + if( !sServer.Len() || !sTopic.Len() || !sItem.Len() ) + return FALSE; + + pConnection = new DdeConnection( sServer, sTopic ); + if( pConnection->GetError() ) + { + // kann man denn das System-Topic ansprechen ? + // dann ist der Server oben, kennt nur nicht das Topic! + if( sTopic.EqualsIgnoreCaseAscii( "SYSTEM" ) ) + { + BOOL bSysTopic; + { + DdeConnection aTmp( sServer, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "SYSTEM" ) ) ); + bSysTopic = !aTmp.GetError(); + } + + if( bSysTopic ) + { + nError = DDELINK_ERROR_DATA; + return FALSE; + } + // ansonsten unter Win/WinNT die Applikation direkt starten + } + +#if defined(WIN) || defined(WNT) + + // Server nicht da, starten und nochmal versuchen + if( !bInWinExec ) + { + rtl::OStringBuffer aCmdLine(rtl::OUStringToOString(sServer, + RTL_TEXTENCODING_ASCII_US)); + aCmdLine.append(".exe "); + aCmdLine.append(rtl::OUStringToOString(sTopic, + RTL_TEXTENCODING_ASCII_US)); + + if( WinExec( aCmdLine.getStr(), SW_SHOWMINIMIZED ) < 32 ) + nError = DDELINK_ERROR_APP; + else + { + USHORT i; + for( i=0; i<5; i++ ) + { + bInWinExec = TRUE; + Application::Reschedule(); + bInWinExec = FALSE; + + delete pConnection; + pConnection = new DdeConnection( sServer, sTopic ); + if( !pConnection->GetError() ) + break; + } + + if( i == 5 ) + { + nError = DDELINK_ERROR_APP; + } + } + } + else +#endif // WIN / WNT + { + nError = DDELINK_ERROR_APP; + } + } + + if( LINKUPDATE_ALWAYS == nLinkType && !pLink && !pConnection->GetError() ) + { + // Hot Link einrichten, Daten kommen irgendwann spaeter + pLink = new DdeHotLink( *pConnection, sItem ); + pLink->SetDataHdl( LINK( this, SvDDEObject, ImplGetDDEData ) ); + pLink->SetDoneHdl( LINK( this, SvDDEObject, ImplDoneDDEData ) ); + pLink->SetFormat( pSvLink->GetContentType() ); + pLink->Execute(); + } + + if( pConnection->GetError() ) + return FALSE; + + AddDataAdvise( pSvLink, + SotExchange::GetFormatMimeType( pSvLink->GetContentType()), + LINKUPDATE_ONCALL == nLinkType + ? ADVISEMODE_ONLYONCE + : 0 ); + AddConnectAdvise( pSvLink ); + SetUpdateTimeout( 0 ); + return TRUE; +} + +String SvDDEObject::Edit( Window* /*pParent*/, SvBaseLink * /*pLink_*/ ) +{ + OSL_FAIL( "SvDDEObject::Edit: not implemented!" ); + // TODO: dead corpses + return String(); +} + +BOOL SvDDEObject::ImplHasOtherFormat( DdeTransaction& rReq ) +{ + USHORT nFmt = 0; + switch( rReq.GetFormat() ) + { + case FORMAT_RTF: + nFmt = FORMAT_STRING; + break; + + case SOT_FORMATSTR_ID_HTML_SIMPLE: + case SOT_FORMATSTR_ID_HTML: + nFmt = FORMAT_RTF; + break; + + case FORMAT_GDIMETAFILE: + nFmt = FORMAT_BITMAP; + break; + + case SOT_FORMATSTR_ID_SVXB: + nFmt = FORMAT_GDIMETAFILE; + break; + + // sonst noch irgendwas ?? + } + if( nFmt ) + rReq.SetFormat( nFmt ); // damit nochmal versuchen + return 0 != nFmt; +} + +BOOL SvDDEObject::IsPending() const +/* [Beschreibung] + + Die Methode stellt fest, ob aus einem DDE-Object die Daten gelesen + werden kann. + Zurueckgegeben wird: + ERRCODE_NONE wenn sie komplett gelesen wurde + ERRCODE_SO_PENDING wenn sie noch nicht komplett gelesen wurde + ERRCODE_SO_FALSE sonst +*/ +{ + return bWaitForData; +} + +BOOL SvDDEObject::IsDataComplete() const +{ + return bWaitForData; +} + +IMPL_LINK( SvDDEObject, ImplGetDDEData, DdeData*, pData ) +{ + ULONG nFmt = pData->GetFormat(); + switch( nFmt ) + { + case FORMAT_GDIMETAFILE: + break; + + case FORMAT_BITMAP: + break; + + default: + { + const sal_Char* p = (sal_Char*)( pData->operator const void*() ); + long nLen = FORMAT_STRING == nFmt ? (p ? strlen( p ) : 0) : (long)*pData; + + Sequence< sal_Int8 > aSeq( (const sal_Int8*)p, nLen ); + if( pGetData ) + { + *pGetData <<= aSeq; // Daten kopieren + pGetData = 0; // und den Pointer bei mir zuruecksetzen + } + else + { + Any aVal; + aVal <<= aSeq; + DataChanged( SotExchange::GetFormatMimeType( + pData->GetFormat() ), aVal ); + bWaitForData = FALSE; + } + } + } + + return 0; +} + +IMPL_LINK( SvDDEObject, ImplDoneDDEData, void*, pData ) +{ + BOOL bValid = (BOOL)(ULONG)pData; + if( !bValid && ( pRequest || pLink )) + { + DdeTransaction* pReq = 0; + if( !pLink || ( pLink && pLink->IsBusy() )) + pReq = pRequest; // dann kann nur der fertig sein + else if( pRequest && pRequest->IsBusy() ) + pReq = pLink; // dann kann nur der fertig sein + + if( pReq ) + { + if( ImplHasOtherFormat( *pReq ) ) + { + pReq->Execute(); + } + else if( pReq == pRequest ) + { + // das wars dann + bWaitForData = FALSE; + } + } + } + else + // das warten ist beendet + bWaitForData = FALSE; + + return 0; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/solink/impldde.hxx b/bf_so3/source/solink/impldde.hxx new file mode 100644 index 000000000..56a2adff2 --- /dev/null +++ b/bf_so3/source/solink/impldde.hxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef _IMPLDDE_HXX +#define _IMPLDDE_HXX + +#include <bf_so3/linksrc.hxx> +#include <tools/link.hxx> +#include <bf_tools/string.hxx> + +namespace binfilter +{ +class DdeConnection; +class DdeData; +class DdeLink; +class DdeRequest; +class DdeTransaction; + +class SvDDEObject : public SvLinkSource +{ + String sItem; + + DdeConnection* pConnection; + DdeLink* pLink; + DdeRequest* pRequest; + ::com::sun::star::uno::Any * pGetData; + + BYTE bWaitForData : 1; // wird auf Daten gewartet? + BYTE nError : 7; // Error Code fuer den Dialog + + + BOOL ImplHasOtherFormat( DdeTransaction& ); + DECL_LINK( ImplGetDDEData, DdeData* ); + DECL_LINK( ImplDoneDDEData, void* ); + +protected: + virtual ~SvDDEObject(); + +public: + SvDDEObject(); + + virtual BOOL GetData( ::com::sun::star::uno::Any & rData /*out param*/, + const String & aMimeType, + BOOL bSynchron = FALSE ); + + virtual BOOL Connect( SvBaseLink * ); + virtual String Edit( Window*, SvBaseLink * ); + + virtual BOOL IsPending() const; + virtual BOOL IsDataComplete() const; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/solink/linkmgr2.cxx b/bf_so3/source/solink/linkmgr2.cxx new file mode 100644 index 000000000..95178e0e7 --- /dev/null +++ b/bf_so3/source/solink/linkmgr2.cxx @@ -0,0 +1,315 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <tools/debug.hxx> +#include "bf_so3/linkmgr.hxx" + +#include <vcl/msgbox.hxx> +#include "bf_so3/lnkbase.hxx" +#include "impldde.hxx" +#include "svuidlg.hrc" +#include <bf_so3/iface.hxx> + +#define _SVSTDARR_STRINGSDTOR + +#include <bf_svtools/svstdarr.hxx> + + +namespace binfilter +{ + +SV_IMPL_PTRARR( SvBaseLinks, SvBaseLinkRefPtr ) + +SvLinkManager::SvLinkManager() + : pPersist( 0 ) +{ +} + + +SvLinkManager::~SvLinkManager() +{ + SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData(); + for( USHORT n = aLinkTbl.Count(); n; --n, ++ppRef ) + { + if( (*ppRef)->Is() ) + { + (*(*ppRef))->Disconnect(); + (*(*ppRef))->pLinkMgr = 0; + } + delete *ppRef; + } +} + + +/************************************************************************ +|* SvLinkManager::Remove() +|* +|* Beschreibung +*************************************************************************/ + +void SvLinkManager::Remove( SvBaseLink *pLink ) +{ + // keine Links doppelt einfuegen + int bFound = FALSE; + SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData(); + for( USHORT n = aLinkTbl.Count(); n; --n, ++ppRef ) + { + if( pLink == *(*ppRef) ) + { + (*(*ppRef))->Disconnect(); + (*(*ppRef))->pLinkMgr = 0; + (*(*ppRef)).Clear(); + bFound = TRUE; + } + + // falls noch leere rum stehen sollten, weg damit + if( !(*ppRef)->Is() ) + { + delete *ppRef; + aLinkTbl.Remove( aLinkTbl.Count() - n, 1 ); + if( bFound ) + return ; + --ppRef; + } + } +} + + +void SvLinkManager::Remove( USHORT nPos, USHORT nCnt ) +{ + if( nCnt && nPos < aLinkTbl.Count() ) + { + if( nPos + nCnt > aLinkTbl.Count() ) + nCnt = aLinkTbl.Count() - nPos; + + SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData() + nPos; + for( USHORT n = nCnt; n; --n, ++ppRef ) + { + if( (*ppRef)->Is() ) + { + (*(*ppRef))->Disconnect(); + (*(*ppRef))->pLinkMgr = 0; + } + delete *ppRef; + } + aLinkTbl.Remove( nPos, nCnt ); + } +} + + +BOOL SvLinkManager::Insert( SvBaseLink* pLink ) +{ + // keine Links doppelt einfuegen + for( USHORT n = 0; n < aLinkTbl.Count(); ++n ) + { + SvBaseLinkRef* pTmp = aLinkTbl[ n ]; + if( !pTmp->Is() ) + aLinkTbl.DeleteAndDestroy( n-- ); + + if( pLink == *pTmp ) + return FALSE; + } + + SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink ); + pLink->pLinkMgr = this; + aLinkTbl.Insert( pTmp, aLinkTbl.Count() ); + return TRUE; +} + + +BOOL SvLinkManager::InsertLink( SvBaseLink * pLink, + USHORT nObjType, + USHORT nUpdateMode, + const String* pName ) +{ + // unbedingt zuerst + pLink->SetObjType( nObjType ); + if( pName ) + pLink->SetName( *pName ); + pLink->SetUpdateMode( nUpdateMode ); + return Insert( pLink ); +} + + +BOOL SvLinkManager::InsertDDELink( SvBaseLink * pLink, + const String& rServer, + const String& rTopic, + const String& rItem ) +{ + if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) ) + return FALSE; + + String sCmd; + ::binfilter::MakeLnkName( sCmd, &rServer, rTopic, rItem ); + + pLink->SetObjType( OBJECT_CLIENT_DDE ); + pLink->SetName( sCmd ); + return Insert( pLink ); +} + + +BOOL SvLinkManager::InsertDDELink( SvBaseLink * pLink ) +{ + DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" ); + if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) ) + return FALSE; + + if( pLink->GetObjType() == OBJECT_CLIENT_SO ) + pLink->SetObjType( OBJECT_CLIENT_DDE ); + + return Insert( pLink ); +} + + +// erfrage die Strings fuer den Dialog +BOOL SvLinkManager::GetDisplayNames( const SvBaseLink * pLink, + String* pType, + String* pFile, + String* pLinkStr, + String* pFilter ) const +{ + (void)pFilter; + + BOOL bRet = FALSE; + String aLN = pLink->GetLinkSourceName(); + if( aLN.Len() != 0 && pLink->GetObjType() == OBJECT_CLIENT_DDE ) + { + USHORT nTmp = 0; + String sCmd( aLN ); + String sServer( + sCmd.GetToken( + 0, + sal::static_int_cast< sal_Unicode >(cTokenSeperator), nTmp ) ); + String sTopic( + sCmd.GetToken( + 0, + sal::static_int_cast< sal_Unicode >(cTokenSeperator), nTmp ) ); + + if( pType ) + *pType = sServer; + if( pFile ) + *pFile = sTopic; + if( pLinkStr ) + *pLinkStr = sCmd.Copy( nTmp ); + bRet = TRUE; + } + return bRet; +} + + +void SvLinkManager::UpdateAllLinks( BOOL bCallErrHdl, + BOOL bUpdateGrfLinks ) +{ + (void)bCallErrHdl; + + SvStringsDtor aApps, aTopics, aItems; + String sApp, sTopic, sItem; + + // erstmal eine Kopie vom Array machen, damit sich updatende Links in + // Links in ... nicht dazwischen funken!! + SvPtrarr aTmpArr( 255, 50 ); + USHORT n; + for( n = 0; n < aLinkTbl.Count(); ++n ) + { + SvBaseLink* pLink = *aLinkTbl[ n ]; + if( !pLink ) + { + Remove( n-- ); + continue; + } + aTmpArr.Insert( pLink, aTmpArr.Count() ); + } + + for( n = 0; n < aTmpArr.Count(); ++n ) + { + SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ]; + + // suche erstmal im Array nach dem Eintrag + USHORT nFndPos = USHRT_MAX; + for( USHORT i = 0; i < aLinkTbl.Count(); ++i ) + if( pLink == *aLinkTbl[ i ] ) + { + nFndPos = i; + break; + } + + if( USHRT_MAX == nFndPos ) + continue; // war noch nicht vorhanden! + + // Graphic-Links noch nicht updaten + if( !pLink->IsVisible() || + ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() )) + continue; + + pLink->Update(); + } +} + +/************************************************************************ +|* SvBaseLink::CreateObject() +|* +|* Beschreibung +*************************************************************************/ + +SvLinkSourceRef SvLinkManager::CreateObj( SvBaseLink * pLink ) +{ + if( OBJECT_CLIENT_DDE == pLink->GetObjType() ) + return new SvDDEObject(); + return SvLinkSourceRef(); +} + +BOOL SvLinkManager::InsertServer( SvLinkSource* pObj ) +{ + // keine doppelt einfuegen + if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) ) + return FALSE; + + aServerTbl.Insert( pObj, aServerTbl.Count() ); + return TRUE; +} + + +void SvLinkManager::RemoveServer( SvLinkSource* pObj ) +{ + USHORT nPos = aServerTbl.GetPos( pObj ); + if( USHRT_MAX != nPos ) + aServerTbl.Remove( nPos, 1 ); +} + + +void MakeLnkName( String& rName, const String* pType, const String& rFile, + const String& rLink, const String* pFilter ) +{ + if( pType ) + (rName = *pType).EraseLeadingChars().EraseTrailingChars() += cTokenSeperator; + else if( rName.Len() ) + rName.Erase(); + + ((rName += rFile).EraseLeadingChars().EraseTrailingChars() += + cTokenSeperator ).EraseLeadingChars().EraseTrailingChars() += rLink; + if( pFilter ) + ((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars(); +} + +} + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/solink/linksrc.cxx b/bf_so3/source/solink/linksrc.cxx new file mode 100644 index 000000000..9475e52ca --- /dev/null +++ b/bf_so3/source/solink/linksrc.cxx @@ -0,0 +1,383 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <bf_so3/linksrc.hxx> +#include "bf_so3/lnkbase.hxx" +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <tools/debug.hxx> +#include <vcl/timer.hxx> +#include <bf_svtools/svarray.hxx> + + +using namespace ::com::sun::star::uno; + +namespace binfilter +{ + +TYPEINIT0( SvLinkSource ) + +/************** class SvLinkSourceTimer *********************************/ +class SvLinkSourceTimer : public Timer +{ + SvLinkSource * pOwner; + virtual void Timeout(); +public: + SvLinkSourceTimer( SvLinkSource * pOwn ); +}; + +SvLinkSourceTimer::SvLinkSourceTimer( SvLinkSource * pOwn ) + : pOwner( pOwn ) +{ +} + +void SvLinkSourceTimer::Timeout() +{ + // sicher gegen zerstoeren im Handler + SvLinkSourceRef aAdv( pOwner ); + pOwner->SendDataChanged(); +} + +static void StartTimer( SvLinkSourceTimer ** ppTimer, SvLinkSource * pOwner, + ULONG nTimeout ) +{ + if( !*ppTimer ) + { + *ppTimer = new SvLinkSourceTimer( pOwner ); + (*ppTimer)->SetTimeout( nTimeout ); + (*ppTimer)->Start(); + } +} + + +struct SvLinkSource_Entry_Impl +{ + SvBaseLinkRef xSink; + String aDataMimeType; + USHORT nAdviseModes; + BOOL bIsDataSink; + + SvLinkSource_Entry_Impl( SvBaseLink* pLink, const String& rMimeType, + USHORT nAdvMode ) + : xSink( pLink ), aDataMimeType( rMimeType ), + nAdviseModes( nAdvMode ), bIsDataSink( TRUE ) + {} + + SvLinkSource_Entry_Impl( SvBaseLink* pLink ) + : xSink( pLink ), nAdviseModes( 0 ), bIsDataSink( FALSE ) + {} + + ~SvLinkSource_Entry_Impl(); +}; + +SvLinkSource_Entry_Impl::~SvLinkSource_Entry_Impl() +{ +} + +typedef SvLinkSource_Entry_Impl* SvLinkSource_Entry_ImplPtr; +SV_DECL_PTRARR_DEL( SvLinkSource_Array_Impl, SvLinkSource_Entry_ImplPtr, 4, 4 ) +SV_IMPL_PTRARR( SvLinkSource_Array_Impl, SvLinkSource_Entry_ImplPtr ); + +class SvLinkSource_EntryIter_Impl +{ + SvLinkSource_Array_Impl aArr; + const SvLinkSource_Array_Impl& rOrigArr; + USHORT nPos; +public: + SvLinkSource_EntryIter_Impl( const SvLinkSource_Array_Impl& rArr ); + ~SvLinkSource_EntryIter_Impl(); + SvLinkSource_Entry_Impl* Curr() + { return nPos < aArr.Count() ? aArr[ nPos ] : 0; } + SvLinkSource_Entry_Impl* Next(); +}; + +SvLinkSource_EntryIter_Impl::SvLinkSource_EntryIter_Impl( + const SvLinkSource_Array_Impl& rArr ) + : rOrigArr( rArr ), nPos( 0 ) +{ + aArr.Insert( &rArr, 0 ); +} +SvLinkSource_EntryIter_Impl::~SvLinkSource_EntryIter_Impl() +{ + aArr.Remove( 0, aArr.Count() ); +} + +SvLinkSource_Entry_Impl* SvLinkSource_EntryIter_Impl::Next() +{ + SvLinkSource_Entry_ImplPtr pRet = 0; + if( nPos + 1 < aArr.Count() ) + { + ++nPos; + if( rOrigArr.Count() == aArr.Count() && + rOrigArr[ nPos ] == aArr[ nPos ] ) + pRet = aArr[ nPos ]; + else + { + // then we must search the current (or the next) in the orig + do { + pRet = aArr[ nPos ]; + if( USHRT_MAX != rOrigArr.GetPos( pRet )) + break; + pRet = 0; + ++nPos; + } while( nPos < aArr.Count() ); + + if( nPos >= aArr.Count() ) + pRet = 0; + } + } + return pRet; +} + +struct SvLinkSource_Impl +{ + SvLinkSource_Array_Impl aArr; + String aDataMimeType; + SvLinkSourceTimer * pTimer; + ULONG nTimeout; + + SvLinkSource_Impl() : pTimer( 0 ), nTimeout( 3000 ) {} + ~SvLinkSource_Impl(); + + void Closed(); +}; + +SvLinkSource_Impl::~SvLinkSource_Impl() +{ + delete pTimer; +} + +SvLinkSource::SvLinkSource() + : pImpl( new SvLinkSource_Impl ) +{ +} + +SvLinkSource::~SvLinkSource() +{ + delete pImpl; +} + +void SvLinkSource::Closed() +{ + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() ) + if( !p->bIsDataSink ) + p->xSink->Closed(); +} + +void SvLinkSource::SetUpdateTimeout( ULONG nTimeout ) +{ + pImpl->nTimeout = nTimeout; + if( pImpl->pTimer ) + pImpl->pTimer->SetTimeout( nTimeout ); +} + +void SvLinkSource::SendDataChanged() +{ + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + { + if( p->bIsDataSink ) + { + String sDataMimeType( pImpl->aDataMimeType ); + if( !sDataMimeType.Len() ) + sDataMimeType = p->aDataMimeType; + + Any aVal; + if( ( p->nAdviseModes & ADVISEMODE_NODATA ) || + GetData( aVal, sDataMimeType, TRUE ) ) + { + p->xSink->DataChanged( sDataMimeType, aVal ); + + if( p->nAdviseModes & ADVISEMODE_ONLYONCE ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } + + } + } + } + if( pImpl->pTimer ) + { + delete pImpl->pTimer; + pImpl->pTimer = NULL; + } + pImpl->aDataMimeType.Erase(); +} + +void SvLinkSource::NotifyDataChanged() +{ + if( pImpl->nTimeout ) + StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // Timeout neu + else + { + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + if( p->bIsDataSink ) + { + Any aVal; + if( ( p->nAdviseModes & ADVISEMODE_NODATA ) || + GetData( aVal, p->aDataMimeType, TRUE ) ) + { + p->xSink->DataChanged( p->aDataMimeType, aVal ); + + if( p->nAdviseModes & ADVISEMODE_ONLYONCE ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } + } + } + + if( pImpl->pTimer ) + { + delete pImpl->pTimer; + pImpl->pTimer = NULL; + } + } +} + +// notify the sink, the mime type is not +// a selection criterion +void SvLinkSource::DataChanged( const String & rMimeType, + const ::com::sun::star::uno::Any & rVal ) +{ + if( pImpl->nTimeout && !rVal.hasValue() ) + { // nur wenn keine Daten mitgegeben wurden + // fire all data to the sink, independent of the requested format + pImpl->aDataMimeType = rMimeType; + StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // Timeout neu + } + else + { + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + { + if( p->bIsDataSink ) + { + p->xSink->DataChanged( rMimeType, rVal ); + + if( p->nAdviseModes & ADVISEMODE_ONLYONCE ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } + } + } + + if( pImpl->pTimer ) + { + delete pImpl->pTimer; + pImpl->pTimer = NULL; + } + } +} + + +// only one link is correct +void SvLinkSource::AddDataAdvise( SvBaseLink * pLink, const String& rMimeType, + USHORT nAdviseModes ) +{ + SvLinkSource_Entry_ImplPtr pNew = new SvLinkSource_Entry_Impl( + pLink, rMimeType, nAdviseModes ); + pImpl->aArr.Insert( pNew, pImpl->aArr.Count() ); +} + +void SvLinkSource::RemoveAllDataAdvise( SvBaseLink * pLink ) +{ + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + if( p->bIsDataSink && &p->xSink == pLink ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } +} + +// only one link is correct +void SvLinkSource::AddConnectAdvise( SvBaseLink * pLink ) +{ + SvLinkSource_Entry_ImplPtr pNew = new SvLinkSource_Entry_Impl( pLink ); + pImpl->aArr.Insert( pNew, pImpl->aArr.Count() ); +} + +void SvLinkSource::RemoveConnectAdvise( SvBaseLink * pLink ) +{ + SvLinkSource_EntryIter_Impl aIter( pImpl->aArr ); + for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() ) + if( !p->bIsDataSink && &p->xSink == pLink ) + { + USHORT nFndPos = pImpl->aArr.GetPos( p ); + if( USHRT_MAX != nFndPos ) + pImpl->aArr.DeleteAndDestroy( nFndPos ); + } +} + +BOOL SvLinkSource::HasDataLinks( const SvBaseLink* pLink ) const +{ + BOOL bRet = FALSE; + const SvLinkSource_Entry_Impl* p; + for( USHORT n = 0, nEnd = pImpl->aArr.Count(); n < nEnd; ++n ) + if( ( p = pImpl->aArr[ n ] )->bIsDataSink && + ( !pLink || &p->xSink == pLink ) ) + { + bRet = TRUE; + break; + } + return bRet; +} + +// TRUE => waitinmg for data +BOOL SvLinkSource::IsPending() const +{ + return FALSE; +} + +// TRUE => data complete loaded +BOOL SvLinkSource::IsDataComplete() const +{ + return TRUE; +} + +BOOL SvLinkSource::Connect( SvBaseLink * ) +{ + return TRUE; +} + +BOOL SvLinkSource::GetData( ::com::sun::star::uno::Any & , + const String & , BOOL ) +{ + return FALSE; +} + +String SvLinkSource::Edit( Window *, SvBaseLink * ) +{ + return String(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/solink/lnkbase2.cxx b/bf_so3/source/solink/lnkbase2.cxx new file mode 100644 index 000000000..92fbd0b1f --- /dev/null +++ b/bf_so3/source/solink/lnkbase2.cxx @@ -0,0 +1,362 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "bf_so3/lnkbase.hxx" +#include <sot/exchange.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <vcl/msgbox.hxx> + +#include "bf_so3/linkmgr.hxx" +#include "svuidlg.hrc" +#include <bf_so3/iface.hxx> +#include <vcl/svapp.hxx> + +#include <tools/debug.hxx> + +#include <bf_svtools/svdde.hxx> + +using namespace ::com::sun::star::uno; + +namespace binfilter +{ + +TYPEINIT0( SvBaseLink ) + +// nur fuer die interne Verwaltung +struct ImplBaseLinkData +{ + struct tClientType + { + // gilt fuer alle Links + ULONG nCntntType; // Update Format + // nicht Ole-Links + BOOL bIntrnlLnk; // ist es ein interner Link + USHORT nUpdateMode;// UpdateMode + }; + + tClientType ClientType; + ImplBaseLinkData() + { + ClientType.nCntntType = 0; + ClientType.bIntrnlLnk = FALSE; + ClientType.nUpdateMode = 0; + } +}; + + +/************************************************************************ +|* SvBaseLink::SvBaseLink() +|* +|* Beschreibung +*************************************************************************/ + +SvBaseLink::SvBaseLink( USHORT nUpdateMode, ULONG nContentType ) +{ + nObjType = OBJECT_CLIENT_SO; + pLinkMgr = 0; + pImplData = new ImplBaseLinkData; + bVisible = bSynchron = bUseCache = TRUE; + + // falls es ein Ole-Link wird, + pImplData->ClientType.nUpdateMode = nUpdateMode; + pImplData->ClientType.nCntntType = nContentType; + pImplData->ClientType.bIntrnlLnk = FALSE; +} + +/************************************************************************ +|* SvBaseLink::~SvBaseLink() +|* +|* Beschreibung +*************************************************************************/ + +SvBaseLink::~SvBaseLink() +{ + Disconnect(); + + delete pImplData; +} + +/************************************************************************ +|* SvBaseLink::SetObjType() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetObjType( USHORT nObjTypeP ) +{ + DBG_ASSERT( nObjType != OBJECT_CLIENT_DDE, "type already set" ); + DBG_ASSERT( !xObj.Is(), "object exist" ); + + nObjType = nObjTypeP; +} + +/************************************************************************ +|* SvBaseLink::SetName() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetName( const String & rNm ) +{ + aLinkName = rNm; +} + +/************************************************************************ +|* SvBaseLink::SetLinkSourceName() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetLinkSourceName( const String & rLnkNm ) +{ + if( aLinkName == rLnkNm ) + return; + + AddNextRef(); // sollte ueberfluessig sein + // Alte Verbindung weg + Disconnect(); + + aLinkName = rLnkNm; + + // Neu verbinden + _GetRealObject(); + ReleaseRef(); // sollte ueberfluessig sein +} + +/************************************************************************ +|* SvBaseLink::GetLinkSourceName() +|* +|* Beschreibung +*************************************************************************/ + +String SvBaseLink::GetLinkSourceName() const +{ + return aLinkName; +} + + +/************************************************************************ +|* SvBaseLink::SetUpdateMode() +|* +|* Beschreibung +*************************************************************************/ + +void SvBaseLink::SetUpdateMode( USHORT nMode ) +{ + if( ( OBJECT_CLIENT_SO & nObjType ) && + pImplData->ClientType.nUpdateMode != nMode ) + { + AddNextRef(); + Disconnect(); + + pImplData->ClientType.nUpdateMode = nMode; + _GetRealObject(); + ReleaseRef(); + } +} + + +BOOL SvBaseLink::Update() +{ + if( OBJECT_CLIENT_SO & nObjType ) + { + AddNextRef(); + Disconnect(); + + _GetRealObject(); + ReleaseRef(); + if( xObj.Is() ) + { + String sMimeType( SotExchange::GetFormatMimeType( + pImplData->ClientType.nCntntType )); + Any aData; + + if( xObj->GetData( aData, sMimeType ) ) + { + DataChanged( sMimeType, aData ); + // for manual Updates there is no + // need to hold the ServerObject + if( OBJECT_CLIENT_DDE == nObjType && + LINKUPDATE_ONCALL == GetUpdateMode() && xObj.Is() ) + xObj->RemoveAllDataAdvise( this ); + return TRUE; + } + if( xObj.Is() ) + { + // sollten wir asynschron sein? + if( xObj->IsPending() ) + return TRUE; + + // dann brauchen wir das Object auch nicht mehr + AddNextRef(); + Disconnect(); + ReleaseRef(); + } + } + } + return FALSE; +} + + +USHORT SvBaseLink::GetUpdateMode() const +{ + return ( OBJECT_CLIENT_SO & nObjType ) + ? pImplData->ClientType.nUpdateMode + : (USHORT)LINKUPDATE_ONCALL; +} + + +void SvBaseLink::_GetRealObject( BOOL bConnect ) +{ + if( !pLinkMgr ) + return; + + DBG_ASSERT( !xObj.Is(), "object already exist" ); + + if( OBJECT_CLIENT_DDE == nObjType ) + { + String sServer; + if( pLinkMgr->GetDisplayNames( this, &sServer ) && + sServer == GetpApp()->GetAppName() ) // interner Link !!! + { + // damit der Internal - Link erzeugt werden kann !!! + nObjType = OBJECT_INTERN; + xObj = pLinkMgr->CreateObj( this ); + + pImplData->ClientType.bIntrnlLnk = TRUE; + nObjType = OBJECT_CLIENT_DDE; // damit wir wissen was es mal war !! + } + else + { + pImplData->ClientType.bIntrnlLnk = FALSE; + xObj = pLinkMgr->CreateObj( this ); + } + } + else if( (OBJECT_CLIENT_SO & nObjType) ) + xObj = pLinkMgr->CreateObj( this ); + + if( bConnect && ( !xObj.Is() || !xObj->Connect( this ) ) ) + Disconnect(); +} + +ULONG SvBaseLink::GetContentType() const +{ + if( OBJECT_CLIENT_SO & nObjType ) + return pImplData->ClientType.nCntntType; + + return 0; // alle Formate ? +} + + +BOOL SvBaseLink::SetContentType( ULONG nType ) +{ + if( OBJECT_CLIENT_SO & nObjType ) + { + pImplData->ClientType.nCntntType = nType; + return TRUE; + } + return FALSE; +} + + +void SvBaseLink::Disconnect() +{ + if( xObj.Is() ) + { + xObj->RemoveAllDataAdvise( this ); + xObj->RemoveConnectAdvise( this ); + xObj.Clear(); + } +} + + +void SvBaseLink::DataChanged( const String &, const ::com::sun::star::uno::Any & ) +{ +} + + +BOOL SvBaseLink::Edit( Window* pParent ) +{ + BOOL bConnect = xObj.Is(); + if( !bConnect ) + _GetRealObject( xObj.Is() ); + + String aNewNm; + + if( OBJECT_CLIENT_SO & nObjType && + pImplData->ClientType.bIntrnlLnk ) + { + if( pLinkMgr ) + { + SvLinkSourceRef ref = pLinkMgr->CreateObj( this ); + if( ref.Is() ) + aNewNm = ref->Edit( pParent, this ); + } + } + else + aNewNm = xObj->Edit( pParent, this ); + + if( aNewNm.Len() != 0 ) + { + SetLinkSourceName( aNewNm ); + if( !Update() ) + { + String sApp, sTopic, sItem, sError; + pLinkMgr->GetDisplayNames( this, &sApp, &sTopic, &sItem ); + if( nObjType == OBJECT_CLIENT_DDE ) + { + sError = ResId(STR_ERROR_DDE, *SOAPP->GetResMgr()).toString(); + USHORT nFndPos = sError.Search( '%' ); + if( STRING_NOTFOUND != nFndPos ) + { + sError.Erase( nFndPos, 1 ).Insert( sApp, nFndPos ); + nFndPos = nFndPos + sApp.Len(); + } + if( STRING_NOTFOUND != ( nFndPos = sError.Search( '%', nFndPos ))) + { + sError.Erase( nFndPos, 1 ).Insert( sTopic, nFndPos ); + nFndPos = nFndPos + sTopic.Len(); + } + if( STRING_NOTFOUND != ( nFndPos = sError.Search( '%', nFndPos ))) + sError.Erase( nFndPos, 1 ).Insert( sItem, nFndPos ); + } + else + return FALSE; + + ErrorBox( pParent, WB_OK, sError ).Execute(); + } + } + else if( !bConnect ) + Disconnect(); + return aNewNm.Len() != 0; +} + + +void SvBaseLink::Closed() +{ + if( xObj.Is() ) + // beim Advise Abmelden + xObj->RemoveAllDataAdvise( this ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bf_so3/source/solink/makefile.mk b/bf_so3/source/solink/makefile.mk new file mode 100644 index 000000000..dcdb06cb0 --- /dev/null +++ b/bf_so3/source/solink/makefile.mk @@ -0,0 +1,50 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. +SUBPRJ=..$/.. + +PRJINC=$(SUBPRJ) + +PRJNAME=binfilter +TARGET=so3_solink + +.IF "$(debug)" != "" +LINK=n:\bin\optlinks\optlinks +.ELSE +OPTLINKS=YES +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(SUBPRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/lnkbase2.obj \ + $(SLO)$/linksrc.obj \ + $(SLO)$/impldde.obj \ + $(SLO)$/linkmgr2.obj + + + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/bf_so3/src/makefile.mk b/bf_so3/src/makefile.mk new file mode 100644 index 000000000..ac47ca1e2 --- /dev/null +++ b/bf_so3/src/makefile.mk @@ -0,0 +1,39 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/.. +PRJNAME=binfilter +TARGET=so3_src + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +alllangiso=en-US + +RSCFLAGS+=-I$(PRJ)$/inc + +# --- Files -------------------------------------------------------- + +SRS1NAME=$(TARGET) +SRC1FILES=\ + nocode.src + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/bf_so3/src/nocode.src b/bf_so3/src/nocode.src new file mode 100644 index 000000000..9cb728a40 --- /dev/null +++ b/bf_so3/src/nocode.src @@ -0,0 +1,212 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "svuidlg.hrc" +#define __RSC +#include "bf_so3/soerr.hxx" +#define S_MAX 0x7fff +Resource RID_SO_ERROR_HANDLER +{ + String ERRCODE_SO_GENERALERROR&S_MAX + { + Text [ en-US ] = "General OLE error" ; + }; + String ERRCODE_SO_CANT_BINDTOSOURCE&S_MAX + { + // ### ACHTUNG: Neuer Text in Resource? Die Verbindung zum Objekt kann nicht hergestellt werden : Die Verbindung zum Objekt kann nicht hergestellt werden. + Text [ en-US ] = "The connection to the object cannot be established." ; + }; + String ERRCODE_SO_NOCACHE_UPDATED&S_MAX + { + Text [ en-US ] = "No cache files were updated" ; + }; + String ERRCODE_SO_SOMECACHES_NOTUPDATED&S_MAX + { + Text [ en-US ] = "Some cache files were not updated" ; + }; + String ERRCODE_SO_MK_UNAVAILABLE&S_MAX + { + Text [ en-US ] = "Status of object cannot be determined in a timely manner" ; + }; + String ERRCODE_SO_E_CLASSDIFF&S_MAX + { + Text [ en-US ] = "Source of the OLE link has been converted" ; + }; + String ERRCODE_SO_MK_NO_OBJECT&S_MAX + { + Text [ en-US ] = "The object could not be found." ; + }; + String ERRCODE_SO_MK_EXCEEDED_DEADLINE&S_MAX + { + Text [ en-US ] = "The process could not be completed within the specified time period." ; + }; + String ERRCODE_SO_MK_CONNECT_MANUALLY&S_MAX + { + Text [ en-US ] = "OLE could not connect to a network device (server)" ; + }; + String ERRCODE_SO_MK_INTERMEDIATE_INTERFACE_NOT_SUPPORTED&S_MAX + { + Text [ en-US ] = "The object found does not support the interface required for the desired operation" ; + }; + String ERRCODE_SO_NO_INTERFACE&S_MAX + { + Text [ en-US ] = "Interface not supported" ; + }; + String ERRCODE_SO_OUT_OF_MEMORY&S_MAX + { + Text [ en-US ] = "Insufficient memory" ; + }; + String ERRCODE_SO_MK_SYNTAX&S_MAX + { + Text [ en-US ] = "The connection name could not be processed." ; + }; + String ERRCODE_SO_MK_REDUCED_TO_SELF&S_MAX + { + Text [ en-US ] = "The connection name could not be reduced further" ; + }; + String ERRCODE_SO_MK_NO_INVERSE&S_MAX + { + Text [ en-US ] = "The connection name has no inverse." ; + }; + String ERRCODE_SO_MK_NO_PREFIX&S_MAX + { + Text [ en-US ] = "No common prefix exists" ; + }; + String ERRCODE_SO_MK_HIM&S_MAX + { + Text [ en-US ] = "The connection name is contained in the other one." ; + }; + String ERRCODE_SO_MK_US&S_MAX + { + Text [ en-US ] = "The connection names (the receiver and the other moniker) are identical." ; + }; + String ERRCODE_SO_MK_ME&S_MAX + { + Text [ en-US ] = "The connection name is contained in the other one." ; + }; + String ERRCODE_SO_MK_NOT_BINDABLE&S_MAX + { + // ### ACHTUNG: Neuer Text in Resource? Der Verbindungsname kann nicht verbunden werden Es handelt sich um einen relativen Namen : Der Verbindungsname kann nicht verbunden werden. Es handelt sich um einen relativen Namen + Text [ en-US ] = "The connection name cannot be connected. This is a relative name." ; + }; + String ERRCODE_SO_NOT_IMPLEMENTED&S_MAX + { + Text [ en-US ] = "Operation not implemented" ; + }; + String ERRCODE_SO_MK_NO_STORAGE&S_MAX + { + Text [ en-US ] = "No storage" ; + }; + String ERRCODE_SO_FALSE&S_MAX + { + Text [ en-US ] = "False" ; + }; + String ERRCODE_SO_MK_NEED_GENERIC&S_MAX + { + Text [ en-US ] = "Monikers must be composed generically" ; + }; + String ERRCODE_SO_PENDING&S_MAX + { + Text [ en-US ] = "Data not available at this time" ; + }; + String ERRCODE_SO_NOT_INPLACEACTIVE & S_MAX + { + /* ### ACHTUNG: Neuer Text in Resource? Objekt wurde nicht InPlace aktiviert : Objetkt wurde nicht InPlace aktiviert */ + Text [ en-US ] = "Object could not be activated InPlace" ; + }; + String ERRCODE_SO_LINDEX & S_MAX + { + /* ### ACHTUNG: Neuer Text in Resource? Ungültiger Index : Ung³ltiger Index */ + Text [ en-US ] = "Invalid index" ; + }; + String ERRCODE_SO_CANNOT_DOVERB_NOW & S_MAX + { + /* ### ACHTUNG: Neuer Text in Resource? Das Objekt kann die Aktion im momentanen Zustand nicht ausführen : Das Objekt kann die Aktion im momentanen Zustand nicht ausf³hren */ + Text [ en-US ] = "The action cannot be executed in the object's current state." ; + }; + String ERRCODE_SO_OLEOBJ_INVALIDHWND & S_MAX + { + /* ### ACHTUNG: Neuer Text in Resource? Bei der Aktivierung wurde ein ungültiges Fenster ist übergeben : Bei der Aktivierung wurde ein ung³ltiges Fenster ist ³bergeben */ + Text [ en-US ] = "An invalid window was passed when activated." ; + }; + String ERRCODE_SO_NOVERBS & S_MAX + { + /* ### ACHTUNG: Neuer Text in Resource? Das Objekt unterstützt keine Aktionen : Das Objekt unterst³tzt keine Aktionen */ + Text [ en-US ] = "The object does not support any actions" ; + }; + String ERRCODE_SO_INVALIDVERB & S_MAX + { + /* ### ACHTUNG: Neuer Text in Resource? Die Aktion ist nicht definiert. Es wird die Default Aktion ausgelöst : Die Aktion ist nicht definiert. Es wird die Default Aktion ausgel÷st */ + Text [ en-US ] = "The action is not defined. The default action will be executed." ; + }; + String ERRCODE_SO_MK_CONNECT & S_MAX + { + /* ### ACHTUNG: Neuer Text in Resource? Eine Verknüpfung auf das Netzwerk konnte nicht wieder hergestellt werden : Eine Verkn³pfung auf das Netzwerk, die nicht wieder hergestellt werden konnte */ + Text [ en-US ] = "A link to the network could not be re-established." ; + }; + String ERRCODE_SO_NOTIMPL & S_MAX + { + /* ### ACHTUNG: Neuer Text in Resource? Das Objekt unterstützt diese Aktion nicht : Das Objekt unterst³tzt diese Aktion nicht */ + Text [ en-US ] = "Object does not support this action" ; + }; + String ERRCODE_SO_MK_CANTOPENFILE & S_MAX + { + Text [ en-US ] = "The specified file could not be opened." ; + }; + /* + String & S_MAX + { + }; +*/ +}; +Resource RID_SO_ERRCTX +{ + String ERRCTX_SO_DOVERB + { + Text [ en-US ] = "$(ERR) activating object" ; + }; +}; +String STR_VERB_OPEN +{ + Text [ en-US ] = "~Open" ; +}; +String STR_VERB_PROPS +{ + Text [ en-US ] = "~Properties" ; +}; +String STR_ERROR_DDE +{ + Text [ en-US ] = "DDE link to % for % area % are not available." ; +}; +String STR_QUERYUPDATELINKS +{ + Text [ en-US ] = "Update all links?" ; +}; +String STR_FURTHER_OBJECT +{ + Text [ en-US ] = "Further objects" ; +}; + +Bitmap BMP_PLUGIN +{ + File = "plugin.bmp" ; +}; +Bitmap BMP_OLEOBJ +{ + File = "oleobj.bmp" ; +}; diff --git a/bf_so3/util/makefile.mk b/bf_so3/util/makefile.mk new file mode 100644 index 000000000..4aa1aa2ed --- /dev/null +++ b/bf_so3/util/makefile.mk @@ -0,0 +1,138 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# +PRJ=..$/.. +SUBPRJ=$(PRJ)$/bf_so3 + +PRJNAME=binfilter +TARGET=bf_so + +USE_LDUMP2=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +alllangiso=en-US +.INCLUDE : $(SUBPRJ)$/util$/makefile.pmk + +RSCFLAGS+=-p + +# --- Files -------------------------------------------------------- + + +LIB1TARGET= $(SLB)$/$(TARGET).lib +LIB1FILES=\ + $(SLB)$/so3_solink.lib \ + $(SLB)$/so3_dialog.lib \ + $(SLB)$/so3_data.lib \ + $(SLB)$/so3_inplace.lib \ + $(SLB)$/so3_misc.lib \ + $(SLB)$/so3_persist.lib \ + $(SLB)$/so3_copied.lib + +.IF "$(GUI)"=="WNT" +LIB1FILES+=$(SLB)$/so3_ole.lib +.ENDIF + +.IF "$(UPDATER)"=="" +RESLIB1NAME=so +RESLIB1SRSFILES= $(SRS)$/so3_src.srs +.ENDIF + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX) +SHL1IMPLIB= $(TARGET) +SHL1STDLIBS=\ + $(VCLLIB) \ + $(SOTLIB) \ + $(UNOTOOLSLIB) \ + $(TOOLSLIB) \ + $(BFSVTOOLLIB) \ + $(COMPHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) \ + $(UCBHELPERLIB) + +.IF "$(linkinc)" == "" +SHL1LIBS= $(SLB)$/$(TARGET).lib +.ENDIF + +.IF "$(GUI)"=="WNT" +SHL1STDLIBS+= \ + $(OLE32LIB) $(UUIDLIB) $(ADVAPI32LIB) $(GDI32LIB) +.ENDIF + +.IF "$(GUI)"=="WIN" +SHL1STDLIBS= \ + ole2.lib compobj.lib storage.lib shell.lib \ + ole2disp.lib typelib.lib +.ENDIF + +.IF "$(GUI)"=="UNX" +SHL1DEPN= $(LIB1TARGET) +.ELSE +SHL1DEPN= $(LIB1TARGET) +.ENDIF + +.IF "$(linkinc)" == "" +.IF "$(GUI)"=="WNT" +.IF "$(COM)"=="GCC" +SHL1OBJS+= $(SHLOBJECTS) +.ELSE +SHL1OBJS+= $(SLO)$/so2dll.obj \ + $(SHLOBJECTS) +.ENDIF +.ENDIF +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +.ELSE #"$(linkinc)" == "" +SHL11FILE= $(MISC)$/so3_data.slo +SHL12FILE= $(MISC)$/so3_dialog.slo +SHL13FILE= $(MISC)$/so3_inplace.slo +SHL14FILE= $(MISC)$/vmisc.slo +.IF "$(GUI)"=="WNT" +SHL15FILE= $(MISC)$/so3_ole.slo +.ENDIF +SHL16FILE= $(MISC)$/so3_persist.slo +SHL17FILE= $(MISC)$/so3_solink.slo +.ENDIF + +DEF1NAME =$(SHL1TARGET) +DEF1DEPN =$(MISC)$/$(SHL1TARGET).flt +DEFLIB1NAME =$(TARGET) +DEF1DES =StarObjects + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +# --- SO2-Filter-Datei --- + +$(MISC)$/$(SHL1TARGET).flt: makefile.mk + @echo ------------------------------ + @echo Making: $@ + @echo WEP > $@ + @echo LIBMAIN >> $@ + @echo LibMain >> $@ + @echo CreateDdeExtern@SvBaseLink >> $@ + @echo RemoveDdeExtern@SvBaseLink >> $@ + @echo DataChanged@SvBaseLink >> $@ + @echo allocator >> $@ + @echo Exception >> $@ + @echo =@8 >> $@ + @echo __CT >> $@ + diff --git a/bf_so3/util/makefile.pmk b/bf_so3/util/makefile.pmk new file mode 100644 index 000000000..f3b8fee66 --- /dev/null +++ b/bf_so3/util/makefile.pmk @@ -0,0 +1,21 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +# Reduction of exported symbols: +CDEFS += -DSO3_DLLIMPLEMENTATION -DNOMINMAX +VISIBILITY_HIDDEN=TRUE |