Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / doc / oleprops.cxx
blob6a8cf4676b8943bb1696ef88d1430304f1416c9c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "oleprops.hxx"
32 #include <comphelper/types.hxx>
33 #include <tools/debug.hxx>
34 #include <tools/datetime.hxx>
35 #include <rtl/tencinfo.h>
36 #include <rtl/strbuf.hxx>
38 // ============================================================================
41 // ============================================================================
43 #define STREAM_BUFFER_SIZE 2048
45 // usings
46 using ::rtl::OUString;
47 using ::com::sun::star::uno::Any;
48 using ::com::sun::star::uno::makeAny;
50 using namespace ::com::sun::star;
52 #define TIMESTAMP_INVALID_DATETIME ( DateTime ( Date ( 1, 1, 1601 ), Time ( 0, 0, 0 ) ) ) /// Invalid value for date and time to create invalid instance of TimeStamp.
53 #define TIMESTAMP_INVALID_UTILDATETIME ( util::DateTime ( 0, 0, 0, 0, 1, 1, 1601 ) ) /// Invalid value for date and time to create invalid instance of TimeStamp.
54 #define TIMESTAMP_INVALID_UTILDATE ( util::Date ( 1, 1, 1601 ) ) /// Invalid value for date to create invalid instance of TimeStamp.
56 static
57 bool operator==(const util::DateTime &i_rLeft, const util::DateTime &i_rRight)
59 return i_rLeft.Year == i_rRight.Year
60 && i_rLeft.Month == i_rRight.Month
61 && i_rLeft.Day == i_rRight.Day
62 && i_rLeft.Hours == i_rRight.Hours
63 && i_rLeft.Minutes == i_rRight.Minutes
64 && i_rLeft.Seconds == i_rRight.Seconds
65 && i_rLeft.HundredthSeconds == i_rRight.HundredthSeconds;
68 static
69 bool operator==(const util::Date &i_rLeft, const util::Date &i_rRight)
71 return i_rLeft.Year == i_rRight.Year
72 && i_rLeft.Month == i_rRight.Month
73 && i_rLeft.Day == i_rRight.Day;
76 // ============================================================================
78 /** Property representing a signed 32-bit integer value. */
79 class SfxOleInt32Property : public SfxOlePropertyBase
81 public:
82 explicit SfxOleInt32Property( sal_Int32 nPropId, sal_Int32 nValue = 0 );
84 inline sal_Int32 GetValue() const { return mnValue; }
85 inline void SetValue( sal_Int32 nValue ) { mnValue = nValue; }
87 private:
88 virtual void ImplLoad( SvStream& rStrm );
89 virtual void ImplSave( SvStream& rStrm );
91 private:
92 sal_Int32 mnValue;
95 // ============================================================================
97 /** Property representing a floating-point value. */
98 class SfxOleDoubleProperty : public SfxOlePropertyBase
100 public:
101 explicit SfxOleDoubleProperty( sal_Int32 nPropId, double fValue = 0.0 );
103 inline double GetValue() const { return mfValue; }
104 inline void SetValue( double fValue ) { mfValue = fValue; }
106 private:
107 virtual void ImplLoad( SvStream& rStrm );
108 virtual void ImplSave( SvStream& rStrm );
110 private:
111 double mfValue;
114 // ============================================================================
116 /** Property representing a boolean value. */
117 class SfxOleBoolProperty : public SfxOlePropertyBase
119 public:
120 explicit SfxOleBoolProperty( sal_Int32 nPropId, bool bValue = false );
122 inline bool GetValue() const { return mbValue; }
123 inline void SetValue( bool bValue ) { mbValue = bValue; }
125 private:
126 virtual void ImplLoad( SvStream& rStrm );
127 virtual void ImplSave( SvStream& rStrm );
129 private:
130 bool mbValue;
133 // ============================================================================
135 /** Base class for properties that contain a single string value. */
136 class SfxOleStringPropertyBase : public SfxOlePropertyBase, public SfxOleStringHelper
138 public:
139 explicit SfxOleStringPropertyBase(
140 sal_Int32 nPropId, sal_Int32 nPropType,
141 const SfxOleTextEncoding& rTextEnc );
142 explicit SfxOleStringPropertyBase(
143 sal_Int32 nPropId, sal_Int32 nPropType,
144 const SfxOleTextEncoding& rTextEnc, const String& rValue );
145 explicit SfxOleStringPropertyBase(
146 sal_Int32 nPropId, sal_Int32 nPropType,
147 rtl_TextEncoding eTextEnc );
149 inline const String& GetValue() const { return maValue; }
150 inline void SetValue( const String& rValue ) { maValue = rValue; }
152 private:
153 String maValue;
156 // ============================================================================
158 /** Property representing a bytestring value. */
159 class SfxOleString8Property : public SfxOleStringPropertyBase
161 public:
162 explicit SfxOleString8Property(
163 sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc );
164 explicit SfxOleString8Property(
165 sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc,
166 const String& rValue );
168 private:
169 virtual void ImplLoad( SvStream& rStrm );
170 virtual void ImplSave( SvStream& rStrm );
173 // ============================================================================
175 /** Property representing a Unicode string value. */
176 class SfxOleString16Property : public SfxOleStringPropertyBase
178 public:
179 explicit SfxOleString16Property( sal_Int32 nPropId );
181 private:
182 virtual void ImplLoad( SvStream& rStrm );
183 virtual void ImplSave( SvStream& rStrm );
186 // ============================================================================
188 /** Property representing a filetime value as defined by the Windows API. */
189 class SfxOleFileTimeProperty : public SfxOlePropertyBase
191 public:
192 explicit SfxOleFileTimeProperty( sal_Int32 nPropId );
193 /** @param rDateTime Date and time as LOCAL time. */
194 explicit SfxOleFileTimeProperty( sal_Int32 nPropId, const util::DateTime& rDateTime );
196 /** Returns the time value as LOCAL time. */
197 inline const util::DateTime& GetValue() const { return maDateTime; }
198 /** @param rDateTime Date and time as LOCAL time. */
199 inline void SetValue( const util::DateTime& rDateTime ) { maDateTime = rDateTime; }
201 private:
202 virtual void ImplLoad( SvStream& rStrm );
203 virtual void ImplSave( SvStream& rStrm );
205 private:
206 util::DateTime maDateTime;
209 /** Property representing a filetime value as defined by the Windows API. */
210 class SfxOleDateProperty : public SfxOlePropertyBase
212 public:
213 explicit SfxOleDateProperty( sal_Int32 nPropId );
215 /** Returns the date value as LOCAL time. */
216 inline const util::Date& GetValue() const { return maDate; }
217 /** @param rDate Date as LOCAL time. */
218 inline void SetValue( const util::Date& rDate ) { maDate = rDate; }
220 private:
221 virtual void ImplLoad( SvStream& rStrm );
222 virtual void ImplSave( SvStream& rStrm );
224 private:
225 util::Date maDate;
228 // ============================================================================
230 /** Property representing a thumbnail picture.
232 Currently, only saving this property is implemented.
234 class SfxOleThumbnailProperty : public SfxOlePropertyBase
236 public:
237 explicit SfxOleThumbnailProperty( sal_Int32 nPropId,
238 const uno::Sequence<sal_uInt8> & i_rData);
240 inline bool IsValid() const { return mData.getLength() > 0; }
242 private:
243 virtual void ImplLoad( SvStream& rStrm );
244 virtual void ImplSave( SvStream& rStrm );
246 private:
247 uno::Sequence<sal_uInt8> mData;
250 // ============================================================================
252 /** Property representing a BLOB (which presumably stands for binary large
253 object).
255 Currently, only saving this property is implemented.
257 class SfxOleBlobProperty : public SfxOlePropertyBase
259 public:
260 explicit SfxOleBlobProperty( sal_Int32 nPropId,
261 const uno::Sequence<sal_uInt8> & i_rData);
262 inline bool IsValid() const { return mData.getLength() > 0; }
264 private:
265 virtual void ImplLoad( SvStream& rStrm );
266 virtual void ImplSave( SvStream& rStrm );
268 private:
269 uno::Sequence<sal_uInt8> mData;
272 // ============================================================================
274 sal_uInt16 SfxOleTextEncoding::GetCodePage() const
276 sal_uInt16 nCodePage = IsUnicode() ? CODEPAGE_UNICODE :
277 static_cast< sal_uInt16 >( rtl_getWindowsCodePageFromTextEncoding( *mxTextEnc ) );
278 return (nCodePage == CODEPAGE_UNKNOWN) ? CODEPAGE_UTF8 : nCodePage;
281 void SfxOleTextEncoding::SetCodePage( sal_uInt16 nCodePage )
283 if( nCodePage == CODEPAGE_UNICODE )
284 SetUnicode();
285 else
287 rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
288 if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
289 *mxTextEnc = eTextEnc;
293 // ----------------------------------------------------------------------------
295 String SfxOleStringHelper::LoadString8( SvStream& rStrm ) const
297 return IsUnicode() ? ImplLoadString16( rStrm ) : ImplLoadString8( rStrm );
300 void SfxOleStringHelper::SaveString8( SvStream& rStrm, const String& rValue ) const
302 if( IsUnicode() )
303 ImplSaveString16( rStrm, rValue );
304 else
305 ImplSaveString8( rStrm, rValue );
308 String SfxOleStringHelper::LoadString16( SvStream& rStrm ) const
310 return ImplLoadString16( rStrm );
313 void SfxOleStringHelper::SaveString16( SvStream& rStrm, const String& rValue ) const
315 ImplSaveString16( rStrm, rValue );
318 String SfxOleStringHelper::ImplLoadString8( SvStream& rStrm ) const
320 String aValue;
321 // read size field (signed 32-bit)
322 sal_Int32 nSize(0);
323 rStrm >> nSize;
324 // size field includes trailing NUL character
325 DBG_ASSERT( (0 < nSize) && (nSize <= 0xFFFF),
326 rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM(
327 "SfxOleStringHelper::ImplLoadString8 - invalid string of len ")).
328 append(nSize).getStr() );
329 if( (0 < nSize) && (nSize <= 0xFFFF) )
331 // load character buffer
332 ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nSize + 1 ), 0 );
333 rStrm.Read( &aBuffer.front(), static_cast< sal_Size >( nSize ) );
334 // create string from encoded character array
335 aValue = String( &aBuffer.front(), GetTextEncoding() );
337 return aValue;
340 String SfxOleStringHelper::ImplLoadString16( SvStream& rStrm ) const
342 String aValue;
343 // read size field (signed 32-bit), may be buffer size or character count
344 sal_Int32 nSize(0);
345 rStrm >> nSize;
346 DBG_ASSERT( (0 < nSize) && (nSize <= 0xFFFF), "SfxOleStringHelper::ImplLoadString16 - invalid string" );
347 // size field includes trailing NUL character
348 if( (0 < nSize) && (nSize <= 0xFFFF) )
350 // load character buffer
351 ::std::vector< sal_Unicode > aBuffer;
352 aBuffer.reserve( static_cast< size_t >( nSize + 1 ) );
353 sal_uInt16 cChar;
354 for( sal_Int32 nIdx = 0; nIdx < nSize; ++nIdx )
356 rStrm >> cChar;
357 aBuffer.push_back( static_cast< sal_Unicode >( cChar ) );
359 // stream is always padded to 32-bit boundary, skip 2 bytes on odd character count
360 if( (nSize & 1) == 1 )
361 rStrm.SeekRel( 2 );
362 // create string from character array
363 aBuffer.push_back( 0 );
364 aValue = String( &aBuffer.front() );
366 return aValue;
369 void SfxOleStringHelper::ImplSaveString8( SvStream& rStrm, const String& rValue ) const
371 // encode to byte string
372 rtl::OString aEncoded(rtl::OUStringToOString(rValue, GetTextEncoding()));
373 // write size field (including trailing NUL character)
374 sal_Int32 nSize = aEncoded.getLength() + 1;
375 rStrm << nSize;
376 // write character array with trailing NUL character
377 rStrm.Write(aEncoded.getStr(), aEncoded.getLength());
378 rStrm << sal_uInt8( 0 );
381 void SfxOleStringHelper::ImplSaveString16( SvStream& rStrm, const String& rValue ) const
383 // write size field (including trailing NUL character)
384 sal_Int32 nSize = static_cast< sal_Int32 >( rValue.Len() + 1 );
385 rStrm << nSize;
386 // write character array with trailing NUL character
387 for( xub_StrLen nIdx = 0; nIdx < rValue.Len(); ++nIdx )
388 rStrm << static_cast< sal_uInt16 >( rValue.GetChar( nIdx ) );
389 rStrm << sal_uInt16( 0 );
390 // stream is always padded to 32-bit boundary, add 2 bytes on odd character count
391 if( (nSize & 1) == 1 )
392 rStrm << sal_uInt16( 0 );
395 // ----------------------------------------------------------------------------
397 SfxOleObjectBase::~SfxOleObjectBase()
401 ErrCode SfxOleObjectBase::Load( SvStream& rStrm )
403 mnErrCode = ERRCODE_NONE;
404 ImplLoad( rStrm );
405 SetError( rStrm.GetErrorCode() );
406 return GetError();
409 ErrCode SfxOleObjectBase::Save( SvStream& rStrm )
411 mnErrCode = ERRCODE_NONE;
412 ImplSave( rStrm );
413 SetError( rStrm.GetErrorCode() );
414 return GetError();
417 void SfxOleObjectBase::LoadObject( SvStream& rStrm, SfxOleObjectBase& rObj )
419 SetError( rObj.Load( rStrm ) );
422 void SfxOleObjectBase::SaveObject( SvStream& rStrm, SfxOleObjectBase& rObj )
424 SetError( rObj.Save( rStrm ) );
427 // ----------------------------------------------------------------------------
429 SfxOleCodePageProperty::SfxOleCodePageProperty() :
430 SfxOlePropertyBase( PROPID_CODEPAGE, PROPTYPE_INT16 )
434 void SfxOleCodePageProperty::ImplLoad( SvStream& rStrm )
436 // property type is signed int16, but we use always unsigned int16 for codepages
437 sal_uInt16 nCodePage;
438 rStrm >> nCodePage;
439 SetCodePage( nCodePage );
442 void SfxOleCodePageProperty::ImplSave( SvStream& rStrm )
444 // property type is signed int16, but we use always unsigned int16 for codepages
445 rStrm << GetCodePage();
448 // ----------------------------------------------------------------------------
450 SfxOleInt32Property::SfxOleInt32Property( sal_Int32 nPropId, sal_Int32 nValue ) :
451 SfxOlePropertyBase( nPropId, PROPTYPE_INT32 ),
452 mnValue( nValue )
456 void SfxOleInt32Property::ImplLoad( SvStream& rStrm )
458 rStrm >> mnValue;
461 void SfxOleInt32Property::ImplSave( SvStream& rStrm )
463 rStrm << mnValue;
466 // ----------------------------------------------------------------------------
468 SfxOleDoubleProperty::SfxOleDoubleProperty( sal_Int32 nPropId, double fValue ) :
469 SfxOlePropertyBase( nPropId, PROPTYPE_DOUBLE ),
470 mfValue( fValue )
474 void SfxOleDoubleProperty::ImplLoad( SvStream& rStrm )
476 rStrm >> mfValue;
479 void SfxOleDoubleProperty::ImplSave( SvStream& rStrm )
481 rStrm << mfValue;
484 // ----------------------------------------------------------------------------
486 SfxOleBoolProperty::SfxOleBoolProperty( sal_Int32 nPropId, bool bValue ) :
487 SfxOlePropertyBase( nPropId, PROPTYPE_BOOL ),
488 mbValue( bValue )
492 void SfxOleBoolProperty::ImplLoad( SvStream& rStrm )
494 sal_Int16 nValue(0);
495 rStrm >> nValue;
496 mbValue = nValue != 0;
499 void SfxOleBoolProperty::ImplSave( SvStream& rStrm )
501 rStrm << static_cast< sal_Int16 >( mbValue ? -1 : 0 );
504 // ----------------------------------------------------------------------------
506 SfxOleStringPropertyBase::SfxOleStringPropertyBase(
507 sal_Int32 nPropId, sal_Int32 nPropType, const SfxOleTextEncoding& rTextEnc ) :
508 SfxOlePropertyBase( nPropId, nPropType ),
509 SfxOleStringHelper( rTextEnc )
513 SfxOleStringPropertyBase::SfxOleStringPropertyBase(
514 sal_Int32 nPropId, sal_Int32 nPropType, const SfxOleTextEncoding& rTextEnc, const String& rValue ) :
515 SfxOlePropertyBase( nPropId, nPropType ),
516 SfxOleStringHelper( rTextEnc ),
517 maValue( rValue )
521 SfxOleStringPropertyBase::SfxOleStringPropertyBase(
522 sal_Int32 nPropId, sal_Int32 nPropType, rtl_TextEncoding eTextEnc ) :
523 SfxOlePropertyBase( nPropId, nPropType ),
524 SfxOleStringHelper( eTextEnc )
528 // ----------------------------------------------------------------------------
530 SfxOleString8Property::SfxOleString8Property(
531 sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc ) :
532 SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING8, rTextEnc )
536 SfxOleString8Property::SfxOleString8Property(
537 sal_Int32 nPropId, const SfxOleTextEncoding& rTextEnc, const String& rValue ) :
538 SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING8, rTextEnc, rValue )
542 void SfxOleString8Property::ImplLoad( SvStream& rStrm )
544 SetValue( LoadString8( rStrm ) );
547 void SfxOleString8Property::ImplSave( SvStream& rStrm )
549 SaveString8( rStrm, GetValue() );
552 // ----------------------------------------------------------------------------
554 SfxOleString16Property::SfxOleString16Property( sal_Int32 nPropId ) :
555 SfxOleStringPropertyBase( nPropId, PROPTYPE_STRING16, RTL_TEXTENCODING_UCS2 )
559 void SfxOleString16Property::ImplLoad( SvStream& rStrm )
561 SetValue( LoadString16( rStrm ) );
564 void SfxOleString16Property::ImplSave( SvStream& rStrm )
566 SaveString16( rStrm, GetValue() );
569 // ----------------------------------------------------------------------------
571 SfxOleFileTimeProperty::SfxOleFileTimeProperty( sal_Int32 nPropId ) :
572 SfxOlePropertyBase( nPropId, PROPTYPE_FILETIME )
576 SfxOleFileTimeProperty::SfxOleFileTimeProperty( sal_Int32 nPropId, const util::DateTime& rDateTime ) :
577 SfxOlePropertyBase( nPropId, PROPTYPE_FILETIME ),
578 maDateTime( rDateTime )
582 void SfxOleFileTimeProperty::ImplLoad( SvStream& rStrm )
584 sal_uInt32 nLower(0), nUpper(0);
585 rStrm >> nLower >> nUpper;
586 ::DateTime aDateTime = DateTime::CreateFromWin32FileDateTime( nLower, nUpper );
587 // note: editing duration is stored as offset to TIMESTAMP_INVALID_DATETIME
588 // of course we should not convert the time zone of a duration!
589 // heuristic to detect editing durations (which we assume to be < 1 year):
590 // check only the year, not the entire date
591 if ( aDateTime.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() )
592 aDateTime.ConvertToLocalTime();
593 maDateTime.Year = aDateTime.GetYear();
594 maDateTime.Month = aDateTime.GetMonth();
595 maDateTime.Day = aDateTime.GetDay();
596 maDateTime.Hours = aDateTime.GetHour();
597 maDateTime.Minutes = aDateTime.GetMin();
598 maDateTime.Seconds = aDateTime.GetSec();
599 maDateTime.HundredthSeconds = aDateTime.Get100Sec();
602 void SfxOleFileTimeProperty::ImplSave( SvStream& rStrm )
604 DateTime aDateTimeUtc(
605 Date(
606 static_cast< sal_uInt16 >( maDateTime.Day ),
607 static_cast< sal_uInt16 >( maDateTime.Month ),
608 static_cast< sal_uInt16 >( maDateTime.Year ) ),
609 Time(
610 static_cast< sal_uIntPtr >( maDateTime.Hours ),
611 static_cast< sal_uIntPtr >( maDateTime.Minutes ),
612 static_cast< sal_uIntPtr >( maDateTime.Seconds ),
613 static_cast< sal_uIntPtr >( maDateTime.HundredthSeconds ) ) );
614 // invalid time stamp is not converted to UTC
615 // heuristic to detect editing durations (which we assume to be < 1 year):
616 // check only the year, not the entire date
617 if( aDateTimeUtc.IsValidAndGregorian()
618 && aDateTimeUtc.GetYear() != TIMESTAMP_INVALID_DATETIME.GetYear() ) {
619 aDateTimeUtc.ConvertToUTC();
621 sal_uInt32 nLower, nUpper;
622 aDateTimeUtc.GetWin32FileDateTime( nLower, nUpper );
623 rStrm << nLower << nUpper;
626 SfxOleDateProperty::SfxOleDateProperty( sal_Int32 nPropId ) :
627 SfxOlePropertyBase( nPropId, PROPTYPE_DATE )
631 void SfxOleDateProperty::ImplLoad( SvStream& rStrm )
633 double fValue(0.0);
634 rStrm >> fValue;
635 //stored as number of days (not seconds) since December 31, 1899
636 ::Date aDate(31, 12, 1899);
637 long nDays = fValue;
638 aDate += nDays;
639 maDate.Day = aDate.GetDay();
640 maDate.Month = aDate.GetMonth();
641 maDate.Year = aDate.GetYear();
644 void SfxOleDateProperty::ImplSave( SvStream& rStrm )
646 long nDays = ::Date::DateToDays(maDate.Day, maDate.Month, maDate.Year);
647 //number of days (not seconds) since December 31, 1899
648 long nStartDays = ::Date::DateToDays(31, 12, 1899);
649 double fValue = nDays-nStartDays;
650 rStrm << fValue;
653 // ----------------------------------------------------------------------------
655 SfxOleThumbnailProperty::SfxOleThumbnailProperty(
656 sal_Int32 nPropId, const uno::Sequence<sal_uInt8> & i_rData) :
657 SfxOlePropertyBase( nPropId, PROPTYPE_CLIPFMT ),
658 mData(i_rData)
662 void SfxOleThumbnailProperty::ImplLoad( SvStream& )
664 SAL_WARN( "sfx2.doc", "SfxOleThumbnailProperty::ImplLoad - not implemented" );
665 SetError( SVSTREAM_INVALID_ACCESS );
668 void SfxOleThumbnailProperty::ImplSave( SvStream& rStrm )
670 /* Type Contents
671 -----------------------------------------------------------------------
672 int32 size of following data
673 int32 clipboard format tag (see below)
674 byte[] clipboard data (see below)
676 Clipboard format tag:
677 -1 = Windows clipboard format
678 -2 = Macintosh clipboard format
679 -3 = GUID that contains a format identifier (FMTID)
680 >0 = custom clipboard format name plus data (see msdn site below)
681 0 = no data
683 References:
684 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stg/stg/propvariant.asp
685 http://jakarta.apache.org/poi/hpsf/thumbnails.html
686 http://linux.com.hk/docs/poi/org/apache/poi/hpsf/Thumbnail.html
687 http://sparks.discreet.com/knowledgebase/public/solutions/ExtractThumbnailImg.htm
689 if( IsValid() )
691 // clipboard size: clip_format_tag + data_format_tag + bitmap_len
692 sal_Int32 nClipSize = static_cast< sal_Int32 >( 4 + 4 + mData.getLength() );
693 rStrm << nClipSize << CLIPFMT_WIN << CLIPDATAFMT_DIB;
694 rStrm.Write( mData.getConstArray(), mData.getLength() );
696 else
698 SAL_WARN( "sfx2.doc", "SfxOleThumbnailProperty::ImplSave - invalid thumbnail property" );
699 SetError( SVSTREAM_INVALID_ACCESS );
703 // ----------------------------------------------------------------------------
705 SfxOleBlobProperty::SfxOleBlobProperty( sal_Int32 nPropId,
706 const uno::Sequence<sal_uInt8> & i_rData) :
707 SfxOlePropertyBase( nPropId, PROPTYPE_BLOB ),
708 mData(i_rData)
712 void SfxOleBlobProperty::ImplLoad( SvStream& )
714 SAL_WARN( "sfx2.doc", "SfxOleBlobProperty::ImplLoad - not implemented" );
715 SetError( SVSTREAM_INVALID_ACCESS );
718 void SfxOleBlobProperty::ImplSave( SvStream& rStrm )
720 if (IsValid()) {
721 rStrm.Write( mData.getConstArray(), mData.getLength() );
722 } else {
723 SAL_WARN( "sfx2.doc", "SfxOleBlobProperty::ImplSave - invalid BLOB property" );
724 SetError( SVSTREAM_INVALID_ACCESS );
728 // ----------------------------------------------------------------------------
730 SfxOleDictionaryProperty::SfxOleDictionaryProperty( const SfxOleTextEncoding& rTextEnc ) :
731 SfxOlePropertyBase( PROPID_DICTIONARY, 0 ),
732 SfxOleStringHelper( rTextEnc )
736 const String& SfxOleDictionaryProperty::GetPropertyName( sal_Int32 nPropId ) const
738 SfxOlePropNameMap::const_iterator aIt = maPropNameMap.find( nPropId );
739 return (aIt == maPropNameMap.end()) ? String::EmptyString() : aIt->second;
742 void SfxOleDictionaryProperty::SetPropertyName( sal_Int32 nPropId, const String& rPropName )
744 maPropNameMap[ nPropId ] = rPropName;
745 // dictionary property contains number of pairs in property type field
746 SetPropType( static_cast< sal_Int32 >( maPropNameMap.size() ) );
749 void SfxOleDictionaryProperty::ImplLoad( SvStream& rStrm )
751 // dictionary property contains number of pairs in property type field
752 sal_Int32 nNameCount = GetPropType();
753 // read property ID/name pairs
754 maPropNameMap.clear();
755 for( sal_Int32 nIdx = 0; (nIdx < nNameCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nIdx )
757 sal_Int32 nPropId(0);
758 rStrm >> nPropId;
759 // name always stored as byte string
760 maPropNameMap[ nPropId ] = LoadString8( rStrm );
764 void SfxOleDictionaryProperty::ImplSave( SvStream& rStrm )
766 // write property ID/name pairs
767 for( SfxOlePropNameMap::const_iterator aIt = maPropNameMap.begin(), aEnd = maPropNameMap.end(); aIt != aEnd; ++aIt )
769 rStrm << aIt->first;
770 // name always stored as byte string
771 SaveString8( rStrm, aIt->second );
775 // ----------------------------------------------------------------------------
777 SfxOleSection::SfxOleSection( bool bSupportsDict ) :
778 maDictProp( maCodePageProp ),
779 mnStartPos( 0 ),
780 mbSupportsDict( bSupportsDict )
784 SfxOlePropertyRef SfxOleSection::GetProperty( sal_Int32 nPropId ) const
786 SfxOlePropertyRef xProp;
787 SfxOlePropMap::const_iterator aIt = maPropMap.find( nPropId );
788 if( aIt != maPropMap.end() )
789 xProp = aIt->second;
790 return xProp;
793 bool SfxOleSection::GetInt32Value( sal_Int32& rnValue, sal_Int32 nPropId ) const
795 SfxOlePropertyRef xProp = GetProperty( nPropId );
796 const SfxOleInt32Property* pProp =
797 dynamic_cast< const SfxOleInt32Property* >( xProp.get() );
798 if( pProp )
799 rnValue = pProp->GetValue();
800 return pProp != 0;
803 bool SfxOleSection::GetDoubleValue( double& rfValue, sal_Int32 nPropId ) const
805 SfxOlePropertyRef xProp = GetProperty( nPropId );
806 const SfxOleDoubleProperty* pProp =
807 dynamic_cast< const SfxOleDoubleProperty* >( xProp.get() );
808 if( pProp )
809 rfValue = pProp->GetValue();
810 return pProp != 0;
813 bool SfxOleSection::GetBoolValue( bool& rbValue, sal_Int32 nPropId ) const
815 SfxOlePropertyRef xProp = GetProperty( nPropId );
816 const SfxOleBoolProperty* pProp =
817 dynamic_cast< const SfxOleBoolProperty* >( xProp.get() );
818 if( pProp )
819 rbValue = pProp->GetValue();
820 return pProp != 0;
823 bool SfxOleSection::GetStringValue( String& rValue, sal_Int32 nPropId ) const
825 SfxOlePropertyRef xProp = GetProperty( nPropId );
826 const SfxOleStringPropertyBase* pProp =
827 dynamic_cast< const SfxOleStringPropertyBase* >( xProp.get() );
828 if( pProp )
829 rValue = pProp->GetValue();
830 return pProp != 0;
833 bool SfxOleSection::GetFileTimeValue( util::DateTime& rValue, sal_Int32 nPropId ) const
835 SfxOlePropertyRef xProp = GetProperty( nPropId );
836 const SfxOleFileTimeProperty* pProp =
837 dynamic_cast< const SfxOleFileTimeProperty* >( xProp.get() );
838 if( pProp )
840 if ( pProp->GetValue() == TIMESTAMP_INVALID_UTILDATETIME )
841 rValue = util::DateTime();
842 else
843 rValue = pProp->GetValue();
845 return pProp != 0;
848 bool SfxOleSection::GetDateValue( util::Date& rValue, sal_Int32 nPropId ) const
850 SfxOlePropertyRef xProp = GetProperty( nPropId );
851 const SfxOleDateProperty* pProp =
852 dynamic_cast< const SfxOleDateProperty* >( xProp.get() );
853 if( pProp )
855 if ( pProp->GetValue() == TIMESTAMP_INVALID_UTILDATE )
856 rValue = util::Date();
857 else
858 rValue = pProp->GetValue();
860 return pProp != 0;
863 void SfxOleSection::SetProperty( SfxOlePropertyRef xProp )
865 if( xProp.get() )
866 maPropMap[ xProp->GetPropId() ] = xProp;
869 void SfxOleSection::SetInt32Value( sal_Int32 nPropId, sal_Int32 nValue )
871 SetProperty( SfxOlePropertyRef( new SfxOleInt32Property( nPropId, nValue ) ) );
874 void SfxOleSection::SetDoubleValue( sal_Int32 nPropId, double fValue )
876 SetProperty( SfxOlePropertyRef( new SfxOleDoubleProperty( nPropId, fValue ) ) );
879 void SfxOleSection::SetBoolValue( sal_Int32 nPropId, bool bValue )
881 SetProperty( SfxOlePropertyRef( new SfxOleBoolProperty( nPropId, bValue ) ) );
884 bool SfxOleSection::SetStringValue( sal_Int32 nPropId, const String& rValue, bool bSkipEmpty )
886 bool bInserted = !bSkipEmpty || (rValue.Len() > 0);
887 if( bInserted )
888 SetProperty( SfxOlePropertyRef( new SfxOleString8Property( nPropId, maCodePageProp, rValue ) ) );
889 return bInserted;
892 void SfxOleSection::SetFileTimeValue( sal_Int32 nPropId, const util::DateTime& rValue )
894 if ( rValue.Year == 0 || rValue.Month == 0 || rValue.Day == 0 )
895 SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, TIMESTAMP_INVALID_UTILDATETIME ) ) );
896 else
897 SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, rValue ) ) );
900 void SfxOleSection::SetDateValue( sal_Int32 nPropId, const util::Date& rValue )
902 //Annoyingly MS2010 considers VT_DATE apparently as an invalid possibility, so here we use VT_FILETIME
903 //instead :-(
904 if ( rValue.Year == 0 || rValue.Month == 0 || rValue.Day == 0 )
905 SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, TIMESTAMP_INVALID_UTILDATETIME ) ) );
906 else
908 const util::DateTime aValue(0, 0, 0, 0, rValue.Day, rValue.Month, rValue.Year );
909 SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId, aValue ) ) );
913 void SfxOleSection::SetThumbnailValue( sal_Int32 nPropId,
914 const uno::Sequence<sal_uInt8> & i_rData)
916 SfxOleThumbnailProperty* pThumbnail = new SfxOleThumbnailProperty( nPropId, i_rData );
917 SfxOlePropertyRef xProp( pThumbnail ); // take ownership
918 if( pThumbnail->IsValid() )
919 SetProperty( xProp );
922 void SfxOleSection::SetBlobValue( sal_Int32 nPropId,
923 const uno::Sequence<sal_uInt8> & i_rData)
925 SfxOleBlobProperty* pBlob( new SfxOleBlobProperty( nPropId, i_rData ) );
926 SfxOlePropertyRef xProp( pBlob );
927 if( pBlob->IsValid() ) {
928 SetProperty( xProp );
932 Any SfxOleSection::GetAnyValue( sal_Int32 nPropId ) const
934 Any aValue;
935 sal_Int32 nInt32 = 0;
936 double fDouble = 0.0;
937 bool bBool = false;
938 String aString;
939 ::com::sun::star::util::DateTime aApiDateTime;
940 ::com::sun::star::util::Date aApiDate;
942 if( GetInt32Value( nInt32, nPropId ) )
943 aValue <<= nInt32;
944 else if( GetDoubleValue( fDouble, nPropId ) )
945 aValue <<= fDouble;
946 else if( GetBoolValue( bBool, nPropId ) )
947 ::comphelper::setBOOL( aValue, bBool ? sal_True : sal_False );
948 else if( GetStringValue( aString, nPropId ) )
949 aValue <<= OUString( aString );
950 else if( GetFileTimeValue( aApiDateTime, nPropId ) )
952 aValue <<= aApiDateTime;
954 else if( GetDateValue( aApiDate, nPropId ) )
956 aValue <<= aApiDate;
958 return aValue;
961 bool SfxOleSection::SetAnyValue( sal_Int32 nPropId, const Any& rValue )
963 bool bInserted = true;
964 sal_Int32 nInt32 = 0;
965 double fDouble = 0.0;
966 OUString aString;
967 ::com::sun::star::util::DateTime aApiDateTime;
968 ::com::sun::star::util::Date aApiDate;
970 if( rValue.getValueType() == ::getBooleanCppuType() )
971 SetBoolValue( nPropId, ::comphelper::getBOOL( rValue ) == sal_True );
972 else if( rValue >>= nInt32 )
973 SetInt32Value( nPropId, nInt32 );
974 else if( rValue >>= fDouble )
975 SetDoubleValue( nPropId, fDouble );
976 else if( rValue >>= aString )
977 bInserted = SetStringValue( nPropId, aString );
978 else if( rValue >>= aApiDateTime )
979 SetFileTimeValue( nPropId, aApiDateTime );
980 else if( rValue >>= aApiDate )
981 SetDateValue( nPropId, aApiDate );
982 else
983 bInserted = false;
984 return bInserted;
987 const String& SfxOleSection::GetPropertyName( sal_Int32 nPropId ) const
989 return maDictProp.GetPropertyName( nPropId );
992 void SfxOleSection::SetPropertyName( sal_Int32 nPropId, const String& rPropName )
994 maDictProp.SetPropertyName( nPropId, rPropName );
997 void SfxOleSection::GetPropertyIds( ::std::vector< sal_Int32 >& rPropIds ) const
999 rPropIds.clear();
1000 for( SfxOlePropMap::const_iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt )
1001 rPropIds.push_back( aIt->first );
1004 sal_Int32 SfxOleSection::GetFreePropertyId() const
1006 return maPropMap.empty() ? PROPID_FIRSTCUSTOM : (maPropMap.rbegin()->first + 1);
1009 void SfxOleSection::ImplLoad( SvStream& rStrm )
1011 // read section header
1012 mnStartPos = rStrm.Tell();
1013 sal_uInt32 nSize(0);
1014 sal_Int32 nPropCount(0);
1015 rStrm >> nSize >> nPropCount;
1017 // read property ID/position pairs
1018 typedef ::std::map< sal_Int32, sal_uInt32 > SfxOlePropPosMap;
1019 SfxOlePropPosMap aPropPosMap;
1020 for( sal_Int32 nPropIdx = 0; (nPropIdx < nPropCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nPropIdx )
1022 sal_Int32 nPropId(0);
1023 sal_uInt32 nPropPos(0);
1024 rStrm >> nPropId >> nPropPos;
1025 aPropPosMap[ nPropId ] = nPropPos;
1028 // read codepage property
1029 SfxOlePropPosMap::iterator aCodePageIt = aPropPosMap.find( PROPID_CODEPAGE );
1030 if( (aCodePageIt != aPropPosMap.end()) && SeekToPropertyPos( rStrm, aCodePageIt->second ) )
1032 // codepage property must be of type signed int-16
1033 sal_Int32 nPropType(0);
1034 rStrm >> nPropType;
1035 if( nPropType == PROPTYPE_INT16 )
1036 LoadObject( rStrm, maCodePageProp );
1037 // remove property position
1038 aPropPosMap.erase( aCodePageIt );
1041 // read dictionary property
1042 SfxOlePropPosMap::iterator aDictIt = aPropPosMap.find( PROPID_DICTIONARY );
1043 if( (aDictIt != aPropPosMap.end()) && SeekToPropertyPos( rStrm, aDictIt->second ) )
1045 // #i66214# #i66428# applications may write broken dictionary properties in wrong sections
1046 if( mbSupportsDict )
1048 // dictionary property contains number of pairs in property type field
1049 sal_Int32 nNameCount(0);
1050 rStrm >> nNameCount;
1051 maDictProp.SetNameCount( nNameCount );
1052 LoadObject( rStrm, maDictProp );
1054 // always remove position of dictionary property (do not try to read it again below)
1055 aPropPosMap.erase( aDictIt );
1058 // read other properties
1059 maPropMap.clear();
1060 for( SfxOlePropPosMap::const_iterator aIt = aPropPosMap.begin(), aEnd = aPropPosMap.end(); aIt != aEnd; ++aIt )
1061 if( SeekToPropertyPos( rStrm, aIt->second ) )
1062 LoadProperty( rStrm, aIt->first );
1065 void SfxOleSection::ImplSave( SvStream& rStrm )
1067 /* Always export with UTF-8 encoding. All dependent properties (bytestring
1068 and dictionary) will be updated automatically. */
1069 maCodePageProp.SetTextEncoding( RTL_TEXTENCODING_UTF8 );
1071 // write section header
1072 mnStartPos = rStrm.Tell();
1073 sal_Int32 nPropCount = static_cast< sal_Int32 >( maPropMap.size() + 1 );
1074 if( maDictProp.HasPropertyNames() )
1075 ++nPropCount;
1076 rStrm << sal_uInt32( 0 ) << nPropCount;
1078 // write placeholders for property ID/position pairs
1079 sal_Size nPropPosPos = rStrm.Tell();
1080 rStrm.SeekRel( static_cast< sal_sSize >( 8 * nPropCount ) );
1082 // write dictionary property
1083 if( maDictProp.HasPropertyNames() )
1084 SaveProperty( rStrm, maDictProp, nPropPosPos );
1085 // write codepage property
1086 SaveProperty( rStrm, maCodePageProp, nPropPosPos );
1087 // write other properties
1088 for( SfxOlePropMap::const_iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt )
1089 SaveProperty( rStrm, *aIt->second, nPropPosPos );
1091 // write section size (first field in section header)
1092 rStrm.Seek( STREAM_SEEK_TO_END );
1093 sal_uInt32 nSectSize = static_cast< sal_uInt32 >( rStrm.Tell() - mnStartPos );
1094 rStrm.Seek( mnStartPos );
1095 rStrm << nSectSize;
1098 bool SfxOleSection::SeekToPropertyPos( SvStream& rStrm, sal_uInt32 nPropPos ) const
1100 rStrm.Seek( static_cast< sal_Size >( mnStartPos + nPropPos ) );
1101 return rStrm.GetErrorCode() == SVSTREAM_OK;
1104 void SfxOleSection::LoadProperty( SvStream& rStrm, sal_Int32 nPropId )
1106 // property data type
1107 sal_Int32 nPropType(0);
1108 rStrm >> nPropType;
1109 // create empty property object
1110 SfxOlePropertyRef xProp;
1111 switch( nPropType )
1113 case PROPTYPE_INT32:
1114 xProp.reset( new SfxOleInt32Property( nPropId ) );
1115 break;
1116 case PROPTYPE_DOUBLE:
1117 xProp.reset( new SfxOleDoubleProperty( nPropId ) );
1118 break;
1119 case PROPTYPE_BOOL:
1120 xProp.reset( new SfxOleBoolProperty( nPropId ) );
1121 break;
1122 case PROPTYPE_STRING8:
1123 xProp.reset( new SfxOleString8Property( nPropId, maCodePageProp ) );
1124 break;
1125 case PROPTYPE_STRING16:
1126 xProp.reset( new SfxOleString16Property( nPropId ) );
1127 break;
1128 case PROPTYPE_FILETIME:
1129 xProp.reset( new SfxOleFileTimeProperty( nPropId ) );
1130 break;
1131 case PROPTYPE_DATE:
1132 xProp.reset( new SfxOleDateProperty( nPropId ) );
1133 break;
1135 // load property contents
1136 if( xProp.get() )
1138 SetError( xProp->Load( rStrm ) );
1139 maPropMap[ nPropId ] = xProp;
1143 void SfxOleSection::SaveProperty( SvStream& rStrm, SfxOlePropertyBase& rProp, sal_Size& rnPropPosPos )
1145 rStrm.Seek( STREAM_SEEK_TO_END );
1146 sal_uInt32 nPropPos = static_cast< sal_uInt32 >( rStrm.Tell() - mnStartPos );
1147 // property data type
1148 rStrm << rProp.GetPropType();
1149 // write property contents
1150 SaveObject( rStrm, rProp );
1151 // align to 32-bit
1152 while( (rStrm.Tell() & 3) != 0 )
1153 rStrm << sal_uInt8( 0 );
1154 // write property ID/position pair
1155 rStrm.Seek( rnPropPosPos );
1156 rStrm << rProp.GetPropId() << nPropPos;
1157 rnPropPosPos = rStrm.Tell();
1160 // ----------------------------------------------------------------------------
1162 ErrCode SfxOlePropertySet::LoadPropertySet( SotStorage* pStrg, const String& rStrmName )
1164 if( pStrg )
1166 SotStorageStreamRef xStrm = pStrg->OpenSotStream( rStrmName, STREAM_STD_READ );
1167 if( xStrm.Is() && (xStrm->GetError() == SVSTREAM_OK) )
1169 xStrm->SetBufferSize( STREAM_BUFFER_SIZE );
1170 Load( *xStrm );
1172 else
1173 SetError( ERRCODE_IO_ACCESSDENIED );
1175 else
1176 SetError( ERRCODE_IO_ACCESSDENIED );
1177 return GetError();
1180 ErrCode SfxOlePropertySet::SavePropertySet( SotStorage* pStrg, const String& rStrmName )
1182 if( pStrg )
1184 SotStorageStreamRef xStrm = pStrg->OpenSotStream( rStrmName, STREAM_TRUNC | STREAM_STD_WRITE );
1185 if( xStrm.Is() )
1186 Save( *xStrm );
1187 else
1188 SetError( ERRCODE_IO_ACCESSDENIED );
1190 else
1191 SetError( ERRCODE_IO_ACCESSDENIED );
1192 return GetError();
1195 SfxOleSectionRef SfxOlePropertySet::GetSection( SfxOleSectionType eSection ) const
1197 return GetSection( GetSectionGuid( eSection ) );
1200 SfxOleSectionRef SfxOlePropertySet::GetSection( const SvGlobalName& rSectionGuid ) const
1202 SfxOleSectionRef xSection;
1203 SfxOleSectionMap::const_iterator aIt = maSectionMap.find( rSectionGuid );
1204 if( aIt != maSectionMap.end() )
1205 xSection = aIt->second;
1206 return xSection;
1209 SfxOleSection& SfxOlePropertySet::AddSection( SfxOleSectionType eSection )
1211 return AddSection( GetSectionGuid( eSection ) );
1214 SfxOleSection& SfxOlePropertySet::AddSection( const SvGlobalName& rSectionGuid )
1216 SfxOleSectionRef xSection = GetSection( rSectionGuid );
1217 if( !xSection )
1219 // #i66214# #i66428# applications may write broken dictionary properties in wrong sections
1220 bool bSupportsDict = rSectionGuid == GetSectionGuid( SECTION_CUSTOM );
1221 xSection.reset( new SfxOleSection( bSupportsDict ) );
1222 maSectionMap[ rSectionGuid ] = xSection;
1224 return *xSection;
1227 void SfxOlePropertySet::ImplLoad( SvStream& rStrm )
1229 // read property set header
1230 sal_uInt16 nByteOrder;
1231 sal_uInt16 nVersion;
1232 sal_uInt16 nOsMinor;
1233 sal_uInt16 nOsType;
1234 SvGlobalName aGuid;
1235 sal_Int32 nSectCount(0);
1236 rStrm >> nByteOrder >> nVersion >> nOsMinor >> nOsType >> aGuid >> nSectCount;
1238 // read sections
1239 sal_Size nSectPosPos = rStrm.Tell();
1240 for( sal_Int32 nSectIdx = 0; (nSectIdx < nSectCount) && (rStrm.GetErrorCode() == SVSTREAM_OK) && !rStrm.IsEof(); ++nSectIdx )
1242 // read section guid/position pair
1243 rStrm.Seek( nSectPosPos );
1244 SvGlobalName aSectGuid;
1245 sal_uInt32 nSectPos;
1246 rStrm >> aSectGuid >> nSectPos;
1247 nSectPosPos = rStrm.Tell();
1248 // read section
1249 rStrm.Seek( static_cast< sal_Size >( nSectPos ) );
1250 if( rStrm.GetErrorCode() == SVSTREAM_OK )
1251 LoadObject( rStrm, AddSection( aSectGuid ) );
1255 void SfxOlePropertySet::ImplSave( SvStream& rStrm )
1257 // write property set header
1258 SvGlobalName aGuid;
1259 sal_Int32 nSectCount = static_cast< sal_Int32 >( maSectionMap.size() );
1260 rStrm << sal_uInt16( 0xFFFE ) // byte order
1261 << sal_uInt16( 0 ) // version
1262 << sal_uInt16( 1 ) // OS minor version
1263 << sal_uInt16( 2 ) // OS type always windows for text encoding
1264 << aGuid // unused guid
1265 << nSectCount; // number of sections
1267 // write placeholders for section guid/position pairs
1268 sal_Size nSectPosPos = rStrm.Tell();
1269 rStrm.SeekRel( static_cast< sal_sSize >( 20 * nSectCount ) );
1271 // write sections
1272 for( SfxOleSectionMap::const_iterator aIt = maSectionMap.begin(), aEnd = maSectionMap.end(); aIt != aEnd; ++aIt )
1274 SfxOleSection& rSection = *aIt->second;
1275 rStrm.Seek( STREAM_SEEK_TO_END );
1276 sal_uInt32 nSectPos = static_cast< sal_uInt32 >( rStrm.Tell() );
1277 // write the section
1278 SaveObject( rStrm, rSection );
1279 // write section guid/position pair
1280 rStrm.Seek( nSectPosPos );
1281 rStrm << aIt->first << nSectPos;
1282 nSectPosPos = rStrm.Tell();
1286 const SvGlobalName& SfxOlePropertySet::GetSectionGuid( SfxOleSectionType eSection )
1288 static const SvGlobalName saGlobalGuid( 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 );
1289 static const SvGlobalName saBuiltInGuid( 0xD5CDD502, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE );
1290 static const SvGlobalName saCustomGuid( 0xD5CDD505, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE );
1291 static const SvGlobalName saEmptyGuid;
1292 switch( eSection )
1294 case SECTION_GLOBAL: return saGlobalGuid;
1295 case SECTION_BUILTIN: return saBuiltInGuid;
1296 case SECTION_CUSTOM: return saCustomGuid;
1297 default: SAL_WARN( "sfx2.doc", "SfxOlePropertySet::GetSectionGuid - unknown section type" );
1299 return saEmptyGuid;
1302 // ============================================================================
1304 //} // namespace
1306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */