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