1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <map> 29 #include <boost/shared_ptr.hpp> 30 #include <sot/storage.hxx> 31 #include <vcl/bitmapex.hxx> 32 33 #include <com/sun/star/util/DateTime.hpp> 34 35 36 // ============================================================================ 37 38 //namespace { 39 40 // ============================================================================ 41 // property type IDs 42 const sal_Int32 PROPTYPE_INT16 = 2; 43 const sal_Int32 PROPTYPE_INT32 = 3; 44 const sal_Int32 PROPTYPE_FLOAT = 4; 45 const sal_Int32 PROPTYPE_DOUBLE = 5; 46 const sal_Int32 PROPTYPE_DATE = 7; 47 const sal_Int32 PROPTYPE_STRING = 8; 48 const sal_Int32 PROPTYPE_STATUS = 10; 49 const sal_Int32 PROPTYPE_BOOL = 11; 50 const sal_Int32 PROPTYPE_VARIANT = 12; 51 const sal_Int32 PROPTYPE_INT8 = 16; 52 const sal_Int32 PROPTYPE_UINT8 = 17; 53 const sal_Int32 PROPTYPE_UINT16 = 18; 54 const sal_Int32 PROPTYPE_UINT32 = 19; 55 const sal_Int32 PROPTYPE_INT64 = 20; 56 const sal_Int32 PROPTYPE_UINT64 = 21; 57 const sal_Int32 PROPTYPE_STRING8 = 30; 58 const sal_Int32 PROPTYPE_STRING16 = 31; 59 const sal_Int32 PROPTYPE_FILETIME = 64; 60 const sal_Int32 PROPTYPE_BLOB = 65; 61 const sal_Int32 PROPTYPE_CLIPFMT = 71; 62 63 // static property IDs 64 const sal_Int32 PROPID_DICTIONARY = 0; 65 const sal_Int32 PROPID_CODEPAGE = 1; 66 const sal_Int32 PROPID_FIRSTCUSTOM = 2; 67 68 // property IDs for GlobalDocPropertySet 69 const sal_Int32 PROPID_TITLE = 2; 70 const sal_Int32 PROPID_SUBJECT = 3; 71 const sal_Int32 PROPID_AUTHOR = 4; 72 const sal_Int32 PROPID_KEYWORDS = 5; 73 const sal_Int32 PROPID_COMMENTS = 6; 74 const sal_Int32 PROPID_TEMPLATE = 7; 75 const sal_Int32 PROPID_LASTAUTHOR = 8; 76 const sal_Int32 PROPID_REVNUMBER = 9; 77 const sal_Int32 PROPID_EDITTIME = 10; 78 const sal_Int32 PROPID_LASTPRINTED = 11; 79 const sal_Int32 PROPID_CREATED = 12; 80 const sal_Int32 PROPID_LASTSAVED = 13; 81 const sal_Int32 PROPID_THUMBNAIL = 17; 82 83 // predefined codepages 84 const sal_uInt16 CODEPAGE_UNKNOWN = 0; 85 const sal_uInt16 CODEPAGE_UNICODE = 1200; 86 const sal_uInt16 CODEPAGE_UTF8 = 65001; 87 88 // predefined clipboard format IDs 89 const sal_Int32 CLIPFMT_WIN = -1; 90 91 // predefined clipboard data format IDs 92 const sal_Int32 CLIPDATAFMT_DIB = 8; 93 94 // ============================================================================ 95 // ============================================================================ 96 97 /** Helper for classes that need text encoding settings. 98 99 Classes derived from this class will include functions to store and use 100 text encoding settings and to convert Windows codepage constants. 101 */ 102 class SfxOleTextEncoding 103 { 104 public: 105 inline explicit SfxOleTextEncoding() : 106 mxTextEnc( new rtl_TextEncoding( gsl_getSystemTextEncoding() ) ) {} 107 inline explicit SfxOleTextEncoding( rtl_TextEncoding eTextEnc ) : 108 mxTextEnc( new rtl_TextEncoding( eTextEnc ) ) {} 109 inline explicit SfxOleTextEncoding( sal_Int16 nCodePage ) : 110 mxTextEnc( new rtl_TextEncoding ) { SetCodePage( nCodePage ); } 111 112 /** Returns the current text encoding identifier. */ 113 inline rtl_TextEncoding GetTextEncoding() const { return *mxTextEnc; } 114 /** Sets the passed text encoding. */ 115 inline void SetTextEncoding( rtl_TextEncoding eTextEnc ) { *mxTextEnc = eTextEnc; } 116 117 /** Returns true, if this object contains Unicode text encoding. */ 118 inline bool IsUnicode() const { return GetTextEncoding() == RTL_TEXTENCODING_UCS2; } 119 /** Sets Unicode text encoding to this object. */ 120 inline void SetUnicode() { SetTextEncoding( RTL_TEXTENCODING_UCS2 ); } 121 122 /** Converts the current settings to a Windows codepage identifier. */ 123 sal_uInt16 GetCodePage() const; 124 /** Sets the current text encoding from a Windows codepage identifier. */ 125 void SetCodePage( sal_uInt16 nCodePage ); 126 127 private: 128 typedef ::boost::shared_ptr< rtl_TextEncoding > TextEncRef; 129 TextEncRef mxTextEnc; 130 }; 131 132 // ============================================================================ 133 134 /** Helper for classes that need to load or save string values. 135 136 Classes derived from this class contain functions to load and save string 137 values with the text encoding passed in the constructor. 138 */ 139 class SfxOleStringHelper : public SfxOleTextEncoding 140 { 141 public: 142 /** Creates a string helper object depending on an external text encoding. */ 143 inline explicit SfxOleStringHelper( const SfxOleTextEncoding& rTextEnc ) : 144 SfxOleTextEncoding( rTextEnc ) {} 145 /** Creates a string helper object with own text encoding. */ 146 inline explicit SfxOleStringHelper( rtl_TextEncoding eTextEnc ) : 147 SfxOleTextEncoding( eTextEnc ) {} 148 149 /** Loads a string from the passed stream with current encoding (maybe Unicode). */ 150 String LoadString8( SvStream& rStrm ) const; 151 /** Saves a string to the passed stream with current encoding (maybe Unicode). */ 152 void SaveString8( SvStream& rStrm, const String& rValue ) const; 153 154 /** Loads a Unicode string from the passed stream, ignores own encoding. */ 155 String LoadString16( SvStream& rStrm ) const; 156 /** Saves a Unicode string to the passed stream, ignores own encoding. */ 157 void SaveString16( SvStream& rStrm, const String& rValue ) const; 158 159 private: 160 String ImplLoadString8( SvStream& rStrm ) const; 161 String ImplLoadString16( SvStream& rStrm ) const; 162 void ImplSaveString8( SvStream& rStrm, const String& rValue ) const; 163 void ImplSaveString16( SvStream& rStrm, const String& rValue ) const; 164 }; 165 166 167 // ============================================================================ 168 // ============================================================================ 169 170 /** Base class for all classes related to OLE property sets. 171 172 Derived calsses have to implement the pure virtual functions ImplLoad() and 173 ImplSave(). 174 */ 175 class SfxOleObjectBase 176 { 177 public: 178 inline explicit SfxOleObjectBase() : mnErrCode( ERRCODE_NONE ) {} 179 virtual ~SfxOleObjectBase(); 180 181 /** Returns true, if an error code (other than ERRCODE_NONE) is set. */ 182 inline bool HasError() const { return mnErrCode != ERRCODE_NONE; } 183 /** Returns the current error code. */ 184 inline ErrCode GetError() const { return mnErrCode; } 185 186 /** Loads this object from the passed stream. Calls virtual ImplLoad(). */ 187 ErrCode Load( SvStream& rStrm ); 188 /** Saves this object to the passed stream. Calls virtual ImplSave(). */ 189 ErrCode Save( SvStream& rStrm ); 190 191 protected: 192 /** Sets the passed error code. Will be returned by Load() and Save() functions. 193 Always the first error code is stored. Multiple calls have no effect. */ 194 inline void SetError( ErrCode nErrCode ) { if( !HasError() ) mnErrCode = nErrCode; } 195 /** Loads the passed object from the stream. Sets returned error code as own error. */ 196 void LoadObject( SvStream& rStrm, SfxOleObjectBase& rObj ); 197 /** Saves the passed object to the stream. Sets returned error code as own error. */ 198 void SaveObject( SvStream& rStrm, SfxOleObjectBase& rObj ); 199 200 private: 201 /** Derived classes implement loading the object from the passed steam. */ 202 virtual void ImplLoad( SvStream& rStrm ) = 0; 203 /** Derived classes implement saving the object to the passed steam. */ 204 virtual void ImplSave( SvStream& rStrm ) = 0; 205 206 private: 207 ErrCode mnErrCode; /// Current error code. 208 }; 209 210 // ============================================================================ 211 // ============================================================================ 212 213 /** Base class for all OLE property objects. */ 214 class SfxOlePropertyBase : public SfxOleObjectBase 215 { 216 public: 217 inline explicit SfxOlePropertyBase( sal_Int32 nPropId, sal_Int32 nPropType ) : 218 mnPropId( nPropId ), mnPropType( nPropType ) {} 219 220 inline sal_Int32 GetPropId() const { return mnPropId; } 221 inline sal_Int32 GetPropType() const { return mnPropType; } 222 223 protected: 224 inline void SetPropId( sal_Int32 nPropId ) { mnPropId = nPropId; } 225 inline void SetPropType( sal_Int32 nPropType ) { mnPropType = nPropType; } 226 227 private: 228 sal_Int32 mnPropId; 229 sal_Int32 mnPropType; 230 }; 231 232 typedef ::boost::shared_ptr< SfxOlePropertyBase > SfxOlePropertyRef; 233 234 // ============================================================================ 235 /** Property representing the codepage used to encode bytestrings in the entire property set. */ 236 class SfxOleCodePageProperty : public SfxOlePropertyBase, public SfxOleTextEncoding 237 { 238 public: 239 explicit SfxOleCodePageProperty(); 240 241 private: 242 virtual void ImplLoad( SvStream& rStrm ); 243 virtual void ImplSave( SvStream& rStrm ); 244 }; 245 246 // ============================================================================ 247 // ============================================================================ 248 249 /** Property containing custom names for other properties in the property set. */ 250 class SfxOleDictionaryProperty : public SfxOlePropertyBase, public SfxOleStringHelper 251 { 252 public: 253 explicit SfxOleDictionaryProperty( const SfxOleTextEncoding& rTextEnc ); 254 255 /** Returns true, if the property contains at least one custom property name. */ 256 inline bool HasPropertyNames() const { return !maPropNameMap.empty(); } 257 /** Prepares the property for loading. Does not affect contained names for its own. */ 258 inline void SetNameCount( sal_Int32 nNameCount ) { SetPropType( nNameCount ); } 259 260 /** Returns the custom name for the passed property ID, or an empty string, if name not found. */ 261 const String& GetPropertyName( sal_Int32 nPropId ) const; 262 /** Sets a custom name for the passed property ID. */ 263 void SetPropertyName( sal_Int32 nPropId, const String& rPropName ); 264 265 private: 266 virtual void ImplLoad( SvStream& rStrm ); 267 virtual void ImplSave( SvStream& rStrm ); 268 269 private: 270 typedef ::std::map< sal_Int32, String > SfxOlePropNameMap; 271 SfxOlePropNameMap maPropNameMap; 272 }; 273 274 // ============================================================================ 275 // ============================================================================ 276 277 /** A section in a property set. Contains properties with unique identifiers. */ 278 class SfxOleSection : public SfxOleObjectBase 279 { 280 private: 281 typedef ::std::map< sal_Int32, SfxOlePropertyRef > SfxOlePropMap; 282 283 public: 284 explicit SfxOleSection( bool bSupportsDict ); 285 286 /** Returns the property with the passed ID, or an empty reference, if nothing found. */ 287 SfxOlePropertyRef GetProperty( sal_Int32 nPropId ) const; 288 /** Returns the value of a signed int32 property with the passed ID in rnValue. 289 @return true = Property found, rnValue is valid; false = Property not found. */ 290 bool GetInt32Value( sal_Int32& rnValue, sal_Int32 nPropId ) const; 291 /** Returns the value of a floating-point property with the passed ID in rfValue. 292 @return true = Property found, rfValue is valid; false = Property not found. */ 293 bool GetDoubleValue( double& rfValue, sal_Int32 nPropId ) const; 294 /** Returns the value of a boolean property with the passed ID in rbValue. 295 @return true = Property found, rbValue is valid; false = Property not found. */ 296 bool GetBoolValue( bool& rbValue, sal_Int32 nPropId ) const; 297 /** Returns the value of a string property with the passed ID in rValue. 298 @return true = Property found, rValue is valid; false = Property not found. */ 299 bool GetStringValue( String& rValue, sal_Int32 nPropId ) const; 300 /** Returns the value of a time stamp property with the passed ID in rValue. 301 @return true = Property found, rValue is valid; false = Property not found. */ 302 bool GetFileTimeValue( ::com::sun::star::util::DateTime& rValue, sal_Int32 nPropId ) const; 303 304 /** Adds the passed property to the property set. Drops an existing old property. */ 305 void SetProperty( SfxOlePropertyRef xProp ); 306 /** Inserts a signed int32 property with the passed value. */ 307 void SetInt32Value( sal_Int32 nPropId, sal_Int32 nValue ); 308 /** Inserts a foating-point property with the passed value. */ 309 void SetDoubleValue( sal_Int32 nPropId, double fValue ); 310 /** Inserts a boolean property with the passed value. */ 311 void SetBoolValue( sal_Int32 nPropId, bool bValue ); 312 /** Inserts a string property with the passed value. 313 @return true = Property inserted; false = String was empty, property not inserted. */ 314 bool SetStringValue( sal_Int32 nPropId, const String& rValue, bool bSkipEmpty = true ); 315 /** Inserts a time stamp property with the passed value. */ 316 void SetFileTimeValue( sal_Int32 nPropId, const ::com::sun::star::util::DateTime& rValue ); 317 /** Inserts a thumbnail property from the passed meta file. */ 318 void SetThumbnailValue( sal_Int32 nPropId, 319 const ::com::sun::star::uno::Sequence<sal_uInt8> & i_rData); 320 /** Inserts a BLOB property with the passed data. */ 321 void SetBlobValue( sal_Int32 nPropId, 322 const ::com::sun::star::uno::Sequence<sal_uInt8> & i_rData); 323 324 /** Returns the value of the property with the passed ID in a UNO any. */ 325 com::sun::star::uno::Any GetAnyValue( sal_Int32 nPropId ) const; 326 /** Inserts a property created from the passed any. 327 @return true = Property converted and inserted; false = Property type not supported. */ 328 bool SetAnyValue( sal_Int32 nPropId, const com::sun::star::uno::Any& rValue ); 329 330 /** Returns the custom name for the passed property ID, or an empty string, if name not found. */ 331 const String& GetPropertyName( sal_Int32 nPropId ) const; 332 /** Sets a custom name for the passed property ID. */ 333 void SetPropertyName( sal_Int32 nPropId, const String& rPropName ); 334 335 /** Returns the identifiers of all existing properties in the passed vector. */ 336 void GetPropertyIds( ::std::vector< sal_Int32 >& rPropIds ) const; 337 /** Returns a property identifier not used in this section. */ 338 sal_Int32 GetFreePropertyId() const; 339 340 private: 341 virtual void ImplLoad( SvStream& rStrm ); 342 virtual void ImplSave( SvStream& rStrm ); 343 344 bool SeekToPropertyPos( SvStream& rStrm, sal_uInt32 nPropPos ) const; 345 void LoadProperty( SvStream& rStrm, sal_Int32 nPropId ); 346 void SaveProperty( SvStream& rStrm, SfxOlePropertyBase& rProp, sal_Size& rnPropPosPos ); 347 348 private: 349 SfxOlePropMap maPropMap; /// All properties in this section, by identifier. 350 SfxOleCodePageProperty maCodePageProp; /// The codepage property. 351 SfxOleDictionaryProperty maDictProp; /// The dictionary property. 352 sal_Size mnStartPos; /// Start stream position of the section. 353 bool mbSupportsDict; /// true = section supports dictionary. 354 }; 355 356 typedef ::boost::shared_ptr< SfxOleSection > SfxOleSectionRef; 357 358 // ============================================================================ 359 // ============================================================================ 360 361 /** Enumerates different section types in OLE property sets. */ 362 enum SfxOleSectionType 363 { 364 SECTION_GLOBAL, /// Globally defined properties. 365 SECTION_BUILTIN, /// Properties built into MS Office. 366 SECTION_CUSTOM /// Custom properties. 367 }; 368 369 // ============================================================================ 370 371 /** Represents a complete property set, may consist of several property sections. */ 372 class SfxOlePropertySet : public SfxOleObjectBase 373 { 374 public: 375 inline explicit SfxOlePropertySet() {} 376 377 /** Loads this object from the passed storage. */ 378 ErrCode LoadPropertySet( SotStorage* pStrg, const String& rStrmName ); 379 /** Saves this object to the passed storage. */ 380 ErrCode SavePropertySet( SotStorage* pStrg, const String& rStrmName ); 381 382 /** Returns the specified section, or an empty reference, if nothing found. */ 383 SfxOleSectionRef GetSection( SfxOleSectionType eSection ) const; 384 /** Returns the specified section, or an empty reference, if nothing found. */ 385 SfxOleSectionRef GetSection( const SvGlobalName& rSectionGuid ) const; 386 387 /** Creates and returns the specified section, or just returns it if it already exists. */ 388 SfxOleSection& AddSection( SfxOleSectionType eSection ); 389 /** Creates and returns the specified section, or just returns it if it already exists. */ 390 SfxOleSection& AddSection( const SvGlobalName& rSectionGuid ); 391 392 private: 393 virtual void ImplLoad( SvStream& rStrm ); 394 virtual void ImplSave( SvStream& rStrm ); 395 396 /** Returns the GUID for the specified section. */ 397 static const SvGlobalName& GetSectionGuid( SfxOleSectionType eSection ); 398 399 private: 400 typedef ::std::map< SvGlobalName, SfxOleSectionRef > SfxOleSectionMap; 401 SfxOleSectionMap maSectionMap; 402 }; 403 404 //}; 405