xref: /aoo41x/main/sfx2/source/dialog/dinfdlg.cxx (revision cf3a8bfb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sfx2.hxx"
30 
31 #include <tools/urlobj.hxx>
32 #include <vcl/msgbox.hxx>
33 #include <svl/eitem.hxx>
34 #include <vcl/svapp.hxx>
35 #include <sfx2/filedlghelper.hxx>
36 #include <unotools/localedatawrapper.hxx>
37 #include <unotools/cmdoptions.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <svl/urihelper.hxx>
40 #include <unotools/useroptions.hxx>
41 #include <svtools/imagemgr.hxx>
42 #include <tools/datetime.hxx>
43 
44 #include <memory>
45 
46 #include <comphelper/string.hxx>
47 #include <comphelper/processfactory.hxx>
48 #include <com/sun/star/security/DocumentSignatureInformation.hpp>
49 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
50 #include <unotools/localedatawrapper.hxx>
51 #include <unotools/syslocale.hxx>
52 #include <rtl/math.hxx>
53 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
54 #include <com/sun/star/beans/PropertyAttribute.hpp>
55 #include <com/sun/star/beans/XPropertyContainer.hpp>
56 #include <com/sun/star/util/DateTime.hpp>
57 #include <com/sun/star/util/Date.hpp>
58 #include <com/sun/star/util/Time.hpp>
59 #include <com/sun/star/util/Duration.hpp>
60 #include <com/sun/star/document/XDocumentProperties.hpp>
61 
62 #include <vcl/timer.hxx>
63 #include "sfx2/dinfdlg.hxx"
64 #include "sfx2/securitypage.hxx"
65 #include "sfxresid.hxx"
66 #include "dinfedt.hxx"
67 #include <sfx2/frame.hxx>
68 #include <sfx2/viewfrm.hxx>
69 #include <sfx2/request.hxx>
70 //#include "exptypes.hxx"
71 #include "helper.hxx"
72 #include <sfx2/objsh.hxx>
73 #include <sfx2/docfile.hxx>
74 #include <comphelper/storagehelper.hxx>
75 
76 #include <sfx2/sfx.hrc>
77 #include "dinfdlg.hrc"
78 #include "sfxlocal.hrc"
79 #include <dialog.hrc>
80 #include <vcl/help.hxx>
81 
82 #include <algorithm>
83 
84 using namespace ::com::sun::star;
85 using namespace ::com::sun::star::lang;
86 using namespace ::com::sun::star::ui::dialogs;
87 using namespace ::com::sun::star::uno;
88 
89 
90 struct CustomProperty
91 {
92     ::rtl::OUString             m_sName;
93     com::sun::star::uno::Any    m_aValue;
94 
95     CustomProperty( const ::rtl::OUString& sName,
96             const com::sun::star::uno::Any& rValue ) :
97         m_sName( sName ), m_aValue( rValue ) {}
98 
99     inline bool operator==( const CustomProperty& rProp )
100     { return m_sName.equals( rProp.m_sName ) && m_aValue == rProp.m_aValue; }
101 };
102 
103 
104 static
105 bool operator==(const util::DateTime &i_rLeft, const util::DateTime &i_rRight)
106 {
107     return i_rLeft.Year             == i_rRight.Year
108         && i_rLeft.Month            == i_rRight.Month
109         && i_rLeft.Day              == i_rRight.Day
110         && i_rLeft.Hours            == i_rRight.Hours
111         && i_rLeft.Minutes          == i_rRight.Minutes
112         && i_rLeft.Seconds          == i_rRight.Seconds
113         && i_rLeft.HundredthSeconds == i_rRight.HundredthSeconds;
114 }
115 
116 // STATIC DATA -----------------------------------------------------------
117 
118 TYPEINIT1_AUTOFACTORY(SfxDocumentInfoItem, SfxStringItem);
119 
120 const sal_uInt16 HI_NAME = 1;
121 const sal_uInt16 HI_TYPE = 2;
122 const sal_uInt16 HI_VALUE = 3;
123 const sal_uInt16 HI_ACTION = 4;
124 
125 static const char DOCUMENT_SIGNATURE_MENU_CMD[]      = "Signature";
126 
127 //------------------------------------------------------------------------
128 String CreateSizeText( sal_uIntPtr nSize, sal_Bool bExtraBytes = sal_True, sal_Bool bSmartExtraBytes = sal_False );
129 String CreateSizeText( sal_uIntPtr nSize, sal_Bool bExtraBytes, sal_Bool bSmartExtraBytes )
130 {
131 	String aUnitStr = ' ';
132 	aUnitStr += String( SfxResId(STR_BYTES) );
133 	sal_uIntPtr nSize1 = nSize;
134 	sal_uIntPtr nSize2 = nSize1;
135 	sal_uIntPtr nMega = 1024 * 1024;
136 	sal_uIntPtr nGiga = nMega * 1024;
137 	double fSize = nSize;
138 	int nDec = 0;
139 	sal_Bool bGB = sal_False;
140 
141 	if ( nSize1 >= 10000 && nSize1 < nMega )
142 	{
143 		nSize1 /= 1024;
144 		aUnitStr = ' ';
145 		aUnitStr += String( SfxResId(STR_KB) );
146 		fSize /= 1024;
147 		nDec = 0;
148 	}
149 	else if ( nSize1 >= nMega && nSize1 < nGiga )
150 	{
151 		nSize1 /= nMega;
152 		aUnitStr = ' ';
153 		aUnitStr += String( SfxResId(STR_MB) );
154 		fSize /= nMega;
155 		nDec = 2;
156 	}
157 	else if ( nSize1 >= nGiga )
158 	{
159 		nSize1 /= nGiga;
160 		aUnitStr = ' ';
161 		aUnitStr += String( SfxResId(STR_GB) );
162 		bGB = sal_True;
163 		fSize /= nGiga;
164 		nDec = 3;
165 	}
166     const SvtSysLocale aSysLocale;
167 	const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData();
168 	String aSizeStr( rLocaleWrapper.getNum( nSize1, 0 ) );
169 	aSizeStr += aUnitStr;
170 	if ( bExtraBytes && ( nSize1 < nSize2 ) )
171 	{
172         aSizeStr = ::rtl::math::doubleToUString( fSize,
173                 rtl_math_StringFormat_F, nDec,
174                 rLocaleWrapper.getNumDecimalSep().GetChar(0) );
175 		aSizeStr += aUnitStr;
176 
177 		aSizeStr += DEFINE_CONST_UNICODE(" (");
178 		aSizeStr += rLocaleWrapper.getNum( nSize2, 0 );
179 		aSizeStr += ' ';
180 		aSizeStr += String( SfxResId(STR_BYTES) );
181 		aSizeStr += ')';
182 	}
183 	else if ( bGB && bSmartExtraBytes )
184 	{
185 		nSize1 = nSize / nMega;
186 		aSizeStr = DEFINE_CONST_UNICODE(" (");
187 		aSizeStr += rLocaleWrapper.getNum( nSize1, 0 );
188 		aSizeStr += aUnitStr;
189 		aSizeStr += ')';
190 	}
191 	return aSizeStr;
192 }
193 
194 String ConvertDateTime_Impl( const String& rName,
195     const util::DateTime& uDT, const LocaleDataWrapper& rWrapper )
196 {
197     Date aD(uDT.Day, uDT.Month, uDT.Year);
198     Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
199 	 const String pDelim ( DEFINE_CONST_UNICODE( ", "));
200 	 String aStr( rWrapper.getDate( aD ) );
201 	 aStr += pDelim;
202 	 aStr += rWrapper.getTime( aT, sal_True, sal_False );
203 	 String aAuthor = rName;
204 	 aAuthor.EraseLeadingChars();
205 	 if ( aAuthor.Len() )
206 	 {
207 		aStr += pDelim;
208 		aStr += aAuthor;
209 	 }
210 	 return aStr;
211 }
212 
213 //------------------------------------------------------------------------
214 
215 SfxDocumentInfoItem::SfxDocumentInfoItem()
216 	: SfxStringItem()
217     , m_AutoloadDelay(0)
218     , m_AutoloadURL()
219     , m_isAutoloadEnabled(sal_False)
220     , m_DefaultTarget()
221     , m_TemplateName()
222     , m_Author()
223     , m_CreationDate()
224     , m_ModifiedBy()
225     , m_ModificationDate()
226     , m_PrintedBy()
227     , m_PrintDate()
228     , m_EditingCycles(0)
229     , m_EditingDuration(0)
230     , m_Description()
231     , m_Keywords()
232     , m_Subject()
233     , m_Title()
234     , m_bHasTemplate( sal_True )
235     , m_bDeleteUserData( sal_False )
236     , m_bUseUserData( sal_True )
237 {
238 }
239 
240 //------------------------------------------------------------------------
241 
242 SfxDocumentInfoItem::SfxDocumentInfoItem( const String& rFile,
243         const uno::Reference<document::XDocumentProperties>& i_xDocProps,
244         sal_Bool bIs )
245 	: SfxStringItem( SID_DOCINFO, rFile )
246     , m_AutoloadDelay( i_xDocProps->getAutoloadSecs() )
247     , m_AutoloadURL( i_xDocProps->getAutoloadURL() )
248     , m_isAutoloadEnabled( (m_AutoloadDelay > 0) || m_AutoloadURL.getLength() )
249     , m_DefaultTarget( i_xDocProps->getDefaultTarget() )
250     , m_TemplateName( i_xDocProps->getTemplateName() )
251     , m_Author( i_xDocProps->getAuthor() )
252     , m_CreationDate( i_xDocProps->getCreationDate() )
253     , m_ModifiedBy( i_xDocProps->getModifiedBy() )
254     , m_ModificationDate( i_xDocProps->getModificationDate() )
255     , m_PrintedBy( i_xDocProps->getPrintedBy() )
256     , m_PrintDate( i_xDocProps->getPrintDate() )
257     , m_EditingCycles( i_xDocProps->getEditingCycles() )
258     , m_EditingDuration( i_xDocProps->getEditingDuration() )
259     , m_Description( i_xDocProps->getDescription() )
260     , m_Keywords( ::comphelper::string::convertCommaSeparated(
261                     i_xDocProps->getKeywords()) )
262     , m_Subject( i_xDocProps->getSubject() )
263     , m_Title( i_xDocProps->getTitle() )
264     , m_bHasTemplate( sal_True )
265     , m_bDeleteUserData( sal_False )
266     , m_bUseUserData( bIs )
267 {
268     try
269     {
270         Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties();
271         if ( xContainer.is() )
272         {
273             Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY );
274             const Sequence< beans::Property > lProps = xSet->getPropertySetInfo()->getProperties();
275             const beans::Property* pProps = lProps.getConstArray();
276             sal_Int32 nCount = lProps.getLength();
277             for ( sal_Int32 i = 0; i < nCount; ++i )
278             {
279                 // "fix" property? => not a custom property => ignore it!
280                 if (!(pProps[i].Attributes &
281                         ::com::sun::star::beans::PropertyAttribute::REMOVABLE))
282                 {
283                     DBG_ASSERT(false, "non-removable user-defined property?");
284                     continue;
285                 }
286 
287                 uno::Any aValue = xSet->getPropertyValue(pProps[i].Name);
288                 CustomProperty* pProp = new CustomProperty( pProps[i].Name, aValue );
289                 m_aCustomProperties.push_back( pProp );
290             }
291         }
292     }
293     catch ( Exception& ) {}
294 }
295 
296 //------------------------------------------------------------------------
297 
298 SfxDocumentInfoItem::SfxDocumentInfoItem( const SfxDocumentInfoItem& rItem )
299 	: SfxStringItem( rItem )
300     , m_AutoloadDelay( rItem.getAutoloadDelay() )
301     , m_AutoloadURL( rItem.getAutoloadURL() )
302     , m_isAutoloadEnabled( rItem.isAutoloadEnabled() )
303     , m_DefaultTarget( rItem.getDefaultTarget() )
304     , m_TemplateName( rItem.getTemplateName() )
305     , m_Author( rItem.getAuthor() )
306     , m_CreationDate( rItem.getCreationDate() )
307     , m_ModifiedBy( rItem.getModifiedBy() )
308     , m_ModificationDate( rItem.getModificationDate() )
309     , m_PrintedBy( rItem.getPrintedBy() )
310     , m_PrintDate( rItem.getPrintDate() )
311     , m_EditingCycles( rItem.getEditingCycles() )
312     , m_EditingDuration( rItem.getEditingDuration() )
313     , m_Description( rItem.getDescription() )
314     , m_Keywords( rItem.getKeywords() )
315     , m_Subject( rItem.getSubject() )
316     , m_Title( rItem.getTitle() )
317     , m_bHasTemplate( rItem.m_bHasTemplate )
318     , m_bDeleteUserData( rItem.m_bDeleteUserData )
319     , m_bUseUserData( rItem.m_bUseUserData )
320 {
321     for ( sal_uInt32 i = 0; i < rItem.m_aCustomProperties.size(); i++ )
322     {
323         CustomProperty* pProp = new CustomProperty( rItem.m_aCustomProperties[i]->m_sName,
324                                                     rItem.m_aCustomProperties[i]->m_aValue );
325         m_aCustomProperties.push_back( pProp );
326     }
327 }
328 
329 //------------------------------------------------------------------------
330 
331 SfxDocumentInfoItem::~SfxDocumentInfoItem()
332 {
333     ClearCustomProperties();
334 }
335 
336 //------------------------------------------------------------------------
337 
338 SfxPoolItem* SfxDocumentInfoItem::Clone( SfxItemPool * ) const
339 {
340 	return new SfxDocumentInfoItem( *this );
341 }
342 
343 //------------------------------------------------------------------------
344 
345 int SfxDocumentInfoItem::operator==( const SfxPoolItem& rItem) const
346 {
347 	if (!(rItem.Type() == Type() && SfxStringItem::operator==(rItem))) {
348         return false;
349     }
350     const SfxDocumentInfoItem& rInfoItem(
351         static_cast<const SfxDocumentInfoItem&>(rItem));
352 
353     return
354          m_AutoloadDelay        == rInfoItem.m_AutoloadDelay     &&
355          m_AutoloadURL          == rInfoItem.m_AutoloadURL       &&
356          m_isAutoloadEnabled    == rInfoItem.m_isAutoloadEnabled &&
357          m_DefaultTarget        == rInfoItem.m_DefaultTarget     &&
358          m_Author               == rInfoItem.m_Author            &&
359          m_CreationDate         == rInfoItem.m_CreationDate      &&
360          m_ModifiedBy           == rInfoItem.m_ModifiedBy        &&
361          m_ModificationDate     == rInfoItem.m_ModificationDate  &&
362          m_PrintedBy            == rInfoItem.m_PrintedBy         &&
363          m_PrintDate            == rInfoItem.m_PrintDate         &&
364          m_EditingCycles        == rInfoItem.m_EditingCycles     &&
365          m_EditingDuration      == rInfoItem.m_EditingDuration   &&
366          m_Description          == rInfoItem.m_Description       &&
367          m_Keywords             == rInfoItem.m_Keywords          &&
368          m_Subject              == rInfoItem.m_Subject           &&
369          m_Title                == rInfoItem.m_Title             &&
370          m_aCustomProperties.size() == rInfoItem.m_aCustomProperties.size() &&
371          std::equal(m_aCustomProperties.begin(), m_aCustomProperties.end(),
372             rInfoItem.m_aCustomProperties.begin());
373 }
374 
375 //------------------------------------------------------------------------
376 
377 void SfxDocumentInfoItem::resetUserData(const ::rtl::OUString & i_rAuthor)
378 {
379     setAuthor(i_rAuthor);
380     DateTime now;
381     setCreationDate( util::DateTime(
382         now.Get100Sec(), now.GetSec(), now.GetMin(), now.GetHour(),
383         now.GetDay(), now.GetMonth(), now.GetYear() ) );
384     setModifiedBy(::rtl::OUString());
385     setPrintedBy(::rtl::OUString());
386     setModificationDate(util::DateTime());
387     setPrintDate(util::DateTime());
388     setEditingDuration(0);
389     setEditingCycles(1);
390 }
391 
392 //------------------------------------------------------------------------
393 
394 void SfxDocumentInfoItem::UpdateDocumentInfo(
395         const uno::Reference<document::XDocumentProperties>& i_xDocProps,
396         bool i_bDoNotUpdateUserDefined) const
397 {
398     if (isAutoloadEnabled()) {
399         i_xDocProps->setAutoloadSecs(getAutoloadDelay());
400         i_xDocProps->setAutoloadURL(getAutoloadURL());
401     } else {
402         i_xDocProps->setAutoloadSecs(0);
403         i_xDocProps->setAutoloadURL(::rtl::OUString());
404     }
405     i_xDocProps->setDefaultTarget(getDefaultTarget());
406 //    i_xDocProps->setTemplateName(getTemplateName());
407     i_xDocProps->setAuthor(getAuthor());
408     i_xDocProps->setCreationDate(getCreationDate());
409     i_xDocProps->setModifiedBy(getModifiedBy());
410     i_xDocProps->setModificationDate(getModificationDate());
411     i_xDocProps->setPrintedBy(getPrintedBy());
412     i_xDocProps->setPrintDate(getPrintDate());
413     i_xDocProps->setEditingCycles(getEditingCycles());
414     i_xDocProps->setEditingDuration(getEditingDuration());
415     i_xDocProps->setDescription(getDescription());
416     i_xDocProps->setKeywords(
417         ::comphelper::string::convertCommaSeparated(getKeywords()));
418     i_xDocProps->setSubject(getSubject());
419     i_xDocProps->setTitle(getTitle());
420 
421     // this is necessary in case of replaying a recorded macro:
422     // in this case, the macro may contain the 4 old user-defined DocumentInfo
423     // fields, but not any of the DocumentInfo properties;
424     // as a consequence, most of the UserDefined properties of the
425     // DocumentProperties would be summarily deleted here, which does not
426     // seem like a good idea.
427     if (i_bDoNotUpdateUserDefined)
428         return;
429 
430     try
431     {
432         Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties();
433         Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY );
434         Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
435         const Sequence< beans::Property > lProps = xSetInfo->getProperties();
436         const beans::Property* pProps = lProps.getConstArray();
437         sal_Int32 nCount = lProps.getLength();
438         for ( sal_Int32 j = 0; j < nCount; ++j )
439         {
440             if ((pProps[j].Attributes &
441                     ::com::sun::star::beans::PropertyAttribute::REMOVABLE))
442             {
443                 xContainer->removeProperty( pProps[j].Name );
444             }
445         }
446 
447         for ( sal_uInt32 k = 0; k < m_aCustomProperties.size(); ++k )
448         {
449             try
450             {
451                 xContainer->addProperty( m_aCustomProperties[k]->m_sName,
452                     beans::PropertyAttribute::REMOVABLE, m_aCustomProperties[k]->m_aValue );
453             }
454             catch ( Exception& )
455             {
456                 DBG_ERRORFILE( "SfxDocumentInfoItem::updateDocumentInfo(): exception while adding custom properties" );
457             }
458         }
459     }
460     catch ( Exception& )
461     {
462         DBG_ERRORFILE( "SfxDocumentInfoItem::updateDocumentInfo(): exception while removing custom properties" );
463     }
464 }
465 
466 //------------------------------------------------------------------------
467 
468 sal_Bool SfxDocumentInfoItem::IsDeleteUserData() const
469 {
470     return m_bDeleteUserData;
471 }
472 
473 void SfxDocumentInfoItem::SetDeleteUserData( sal_Bool bSet )
474 {
475     m_bDeleteUserData = bSet;
476 }
477 
478 sal_Bool SfxDocumentInfoItem::IsUseUserData() const
479 {
480     return m_bUseUserData;
481 }
482 
483 void SfxDocumentInfoItem::SetUseUserData( sal_Bool bSet )
484 {
485     m_bUseUserData = bSet;
486 }
487 
488 std::vector< CustomProperty* > SfxDocumentInfoItem::GetCustomProperties() const
489 {
490     std::vector< CustomProperty* > aRet;
491     for ( sal_uInt32 i = 0; i < m_aCustomProperties.size(); i++ )
492     {
493         CustomProperty* pProp = new CustomProperty( m_aCustomProperties[i]->m_sName,
494                                                     m_aCustomProperties[i]->m_aValue );
495         aRet.push_back( pProp );
496     }
497 
498     return aRet;
499 }
500 
501 void SfxDocumentInfoItem::ClearCustomProperties()
502 {
503     for ( sal_uInt32 i = 0; i < m_aCustomProperties.size(); i++ )
504         delete m_aCustomProperties[i];
505     m_aCustomProperties.clear();
506 }
507 
508 void SfxDocumentInfoItem::AddCustomProperty( const ::rtl::OUString& sName, const Any& rValue )
509 {
510     CustomProperty* pProp = new CustomProperty( sName, rValue );
511     m_aCustomProperties.push_back( pProp );
512 }
513 
514 sal_Bool SfxDocumentInfoItem::QueryValue( Any& rVal, sal_uInt8 nMemberId ) const
515 {
516     String aValue;
517     sal_Int32 nValue = 0;
518 	sal_Bool bValue = sal_False;
519     sal_Bool bIsInt = sal_False;
520     sal_Bool bIsString = sal_False;
521     nMemberId &= ~CONVERT_TWIPS;
522     switch ( nMemberId )
523     {
524 		case MID_DOCINFO_USEUSERDATA:
525 			bValue = IsUseUserData();
526 			break;
527 		case MID_DOCINFO_DELETEUSERDATA:
528 			bValue = IsDeleteUserData();
529 			break;
530 		case MID_DOCINFO_AUTOLOADENABLED:
531 			bValue = isAutoloadEnabled();
532 			break;
533 		case MID_DOCINFO_AUTOLOADSECS:
534 			bIsInt = sal_True;
535 			nValue = getAutoloadDelay();
536 			break;
537 		case MID_DOCINFO_AUTOLOADURL:
538 			bIsString = sal_True;
539 			aValue = getAutoloadURL();
540 			break;
541 		case MID_DOCINFO_DEFAULTTARGET:
542 			bIsString = sal_True;
543 			aValue = getDefaultTarget();
544 			break;
545         case MID_DOCINFO_DESCRIPTION:
546 			bIsString = sal_True;
547             aValue = getDescription();
548             break;
549         case MID_DOCINFO_KEYWORDS:
550 			bIsString = sal_True;
551             aValue = getKeywords();
552             break;
553         case MID_DOCINFO_SUBJECT:
554 			bIsString = sal_True;
555             aValue = getSubject();
556             break;
557         case MID_DOCINFO_TITLE:
558 			bIsString = sal_True;
559             aValue = getTitle();
560             break;
561         default:
562 			DBG_ERROR("Wrong MemberId!");
563             return sal_False;
564 	 }
565 
566 	if ( bIsString )
567 		rVal <<= ::rtl::OUString( aValue );
568 	else if ( bIsInt )
569 		rVal <<= nValue;
570 	else
571 		rVal <<= bValue;
572     return sal_True;
573 }
574 
575 sal_Bool SfxDocumentInfoItem::PutValue( const Any& rVal, sal_uInt8 nMemberId )
576 {
577     ::rtl::OUString aValue;
578     sal_Int32 nValue=0;
579 	sal_Bool bValue = sal_False;
580 	sal_Bool bRet = sal_False;
581     nMemberId &= ~CONVERT_TWIPS;
582     switch ( nMemberId )
583     {
584 		case MID_DOCINFO_USEUSERDATA:
585 			bRet = (rVal >>= bValue);
586 			if ( bRet )
587 				SetUseUserData( bValue );
588 			break;
589 		case MID_DOCINFO_DELETEUSERDATA:
590 			// QUESTION: deleting user data was done here; seems to be superfluous!
591 			bRet = (rVal >>= bValue);
592 			if ( bRet )
593 				SetDeleteUserData( bValue );
594 			break;
595 		case MID_DOCINFO_AUTOLOADENABLED:
596 			bRet = (rVal >>= bValue);
597 			if ( bRet )
598 				setAutoloadEnabled(bValue);
599 			break;
600 		case MID_DOCINFO_AUTOLOADSECS:
601 			bRet = (rVal >>= nValue);
602 			if ( bRet )
603 				setAutoloadDelay(nValue);
604 			break;
605 		case MID_DOCINFO_AUTOLOADURL:
606 			bRet = (rVal >>= aValue);
607 			if ( bRet )
608 				setAutoloadURL(aValue);
609 			break;
610 		case MID_DOCINFO_DEFAULTTARGET:
611 			bRet = (rVal >>= aValue);
612 			if ( bRet )
613 				setDefaultTarget(aValue);
614 			break;
615         case MID_DOCINFO_DESCRIPTION:
616 			bRet = (rVal >>= aValue);
617 			if ( bRet )
618                 setDescription(aValue);
619             break;
620         case MID_DOCINFO_KEYWORDS:
621 			bRet = (rVal >>= aValue);
622 			if ( bRet )
623                 setKeywords(aValue);
624             break;
625         case MID_DOCINFO_SUBJECT:
626 			bRet = (rVal >>= aValue);
627 			if ( bRet )
628                 setSubject(aValue);
629             break;
630         case MID_DOCINFO_TITLE:
631 			bRet = (rVal >>= aValue);
632 			if ( bRet )
633                 setTitle(aValue);
634             break;
635         default:
636 			DBG_ERROR("Wrong MemberId!");
637             return sal_False;
638     }
639 
640     return bRet;
641 }
642 
643 //------------------------------------------------------------------------
644 
645 SfxDocumentDescPage::SfxDocumentDescPage( Window * pParent, const SfxItemSet& rItemSet )  :
646 
647     SfxTabPage( pParent, SfxResId( TP_DOCINFODESC ), rItemSet ),
648 
649     aTitleFt    ( this, SfxResId( FT_TITLE ) ),
650     aTitleEd    ( this, SfxResId( ED_TITLE ) ),
651     aThemaFt    ( this, SfxResId( FT_THEMA ) ),
652     aThemaEd    ( this, SfxResId( ED_THEMA ) ),
653     aKeywordsFt ( this, SfxResId( FT_KEYWORDS ) ),
654     aKeywordsEd ( this, SfxResId( ED_KEYWORDS ) ),
655     aCommentFt  ( this, SfxResId( FT_COMMENT ) ),
656     aCommentEd  ( this, SfxResId( ED_COMMENT ) ),
657 
658     pInfoItem   ( NULL )
659 
660 {
661     FreeResource();
662 }
663 
664 //------------------------------------------------------------------------
665 
666 SfxTabPage *SfxDocumentDescPage::Create(Window *pParent, const SfxItemSet &rItemSet)
667 {
668 	 return new SfxDocumentDescPage(pParent, rItemSet);
669 }
670 
671 //------------------------------------------------------------------------
672 
673 sal_Bool SfxDocumentDescPage::FillItemSet(SfxItemSet &rSet)
674 {
675 	// Pruefung, ob eine Aenderung vorliegt
676 	const sal_Bool bTitleMod = aTitleEd.IsModified();
677 	const sal_Bool bThemeMod = aThemaEd.IsModified();
678 	const sal_Bool bKeywordsMod = aKeywordsEd.IsModified();
679 	const sal_Bool bCommentMod = aCommentEd.IsModified();
680 	if( !( bTitleMod || bThemeMod || bKeywordsMod || bCommentMod ) )
681 	{
682 		return sal_False;
683 	}
684 
685 	// Erzeugung der Ausgabedaten
686     const SfxPoolItem* pItem = NULL;
687     SfxDocumentInfoItem* pInfo = NULL;
688 	SfxTabDialog* pDlg = GetTabDialog();
689 	const SfxItemSet* pExSet = NULL;
690 
691 	if ( pDlg )
692 		pExSet = pDlg->GetExampleSet();
693 
694 	if ( pExSet && SFX_ITEM_SET != pExSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
695 		pInfo = pInfoItem;
696     else if ( pItem )
697         pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem *)pItem );
698 
699     if ( !pInfo )
700     {
701         DBG_ERRORFILE( "SfxDocumentDescPage::FillItemSet(): no item found" );
702         return sal_False;
703     }
704 
705     if( bTitleMod )
706 	{
707 		pInfo->setTitle( aTitleEd.GetText() );
708 	}
709 	if( bThemeMod )
710 	{
711 		pInfo->setSubject( aThemaEd.GetText() );
712 	}
713 	if( bKeywordsMod )
714 	{
715 		pInfo->setKeywords( aKeywordsEd.GetText() );
716 	}
717 	if( bCommentMod )
718 	{
719 		pInfo->setDescription( aCommentEd.GetText() );
720 	}
721 	rSet.Put( SfxDocumentInfoItem( *pInfo ) );
722 	if( pInfo != pInfoItem )
723 	{
724 		delete pInfo;
725 	}
726 
727 	return sal_True;
728 }
729 
730 //------------------------------------------------------------------------
731 
732 void SfxDocumentDescPage::Reset(const SfxItemSet &rSet)
733 {
734 	 pInfoItem = &(SfxDocumentInfoItem &)rSet.Get(SID_DOCINFO);
735 
736 	 aTitleEd.SetText( pInfoItem->getTitle() );
737 	 aThemaEd.SetText( pInfoItem->getSubject() );
738 	 aKeywordsEd.SetText( pInfoItem->getKeywords() );
739 	 aCommentEd.SetText( pInfoItem->getDescription() );
740 
741      SFX_ITEMSET_ARG( &rSet, pROItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
742 	 if ( pROItem && pROItem->GetValue() )
743 	 {
744 		aTitleEd.SetReadOnly( sal_True );
745 		aThemaEd.SetReadOnly( sal_True );
746 		aKeywordsEd.SetReadOnly( sal_True );
747 		aCommentEd.SetReadOnly( sal_True );
748 	}
749 }
750 
751 //------------------------------------------------------------------------
752 
753 namespace
754 {
755 	String GetDateTimeString( sal_Int32 _nDate, sal_Int32 _nTime )
756 	{
757 		LocaleDataWrapper aWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
758 
759 		Date aDate( _nDate );
760 		Time aTime( _nTime );
761 		String aStr( aWrapper.getDate( aDate ) );
762 		aStr.AppendAscii( ", " );
763 		aStr += aWrapper.getTime( aTime );
764 		return aStr;
765 	}
766 
767 	// copy from xmlsecurity/source/dialog/resourcemanager.cxx
768 	String GetContentPart( const String& _rRawString, const String& _rPartId )
769 	{
770 		String		s;
771 
772 		xub_StrLen	nContStart = _rRawString.Search( _rPartId );
773 		if( nContStart != STRING_NOTFOUND )
774 		{
775 			nContStart = nContStart + _rPartId.Len();
776 			++nContStart;					// now it's start of content, directly after Id
777 
778 			xub_StrLen	nContEnd = _rRawString.Search( sal_Unicode( ',' ), nContStart );
779 
780 			s = String( _rRawString, nContStart, nContEnd - nContStart );
781 		}
782 
783 		return s;
784 	}
785 
786 }
787 
788 SfxDocumentPage::SfxDocumentPage( Window* pParent, const SfxItemSet& rItemSet ) :
789 
790 	SfxTabPage( pParent, SfxResId( TP_DOCINFODOC ), rItemSet ),
791 
792     aBmp1           ( this, SfxResId( BMP_FILE_1 ) ),
793     aNameED         ( this, SfxResId( ED_FILE_NAME ) ),
794 
795     aLine1FL        ( this, SfxResId( FL_FILE_1 ) ),
796     aTypeFT         ( this, SfxResId( FT_FILE_TYP ) ),
797     aShowTypeFT     ( this, SfxResId( FT_FILE_SHOW_TYP ) ),
798     aReadOnlyCB     ( this, SfxResId( CB_FILE_READONLY ) ),
799     aFileFt         ( this, SfxResId( FT_FILE ) ),
800     aFileValFt      ( this, SfxResId( FT_FILE_VAL ) ),
801     aSizeFT         ( this, SfxResId( FT_FILE_SIZE ) ),
802     aShowSizeFT     ( this, SfxResId( FT_FILE_SHOW_SIZE ) ),
803 
804     aLine2FL        ( this, SfxResId( FL_FILE_2 ) ),
805     aCreateFt       ( this, SfxResId( FT_CREATE ) ),
806     aCreateValFt    ( this, SfxResId( FT_CREATE_VAL ) ),
807     aChangeFt       ( this, SfxResId( FT_CHANGE ) ),
808     aChangeValFt    ( this, SfxResId( FT_CHANGE_VAL ) ),
809     aSignedFt       ( this, SfxResId( FT_SIGNED ) ),
810     aSignedValFt    ( this, SfxResId( FT_SIGNED_VAL ) ),
811     aSignatureBtn   ( this, SfxResId( BTN_SIGNATURE ) ),
812     aPrintFt        ( this, SfxResId( FT_PRINT ) ),
813     aPrintValFt     ( this, SfxResId( FT_PRINT_VAL ) ),
814     aTimeLogFt      ( this, SfxResId( FT_TIMELOG ) ),
815     aTimeLogValFt   ( this, SfxResId( FT_TIMELOG_VAL ) ),
816     aDocNoFt        ( this, SfxResId( FT_DOCNO ) ),
817     aDocNoValFt     ( this, SfxResId( FT_DOCNO_VAL ) ),
818     aUseUserDataCB  ( this, SfxResId( CB_USE_USERDATA ) ),
819     aDeleteBtn      ( this, SfxResId( BTN_DELETE ) ),
820 
821     aLine3FL        ( this, SfxResId( FL_FILE_3 ) ),
822     aTemplFt        ( this, SfxResId( FT_TEMPL ) ),
823     aTemplValFt     ( this, SfxResId( FT_TEMPL_VAL ) ),
824 
825 	aUnknownSize	( SfxResId( STR_UNKNOWNSIZE ) ),
826 	aMultiSignedStr	( SfxResId( STR_MULTSIGNED ) ),
827 
828 	bEnableUseUserData	( sal_False ),
829 	bHandleDelete		( sal_False )
830 
831 {
832 	aNameED.SetAccessibleName(String(SfxResId(EDIT_FILE_NAME)));
833 	FreeResource();
834 
835     ImplUpdateSignatures();
836 	aDeleteBtn.SetClickHdl( LINK( this, SfxDocumentPage, DeleteHdl ) );
837 	aSignatureBtn.SetClickHdl( LINK( this, SfxDocumentPage, SignatureHdl ) );
838 
839     // if the button text is too wide, then broaden it
840     const long nOffset = 12;
841     String sText = aSignatureBtn.GetText();
842     long nTxtW = aSignatureBtn.GetTextWidth( sText );
843     if ( sText.Search( '~' ) == STRING_NOTFOUND )
844         nTxtW += nOffset;
845     long nBtnW = aSignatureBtn.GetSizePixel().Width();
846     if ( nTxtW >= nBtnW )
847     {
848         long nDelta = Max( nTxtW - nBtnW, nOffset/3 );
849         Size aNewSize = aSignatureBtn.GetSizePixel();
850         aNewSize.Width() += nDelta;
851         aSignatureBtn.SetSizePixel( aNewSize );
852         aDeleteBtn.SetSizePixel( aNewSize );
853         // and give them a new position
854         Point aNewPos = aSignatureBtn.GetPosPixel();
855         aNewPos.X() -= nDelta;
856         aSignatureBtn.SetPosPixel( aNewPos );
857         aNewPos = aDeleteBtn.GetPosPixel();
858         aNewPos.X() -= nDelta;
859         aDeleteBtn.SetPosPixel( aNewPos );
860 
861         aNewSize = aSignedValFt.GetSizePixel();
862         aNewSize.Width() -= nDelta;
863         aSignedValFt.SetSizePixel( aNewSize );
864         aNewSize = aUseUserDataCB.GetSizePixel();
865         aNewSize.Width() -= nDelta;
866         aUseUserDataCB.SetSizePixel( aNewSize );
867     }
868     // See i96288
869     // Check if the document signature command is enabled
870     // on the main list enable/disable the pushbutton accordingly
871     SvtCommandOptions aCmdOptions;
872     if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
873                              rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( DOCUMENT_SIGNATURE_MENU_CMD ) ) ) )
874         aSignatureBtn.Disable();
875 }
876 
877 //------------------------------------------------------------------------
878 
879 IMPL_LINK( SfxDocumentPage, DeleteHdl, PushButton*, EMPTYARG )
880 {
881 	String aName;
882 	if ( bEnableUseUserData && aUseUserDataCB.IsChecked() )
883     	aName = SvtUserOptions().GetFullName();
884 	LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
885     DateTime now;
886     util::DateTime uDT(
887         now.Get100Sec(), now.GetSec(), now.GetMin(), now.GetHour(),
888         now.GetDay(), now.GetMonth(), now.GetYear() );
889 	aCreateValFt.SetText( ConvertDateTime_Impl( aName, uDT, aLocaleWrapper ) );
890 	XubString aEmpty;
891 	aChangeValFt.SetText( aEmpty );
892 	aPrintValFt.SetText( aEmpty );
893 	const Time aTime( 0 );
894 	aTimeLogValFt.SetText( aLocaleWrapper.getDuration( aTime ) );
895 	aDocNoValFt.SetText( '1' );
896 	bHandleDelete = sal_True;
897 	return 0;
898 }
899 
900 IMPL_LINK( SfxDocumentPage, SignatureHdl, PushButton*, EMPTYARG )
901 {
902 	SfxObjectShell*	pDoc = SfxObjectShell::Current();
903 	if( pDoc )
904 	{
905         pDoc->SignDocumentContent();
906 
907         ImplUpdateSignatures();
908     }
909 
910     return 0;
911 }
912 
913 void SfxDocumentPage::ImplUpdateSignatures()
914 {
915 	SfxObjectShell*	pDoc = SfxObjectShell::Current();
916 	if( pDoc )
917 	{
918 		SfxMedium* pMedium = pDoc->GetMedium();
919         if ( pMedium && pMedium->GetName().Len() && pMedium->GetStorage().is() )
920 		{
921 			Reference< security::XDocumentDigitalSignatures > xD(
922 				comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), uno::UNO_QUERY );
923 
924 			if( xD.is() )
925 			{
926 				String s;
927 				Sequence< security::DocumentSignatureInformation > aInfos;
928 				aInfos = xD->verifyDocumentContentSignatures( pMedium->GetZipStorageToSign_Impl(),
929 																uno::Reference< io::XInputStream >() );
930 				if( aInfos.getLength() > 1 )
931 				{
932 					s = aMultiSignedStr;
933 				}
934 				else if( aInfos.getLength() == 1 )
935 				{
936 					String aCN_Id( String::CreateFromAscii( "CN" ) );
937 					const security::DocumentSignatureInformation& rInfo = aInfos[ 0 ];
938 					s = GetDateTimeString( rInfo.SignatureDate, rInfo.SignatureTime );
939 					s.AppendAscii( ", " );
940 					s += GetContentPart( rInfo.Signer->getSubjectName(), aCN_Id );
941 				}
942 				aSignedValFt.SetText( s );
943 			}
944 		}
945 	}
946 }
947 
948 //------------------------------------------------------------------------
949 
950 SfxTabPage* SfxDocumentPage::Create( Window* pParent, const SfxItemSet& rItemSet )
951 {
952 	 return new SfxDocumentPage( pParent, rItemSet );
953 }
954 
955 //------------------------------------------------------------------------
956 
957 void SfxDocumentPage::EnableUseUserData()
958 {
959 	bEnableUseUserData = sal_True;
960 	aUseUserDataCB.Show();
961 	aDeleteBtn.Show();
962 }
963 
964 //------------------------------------------------------------------------
965 
966 sal_Bool SfxDocumentPage::FillItemSet( SfxItemSet& rSet )
967 {
968 	sal_Bool bRet = sal_False;
969 
970 	if ( !bHandleDelete && bEnableUseUserData &&
971 		 aUseUserDataCB.GetState() != aUseUserDataCB.GetSavedValue() &&
972 		 GetTabDialog() && GetTabDialog()->GetExampleSet() )
973 	{
974 		const SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet();
975 		const SfxPoolItem* pItem;
976 
977 		if ( pExpSet && SFX_ITEM_SET == pExpSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
978 		{
979 			SfxDocumentInfoItem* pInfoItem = (SfxDocumentInfoItem*)pItem;
980 			sal_Bool bUseData = ( STATE_CHECK == aUseUserDataCB.GetState() );
981 			pInfoItem->SetUseUserData( bUseData );
982 /*
983 			if ( !bUseData )
984 			{
985 				// "Benutzerdaten verwenden" ausgeschaltet ->
986 				// den Benutzer aus den Stamps l"oschen
987 				String aEmptyUser;
988 				aInfo.SetCreated(
989 					SfxStamp( aEmptyUser, aInfo.GetCreated().GetTime() ) );
990 				aInfo.SetChanged(
991 					SfxStamp( aEmptyUser, aInfo.GetChanged().GetTime() ) );
992 				aInfo.SetPrinted(
993 					SfxStamp( aEmptyUser, aInfo.GetPrinted().GetTime() ) );
994 			}
995 */
996 			rSet.Put( SfxDocumentInfoItem( *pInfoItem ) );
997 			bRet = sal_True;
998 		}
999 	}
1000 
1001 	if ( bHandleDelete )
1002 	{
1003 		const SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet();
1004 		const SfxPoolItem* pItem;
1005 		if ( pExpSet && SFX_ITEM_SET == pExpSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
1006 		{
1007 			SfxDocumentInfoItem* pInfoItem = (SfxDocumentInfoItem*)pItem;
1008 			sal_Bool bUseAuthor = bEnableUseUserData && aUseUserDataCB.IsChecked();
1009 			SfxDocumentInfoItem newItem( *pInfoItem );
1010             newItem.resetUserData( bUseAuthor
1011                 ? SvtUserOptions().GetFullName()
1012                 : ::rtl::OUString() );
1013 			pInfoItem->SetUseUserData( STATE_CHECK == aUseUserDataCB.GetState() );
1014 			newItem.SetUseUserData( STATE_CHECK == aUseUserDataCB.GetState() );
1015 
1016 			newItem.SetDeleteUserData( sal_True );
1017 			rSet.Put( newItem );
1018 			bRet = sal_True;
1019 		}
1020 	}
1021 
1022 	if ( aNameED.IsModified() && aNameED.GetText().Len() )
1023 	{
1024 		rSet.Put( SfxStringItem( ID_FILETP_TITLE, aNameED.GetText() ) );
1025 		bRet = sal_True;
1026 	}
1027 
1028 	if ( /* aReadOnlyCB.IsModified() */ sal_True )
1029 	{
1030 		rSet.Put( SfxBoolItem( ID_FILETP_READONLY, aReadOnlyCB.IsChecked() ) );
1031 		bRet = sal_True;
1032 	}
1033 
1034 	return bRet;
1035 }
1036 
1037 //------------------------------------------------------------------------
1038 
1039 void SfxDocumentPage::Reset( const SfxItemSet& rSet )
1040 {
1041 	// Bestimmung der Dokumentinformationen
1042 	const SfxDocumentInfoItem *pInfoItem =
1043 		&(const SfxDocumentInfoItem &)rSet.Get(SID_DOCINFO);
1044 
1045 	// template data
1046 	if ( pInfoItem->HasTemplate() )
1047 	{
1048 		aTemplValFt.SetText( pInfoItem->getTemplateName() );
1049 	}
1050 	else
1051 	{
1052 		aTemplFt.Hide();
1053 		aTemplValFt.Hide();
1054 	}
1055 
1056 	// determine file name
1057 	String aFile( pInfoItem->GetValue() );
1058 	String aFactory( aFile );
1059 	if ( aFile.Len() > 2 && aFile.GetChar(0) == '[' )
1060 	{
1061 		sal_uInt16 nPos = aFile.Search( ']' );
1062 		aFactory = aFile.Copy( 1, nPos-1  );
1063 		aFile = aFile.Copy( nPos+1 );
1064 	}
1065 
1066 	// determine name
1067 	String aName;
1068 	const SfxPoolItem* pItem = 0;
1069 	if ( SFX_ITEM_SET != rSet.GetItemState( ID_FILETP_TITLE, sal_False, &pItem ) )
1070 	{
1071 		INetURLObject aURL(aFile);
1072 		aName = aURL.GetName( INetURLObject::DECODE_WITH_CHARSET );
1073 		if ( !aName.Len() || aURL.GetProtocol() == INET_PROT_PRIVATE )
1074 			aName = String( SfxResId( STR_NONAME ) );
1075 		aNameED.SetReadOnly( sal_True );
1076 	}
1077 	else
1078 	{
1079 		DBG_ASSERT( pItem->IsA( TYPE( SfxStringItem ) ), "SfxDocumentPage:<SfxStringItem> erwartet" );
1080 		aName = ( ( SfxStringItem* ) pItem )->GetValue();
1081 	}
1082 	aNameED.SetText( aName );
1083 	aNameED.ClearModifyFlag();
1084 
1085 	// determine RO-Flag
1086 	if ( SFX_ITEM_UNKNOWN == rSet.GetItemState( ID_FILETP_READONLY, sal_False, &pItem )
1087 		 || !pItem )
1088 		aReadOnlyCB.Hide();
1089 	else
1090 		aReadOnlyCB.Check( ( (SfxBoolItem*)pItem )->GetValue() );
1091 
1092 	// determine context symbol
1093 	INetURLObject aURL;
1094 	aURL.SetSmartProtocol( INET_PROT_FILE );
1095 	aURL.SetSmartURL( aFactory);
1096 	const String& rMainURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
1097     aBmp1.SetImage( SvFileInformationManager::GetImage( aURL, sal_True ) );
1098 
1099 	// determine size and type
1100 	String aSizeText( aUnknownSize );
1101 	if ( aURL.GetProtocol() == INET_PROT_FILE )
1102 		aSizeText = CreateSizeText( SfxContentHelper::GetSize( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
1103 	aShowSizeFT.SetText( aSizeText );
1104 
1105 	String aDescription = SvFileInformationManager::GetDescription( INetURLObject(rMainURL) );
1106 	if ( aDescription.Len() == 0 )
1107 		aDescription = String( SfxResId( STR_SFX_NEWOFFICEDOC ) );
1108 	aShowTypeFT.SetText( aDescription );
1109 
1110 	// determine location
1111 	aURL.SetSmartURL( aFile);
1112 	if ( aURL.GetProtocol() == INET_PROT_FILE )
1113 	{
1114 		INetURLObject aPath( aURL );
1115 		aPath.setFinalSlash();
1116 		aPath.removeSegment();
1117         // we know it's a folder -> don't need the final slash, but it's better for WB_PATHELLIPSIS
1118         aPath.removeFinalSlash();
1119         String aText( aPath.PathToFileName() ); //! (pb) MaxLen?
1120 		aFileValFt.SetText( aText );
1121 	}
1122 	else if ( aURL.GetProtocol() != INET_PROT_PRIVATE )
1123 		aFileValFt.SetText( aURL.GetPartBeforeLastName() );
1124 
1125 	// handle access data
1126     sal_Bool m_bUseUserData = pInfoItem->IsUseUserData();
1127 	LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
1128 	aCreateValFt.SetText( ConvertDateTime_Impl( pInfoItem->getAuthor(),
1129         pInfoItem->getCreationDate(), aLocaleWrapper ) );
1130 	util::DateTime aTime( pInfoItem->getModificationDate() );
1131 //	if ( aTime.IsValid() )
1132 	if ( aTime.Month > 0 )
1133 		aChangeValFt.SetText( ConvertDateTime_Impl(
1134             pInfoItem->getModifiedBy(), aTime, aLocaleWrapper ) );
1135 	aTime = pInfoItem->getPrintDate();
1136 //	if ( aTime.IsValid())
1137 	if ( aTime.Month > 0 )
1138 		aPrintValFt.SetText( ConvertDateTime_Impl( pInfoItem->getPrintedBy(),
1139             aTime, aLocaleWrapper ) );
1140 	const long nTime = pInfoItem->getEditingDuration();
1141     if ( m_bUseUserData )
1142     {
1143 		const Time aT( nTime/3600, (nTime%3600)/60, nTime%60 );
1144 		aTimeLogValFt.SetText( aLocaleWrapper.getDuration( aT ) );
1145 		aDocNoValFt.SetText( String::CreateFromInt32(
1146             pInfoItem->getEditingCycles() ) );
1147 	}
1148 
1149     TriState eState = (TriState)m_bUseUserData;
1150 
1151 	if ( STATE_DONTKNOW == eState )
1152 		aUseUserDataCB.EnableTriState( sal_True );
1153 
1154 	aUseUserDataCB.SetState( eState );
1155 	aUseUserDataCB.SaveValue();
1156 	aUseUserDataCB.Enable( bEnableUseUserData );
1157 	bHandleDelete = sal_False;
1158 	aDeleteBtn.Enable( bEnableUseUserData );
1159 }
1160 
1161 //------------------------------------------------------------------------
1162 
1163 SfxInternetPage::SfxInternetPage( Window* pParent, const SfxItemSet& rItemSet ) :
1164 
1165 	SfxTabPage( pParent, SfxResId( TP_DOCINFORELOAD ), rItemSet ),
1166 
1167 	aRBNoAutoUpdate		( this, SfxResId( RB_NOAUTOUPDATE		) ),
1168 
1169 	aRBReloadUpdate		( this, SfxResId( RB_RELOADUPDATE		) ),
1170 
1171 	aRBForwardUpdate	( this, SfxResId( RB_FORWARDUPDATE		) ),
1172 	aFTEvery			( this, SfxResId( FT_EVERY				) ),
1173 	aNFReload			( this, SfxResId( ED_RELOAD			) ),
1174 	aFTReloadSeconds	( this, SfxResId( FT_RELOADSECS		) ),
1175 	aFTAfter			( this, SfxResId( FT_AFTER				) ),
1176 	aNFAfter			( this, SfxResId( ED_FORWARD			) ),
1177 	aFTAfterSeconds		( this, SfxResId( FT_FORWARDSECS		) ),
1178 	aFTURL				( this, SfxResId( FT_URL				) ),
1179 	aEDForwardURL		( this, SfxResId( ED_URL				) ),
1180 	aPBBrowseURL		( this, SfxResId( PB_BROWSEURL			) ),
1181 	aFTFrame			( this, SfxResId( FT_FRAME				) ),
1182 	aCBFrame			( this, SfxResId( CB_FRAME				) ),
1183 
1184 	aForwardErrorMessg	(		SfxResId( STR_FORWARD_ERRMSSG	) ),
1185     pInfoItem           ( NULL ),
1186     pFileDlg            ( NULL ),
1187     eState              ( S_Init )
1188 
1189 {
1190 	FreeResource();
1191 	pInfoItem = &( SfxDocumentInfoItem& ) rItemSet.Get( SID_DOCINFO );
1192 	TargetList			aList;
1193 	SfxViewFrame*		pFrame = SfxViewFrame::Current();
1194 	if( pFrame )
1195     {
1196         pFrame = pFrame->GetTopViewFrame();
1197         if( pFrame )
1198         {
1199             pFrame->GetTargetList( aList );
1200 
1201             String*			pObj;
1202             for( sal_uInt16 nPos = ( sal_uInt16 ) aList.Count() ; nPos ; )
1203             {
1204                 pObj = aList.GetObject( --nPos );
1205                 aCBFrame.InsertEntry( *pObj );
1206                 delete pObj;
1207             }
1208         }
1209 	}
1210 
1211 	aRBNoAutoUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlNoUpdate ) );
1212 	aRBReloadUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlReload ) );
1213 	aRBForwardUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlForward ) );
1214 	aPBBrowseURL.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlBrowseURL ) );
1215 
1216 	aForwardErrorMessg.SearchAndReplaceAscii( "%PLACEHOLDER%", aRBForwardUpdate.GetText() );
1217 
1218 	ChangeState( S_NoUpdate );
1219 }
1220 
1221 //------------------------------------------------------------------------
1222 
1223 SfxInternetPage::~SfxInternetPage()
1224 {
1225     delete pFileDlg;
1226 }
1227 
1228 //------------------------------------------------------------------------
1229 
1230 void SfxInternetPage::ChangeState( STATE eNewState )
1231 {
1232 	DBG_ASSERT( eNewState != S_Init, "*SfxInternetPage::ChangeState(): new state init is supposed to not work here!" );
1233 
1234 	if( eState == eNewState  )
1235 		return;
1236 
1237 	switch( eState )
1238 	{
1239 		case S_Init:
1240 			EnableNoUpdate( sal_True );
1241 			EnableReload( sal_False );
1242 			EnableForward( sal_False );
1243 			break;
1244 		case S_NoUpdate:
1245 			EnableNoUpdate( sal_False );
1246 			if( eNewState == S_Reload )
1247 				EnableReload( sal_True );
1248 			else
1249 				EnableForward( sal_True );
1250 			break;
1251 		case S_Reload:
1252 			EnableReload( sal_False );
1253 			if( eNewState == S_NoUpdate )
1254 				EnableNoUpdate( sal_True );
1255 			else
1256 				EnableForward( sal_True );
1257 			break;
1258 		case S_Forward:
1259 			EnableForward( sal_False );
1260 			if( eNewState == S_NoUpdate )
1261 				EnableNoUpdate( sal_True );
1262 			else
1263 				EnableReload( sal_True );
1264 			break;
1265 		default:
1266 			DBG_ERROR( "*SfxInternetPage::SetState(): unhandled state!" );
1267 	}
1268 
1269 	eState = eNewState;
1270 }
1271 
1272 //------------------------------------------------------------------------
1273 
1274 void SfxInternetPage::EnableNoUpdate( sal_Bool bEnable )
1275 {
1276 	if( bEnable )
1277 		aRBNoAutoUpdate.Check();
1278 }
1279 
1280 //------------------------------------------------------------------------
1281 
1282 void SfxInternetPage::EnableReload( sal_Bool bEnable )
1283 {
1284 	aFTEvery.Enable( bEnable );
1285 	aNFReload.Enable( bEnable );
1286 	aFTReloadSeconds.Enable( bEnable );
1287 
1288 	if( bEnable )
1289 		aRBReloadUpdate.Check();
1290 }
1291 
1292 //------------------------------------------------------------------------
1293 
1294 void SfxInternetPage::EnableForward( sal_Bool bEnable )
1295 {
1296 	aFTAfter.Enable( bEnable );
1297 	aNFAfter.Enable( bEnable );
1298 	aFTAfterSeconds.Enable( bEnable );
1299 	aFTURL.Enable( bEnable );
1300 	aEDForwardURL.Enable( bEnable );
1301 	aPBBrowseURL.Enable( bEnable );
1302 	aFTFrame.Enable( bEnable );
1303 	aCBFrame.Enable( bEnable );
1304 
1305 	if( bEnable )
1306 		aRBForwardUpdate.Check();
1307 }
1308 
1309 //------------------------------------------------------------------------
1310 
1311 IMPL_LINK( SfxInternetPage, ClickHdlNoUpdate, Control*, pCtrl )
1312 {
1313     (void)pCtrl; //unused
1314 	ChangeState( S_NoUpdate );
1315 	return 0;
1316 }
1317 
1318 //------------------------------------------------------------------------
1319 
1320 IMPL_LINK( SfxInternetPage, ClickHdlReload, Control*, pCtrl )
1321 {
1322     (void)pCtrl; //unused
1323 	ChangeState( S_Reload );
1324 	return 0;
1325 }
1326 
1327 //------------------------------------------------------------------------
1328 
1329 IMPL_LINK( SfxInternetPage, ClickHdlForward, Control*, pCtrl )
1330 {
1331     (void)pCtrl; //unused
1332 	ChangeState( S_Forward );
1333 	return 0;
1334 }
1335 
1336 //------------------------------------------------------------------------
1337 
1338 IMPL_LINK( SfxInternetPage, ClickHdlBrowseURL, PushButton*, EMPTYARG )
1339 {
1340     if ( !pFileDlg )
1341         pFileDlg = new sfx2::FileDialogHelper( TemplateDescription::FILEOPEN_SIMPLE, WB_OPEN );
1342     pFileDlg->SetDisplayDirectory( aEDForwardURL.GetText() );
1343     pFileDlg->StartExecuteModal( LINK( this, SfxInternetPage, DialogClosedHdl ) );
1344 
1345     return 0;
1346 }
1347 
1348 //------------------------------------------------------------------------
1349 
1350 IMPL_LINK( SfxInternetPage, DialogClosedHdl, sfx2::FileDialogHelper*, EMPTYARG )
1351 {
1352     DBG_ASSERT( pFileDlg, "SfxInternetPage::DialogClosedHdl(): no file dialog" );
1353 
1354     if ( ERRCODE_NONE == pFileDlg->GetError() )
1355         aEDForwardURL.SetText( pFileDlg->GetPath() );
1356 
1357     return 0;
1358 }
1359 
1360 //------------------------------------------------------------------------
1361 
1362 sal_Bool SfxInternetPage::FillItemSet( SfxItemSet& rSet )
1363 {
1364 	const SfxPoolItem*			pItem = NULL;
1365 	SfxDocumentInfoItem*		pInfo = NULL;
1366 	SfxTabDialog*				pDlg = GetTabDialog();
1367 	const SfxItemSet*			pExSet = NULL;
1368 
1369 	if( pDlg )
1370 		pExSet = pDlg->GetExampleSet();
1371 
1372 	if( pExSet && SFX_ITEM_SET != pExSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
1373 		pInfo = pInfoItem;
1374     else if ( pItem )
1375         pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem*)pItem );
1376 
1377     if ( !pInfo )
1378     {
1379         DBG_ERRORFILE( "SfxInternetPage::FillItemSet(): no item found" );
1380         return sal_False;
1381     }
1382 
1383     DBG_ASSERT( eState != S_Init, "*SfxInternetPage::FillItemSet(): state init is not acceptable at this point!" );
1384 
1385 	sal_Bool						bEnableReload = sal_False;
1386 	::std::auto_ptr< String >	aURL( NULL );
1387 	::std::auto_ptr< String >	aFrame( NULL );
1388 	sal_uIntPtr						nDelay = 0;
1389 
1390 	switch( eState )
1391 	{
1392 		case S_NoUpdate:
1393 			break;
1394 		case S_Reload:
1395 			bEnableReload = sal_True;
1396 			aURL = ::std::auto_ptr< String >( new String() );
1397 			aFrame = ::std::auto_ptr< String >( new String() );
1398 			nDelay = static_cast<sal_uIntPtr>(aNFReload.GetValue());
1399 			break;
1400 		case S_Forward:
1401 			DBG_ASSERT( aEDForwardURL.GetText().Len(), "+SfxInternetPage::FillItemSet(): empty URL should be not possible for forward option!" );
1402 
1403 			bEnableReload = sal_True;
1404             aURL = ::std::auto_ptr< String >( new String( URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), aEDForwardURL.GetText(), URIHelper::GetMaybeFileHdl(), true ) ) );
1405 			aFrame = ::std::auto_ptr< String >( new String( aCBFrame.GetText() ) );
1406 			nDelay = static_cast<sal_uIntPtr>(aNFAfter.GetValue());
1407 			break;
1408               default:
1409                   break;
1410 	}
1411 
1412 	pInfo->setAutoloadEnabled( bEnableReload );
1413 
1414 	if( bEnableReload )
1415 	{
1416 		pInfo->setAutoloadURL( *aURL.get() );
1417 		pInfo->setDefaultTarget( *aFrame.get() );
1418 		pInfo->setAutoloadDelay( nDelay );
1419 	}
1420 
1421 	rSet.Put( *pInfo );
1422 	if( pInfo != pInfoItem )
1423 		delete pInfo;
1424 	return sal_True;
1425 }
1426 
1427 //------------------------------------------------------------------------
1428 
1429 SfxTabPage *SfxInternetPage::Create( Window* pParent, const SfxItemSet& rItemSet )
1430 {
1431 	return new SfxInternetPage(pParent, rItemSet);
1432 }
1433 
1434 //------------------------------------------------------------------------
1435 
1436 void SfxInternetPage::Reset( const SfxItemSet& rSet )
1437 {
1438 	pInfoItem = &( SfxDocumentInfoItem& ) rSet.Get( SID_DOCINFO );
1439     SFX_ITEMSET_ARG( &rSet, pURLItem, SfxStringItem, SID_BASEURL, sal_False );
1440     DBG_ASSERT( pURLItem, "No BaseURL provided for InternetTabPage!" );
1441     if ( pURLItem )
1442         aBaseURL = pURLItem->GetValue();
1443 
1444 	STATE				eNewState = S_NoUpdate;
1445 
1446 	if( pInfoItem->isAutoloadEnabled() )
1447 	{
1448 		const String&	rURL = pInfoItem->getAutoloadURL();
1449 
1450 		if( rURL.Len() )
1451 		{
1452 			aNFAfter.SetValue( pInfoItem->getAutoloadDelay() );
1453 			aEDForwardURL.SetText( rURL );
1454 			aCBFrame.SetText( pInfoItem->getDefaultTarget() );
1455 			eNewState = S_Forward;
1456 		}
1457 		else
1458 		{
1459 			aNFReload.SetValue( pInfoItem->getAutoloadDelay() );
1460 			eNewState = S_Reload;
1461 		}
1462 	}
1463 
1464 	ChangeState( eNewState );
1465 
1466 	// #102907# ------------------------
1467     SFX_ITEMSET_ARG( &rSet, pROItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
1468 	if ( pROItem && pROItem->GetValue() )
1469 	{
1470 		aRBNoAutoUpdate.Disable();
1471 		aRBReloadUpdate.Disable();
1472 		aRBForwardUpdate.Disable();
1473 		aNFReload.Disable();
1474 		aNFAfter.Disable();
1475 		aEDForwardURL.Disable();
1476 		aPBBrowseURL.Disable();
1477 		aCBFrame.Disable();
1478 		aFTEvery.Disable();
1479 		aFTReloadSeconds.Disable();
1480 		aFTAfter.Disable();
1481 		aFTAfterSeconds.Disable();
1482 		aFTURL.Disable();
1483 		aFTFrame.Disable();
1484 	}
1485 }
1486 
1487 //------------------------------------------------------------------------
1488 
1489 int SfxInternetPage::DeactivatePage( SfxItemSet* /*pSet*/ )
1490 {
1491 	int				nRet = LEAVE_PAGE;
1492 
1493 	if( eState == S_Forward && !aEDForwardURL.GetText().Len() )
1494 	{
1495 		ErrorBox	aErrBox( this, WB_OK, aForwardErrorMessg );
1496 		aErrBox.Execute();
1497 
1498 		nRet = KEEP_PAGE;
1499 	}
1500 
1501 	return nRet;
1502 }
1503 
1504 //------------------------------------------------------------------------
1505 
1506 SfxDocumentInfoDialog::SfxDocumentInfoDialog( Window* pParent,
1507 											  const SfxItemSet& rItemSet ) :
1508 
1509 	SfxTabDialog( 0, pParent, SfxResId( SID_DOCINFO ), &rItemSet )
1510 
1511 {
1512 	FreeResource();
1513 
1514 	 const SfxDocumentInfoItem* pInfoItem =
1515 		&(const SfxDocumentInfoItem &)rItemSet.Get( SID_DOCINFO );
1516 
1517 #ifdef DBG_UTIL
1518     SFX_ITEMSET_ARG( &rItemSet, pURLItem, SfxStringItem, SID_BASEURL, sal_False );
1519     DBG_ASSERT( pURLItem, "No BaseURL provided for InternetTabPage!" );
1520 #endif
1521 
1522 	 // Bestimmung des Titels
1523 	const SfxPoolItem* pItem = 0;
1524 	String aTitle( GetText() );
1525 	if ( SFX_ITEM_SET !=
1526 		 rItemSet.GetItemState( SID_EXPLORER_PROPS_START, sal_False, &pItem ) )
1527 	{
1528 		// Dateiname
1529 		String aFile( pInfoItem->GetValue() );
1530 
1531 		INetURLObject aURL;
1532 		aURL.SetSmartProtocol( INET_PROT_FILE );
1533 		aURL.SetSmartURL( aFile);
1534 		if ( INET_PROT_PRIV_SOFFICE != aURL.GetProtocol() )
1535 		{
1536 			String aLastName( aURL.GetLastName() );
1537 			if ( aLastName.Len() )
1538 				aTitle += aLastName;
1539 			else
1540 				aTitle += aFile;
1541 		}
1542 		else
1543 			aTitle += String( SfxResId( STR_NONAME ) );
1544 	}
1545 	else
1546 	{
1547 		DBG_ASSERT( pItem->IsA( TYPE( SfxStringItem ) ),
1548 					"SfxDocumentInfoDialog:<SfxStringItem> erwartet" );
1549 		aTitle += ( ( SfxStringItem* ) pItem )->GetValue();
1550 	}
1551 	SetText( aTitle );
1552 
1553 	// Eigenschaftenseiten
1554 	AddTabPage(TP_DOCINFODESC, SfxDocumentDescPage::Create, 0);
1555 	AddTabPage(TP_DOCINFODOC, SfxDocumentPage::Create, 0);
1556     AddTabPage(TP_CUSTOMPROPERTIES, SfxCustomPropertiesPage::Create, 0);
1557     AddTabPage(TP_DOCINFORELOAD, SfxInternetPage::Create, 0);
1558     AddTabPage(TP_DOCINFOSECURITY, SfxSecurityPage::Create, 0);
1559 }
1560 
1561 // -----------------------------------------------------------------------
1562 
1563 void SfxDocumentInfoDialog::PageCreated( sal_uInt16 nId, SfxTabPage &rPage )
1564 {
1565 	if ( TP_DOCINFODOC == nId )
1566 		( (SfxDocumentPage&)rPage ).EnableUseUserData();
1567 }
1568 
1569 // class CustomPropertiesYesNoButton -------------------------------------
1570 
1571 CustomPropertiesYesNoButton::CustomPropertiesYesNoButton( Window* pParent, const ResId& rResId ) :
1572     Control( pParent, rResId ),
1573     m_aYesButton( this, ResId( RB_PROPERTY_YES, *rResId.GetResMgr() ) ),
1574     m_aNoButton ( this, ResId( RB_PROPERTY_NO, *rResId.GetResMgr() ) )
1575 {
1576     FreeResource();
1577     Wallpaper aWall( Color( COL_TRANSPARENT ) );
1578     SetBackground( aWall );
1579     SetBorderStyle( WINDOW_BORDER_MONO  );
1580     CheckNo();
1581     m_aYesButton.SetBackground( aWall );
1582     m_aNoButton.SetBackground( aWall );
1583 }
1584 class DurationDialog_Impl : public ModalDialog
1585 {
1586     FixedLine       aDurationFL;
1587 
1588     OKButton        aOKPB;
1589     CancelButton    aCancelPB;
1590     HelpButton      aHelpPB;
1591 
1592     CheckBox        aNegativeCB;
1593     FixedText       aYearFT;
1594     NumericField    aYearNF;
1595     FixedText       aMonthFT;
1596     NumericField    aMonthNF;
1597     FixedText       aDayFT;
1598     NumericField    aDayNF;
1599     FixedText       aHourFT;
1600     NumericField    aHourNF;
1601     FixedText       aMinuteFT;
1602     NumericField    aMinuteNF;
1603     FixedText       aSecondFT;
1604     NumericField    aSecondNF;
1605     FixedText       aMSecondFT;
1606     NumericField    aMSecondNF;
1607 
1608 public:
1609 
1610     DurationDialog_Impl( Window* pParent, const util::Duration& rDuration );
1611     ~DurationDialog_Impl();
1612 
1613     util::Duration  GetDuration() const;
1614 };
1615 /*-- 20.11.2009 15:40:46---------------------------------------------------
1616 
1617   -----------------------------------------------------------------------*/
1618 DurationDialog_Impl::DurationDialog_Impl(
1619     Window* pParent, const util::Duration& rDuration)
1620         :   ModalDialog( pParent, SfxResId( RID_EDIT_DURATIONS ) ),
1621             aDurationFL(this, SfxResId( FL_DURATION       )),
1622             aOKPB(      this, SfxResId( PB_OK       )),
1623             aCancelPB(  this, SfxResId( PB_CANCEL   )),
1624             aHelpPB(    this, SfxResId( PB_HELP     )),
1625             aNegativeCB(this, SfxResId( CB_NEGATIVE     )),
1626             aYearFT(    this, SfxResId( FT_YEAR         )),
1627             aYearNF(    this, SfxResId( ED_YEAR         )),
1628             aMonthFT(   this, SfxResId( FT_MONTH        )),
1629             aMonthNF(   this, SfxResId( ED_MONTH        )),
1630             aDayFT(     this, SfxResId( FT_DAY          )),
1631             aDayNF(     this, SfxResId( ED_DAY          )),
1632             aHourFT(    this, SfxResId( FT_HOUR         )),
1633             aHourNF(    this, SfxResId( ED_HOUR         )),
1634             aMinuteFT(  this, SfxResId( FT_MINUTE       )),
1635             aMinuteNF(  this, SfxResId( ED_MINUTE       )),
1636             aSecondFT(  this, SfxResId( FT_SECOND       )),
1637             aSecondNF(  this, SfxResId( ED_SECOND       )),
1638             aMSecondFT( this, SfxResId( FT_MSECOND      )),
1639             aMSecondNF( this, SfxResId( ED_MSECOND      ))
1640 {
1641     FreeResource();
1642     aNegativeCB.Check(rDuration.Negative);
1643     aYearNF.SetValue(rDuration.Years);
1644     aMonthNF.SetValue(rDuration.Months );
1645     aDayNF.SetValue(rDuration.Days   );
1646     aHourNF.SetValue(rDuration.Hours  );
1647     aMinuteNF.SetValue(rDuration.Minutes);
1648     aSecondNF.SetValue(rDuration.Seconds);
1649     aMSecondNF.SetValue(rDuration.MilliSeconds);
1650 }
1651 /*-- 20.11.2009 16:08:55---------------------------------------------------
1652 
1653   -----------------------------------------------------------------------*/
1654 DurationDialog_Impl::~DurationDialog_Impl()
1655 {
1656 }
1657 /*-- 20.11.2009 15:41:47---------------------------------------------------
1658 
1659   -----------------------------------------------------------------------*/
1660 util::Duration  DurationDialog_Impl::GetDuration() const
1661 {
1662     util::Duration  aRet;
1663     aRet.Negative = aNegativeCB.IsChecked();
1664     aRet.Years = aYearNF.GetValue();
1665     aRet.Months = aMonthNF.GetValue( );
1666     aRet.Days = aDayNF.GetValue(   );
1667     aRet.Hours  = aHourNF.GetValue( );
1668     aRet.Minutes = aMinuteNF.GetValue();
1669     aRet.Seconds = aSecondNF.GetValue();
1670     aRet.MilliSeconds = aMSecondNF.GetValue();
1671     return aRet;
1672 }
1673 
1674 /*-- 20.11.2009 15:30:58---------------------------------------------------
1675 
1676   -----------------------------------------------------------------------*/
1677 CustomPropertiesDurationField::CustomPropertiesDurationField( Window* pParent, const ResId& rResId, CustomPropertyLine* pLine ) :
1678         Edit( pParent, rResId ), m_pLine( pLine )
1679 
1680 {
1681     SetDuration( util::Duration(false, 0, 0, 0, 0, 0, 0, 0) );
1682 }
1683 /*-- 23.11.2009 08:46:02---------------------------------------------------
1684 
1685   -----------------------------------------------------------------------*/
1686 CustomPropertiesDurationField::~CustomPropertiesDurationField()
1687 {
1688 }
1689 /*-- 23.11.2009 09:23:35---------------------------------------------------
1690 
1691   -----------------------------------------------------------------------*/
1692 void CustomPropertiesDurationField::RequestHelp( const HelpEvent& rHEvt )
1693 {
1694     if( rHEvt.GetMode() & HELPMODE_QUICK )
1695     {
1696         Size aSize( GetSizePixel() );
1697         Rectangle aItemRect( rHEvt.GetMousePosPixel(), aSize );
1698         if(Help::IsBalloonHelpEnabled())
1699             Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), GetText() );
1700         else
1701             Help::ShowQuickHelp( this, aItemRect, GetText(),
1702                 QUICKHELP_LEFT|QUICKHELP_VCENTER );
1703     }
1704 }
1705 /*-- 20.11.2009 15:30:58---------------------------------------------------
1706 
1707   -----------------------------------------------------------------------*/
1708 void CustomPropertiesDurationField::SetDuration( const util::Duration& rDuration )
1709 {
1710     m_aDuration = rDuration;
1711     String sText(rDuration.Negative ? '-' : '+');
1712     sText += m_pLine->m_sDurationFormat;
1713     sText.SearchAndReplace(String::CreateFromAscii( "%1"), String::CreateFromInt32( rDuration.Years ) );
1714     sText.SearchAndReplace(String::CreateFromAscii( "%2"), String::CreateFromInt32( rDuration.Months ) );
1715     sText.SearchAndReplace(String::CreateFromAscii( "%3"), String::CreateFromInt32( rDuration.Days   ) );
1716     sText.SearchAndReplace(String::CreateFromAscii( "%4"), String::CreateFromInt32( rDuration.Hours  ) );
1717     sText.SearchAndReplace(String::CreateFromAscii( "%5"), String::CreateFromInt32( rDuration.Minutes) );
1718     sText.SearchAndReplace(String::CreateFromAscii( "%6"), String::CreateFromInt32( rDuration.Seconds) );
1719     SetText( sText );
1720 }
1721 /*-- 23.11.2009 08:51:15---------------------------------------------------
1722 
1723   -----------------------------------------------------------------------*/
1724 CustomPropertiesEditButton::CustomPropertiesEditButton( Window* pParent, const ResId& rResId, CustomPropertyLine* pLine ) :
1725         PushButton( pParent, rResId ), m_pLine( pLine )
1726 {
1727     SetClickHdl( LINK( this, CustomPropertiesEditButton, ClickHdl ));
1728 }
1729 /*-- 23.11.2009 08:51:15---------------------------------------------------
1730 
1731   -----------------------------------------------------------------------*/
1732 CustomPropertiesEditButton::~CustomPropertiesEditButton()
1733 {
1734 }
1735 /*-- 23.11.2009 08:47:37---------------------------------------------------
1736 
1737   -----------------------------------------------------------------------*/
1738 IMPL_LINK( CustomPropertiesEditButton, ClickHdl, PushButton*, EMPTYARG )
1739 {
1740     DurationDialog_Impl* pDurationDlg = new DurationDialog_Impl( this, m_pLine->m_aDurationField.GetDuration() );
1741     if( RET_OK == pDurationDlg->Execute() )
1742         m_pLine->m_aDurationField.SetDuration( pDurationDlg->GetDuration() );
1743     delete pDurationDlg;
1744     return 1;
1745 }
1746 //--------------------------------------------------------------------------
1747 void CustomPropertiesYesNoButton::Resize()
1748 {
1749     const long nWidth = GetSizePixel().Width();
1750     const long n3Width = LogicToPixel( Size( 3, 3 ), MAP_APPFONT ).Width();
1751     const long nNewWidth = ( nWidth / 2 ) - n3Width - 2;
1752     Size aSize = m_aYesButton.GetSizePixel();
1753     const long nDelta = aSize.Width() - nNewWidth;
1754     aSize.Width() = nNewWidth;
1755     m_aYesButton.SetSizePixel( aSize );
1756     Point aPos = m_aNoButton.GetPosPixel();
1757     aPos.X() -= nDelta;
1758     m_aNoButton.SetPosSizePixel( aPos, aSize );
1759 }
1760 
1761 // struct CustomPropertyLine ---------------------------------------------
1762 
1763 CustomPropertyLine::CustomPropertyLine( Window* pParent ) :
1764     m_aNameBox      ( pParent, SfxResId( SFX_CB_PROPERTY_NAME ) ),
1765     m_aTypeBox      ( pParent, SfxResId( SFX_LB_PROPERTY_TYPE ), this ),
1766     m_aValueEdit    ( pParent, SfxResId( SFX_ED_PROPERTY_VALUE ), this ),
1767     m_aDateField    ( pParent, SfxResId( SFX_FLD_DATE), this),
1768     m_aTimeField    ( pParent, SfxResId( SFX_FLD_TIME), this),
1769     m_sDurationFormat( SfxResId( SFX_ST_DURATION_FORMAT )),
1770     m_aDurationField( pParent, SfxResId( SFX_FLD_DURATION), this),
1771     m_aEditButton(    pParent, SfxResId( SFX_PB_EDIT ), this),
1772     m_aYesNoButton  ( pParent, SfxResId( SFX_WIN_PROPERTY_YESNO ) ),
1773     m_aRemoveButton ( pParent, SfxResId( SFX_PB_PROPERTY_REMOVE ), this ),
1774     m_bIsRemoved    ( false ),
1775     m_bTypeLostFocus( false )
1776 
1777 {
1778     m_aTimeField.SetExtFormat( EXTTIMEF_24H_LONG );
1779     m_aDateField.SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY );
1780 
1781     m_aRemoveButton.SetModeImage( SfxResId( SFX_IMG_PROPERTY_REMOVE ), BMP_COLOR_NORMAL );
1782     m_aRemoveButton.SetModeImage( SfxResId( SFX_IMG_PROPERTY_REMOVE_HC ), BMP_COLOR_HIGHCONTRAST );
1783 }
1784 
1785 void CustomPropertyLine::SetRemoved()
1786 {
1787     DBG_ASSERT( !m_bIsRemoved, "CustomPropertyLine::SetRemoved(): line already removed" );
1788     m_bIsRemoved = true;
1789     m_aNameBox.Hide();
1790     m_aTypeBox.Hide();
1791     m_aValueEdit.Hide();
1792     m_aDateField.Hide();
1793     m_aTimeField.Hide();
1794     m_aDurationField.Hide();
1795     m_aEditButton.Hide();
1796     m_aYesNoButton.Hide();
1797     m_aRemoveButton.Hide();
1798 }
1799 
1800 // class CustomPropertiesWindow ------------------------------------------
1801 
1802 CustomPropertiesWindow::CustomPropertiesWindow( Window* pParent, const ResId& rResId ) :
1803 
1804     Window( pParent, rResId ),
1805     m_aNameBox      ( this, SfxResId( SFX_CB_PROPERTY_NAME ) ),
1806     m_aTypeBox      ( this, SfxResId( SFX_LB_PROPERTY_TYPE ) ),
1807     m_aValueEdit    ( this, SfxResId( SFX_ED_PROPERTY_VALUE ) ),
1808     m_aDateField    ( this, SfxResId( SFX_FLD_DATE) ),
1809     m_aTimeField    ( this, SfxResId( SFX_FLD_TIME) ),
1810     m_aDurationField( this, SfxResId( SFX_FLD_DURATION) ),
1811     m_aEditButton(    this, SfxResId( SFX_PB_EDIT )),
1812     m_aYesNoButton  ( this, SfxResId( SFX_WIN_PROPERTY_YESNO ) ),
1813     m_aRemoveButton ( this, SfxResId( SFX_PB_PROPERTY_REMOVE ) ),
1814 	m_nScrollPos (0),
1815     m_aNumberFormatter( ::comphelper::getProcessServiceFactory(),
1816                         Application::GetSettings().GetLanguage() )
1817 
1818 {
1819     m_aEditLoseFocusTimer.SetTimeout( 300 );
1820     m_aEditLoseFocusTimer.SetTimeoutHdl( LINK( this, CustomPropertiesWindow, EditTimeoutHdl ) );
1821     m_aBoxLoseFocusTimer.SetTimeout( 300 );
1822     m_aBoxLoseFocusTimer.SetTimeoutHdl( LINK( this, CustomPropertiesWindow, BoxTimeoutHdl ) );
1823 
1824 	ResMgr* pResMgr = rResId.GetResMgr();
1825 	m_aNameBox.SetAccessibleName( String( ResId( STR_HEADER_NAME, *pResMgr ) ) );
1826 	m_aTypeBox.SetAccessibleName( String( ResId( STR_HEADER_TYPE, *pResMgr ) ) );
1827 	m_aValueEdit.SetAccessibleName( String( ResId( STR_HEADER_VALUE, *pResMgr ) ) );
1828 }
1829 
1830 CustomPropertiesWindow::~CustomPropertiesWindow()
1831 {
1832     m_aEditLoseFocusTimer.Stop();
1833     m_aBoxLoseFocusTimer.Stop();
1834     ClearAllLines();
1835 }
1836 
1837 IMPL_LINK( CustomPropertiesWindow, TypeHdl, CustomPropertiesTypeBox*, pBox )
1838 {
1839     sal_Int64 nType = sal_Int64( (long)pBox->GetEntryData( pBox->GetSelectEntryPos() ) );
1840     CustomPropertyLine* pLine = pBox->GetLine();
1841     pLine->m_aValueEdit.Show( (CUSTOM_TYPE_TEXT == nType) || (CUSTOM_TYPE_NUMBER  == nType) );
1842     pLine->m_aDateField.Show( (CUSTOM_TYPE_DATE == nType) || (CUSTOM_TYPE_DATETIME  == nType) );
1843     pLine->m_aTimeField.Show( CUSTOM_TYPE_DATETIME  == nType );
1844     pLine->m_aDurationField.Show( CUSTOM_TYPE_DURATION == nType );
1845     pLine->m_aEditButton.Show( CUSTOM_TYPE_DURATION == nType );
1846     pLine->m_aYesNoButton.Show( CUSTOM_TYPE_BOOLEAN == nType );
1847     //adjust positions of date and time controls
1848     if( nType == CUSTOM_TYPE_DATE )
1849     {
1850         pLine->m_aDateField.SetPosSizePixel(pLine->m_aValueEdit.GetPosPixel(), pLine->m_aValueEdit.GetSizePixel());
1851     }
1852     else if( nType == CUSTOM_TYPE_DATETIME)
1853     {
1854         pLine->m_aDateField.SetPosSizePixel( pLine->m_aDatePos, pLine->m_aDateTimeSize );
1855         pLine->m_aTimeField.SetPosSizePixel(pLine->m_aTimePos, pLine->m_aDateTimeSize );
1856     }
1857 
1858     return 0;
1859 }
1860 
1861 IMPL_LINK( CustomPropertiesWindow, RemoveHdl, CustomPropertiesRemoveButton*, pButton )
1862 {
1863     CustomPropertyLine* pLine = pButton->GetLine();
1864     std::vector< CustomPropertyLine* >::iterator pFound =
1865         std::find( m_aCustomPropertiesLines.begin(), m_aCustomPropertiesLines.end(), pLine );
1866     if ( pFound != m_aCustomPropertiesLines.end() )
1867     {
1868         pLine = *pFound;
1869         pLine->SetRemoved();
1870         std::vector< CustomPropertyLine* >::iterator pIter = pFound + 1;
1871         const long nDelta = GetLineHeight();
1872         for ( ; pIter != m_aCustomPropertiesLines.end(); ++pIter )
1873         {
1874             pLine = *pIter;
1875             if ( pLine->m_bIsRemoved )
1876                 continue;
1877 
1878             Window* pWindows[] = {  &pLine->m_aNameBox, &pLine->m_aTypeBox, &pLine->m_aValueEdit,
1879                                     &pLine->m_aDateField, &pLine->m_aTimeField,
1880                                     &pLine->m_aDurationField, &pLine->m_aEditButton,
1881                                     &pLine->m_aYesNoButton, &pLine->m_aRemoveButton, NULL };
1882             Window** pCurrent = pWindows;
1883             while ( *pCurrent )
1884             {
1885                 Point aPos = (*pCurrent)->GetPosPixel();
1886                 aPos.Y() -= nDelta;
1887                 (*pCurrent)->SetPosPixel( aPos );
1888                 pCurrent++;
1889             }
1890         }
1891     }
1892 
1893 	m_aRemovedHdl.Call(0);
1894     return 0;
1895 }
1896 
1897 IMPL_LINK( CustomPropertiesWindow, EditLoseFocusHdl, CustomPropertiesEdit*, pEdit )
1898 {
1899     if ( pEdit )
1900     {
1901         CustomPropertyLine* pLine = pEdit->GetLine();
1902         if ( !pLine->m_bTypeLostFocus )
1903         {
1904             m_pCurrentLine = pLine;
1905             m_aEditLoseFocusTimer.Start();
1906         }
1907         else
1908             pLine->m_bTypeLostFocus = false;
1909     }
1910     return 0;
1911 }
1912 
1913 IMPL_LINK( CustomPropertiesWindow, BoxLoseFocusHdl, CustomPropertiesTypeBox*, pBox )
1914 {
1915     if ( pBox )
1916     {
1917         m_pCurrentLine = pBox->GetLine();
1918         m_aBoxLoseFocusTimer.Start();
1919     }
1920 
1921     return 0;
1922 }
1923 
1924 IMPL_LINK( CustomPropertiesWindow, EditTimeoutHdl, Timer*, EMPTYARG )
1925 {
1926     ValidateLine( m_pCurrentLine, false );
1927     return 0;
1928 }
1929 
1930 IMPL_LINK( CustomPropertiesWindow, BoxTimeoutHdl, Timer*, EMPTYARG )
1931 {
1932     ValidateLine( m_pCurrentLine, true );
1933     return 0;
1934 }
1935 
1936 bool CustomPropertiesWindow::IsLineValid( CustomPropertyLine* pLine ) const
1937 {
1938     bool bIsValid = true;
1939     pLine->m_bTypeLostFocus = false;
1940     sal_Int64 nType = sal_Int64(
1941         (long)pLine->m_aTypeBox.GetEntryData( pLine->m_aTypeBox.GetSelectEntryPos() ) );
1942     String sValue = pLine->m_aValueEdit.GetText();
1943     if ( sValue.Len() == 0 )
1944         return true;
1945 
1946     double fDummy = 0.0;
1947     sal_uInt32 nIndex = 0xFFFFFFFF;
1948     if ( CUSTOM_TYPE_NUMBER == nType )
1949         nIndex = const_cast< SvNumberFormatter& >(
1950             m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
1951     else if ( CUSTOM_TYPE_DATE == nType )
1952         nIndex = const_cast< SvNumberFormatter& >(
1953             m_aNumberFormatter).GetFormatIndex( NF_DATE_SYS_DDMMYYYY );
1954 
1955     if ( nIndex != 0xFFFFFFFF )
1956     {
1957         sal_uInt32 nTemp = nIndex;
1958         bIsValid = const_cast< SvNumberFormatter& >(
1959             m_aNumberFormatter ).IsNumberFormat( sValue, nIndex, fDummy ) != sal_False;
1960         if ( bIsValid && nTemp != nIndex )
1961             // sValue is a number but the format doesn't match the index
1962             bIsValid = false;
1963     }
1964 
1965     return bIsValid;
1966 }
1967 
1968 void CustomPropertiesWindow::ValidateLine( CustomPropertyLine* pLine, bool bIsFromTypeBox )
1969 {
1970     if ( !IsLineValid( pLine ) )
1971     {
1972         if ( bIsFromTypeBox ) // LoseFocus of TypeBox
1973             pLine->m_bTypeLostFocus = true;
1974         Window* pParent = GetParent()->GetParent();
1975         if ( QueryBox( pParent, SfxResId( SFX_QB_WRONG_TYPE ) ).Execute() == RET_OK )
1976             pLine->m_aTypeBox.SelectEntryPos( m_aTypeBox.GetEntryPos( (void*)CUSTOM_TYPE_TEXT ) );
1977         else
1978             pLine->m_aValueEdit.GrabFocus();
1979     }
1980 }
1981 
1982 void CustomPropertiesWindow::InitControls( HeaderBar* pHeaderBar, const ScrollBar* pScrollBar )
1983 {
1984     DBG_ASSERT( pHeaderBar, "CustomPropertiesWindow::InitControls(): invalid headerbar" );
1985     DBG_ASSERT( pScrollBar, "CustomPropertiesWindow::InitControls(): invalid scrollbar" );
1986 
1987     m_aNameBox.Hide();
1988     m_aTypeBox.Hide();
1989     m_aValueEdit.Hide();
1990     m_aDateField.Hide();
1991     m_aTimeField.Hide();
1992     m_aDurationField.Hide();
1993     m_aEditButton.Hide();
1994     m_aYesNoButton.Hide();
1995     m_aRemoveButton.Hide();
1996 
1997     const long nOffset = 4;
1998     const long nScrollBarWidth = pScrollBar->GetSizePixel().Width();
1999     const long nButtonWidth = m_aRemoveButton.GetSizePixel().Width() + nScrollBarWidth + nOffset;
2000     long nTypeWidth = m_aTypeBox.CalcMinimumSize().Width() + ( 2 * nOffset );
2001     long nFullWidth = pHeaderBar->GetSizePixel().Width();
2002     long nItemWidth = ( nFullWidth - nTypeWidth - nButtonWidth ) / 2;
2003     pHeaderBar->SetItemSize( HI_NAME, nItemWidth );
2004     pHeaderBar->SetItemSize( HI_TYPE, nTypeWidth );
2005     pHeaderBar->SetItemSize( HI_VALUE, nItemWidth );
2006     pHeaderBar->SetItemSize( HI_ACTION, nButtonWidth );
2007 
2008     Window* pWindows[] = { &m_aNameBox, &m_aTypeBox, &m_aValueEdit, &m_aRemoveButton, NULL };
2009     Window** pCurrent = pWindows;
2010     sal_uInt16 nPos = 0;
2011     while ( *pCurrent )
2012     {
2013         Rectangle aRect = pHeaderBar->GetItemRect( pHeaderBar->GetItemId( nPos++ ) );
2014         Size aSize = (*pCurrent)->GetSizePixel();
2015         Point aPos = (*pCurrent)->GetPosPixel();
2016         long nWidth = aRect.getWidth() - nOffset;
2017         if ( *pCurrent == &m_aRemoveButton )
2018             nWidth -= pScrollBar->GetSizePixel().Width();
2019         aSize.Width() = nWidth;
2020         aPos.X() = aRect.getX() + ( nOffset / 2 );
2021         (*pCurrent)->SetPosSizePixel( aPos, aSize );
2022 
2023         if ( *pCurrent == &m_aValueEdit )
2024         {
2025             Point aDurationPos( aPos );
2026             m_aDurationField.SetPosPixel( aDurationPos );
2027             Size aDurationSize(aSize);
2028             aDurationSize.Width() -= (m_aEditButton.GetSizePixel().Width() + 3 );
2029             m_aDurationField.SetSizePixel(aDurationSize);
2030             aDurationPos.X() = aPos.X() - m_aEditButton.GetSizePixel().Width() + aSize.Width();
2031             m_aEditButton.SetPosPixel(aDurationPos);
2032             aSize = m_aYesNoButton.GetSizePixel();
2033             aPos = m_aYesNoButton.GetPosPixel();
2034             aSize.Width() = nWidth;
2035             aPos.X() = aRect.getX() + ( nOffset / 2 );
2036             m_aYesNoButton.SetPosSizePixel( aPos, aSize );
2037             aSize.Width() /= 2;
2038             aSize.Width() -= 2;
2039             m_aDateField.SetPosSizePixel( aPos, aSize );
2040             aPos.X() += aSize.Width() + 4;
2041             m_aTimeField.SetPosSizePixel( aPos, aSize );
2042         }
2043 
2044         pCurrent++;
2045     }
2046 
2047     m_nLineHeight =
2048         ( m_aRemoveButton.GetPosPixel().Y() * 2 ) + m_aRemoveButton.GetSizePixel().Height();
2049 }
2050 
2051 sal_uInt16 CustomPropertiesWindow::GetVisibleLineCount() const
2052 {
2053     sal_uInt16 nCount = 0;
2054     std::vector< CustomPropertyLine* >::const_iterator pIter;
2055     for ( pIter = m_aCustomPropertiesLines.begin();
2056             pIter != m_aCustomPropertiesLines.end(); ++pIter )
2057     {
2058         CustomPropertyLine* pLine = *pIter;
2059         if ( !pLine->m_bIsRemoved )
2060             nCount++;
2061     }
2062     return nCount;
2063 }
2064 
2065 void CustomPropertiesWindow::AddLine( const ::rtl::OUString& sName, Any& rAny )
2066 {
2067     CustomPropertyLine* pNewLine = new CustomPropertyLine( this );
2068     pNewLine->m_aTypeBox.SetSelectHdl( LINK( this, CustomPropertiesWindow, TypeHdl ) );
2069     pNewLine->m_aRemoveButton.SetClickHdl( LINK( this, CustomPropertiesWindow, RemoveHdl ) );
2070     pNewLine->m_aValueEdit.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, EditLoseFocusHdl ) );
2071     //add lose focus handlers of date/time fields
2072 
2073     pNewLine->m_aTypeBox.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, BoxLoseFocusHdl ) );
2074 
2075 	pNewLine->m_aNameBox.SetAccessibleName(m_aNameBox.GetAccessibleName());
2076 	pNewLine->m_aTypeBox.SetAccessibleName(m_aTypeBox.GetAccessibleName());
2077 	pNewLine->m_aValueEdit.SetAccessibleName(m_aValueEdit.GetAccessibleName());
2078 
2079     long nPos = GetVisibleLineCount() * GetLineHeight();
2080     m_aCustomPropertiesLines.push_back( pNewLine );
2081     Window* pWindows[] = {  &m_aNameBox, &m_aTypeBox, &m_aValueEdit,
2082                             &m_aDateField, &m_aTimeField,
2083                             &m_aDurationField, &m_aEditButton,
2084                             &m_aYesNoButton, &m_aRemoveButton, NULL };
2085     Window* pNewWindows[] =
2086         {   &pNewLine->m_aNameBox, &pNewLine->m_aTypeBox, &pNewLine->m_aValueEdit,
2087             &pNewLine->m_aDateField, &pNewLine->m_aTimeField,
2088             &pNewLine->m_aDurationField, &pNewLine->m_aEditButton,
2089             &pNewLine->m_aYesNoButton, &pNewLine->m_aRemoveButton, NULL };
2090     Window** pCurrent = pWindows;
2091     Window** pNewCurrent = pNewWindows;
2092     while ( *pCurrent )
2093     {
2094         Size aSize = (*pCurrent)->GetSizePixel();
2095         Point aPos = (*pCurrent)->GetPosPixel();
2096         aPos.Y() += nPos;
2097 		aPos.Y() += m_nScrollPos;
2098         (*pNewCurrent)->SetPosSizePixel( aPos, aSize );
2099         (*pNewCurrent)->Show();
2100         pCurrent++;
2101         pNewCurrent++;
2102     }
2103     //
2104     pNewLine->m_aDatePos = pNewLine->m_aDateField.GetPosPixel();
2105     pNewLine->m_aTimePos = pNewLine->m_aTimeField.GetPosPixel();
2106     pNewLine->m_aDateTimeSize = pNewLine->m_aDateField.GetSizePixel();
2107 
2108     double nTmpValue = 0;
2109     bool bTmpValue = false;
2110     ::rtl::OUString sTmpValue;
2111     util::DateTime aTmpDateTime;
2112     util::Date aTmpDate;
2113     util::Duration aTmpDuration;
2114     SvtSysLocale aSysLocale;
2115     const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData();
2116     pNewLine->m_aNameBox.SetText( sName );
2117     sal_Int32 nType = CUSTOM_TYPE_UNKNOWN;
2118     String sValue;
2119 
2120     if ( rAny >>= nTmpValue )
2121     {
2122         sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM );
2123         m_aNumberFormatter.GetInputLineString( nTmpValue, nIndex, sValue );
2124         pNewLine->m_aValueEdit.SetText( sValue );
2125         nType = CUSTOM_TYPE_NUMBER;
2126     }
2127     else if ( rAny >>= bTmpValue )
2128     {
2129         sValue = ( bTmpValue ? rLocaleWrapper.getTrueWord() : rLocaleWrapper.getFalseWord() );
2130         nType = CUSTOM_TYPE_BOOLEAN;
2131     }
2132     else if ( rAny >>= sTmpValue )
2133     {
2134         pNewLine->m_aValueEdit.SetText( sTmpValue );
2135         nType = CUSTOM_TYPE_TEXT;
2136     }
2137     else if ( rAny >>= aTmpDate )
2138     {
2139         nType = CUSTOM_TYPE_DATE;
2140         pNewLine->m_aDateField.SetDate( Date( aTmpDate.Day, aTmpDate.Month, aTmpDate.Year ) );
2141 
2142     }
2143     else if ( rAny >>= aTmpDuration )
2144     {
2145         nType = CUSTOM_TYPE_DURATION;
2146         pNewLine->m_aDurationField.SetDuration( aTmpDuration );
2147     }
2148     else if ( rAny >>= aTmpDateTime )
2149     {
2150         pNewLine->m_aDateField.SetDate( Date( aTmpDateTime.Day, aTmpDateTime.Month, aTmpDateTime.Year ) );
2151         pNewLine->m_aTimeField.SetTime( Time( aTmpDateTime.Hours, aTmpDateTime.Minutes, aTmpDateTime.Seconds, aTmpDateTime.HundredthSeconds ) );
2152 
2153         nType = CUSTOM_TYPE_DATETIME;
2154     }
2155 
2156     if ( nType != CUSTOM_TYPE_UNKNOWN )
2157     {
2158         if ( CUSTOM_TYPE_BOOLEAN == nType )
2159         {
2160             if ( bTmpValue )
2161                 pNewLine->m_aYesNoButton.CheckYes();
2162             else
2163                 pNewLine->m_aYesNoButton.CheckNo();
2164         }
2165         pNewLine->m_aTypeBox.SelectEntryPos( m_aTypeBox.GetEntryPos( (void*)nType ) );
2166     }
2167 
2168     TypeHdl( &pNewLine->m_aTypeBox );
2169     pNewLine->m_aNameBox.GrabFocus();
2170 }
2171 
2172 bool CustomPropertiesWindow::AreAllLinesValid() const
2173 {
2174     bool bRet = true;
2175     std::vector< CustomPropertyLine* >::const_iterator pIter;
2176     for ( pIter = m_aCustomPropertiesLines.begin();
2177             pIter != m_aCustomPropertiesLines.end(); ++pIter )
2178     {
2179         CustomPropertyLine* pLine = *pIter;
2180         if ( !IsLineValid( pLine ) )
2181         {
2182             bRet = false;
2183             break;
2184         }
2185     }
2186 
2187     return bRet;
2188 }
2189 
2190 void CustomPropertiesWindow::ClearAllLines()
2191 {
2192     std::vector< CustomPropertyLine* >::iterator pIter;
2193     for ( pIter = m_aCustomPropertiesLines.begin();
2194           pIter != m_aCustomPropertiesLines.end(); ++pIter )
2195     {
2196         CustomPropertyLine* pLine = *pIter;
2197         pLine->SetRemoved();
2198         delete pLine;
2199     }
2200     m_aCustomPropertiesLines.clear();
2201 	m_nScrollPos = 0;
2202 }
2203 
2204 void CustomPropertiesWindow::DoScroll( sal_Int32 nNewPos )
2205 {
2206 	m_nScrollPos += nNewPos;
2207 	std::vector< CustomPropertyLine* >::iterator pIter;
2208     for ( pIter = m_aCustomPropertiesLines.begin();
2209             pIter != m_aCustomPropertiesLines.end(); ++pIter )
2210     {
2211         CustomPropertyLine* pLine = *pIter;
2212         if ( pLine->m_bIsRemoved )
2213             continue;
2214 
2215         Window* pWindows[] = {  &pLine->m_aNameBox, &pLine->m_aTypeBox, &pLine->m_aValueEdit, &pLine->m_aDurationField,
2216                                 &pLine->m_aYesNoButton, &pLine->m_aRemoveButton, NULL };
2217         Window** pCurrent = pWindows;
2218         while ( *pCurrent )
2219         {
2220             Point aPos = (*pCurrent)->GetPosPixel();
2221             aPos.Y() += nNewPos;
2222             (*pCurrent)->SetPosPixel( aPos );
2223             pCurrent++;
2224         }
2225     }
2226 }
2227 
2228 bool CustomPropertiesWindow::DoesCustomPropertyExist( const String& rName ) const
2229 {
2230     bool bRet = false;
2231     std::vector< CustomPropertyLine* >::const_iterator pIter;
2232     for ( pIter = m_aCustomPropertiesLines.begin();
2233             pIter != m_aCustomPropertiesLines.end(); ++pIter )
2234     {
2235         CustomPropertyLine* pLine = *pIter;
2236         if ( !pLine->m_bIsRemoved && pLine->m_aNameBox.GetText() == rName )
2237         {
2238             bRet = true;
2239             break;
2240         }
2241     }
2242 
2243     return bRet;
2244 }
2245 
2246 Sequence< beans::PropertyValue > CustomPropertiesWindow::GetCustomProperties() const
2247 {
2248     Sequence< beans::PropertyValue > aPropertiesSeq( m_aCustomPropertiesLines.size() );
2249     sal_Int32 i = 0;
2250     std::vector< CustomPropertyLine* >::const_iterator pIter;
2251     for ( pIter = m_aCustomPropertiesLines.begin();
2252             pIter != m_aCustomPropertiesLines.end(); ++pIter, ++i )
2253     {
2254         CustomPropertyLine* pLine = *pIter;
2255         if ( pLine->m_bIsRemoved )
2256             continue;
2257 
2258         String sPropertyName = pLine->m_aNameBox.GetText();
2259         if ( sPropertyName.Len() > 0 )
2260         {
2261             aPropertiesSeq[i].Name = sPropertyName;
2262             sal_Int64 nType = sal_Int64(
2263                 (long)pLine->m_aTypeBox.GetEntryData( pLine->m_aTypeBox.GetSelectEntryPos() ) );
2264             if ( CUSTOM_TYPE_NUMBER == nType )
2265             {
2266                 double nValue = 0;
2267                 sal_uInt32 nIndex = const_cast< SvNumberFormatter& >(
2268                     m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
2269                 sal_Bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ).
2270                     IsNumberFormat( pLine->m_aValueEdit.GetText(), nIndex, nValue );
2271                 if ( bIsNum )
2272                     aPropertiesSeq[i].Value <<= makeAny( nValue );
2273             }
2274             else if ( CUSTOM_TYPE_BOOLEAN == nType )
2275             {
2276                 bool bValue = pLine->m_aYesNoButton.IsYesChecked();
2277                 aPropertiesSeq[i].Value <<= makeAny( bValue );
2278             }
2279             else if ( CUSTOM_TYPE_DATETIME == nType )
2280             {
2281                 Date aTmpDate = pLine->m_aDateField.GetDate();
2282                 Time aTmpTime = pLine->m_aTimeField.GetTime();
2283                 util::DateTime aDateTime(aTmpTime.Get100Sec(), aTmpTime.GetSec(), aTmpTime.GetMin(), aTmpTime.GetHour(),
2284                         aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear() );
2285                 aPropertiesSeq[i].Value <<= aDateTime;
2286             }
2287             else if ( CUSTOM_TYPE_DURATION == nType )
2288             {
2289                 aPropertiesSeq[i].Value <<= pLine->m_aDurationField.GetDuration();
2290             }
2291             else if ( CUSTOM_TYPE_DATE == nType )
2292             {
2293                 Date aTmpDate = pLine->m_aDateField.GetDate();
2294                 util::Date aDate(aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear());
2295                 aPropertiesSeq[i].Value <<= aDate;
2296 
2297             }
2298             else
2299             {
2300                 ::rtl::OUString sValue( pLine->m_aValueEdit.GetText() );
2301                 aPropertiesSeq[i].Value <<= makeAny( sValue );
2302             }
2303         }
2304     }
2305 
2306     return aPropertiesSeq;
2307 }
2308 
2309 // class CustomPropertiesControl -----------------------------------------
2310 
2311 CustomPropertiesControl::CustomPropertiesControl( Window* pParent, const ResId& rResId ) :
2312 
2313     Control( pParent, rResId ),
2314 
2315     m_aHeaderBar    ( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER ),
2316     m_aPropertiesWin( this, ResId( WIN_PROPERTIES, *rResId.GetResMgr() ) ),
2317     m_aVertScroll   ( this, ResId( SB_VERTICAL, *rResId.GetResMgr() ) ),
2318 
2319     m_bIsInitialized( false ),
2320     m_nThumbPos     ( 0 )
2321 
2322 {
2323     m_aPropertiesWin.SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
2324     m_aVertScroll.EnableDrag();
2325     m_aVertScroll.Show();
2326     long nWidth = GetOutputSizePixel().Width();
2327     m_aHeaderBar.SetPosSizePixel( Point(), Size( nWidth, m_aVertScroll.GetPosPixel().Y() ) );
2328     const HeaderBarItemBits nHeadBits = HIB_VCENTER | HIB_FIXED | HIB_FIXEDPOS | HIB_LEFT;
2329     nWidth = nWidth / 4;
2330     ResMgr* pResMgr = rResId.GetResMgr();
2331     m_aHeaderBar.InsertItem( HI_NAME, String( ResId( STR_HEADER_NAME, *pResMgr ) ), nWidth, nHeadBits );
2332     m_aHeaderBar.InsertItem( HI_TYPE, String( ResId( STR_HEADER_TYPE, *pResMgr ) ), nWidth, nHeadBits );
2333     m_aHeaderBar.InsertItem( HI_VALUE, String( ResId( STR_HEADER_VALUE, *pResMgr ) ), nWidth, nHeadBits );
2334     m_aHeaderBar.InsertItem( HI_ACTION, String( ResId( STR_HEADER_ACTION, *pResMgr ) ), nWidth, nHeadBits );
2335     m_aHeaderBar.Show();
2336 
2337     FreeResource();
2338 
2339     XubString sTEST = m_aHeaderBar.GetItemText( HI_NAME );
2340 
2341     m_aPropertiesWin.InitControls( &m_aHeaderBar, &m_aVertScroll );
2342 	m_aPropertiesWin.SetRemovedHdl( LINK( this, CustomPropertiesControl, RemovedHdl ) );
2343 
2344     m_aVertScroll.SetRangeMin( 0 );
2345     sal_Int32 nScrollOffset = m_aPropertiesWin.GetLineHeight();
2346     sal_Int32 nVisibleEntries = m_aPropertiesWin.GetSizePixel().Height() / nScrollOffset;
2347     m_aVertScroll.SetRangeMax( nVisibleEntries );
2348     m_aVertScroll.SetPageSize( nVisibleEntries - 1 );
2349     m_aVertScroll.SetVisibleSize( nVisibleEntries );
2350 
2351     Point aPos = m_aHeaderBar.GetPosPixel();
2352     Size aSize = m_aHeaderBar.GetSizePixel();
2353     aPos = m_aVertScroll.GetPosPixel();
2354     aSize = m_aVertScroll.GetSizePixel();
2355 
2356     Link aScrollLink = LINK( this, CustomPropertiesControl, ScrollHdl );
2357     m_aVertScroll.SetScrollHdl( aScrollLink );
2358 //    m_aVertScroll.SetEndScrollHdl( aScrollLink );
2359 }
2360 
2361 CustomPropertiesControl::~CustomPropertiesControl()
2362 {
2363 }
2364 
2365 void CustomPropertiesControl::Initialize()
2366 {
2367 }
2368 
2369 IMPL_LINK( CustomPropertiesControl, ScrollHdl, ScrollBar*, pScrollBar )
2370 {
2371     sal_Int32 nOffset = m_aPropertiesWin.GetLineHeight();
2372     nOffset *= ( m_nThumbPos - pScrollBar->GetThumbPos() );
2373     m_nThumbPos = pScrollBar->GetThumbPos();
2374     m_aPropertiesWin.DoScroll( nOffset );
2375     return 0;
2376 }
2377 
2378 IMPL_LINK( CustomPropertiesControl, RemovedHdl, void*, EMPTYARG )
2379 {
2380     m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 );
2381 	if ( m_aPropertiesWin.GetOutputSizePixel().Height() < m_aPropertiesWin.GetVisibleLineCount() * m_aPropertiesWin.GetLineHeight() )
2382 		m_aVertScroll.DoScrollAction ( SCROLL_LINEUP );
2383 	return 0;
2384 }
2385 
2386 void CustomPropertiesControl::AddLine( const ::rtl::OUString& sName, Any& rAny, bool bInteractive )
2387 {
2388     m_aPropertiesWin.AddLine( sName, rAny );
2389     m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 );
2390 	if ( bInteractive && m_aPropertiesWin.GetOutputSizePixel().Height() < m_aPropertiesWin.GetVisibleLineCount() * m_aPropertiesWin.GetLineHeight() )
2391 		m_aVertScroll.DoScroll( m_aPropertiesWin.GetVisibleLineCount() + 1 );
2392 }
2393 
2394 // class SfxCustomPropertiesPage -----------------------------------------
2395 
2396 SfxCustomPropertiesPage::SfxCustomPropertiesPage( Window* pParent, const SfxItemSet& rItemSet ) :
2397 
2398     SfxTabPage( pParent, SfxResId( TP_CUSTOMPROPERTIES ), rItemSet ),
2399     m_aPropertiesCtrl   ( this, SfxResId( CTRL_PROPERTIES ) ),
2400     m_aAddBtn           ( this, SfxResId( BTN_ADD ) ),
2401     m_aPropertiesFT     ( this, SfxResId( FT_PROPERTIES ) )
2402 
2403 {
2404     FreeResource();
2405 
2406     m_aAddBtn.SetClickHdl( LINK( this, SfxCustomPropertiesPage, AddHdl ) );
2407 }
2408 
2409 IMPL_LINK( SfxCustomPropertiesPage, AddHdl, PushButton*, EMPTYARG )
2410 {
2411     Any aAny;
2412     m_aPropertiesCtrl.AddLine( ::rtl::OUString(), aAny, true );
2413     return 0;
2414 }
2415 
2416 sal_Bool SfxCustomPropertiesPage::FillItemSet( SfxItemSet& rSet )
2417 {
2418     sal_Bool bModified = sal_False;
2419     const SfxPoolItem*      pItem = NULL;
2420     SfxDocumentInfoItem*    pInfo = NULL;
2421     bool                    bMustDelete = false;
2422 
2423     if ( GetTabDialog() && GetTabDialog()->GetExampleSet() )
2424     {
2425         if( SFX_ITEM_SET !=
2426                 GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
2427             pInfo = &( SfxDocumentInfoItem& )rSet.Get( SID_DOCINFO );
2428         else
2429         {
2430             bMustDelete = true;
2431             pInfo = new SfxDocumentInfoItem( *( const SfxDocumentInfoItem* ) pItem );
2432         }
2433     }
2434 
2435     if ( pInfo )
2436     {
2437         pInfo->ClearCustomProperties();
2438         Sequence< beans::PropertyValue > aPropertySeq = m_aPropertiesCtrl.GetCustomProperties();
2439         sal_Int32 i = 0, nCount = aPropertySeq.getLength();
2440         for ( ; i < nCount; ++i )
2441         {
2442             if ( aPropertySeq[i].Name.getLength() > 0 )
2443                 pInfo->AddCustomProperty( aPropertySeq[i].Name, aPropertySeq[i].Value );
2444         }
2445     }
2446 
2447     bModified = sal_True; //!!!
2448     if ( bModified )
2449         rSet.Put( *pInfo );
2450     if ( bMustDelete )
2451         delete pInfo;
2452     return bModified;
2453 }
2454 
2455 void SfxCustomPropertiesPage::Reset( const SfxItemSet& rItemSet )
2456 {
2457     m_aPropertiesCtrl.ClearAllLines();
2458     const SfxDocumentInfoItem* pInfoItem = &(const SfxDocumentInfoItem &)rItemSet.Get(SID_DOCINFO);
2459     std::vector< CustomProperty* > aCustomProps = pInfoItem->GetCustomProperties();
2460     for ( sal_uInt32 i = 0; i < aCustomProps.size(); i++ )
2461     {
2462         m_aPropertiesCtrl.AddLine( aCustomProps[i]->m_sName, aCustomProps[i]->m_aValue, false );
2463     }
2464 }
2465 
2466 int SfxCustomPropertiesPage::DeactivatePage( SfxItemSet* /*pSet*/ )
2467 {
2468     int nRet = LEAVE_PAGE;
2469     if ( !m_aPropertiesCtrl.AreAllLinesValid() )
2470         nRet = KEEP_PAGE;
2471     return nRet;
2472 }
2473 
2474 SfxTabPage* SfxCustomPropertiesPage::Create( Window* pParent, const SfxItemSet& rItemSet )
2475 {
2476     return new SfxCustomPropertiesPage( pParent, rItemSet );
2477 }
2478 
2479