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