Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <map>
21 : #include <boost/shared_ptr.hpp>
22 : #include <sot/storage.hxx>
23 : #include <vcl/bitmapex.hxx>
24 :
25 : #include <com/sun/star/util/DateTime.hpp>
26 : #include <com/sun/star/util/Date.hpp>
27 :
28 :
29 : // ============================================================================
30 :
31 : //namespace {
32 :
33 : // ============================================================================
34 : // property type IDs
35 : const sal_Int32 PROPTYPE_INT16 = 2;
36 : const sal_Int32 PROPTYPE_INT32 = 3;
37 : const sal_Int32 PROPTYPE_FLOAT = 4;
38 : const sal_Int32 PROPTYPE_DOUBLE = 5;
39 : const sal_Int32 PROPTYPE_DATE = 7;
40 : const sal_Int32 PROPTYPE_STRING = 8;
41 : const sal_Int32 PROPTYPE_STATUS = 10;
42 : const sal_Int32 PROPTYPE_BOOL = 11;
43 : const sal_Int32 PROPTYPE_VARIANT = 12;
44 : const sal_Int32 PROPTYPE_INT8 = 16;
45 : const sal_Int32 PROPTYPE_UINT8 = 17;
46 : const sal_Int32 PROPTYPE_UINT16 = 18;
47 : const sal_Int32 PROPTYPE_UINT32 = 19;
48 : const sal_Int32 PROPTYPE_INT64 = 20;
49 : const sal_Int32 PROPTYPE_UINT64 = 21;
50 : const sal_Int32 PROPTYPE_STRING8 = 30;
51 : const sal_Int32 PROPTYPE_STRING16 = 31;
52 : const sal_Int32 PROPTYPE_FILETIME = 64;
53 : const sal_Int32 PROPTYPE_BLOB = 65;
54 : const sal_Int32 PROPTYPE_CLIPFMT = 71;
55 :
56 : // static property IDs
57 : const sal_Int32 PROPID_DICTIONARY = 0;
58 : const sal_Int32 PROPID_CODEPAGE = 1;
59 : const sal_Int32 PROPID_FIRSTCUSTOM = 2;
60 :
61 : // property IDs for GlobalDocPropertySet
62 : const sal_Int32 PROPID_TITLE = 2;
63 : const sal_Int32 PROPID_SUBJECT = 3;
64 : const sal_Int32 PROPID_AUTHOR = 4;
65 : const sal_Int32 PROPID_KEYWORDS = 5;
66 : const sal_Int32 PROPID_COMMENTS = 6;
67 : const sal_Int32 PROPID_TEMPLATE = 7;
68 : const sal_Int32 PROPID_LASTAUTHOR = 8;
69 : const sal_Int32 PROPID_REVNUMBER = 9;
70 : const sal_Int32 PROPID_EDITTIME = 10;
71 : const sal_Int32 PROPID_LASTPRINTED = 11;
72 : const sal_Int32 PROPID_CREATED = 12;
73 : const sal_Int32 PROPID_LASTSAVED = 13;
74 : const sal_Int32 PROPID_THUMBNAIL = 17;
75 :
76 : // some Builtin properties
77 : const sal_Int32 PROPID_CATEGORY = 0x2;
78 : const sal_Int32 PROPID_COMPANY = 0xf;
79 : const sal_Int32 PROPID_MANAGER = 0xe;
80 : // predefined codepages
81 : const sal_uInt16 CODEPAGE_UNKNOWN = 0;
82 : const sal_uInt16 CODEPAGE_UNICODE = 1200;
83 : const sal_uInt16 CODEPAGE_UTF8 = 65001;
84 :
85 : // predefined clipboard format IDs
86 : const sal_Int32 CLIPFMT_WIN = -1;
87 :
88 : // predefined clipboard data format IDs
89 : const sal_Int32 CLIPDATAFMT_DIB = 8;
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 989 : class SfxOleTextEncoding
99 : {
100 : public:
101 123 : inline explicit SfxOleTextEncoding() :
102 123 : mxTextEnc( new rtl_TextEncoding( osl_getThreadTextEncoding() ) ) {}
103 0 : inline explicit SfxOleTextEncoding( rtl_TextEncoding eTextEnc ) :
104 0 : mxTextEnc( new rtl_TextEncoding( eTextEnc ) ) {}
105 : inline explicit SfxOleTextEncoding( sal_Int16 nCodePage ) :
106 : mxTextEnc( new rtl_TextEncoding ) { SetCodePage( nCodePage ); }
107 :
108 : /** Returns the current text encoding identifier. */
109 644 : inline rtl_TextEncoding GetTextEncoding() const { return *mxTextEnc; }
110 : /** Sets the passed text encoding. */
111 2 : inline void SetTextEncoding( rtl_TextEncoding eTextEnc ) { *mxTextEnc = eTextEnc; }
112 :
113 : /** Returns true, if this object contains Unicode text encoding. */
114 322 : inline bool IsUnicode() const { return GetTextEncoding() == RTL_TEXTENCODING_UCS2; }
115 : /** Sets Unicode text encoding to this object. */
116 2 : 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 433 : class SfxOleStringHelper : public SfxOleTextEncoding
136 : {
137 : public:
138 : /** Creates a string helper object depending on an external text encoding. */
139 433 : inline explicit SfxOleStringHelper( const SfxOleTextEncoding& rTextEnc ) :
140 433 : SfxOleTextEncoding( rTextEnc ) {}
141 : /** Creates a string helper object with own text encoding. */
142 0 : inline explicit SfxOleStringHelper( rtl_TextEncoding eTextEnc ) :
143 0 : 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 : /** Base class for all classes related to OLE property sets.
165 :
166 : Derived calsses have to implement the pure virtual functions ImplLoad() and
167 : ImplSave().
168 : */
169 : class SfxOleObjectBase
170 : {
171 : public:
172 1343 : inline explicit SfxOleObjectBase() : mnErrCode( ERRCODE_NONE ) {}
173 : virtual ~SfxOleObjectBase();
174 :
175 : /** Returns true, if an error code (other than ERRCODE_NONE) is set. */
176 2344 : inline bool HasError() const { return mnErrCode != ERRCODE_NONE; }
177 : /** Returns the current error code. */
178 1329 : inline ErrCode GetError() const { return mnErrCode; }
179 :
180 : /** Loads this object from the passed stream. Calls virtual ImplLoad(). */
181 : ErrCode Load( SvStream& rStrm );
182 : /** Saves this object to the passed stream. Calls virtual ImplSave(). */
183 : ErrCode Save( SvStream& rStrm );
184 :
185 : protected:
186 : /** Sets the passed error code. Will be returned by Load() and Save() functions.
187 : Always the first error code is stored. Multiple calls have no effect. */
188 2344 : inline void SetError( ErrCode nErrCode ) { if( !HasError() ) mnErrCode = nErrCode; }
189 : /** Loads the passed object from the stream. Sets returned error code as own error. */
190 : void LoadObject( SvStream& rStrm, SfxOleObjectBase& rObj );
191 : /** Saves the passed object to the stream. Sets returned error code as own error. */
192 : void SaveObject( SvStream& rStrm, SfxOleObjectBase& rObj );
193 :
194 : private:
195 : /** Derived classes implement loading the object from the passed steam. */
196 : virtual void ImplLoad( SvStream& rStrm ) = 0;
197 : /** Derived classes implement saving the object to the passed steam. */
198 : virtual void ImplSave( SvStream& rStrm ) = 0;
199 :
200 : private:
201 : ErrCode mnErrCode; /// Current error code.
202 : };
203 :
204 : // ============================================================================
205 :
206 : /** Base class for all OLE property objects. */
207 1108 : class SfxOlePropertyBase : public SfxOleObjectBase
208 : {
209 : public:
210 1108 : inline explicit SfxOlePropertyBase( sal_Int32 nPropId, sal_Int32 nPropType ) :
211 1108 : mnPropId( nPropId ), mnPropType( nPropType ) {}
212 :
213 0 : inline sal_Int32 GetPropId() const { return mnPropId; }
214 14 : inline sal_Int32 GetPropType() const { return mnPropType; }
215 :
216 : protected:
217 : inline void SetPropId( sal_Int32 nPropId ) { mnPropId = nPropId; }
218 14 : inline void SetPropType( sal_Int32 nPropType ) { mnPropType = nPropType; }
219 :
220 : private:
221 : sal_Int32 mnPropId;
222 : sal_Int32 mnPropType;
223 : };
224 :
225 : typedef ::boost::shared_ptr< SfxOlePropertyBase > SfxOlePropertyRef;
226 :
227 : // ============================================================================
228 : /** Property representing the codepage used to encode bytestrings in the entire property set. */
229 123 : class SfxOleCodePageProperty : public SfxOlePropertyBase, public SfxOleTextEncoding
230 : {
231 : public:
232 : explicit SfxOleCodePageProperty();
233 :
234 : private:
235 : virtual void ImplLoad( SvStream& rStrm );
236 : virtual void ImplSave( SvStream& rStrm );
237 : };
238 :
239 : // ============================================================================
240 :
241 : /** Property containing custom names for other properties in the property set. */
242 123 : class SfxOleDictionaryProperty : public SfxOlePropertyBase, public SfxOleStringHelper
243 : {
244 : public:
245 : explicit SfxOleDictionaryProperty( const SfxOleTextEncoding& rTextEnc );
246 :
247 : /** Returns true, if the property contains at least one custom property name. */
248 0 : inline bool HasPropertyNames() const { return !maPropNameMap.empty(); }
249 : /** Prepares the property for loading. Does not affect contained names for its own. */
250 14 : inline void SetNameCount( sal_Int32 nNameCount ) { SetPropType( nNameCount ); }
251 :
252 : /** Returns the custom name for the passed property ID, or an empty string, if name not found. */
253 : const String& GetPropertyName( sal_Int32 nPropId ) const;
254 : /** Sets a custom name for the passed property ID. */
255 : void SetPropertyName( sal_Int32 nPropId, const String& rPropName );
256 :
257 : private:
258 : virtual void ImplLoad( SvStream& rStrm );
259 : virtual void ImplSave( SvStream& rStrm );
260 :
261 : private:
262 : typedef ::std::map< sal_Int32, String > SfxOlePropNameMap;
263 : SfxOlePropNameMap maPropNameMap;
264 : };
265 :
266 : // ============================================================================
267 :
268 : /** A section in a property set. Contains properties with unique identifiers. */
269 246 : class SfxOleSection : public SfxOleObjectBase
270 : {
271 : private:
272 : typedef ::std::map< sal_Int32, SfxOlePropertyRef > SfxOlePropMap;
273 :
274 : public:
275 : explicit SfxOleSection( bool bSupportsDict );
276 :
277 : /** Returns the property with the passed ID, or an empty reference, if nothing found. */
278 : SfxOlePropertyRef GetProperty( sal_Int32 nPropId ) const;
279 : /** Returns the value of a signed int32 property with the passed ID in rnValue.
280 : @return true = Property found, rnValue is valid; false = Property not found. */
281 : bool GetInt32Value( sal_Int32& rnValue, sal_Int32 nPropId ) const;
282 : /** Returns the value of a floating-point property with the passed ID in rfValue.
283 : @return true = Property found, rfValue is valid; false = Property not found. */
284 : bool GetDoubleValue( double& rfValue, sal_Int32 nPropId ) const;
285 : /** Returns the value of a boolean property with the passed ID in rbValue.
286 : @return true = Property found, rbValue is valid; false = Property not found. */
287 : bool GetBoolValue( bool& rbValue, sal_Int32 nPropId ) const;
288 : /** Returns the value of a string property with the passed ID in rValue.
289 : @return true = Property found, rValue is valid; false = Property not found. */
290 : bool GetStringValue( String& rValue, sal_Int32 nPropId ) const;
291 : /** Returns the value of a time stamp property with the passed ID in rValue.
292 : @return true = Property found, rValue is valid; false = Property not found. */
293 : bool GetFileTimeValue( ::com::sun::star::util::DateTime& rValue, sal_Int32 nPropId ) const;
294 : /** Returns the value of a date property with the passed ID in rValue.
295 : @return true = Property found, rValue is valid; false = Property not found. */
296 : bool GetDateValue( ::com::sun::star::util::Date& rValue, sal_Int32 nPropId ) const;
297 :
298 : /** Adds the passed property to the property set. Drops an existing old property. */
299 : void SetProperty( SfxOlePropertyRef xProp );
300 : /** Inserts a signed int32 property with the passed value. */
301 : void SetInt32Value( sal_Int32 nPropId, sal_Int32 nValue );
302 : /** Inserts a floating-point property with the passed value. */
303 : void SetDoubleValue( sal_Int32 nPropId, double fValue );
304 : /** Inserts a boolean property with the passed value. */
305 : void SetBoolValue( sal_Int32 nPropId, bool bValue );
306 : /** Inserts a string property with the passed value.
307 : @return true = Property inserted; false = String was empty, property not inserted. */
308 : bool SetStringValue( sal_Int32 nPropId, const String& rValue, bool bSkipEmpty = true );
309 : /** Inserts a time stamp property with the passed value. */
310 : void SetFileTimeValue( sal_Int32 nPropId, const ::com::sun::star::util::DateTime& rValue );
311 : /** Inserts a date property with the passed value. */
312 : void SetDateValue( sal_Int32 nPropId, const ::com::sun::star::util::Date& 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 : /** Enumerates different section types in OLE property sets. */
357 : enum SfxOleSectionType
358 : {
359 : SECTION_GLOBAL, /// Globally defined properties.
360 : SECTION_BUILTIN, /// Properties built into MS Office.
361 : SECTION_CUSTOM /// Custom properties.
362 : };
363 :
364 : // ============================================================================
365 :
366 : /** Represents a complete property set, may consist of several property sections. */
367 112 : class SfxOlePropertySet : public SfxOleObjectBase
368 : {
369 : public:
370 112 : inline explicit SfxOlePropertySet() {}
371 :
372 : /** Loads this object from the passed storage. */
373 : ErrCode LoadPropertySet( SotStorage* pStrg, const String& rStrmName );
374 : /** Saves this object to the passed storage. */
375 : ErrCode SavePropertySet( SotStorage* pStrg, const String& rStrmName );
376 :
377 : /** Returns the specified section, or an empty reference, if nothing found. */
378 : SfxOleSectionRef GetSection( SfxOleSectionType eSection ) const;
379 : /** Returns the specified section, or an empty reference, if nothing found. */
380 : SfxOleSectionRef GetSection( const SvGlobalName& rSectionGuid ) const;
381 :
382 : /** Creates and returns the specified section, or just returns it if it already exists. */
383 : SfxOleSection& AddSection( SfxOleSectionType eSection );
384 : /** Creates and returns the specified section, or just returns it if it already exists. */
385 : SfxOleSection& AddSection( const SvGlobalName& rSectionGuid );
386 :
387 : private:
388 : virtual void ImplLoad( SvStream& rStrm );
389 : virtual void ImplSave( SvStream& rStrm );
390 :
391 : /** Returns the GUID for the specified section. */
392 : static const SvGlobalName& GetSectionGuid( SfxOleSectionType eSection );
393 :
394 : private:
395 : typedef ::std::map< SvGlobalName, SfxOleSectionRef > SfxOleSectionMap;
396 : SfxOleSectionMap maSectionMap;
397 : };
398 :
399 :
400 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|