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
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.
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
;
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
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
; }
88 virtual void ImplLoad( SvStream
& rStrm
);
89 virtual void ImplSave( SvStream
& rStrm
);
95 // ============================================================================
97 /** Property representing a floating-point value. */
98 class SfxOleDoubleProperty
: public SfxOlePropertyBase
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
; }
107 virtual void ImplLoad( SvStream
& rStrm
);
108 virtual void ImplSave( SvStream
& rStrm
);
114 // ============================================================================
116 /** Property representing a boolean value. */
117 class SfxOleBoolProperty
: public SfxOlePropertyBase
120 explicit SfxOleBoolProperty( sal_Int32 nPropId
, bool bValue
= false );
122 inline bool GetValue() const { return mbValue
; }
123 inline void SetValue( bool bValue
) { mbValue
= bValue
; }
126 virtual void ImplLoad( SvStream
& rStrm
);
127 virtual void ImplSave( SvStream
& rStrm
);
133 // ============================================================================
135 /** Base class for properties that contain a single string value. */
136 class SfxOleStringPropertyBase
: public SfxOlePropertyBase
, public SfxOleStringHelper
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
; }
156 // ============================================================================
158 /** Property representing a bytestring value. */
159 class SfxOleString8Property
: public SfxOleStringPropertyBase
162 explicit SfxOleString8Property(
163 sal_Int32 nPropId
, const SfxOleTextEncoding
& rTextEnc
);
164 explicit SfxOleString8Property(
165 sal_Int32 nPropId
, const SfxOleTextEncoding
& rTextEnc
,
166 const String
& rValue
);
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
179 explicit SfxOleString16Property( sal_Int32 nPropId
);
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
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
; }
202 virtual void ImplLoad( SvStream
& rStrm
);
203 virtual void ImplSave( SvStream
& rStrm
);
206 util::DateTime maDateTime
;
209 /** Property representing a filetime value as defined by the Windows API. */
210 class SfxOleDateProperty
: public SfxOlePropertyBase
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
; }
221 virtual void ImplLoad( SvStream
& rStrm
);
222 virtual void ImplSave( SvStream
& rStrm
);
228 // ============================================================================
230 /** Property representing a thumbnail picture.
232 Currently, only saving this property is implemented.
234 class SfxOleThumbnailProperty
: public SfxOlePropertyBase
237 explicit SfxOleThumbnailProperty( sal_Int32 nPropId
,
238 const uno::Sequence
<sal_uInt8
> & i_rData
);
240 inline bool IsValid() const { return mData
.getLength() > 0; }
243 virtual void ImplLoad( SvStream
& rStrm
);
244 virtual void ImplSave( SvStream
& rStrm
);
247 uno::Sequence
<sal_uInt8
> mData
;
250 // ============================================================================
252 /** Property representing a BLOB (which presumably stands for binary large
255 Currently, only saving this property is implemented.
257 class SfxOleBlobProperty
: public SfxOlePropertyBase
260 explicit SfxOleBlobProperty( sal_Int32 nPropId
,
261 const uno::Sequence
<sal_uInt8
> & i_rData
);
262 inline bool IsValid() const { return mData
.getLength() > 0; }
265 virtual void ImplLoad( SvStream
& rStrm
);
266 virtual void ImplSave( SvStream
& rStrm
);
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
)
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
303 ImplSaveString16( rStrm
, rValue
);
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
321 // read size field (signed 32-bit)
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() );
340 String
SfxOleStringHelper::ImplLoadString16( SvStream
& rStrm
) const
343 // read size field (signed 32-bit), may be buffer size or character count
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 ) );
354 for( sal_Int32 nIdx
= 0; nIdx
< nSize
; ++nIdx
)
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 )
362 // create string from character array
363 aBuffer
.push_back( 0 );
364 aValue
= String( &aBuffer
.front() );
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;
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 );
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
;
405 SetError( rStrm
.GetErrorCode() );
409 ErrCode
SfxOleObjectBase::Save( SvStream
& rStrm
)
411 mnErrCode
= ERRCODE_NONE
;
413 SetError( rStrm
.GetErrorCode() );
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
;
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
),
456 void SfxOleInt32Property::ImplLoad( SvStream
& rStrm
)
461 void SfxOleInt32Property::ImplSave( SvStream
& rStrm
)
466 // ----------------------------------------------------------------------------
468 SfxOleDoubleProperty::SfxOleDoubleProperty( sal_Int32 nPropId
, double fValue
) :
469 SfxOlePropertyBase( nPropId
, PROPTYPE_DOUBLE
),
474 void SfxOleDoubleProperty::ImplLoad( SvStream
& rStrm
)
479 void SfxOleDoubleProperty::ImplSave( SvStream
& rStrm
)
484 // ----------------------------------------------------------------------------
486 SfxOleBoolProperty::SfxOleBoolProperty( sal_Int32 nPropId
, bool bValue
) :
487 SfxOlePropertyBase( nPropId
, PROPTYPE_BOOL
),
492 void SfxOleBoolProperty::ImplLoad( SvStream
& rStrm
)
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
),
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(
606 static_cast< sal_uInt16
>( maDateTime
.Day
),
607 static_cast< sal_uInt16
>( maDateTime
.Month
),
608 static_cast< sal_uInt16
>( maDateTime
.Year
) ),
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
)
635 //stored as number of days (not seconds) since December 31, 1899
636 ::Date
aDate(31, 12, 1899);
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
;
653 // ----------------------------------------------------------------------------
655 SfxOleThumbnailProperty::SfxOleThumbnailProperty(
656 sal_Int32 nPropId
, const uno::Sequence
<sal_uInt8
> & i_rData
) :
657 SfxOlePropertyBase( nPropId
, PROPTYPE_CLIPFMT
),
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
)
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)
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
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() );
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
),
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
)
721 rStrm
.Write( mData
.getConstArray(), mData
.getLength() );
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);
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
)
770 // name always stored as byte string
771 SaveString8( rStrm
, aIt
->second
);
775 // ----------------------------------------------------------------------------
777 SfxOleSection::SfxOleSection( bool bSupportsDict
) :
778 maDictProp( maCodePageProp
),
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() )
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() );
799 rnValue
= pProp
->GetValue();
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() );
809 rfValue
= pProp
->GetValue();
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() );
819 rbValue
= pProp
->GetValue();
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() );
829 rValue
= pProp
->GetValue();
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() );
840 if ( pProp
->GetValue() == TIMESTAMP_INVALID_UTILDATETIME
)
841 rValue
= util::DateTime();
843 rValue
= pProp
->GetValue();
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() );
855 if ( pProp
->GetValue() == TIMESTAMP_INVALID_UTILDATE
)
856 rValue
= util::Date();
858 rValue
= pProp
->GetValue();
863 void SfxOleSection::SetProperty( SfxOlePropertyRef xProp
)
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);
888 SetProperty( SfxOlePropertyRef( new SfxOleString8Property( nPropId
, maCodePageProp
, rValue
) ) );
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
) ) );
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
904 if ( rValue
.Year
== 0 || rValue
.Month
== 0 || rValue
.Day
== 0 )
905 SetProperty( SfxOlePropertyRef( new SfxOleFileTimeProperty( nPropId
, TIMESTAMP_INVALID_UTILDATETIME
) ) );
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
935 sal_Int32 nInt32
= 0;
936 double fDouble
= 0.0;
939 ::com::sun::star::util::DateTime aApiDateTime
;
940 ::com::sun::star::util::Date aApiDate
;
942 if( GetInt32Value( nInt32
, nPropId
) )
944 else if( GetDoubleValue( fDouble
, nPropId
) )
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
) )
961 bool SfxOleSection::SetAnyValue( sal_Int32 nPropId
, const Any
& rValue
)
963 bool bInserted
= true;
964 sal_Int32 nInt32
= 0;
965 double fDouble
= 0.0;
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
);
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
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);
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
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() )
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
);
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);
1109 // create empty property object
1110 SfxOlePropertyRef xProp
;
1113 case PROPTYPE_INT32
:
1114 xProp
.reset( new SfxOleInt32Property( nPropId
) );
1116 case PROPTYPE_DOUBLE
:
1117 xProp
.reset( new SfxOleDoubleProperty( nPropId
) );
1120 xProp
.reset( new SfxOleBoolProperty( nPropId
) );
1122 case PROPTYPE_STRING8
:
1123 xProp
.reset( new SfxOleString8Property( nPropId
, maCodePageProp
) );
1125 case PROPTYPE_STRING16
:
1126 xProp
.reset( new SfxOleString16Property( nPropId
) );
1128 case PROPTYPE_FILETIME
:
1129 xProp
.reset( new SfxOleFileTimeProperty( nPropId
) );
1132 xProp
.reset( new SfxOleDateProperty( nPropId
) );
1135 // load property contents
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
);
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
)
1166 SotStorageStreamRef xStrm
= pStrg
->OpenSotStream( rStrmName
, STREAM_STD_READ
);
1167 if( xStrm
.Is() && (xStrm
->GetError() == SVSTREAM_OK
) )
1169 xStrm
->SetBufferSize( STREAM_BUFFER_SIZE
);
1173 SetError( ERRCODE_IO_ACCESSDENIED
);
1176 SetError( ERRCODE_IO_ACCESSDENIED
);
1180 ErrCode
SfxOlePropertySet::SavePropertySet( SotStorage
* pStrg
, const String
& rStrmName
)
1184 SotStorageStreamRef xStrm
= pStrg
->OpenSotStream( rStrmName
, STREAM_TRUNC
| STREAM_STD_WRITE
);
1188 SetError( ERRCODE_IO_ACCESSDENIED
);
1191 SetError( ERRCODE_IO_ACCESSDENIED
);
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
;
1209 SfxOleSection
& SfxOlePropertySet::AddSection( SfxOleSectionType eSection
)
1211 return AddSection( GetSectionGuid( eSection
) );
1214 SfxOleSection
& SfxOlePropertySet::AddSection( const SvGlobalName
& rSectionGuid
)
1216 SfxOleSectionRef xSection
= GetSection( rSectionGuid
);
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
;
1227 void SfxOlePropertySet::ImplLoad( SvStream
& rStrm
)
1229 // read property set header
1230 sal_uInt16 nByteOrder
;
1231 sal_uInt16 nVersion
;
1232 sal_uInt16 nOsMinor
;
1235 sal_Int32
nSectCount(0);
1236 rStrm
>> nByteOrder
>> nVersion
>> nOsMinor
>> nOsType
>> aGuid
>> nSectCount
;
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();
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
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
) );
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
;
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" );
1302 // ============================================================================
1306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */