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