Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / dialog / dinfdlg.cxx
blobba0d0c29d4a6aa8fb759c323d15c6952c4754941
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <tools/urlobj.hxx>
30 #include <vcl/msgbox.hxx>
31 #include <svl/eitem.hxx>
32 #include <vcl/svapp.hxx>
33 #include <unotools/localedatawrapper.hxx>
34 #include <unotools/cmdoptions.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <svl/urihelper.hxx>
37 #include <unotools/useroptions.hxx>
38 #include <svtools/imagemgr.hxx>
39 #include <tools/datetime.hxx>
41 #include <memory>
43 #include <comphelper/string.hxx>
44 #include <com/sun/star/security/DocumentSignatureInformation.hpp>
45 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
46 #include <unotools/syslocale.hxx>
47 #include <rtl/math.hxx>
48 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
49 #include <com/sun/star/beans/PropertyAttribute.hpp>
50 #include <com/sun/star/beans/XPropertyContainer.hpp>
51 #include <com/sun/star/util/DateTime.hpp>
52 #include <com/sun/star/util/Date.hpp>
53 #include <com/sun/star/util/Time.hpp>
54 #include <com/sun/star/util/Duration.hpp>
55 #include <com/sun/star/document/XDocumentProperties.hpp>
57 #include <vcl/timer.hxx>
58 #include "sfx2/dinfdlg.hxx"
59 #include "sfx2/securitypage.hxx"
60 #include "sfxresid.hxx"
61 #include "dinfedt.hxx"
62 #include <sfx2/frame.hxx>
63 #include <sfx2/viewfrm.hxx>
64 #include <sfx2/request.hxx>
65 #include <sfx2/passwd.hxx>
66 #include <sfx2/filedlghelper.hxx>
67 #include "helper.hxx"
68 #include <sfx2/objsh.hxx>
69 #include <sfx2/docfile.hxx>
70 #include <comphelper/storagehelper.hxx>
72 #include <sfx2/sfx.hrc>
73 #include "dinfdlg.hrc"
74 #include "sfxlocal.hrc"
75 #include <dialog.hrc>
76 #include <vcl/help.hxx>
78 #include <algorithm>
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;
85 struct CustomProperty
87 ::rtl::OUString m_sName;
88 com::sun::star::uno::Any m_aValue;
90 CustomProperty( const ::rtl::OUString& sName,
91 const com::sun::star::uno::Any& rValue ) :
92 m_sName( sName ), m_aValue( rValue ) {}
94 inline bool operator==( const CustomProperty& rProp )
95 { return m_sName.equals( rProp.m_sName ) && m_aValue == rProp.m_aValue; }
98 static
99 bool operator==(const util::DateTime &i_rLeft, const util::DateTime &i_rRight)
101 return i_rLeft.Year == i_rRight.Year
102 && i_rLeft.Month == i_rRight.Month
103 && i_rLeft.Day == i_rRight.Day
104 && i_rLeft.Hours == i_rRight.Hours
105 && i_rLeft.Minutes == i_rRight.Minutes
106 && i_rLeft.Seconds == i_rRight.Seconds
107 && i_rLeft.HundredthSeconds == i_rRight.HundredthSeconds;
110 // STATIC DATA -----------------------------------------------------------
111 TYPEINIT1_AUTOFACTORY(SfxDocumentInfoItem, SfxStringItem);
113 const sal_uInt16 HI_NAME = 1;
114 const sal_uInt16 HI_TYPE = 2;
115 const sal_uInt16 HI_VALUE = 3;
116 const sal_uInt16 HI_ACTION = 4;
118 static const char DOCUMENT_SIGNATURE_MENU_CMD[] = "Signature";
120 //------------------------------------------------------------------------
121 String CreateSizeText( sal_uIntPtr nSize, sal_Bool bExtraBytes = sal_True, sal_Bool bSmartExtraBytes = sal_False );
122 String CreateSizeText( sal_uIntPtr nSize, sal_Bool bExtraBytes, sal_Bool bSmartExtraBytes )
124 String aUnitStr = ' ';
125 aUnitStr += String( SfxResId(STR_BYTES) );
126 sal_uIntPtr nSize1 = nSize;
127 sal_uIntPtr nSize2 = nSize1;
128 sal_uIntPtr nMega = 1024 * 1024;
129 sal_uIntPtr nGiga = nMega * 1024;
130 double fSize = nSize;
131 int nDec = 0;
132 sal_Bool bGB = sal_False;
134 if ( nSize1 >= 10000 && nSize1 < nMega )
136 nSize1 /= 1024;
137 aUnitStr = ' ';
138 aUnitStr += String( SfxResId(STR_KB) );
139 fSize /= 1024;
140 nDec = 0;
142 else if ( nSize1 >= nMega && nSize1 < nGiga )
144 nSize1 /= nMega;
145 aUnitStr = ' ';
146 aUnitStr += String( SfxResId(STR_MB) );
147 fSize /= nMega;
148 nDec = 2;
150 else if ( nSize1 >= nGiga )
152 nSize1 /= nGiga;
153 aUnitStr = ' ';
154 aUnitStr += String( SfxResId(STR_GB) );
155 bGB = sal_True;
156 fSize /= nGiga;
157 nDec = 3;
159 const SvtSysLocale aSysLocale;
160 const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData();
161 String aSizeStr( rLocaleWrapper.getNum( nSize1, 0 ) );
162 aSizeStr += aUnitStr;
163 if ( bExtraBytes && ( nSize1 < nSize2 ) )
165 aSizeStr = ::rtl::math::doubleToUString( fSize,
166 rtl_math_StringFormat_F, nDec,
167 rLocaleWrapper.getNumDecimalSep().GetChar(0) );
168 aSizeStr += aUnitStr;
170 aSizeStr += DEFINE_CONST_UNICODE(" (");
171 aSizeStr += rLocaleWrapper.getNum( nSize2, 0 );
172 aSizeStr += ' ';
173 aSizeStr += String( SfxResId(STR_BYTES) );
174 aSizeStr += ')';
176 else if ( bGB && bSmartExtraBytes )
178 nSize1 = nSize / nMega;
179 aSizeStr = DEFINE_CONST_UNICODE(" (");
180 aSizeStr += rLocaleWrapper.getNum( nSize1, 0 );
181 aSizeStr += aUnitStr;
182 aSizeStr += ')';
184 return aSizeStr;
187 String ConvertDateTime_Impl( const String& rName,
188 const util::DateTime& uDT, const LocaleDataWrapper& rWrapper )
190 Date aD(uDT.Day, uDT.Month, uDT.Year);
191 Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
192 const String pDelim ( DEFINE_CONST_UNICODE( ", "));
193 String aStr( rWrapper.getDate( aD ) );
194 aStr += pDelim;
195 aStr += rWrapper.getTime( aT, sal_True, sal_False );
196 String aAuthor = rName;
197 aAuthor.EraseLeadingChars();
198 if ( aAuthor.Len() )
200 aStr += pDelim;
201 aStr += aAuthor;
203 return aStr;
206 //------------------------------------------------------------------------
208 SfxDocumentInfoItem::SfxDocumentInfoItem()
209 : SfxStringItem()
210 , m_AutoloadDelay(0)
211 , m_AutoloadURL()
212 , m_isAutoloadEnabled(sal_False)
213 , m_DefaultTarget()
214 , m_TemplateName()
215 , m_Author()
216 , m_CreationDate()
217 , m_ModifiedBy()
218 , m_ModificationDate()
219 , m_PrintedBy()
220 , m_PrintDate()
221 , m_EditingCycles(0)
222 , m_EditingDuration(0)
223 , m_Description()
224 , m_Keywords()
225 , m_Subject()
226 , m_Title()
227 , m_bHasTemplate( sal_True )
228 , m_bDeleteUserData( sal_False )
229 , m_bUseUserData( sal_True )
233 //------------------------------------------------------------------------
235 SfxDocumentInfoItem::SfxDocumentInfoItem( const String& rFile,
236 const uno::Reference<document::XDocumentProperties>& i_xDocProps,
237 sal_Bool bIs )
238 : SfxStringItem( SID_DOCINFO, rFile )
239 , m_AutoloadDelay( i_xDocProps->getAutoloadSecs() )
240 , m_AutoloadURL( i_xDocProps->getAutoloadURL() )
241 , m_isAutoloadEnabled( (m_AutoloadDelay > 0) || !m_AutoloadURL.isEmpty() )
242 , m_DefaultTarget( i_xDocProps->getDefaultTarget() )
243 , m_TemplateName( i_xDocProps->getTemplateName() )
244 , m_Author( i_xDocProps->getAuthor() )
245 , m_CreationDate( i_xDocProps->getCreationDate() )
246 , m_ModifiedBy( i_xDocProps->getModifiedBy() )
247 , m_ModificationDate( i_xDocProps->getModificationDate() )
248 , m_PrintedBy( i_xDocProps->getPrintedBy() )
249 , m_PrintDate( i_xDocProps->getPrintDate() )
250 , m_EditingCycles( i_xDocProps->getEditingCycles() )
251 , m_EditingDuration( i_xDocProps->getEditingDuration() )
252 , m_Description( i_xDocProps->getDescription() )
253 , m_Keywords( ::comphelper::string::convertCommaSeparated(
254 i_xDocProps->getKeywords()) )
255 , m_Subject( i_xDocProps->getSubject() )
256 , m_Title( i_xDocProps->getTitle() )
257 , m_bHasTemplate( sal_True )
258 , m_bDeleteUserData( sal_False )
259 , m_bUseUserData( bIs )
263 Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties();
264 if ( xContainer.is() )
266 Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY );
267 const Sequence< beans::Property > lProps = xSet->getPropertySetInfo()->getProperties();
268 const beans::Property* pProps = lProps.getConstArray();
269 sal_Int32 nCount = lProps.getLength();
270 for ( sal_Int32 i = 0; i < nCount; ++i )
272 // "fix" property? => not a custom property => ignore it!
273 if (!(pProps[i].Attributes &
274 ::com::sun::star::beans::PropertyAttribute::REMOVABLE))
276 DBG_ASSERT(false, "non-removable user-defined property?");
277 continue;
280 uno::Any aValue = xSet->getPropertyValue(pProps[i].Name);
281 CustomProperty* pProp = new CustomProperty( pProps[i].Name, aValue );
282 m_aCustomProperties.push_back( pProp );
286 catch ( Exception& ) {}
289 //------------------------------------------------------------------------
291 SfxDocumentInfoItem::SfxDocumentInfoItem( const SfxDocumentInfoItem& rItem )
292 : SfxStringItem( rItem )
293 , m_AutoloadDelay( rItem.getAutoloadDelay() )
294 , m_AutoloadURL( rItem.getAutoloadURL() )
295 , m_isAutoloadEnabled( rItem.isAutoloadEnabled() )
296 , m_DefaultTarget( rItem.getDefaultTarget() )
297 , m_TemplateName( rItem.getTemplateName() )
298 , m_Author( rItem.getAuthor() )
299 , m_CreationDate( rItem.getCreationDate() )
300 , m_ModifiedBy( rItem.getModifiedBy() )
301 , m_ModificationDate( rItem.getModificationDate() )
302 , m_PrintedBy( rItem.getPrintedBy() )
303 , m_PrintDate( rItem.getPrintDate() )
304 , m_EditingCycles( rItem.getEditingCycles() )
305 , m_EditingDuration( rItem.getEditingDuration() )
306 , m_Description( rItem.getDescription() )
307 , m_Keywords( rItem.getKeywords() )
308 , m_Subject( rItem.getSubject() )
309 , m_Title( rItem.getTitle() )
310 , m_bHasTemplate( rItem.m_bHasTemplate )
311 , m_bDeleteUserData( rItem.m_bDeleteUserData )
312 , m_bUseUserData( rItem.m_bUseUserData )
314 for ( sal_uInt32 i = 0; i < rItem.m_aCustomProperties.size(); i++ )
316 CustomProperty* pProp = new CustomProperty( rItem.m_aCustomProperties[i]->m_sName,
317 rItem.m_aCustomProperties[i]->m_aValue );
318 m_aCustomProperties.push_back( pProp );
322 //------------------------------------------------------------------------
323 SfxDocumentInfoItem::~SfxDocumentInfoItem()
325 ClearCustomProperties();
328 //------------------------------------------------------------------------
329 SfxPoolItem* SfxDocumentInfoItem::Clone( SfxItemPool * ) const
331 return new SfxDocumentInfoItem( *this );
334 //------------------------------------------------------------------------
335 int SfxDocumentInfoItem::operator==( const SfxPoolItem& rItem) const
337 if (!(rItem.Type() == Type() && SfxStringItem::operator==(rItem)))
338 return false;
339 const SfxDocumentInfoItem& rInfoItem(static_cast<const SfxDocumentInfoItem&>(rItem));
341 return
342 m_AutoloadDelay == rInfoItem.m_AutoloadDelay &&
343 m_AutoloadURL == rInfoItem.m_AutoloadURL &&
344 m_isAutoloadEnabled == rInfoItem.m_isAutoloadEnabled &&
345 m_DefaultTarget == rInfoItem.m_DefaultTarget &&
346 m_Author == rInfoItem.m_Author &&
347 m_CreationDate == rInfoItem.m_CreationDate &&
348 m_ModifiedBy == rInfoItem.m_ModifiedBy &&
349 m_ModificationDate == rInfoItem.m_ModificationDate &&
350 m_PrintedBy == rInfoItem.m_PrintedBy &&
351 m_PrintDate == rInfoItem.m_PrintDate &&
352 m_EditingCycles == rInfoItem.m_EditingCycles &&
353 m_EditingDuration == rInfoItem.m_EditingDuration &&
354 m_Description == rInfoItem.m_Description &&
355 m_Keywords == rInfoItem.m_Keywords &&
356 m_Subject == rInfoItem.m_Subject &&
357 m_Title == rInfoItem.m_Title &&
358 m_aCustomProperties.size() == rInfoItem.m_aCustomProperties.size() &&
359 std::equal(m_aCustomProperties.begin(), m_aCustomProperties.end(),
360 rInfoItem.m_aCustomProperties.begin());
363 //------------------------------------------------------------------------
364 void SfxDocumentInfoItem::resetUserData(const ::rtl::OUString & i_rAuthor)
366 setAuthor(i_rAuthor);
367 DateTime now( DateTime::SYSTEM );
368 setCreationDate( util::DateTime(
369 now.Get100Sec(), now.GetSec(), now.GetMin(), now.GetHour(),
370 now.GetDay(), now.GetMonth(), now.GetYear() ) );
371 setModifiedBy(::rtl::OUString());
372 setPrintedBy(::rtl::OUString());
373 setModificationDate(util::DateTime());
374 setPrintDate(util::DateTime());
375 setEditingDuration(0);
376 setEditingCycles(1);
379 //------------------------------------------------------------------------
380 void SfxDocumentInfoItem::UpdateDocumentInfo(
381 const uno::Reference<document::XDocumentProperties>& i_xDocProps,
382 bool i_bDoNotUpdateUserDefined) const
384 if (isAutoloadEnabled()) {
385 i_xDocProps->setAutoloadSecs(getAutoloadDelay());
386 i_xDocProps->setAutoloadURL(getAutoloadURL());
387 } else {
388 i_xDocProps->setAutoloadSecs(0);
389 i_xDocProps->setAutoloadURL(::rtl::OUString());
391 i_xDocProps->setDefaultTarget(getDefaultTarget());
392 i_xDocProps->setAuthor(getAuthor());
393 i_xDocProps->setCreationDate(getCreationDate());
394 i_xDocProps->setModifiedBy(getModifiedBy());
395 i_xDocProps->setModificationDate(getModificationDate());
396 i_xDocProps->setPrintedBy(getPrintedBy());
397 i_xDocProps->setPrintDate(getPrintDate());
398 i_xDocProps->setEditingCycles(getEditingCycles());
399 i_xDocProps->setEditingDuration(getEditingDuration());
400 i_xDocProps->setDescription(getDescription());
401 i_xDocProps->setKeywords(
402 ::comphelper::string::convertCommaSeparated(getKeywords()));
403 i_xDocProps->setSubject(getSubject());
404 i_xDocProps->setTitle(getTitle());
406 // this is necessary in case of replaying a recorded macro:
407 // in this case, the macro may contain the 4 old user-defined DocumentInfo
408 // fields, but not any of the DocumentInfo properties;
409 // as a consequence, most of the UserDefined properties of the
410 // DocumentProperties would be summarily deleted here, which does not
411 // seem like a good idea.
412 if (i_bDoNotUpdateUserDefined)
413 return;
417 Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties();
418 Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY );
419 Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
420 const Sequence< beans::Property > lProps = xSetInfo->getProperties();
421 const beans::Property* pProps = lProps.getConstArray();
422 sal_Int32 nCount = lProps.getLength();
423 for ( sal_Int32 j = 0; j < nCount; ++j )
425 if ((pProps[j].Attributes &
426 ::com::sun::star::beans::PropertyAttribute::REMOVABLE))
428 xContainer->removeProperty( pProps[j].Name );
432 for ( sal_uInt32 k = 0; k < m_aCustomProperties.size(); ++k )
436 xContainer->addProperty( m_aCustomProperties[k]->m_sName,
437 beans::PropertyAttribute::REMOVABLE, m_aCustomProperties[k]->m_aValue );
439 catch ( Exception& )
441 SAL_WARN( "sfx2.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while adding custom properties" );
445 catch ( Exception& )
447 SAL_WARN( "sfx2.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while removing custom properties" );
451 //------------------------------------------------------------------------
452 sal_Bool SfxDocumentInfoItem::IsDeleteUserData() const
454 return m_bDeleteUserData;
457 void SfxDocumentInfoItem::SetDeleteUserData( sal_Bool bSet )
459 m_bDeleteUserData = bSet;
462 sal_Bool SfxDocumentInfoItem::IsUseUserData() const
464 return m_bUseUserData;
467 void SfxDocumentInfoItem::SetUseUserData( sal_Bool bSet )
469 m_bUseUserData = bSet;
472 std::vector< CustomProperty* > SfxDocumentInfoItem::GetCustomProperties() const
474 std::vector< CustomProperty* > aRet;
475 for ( sal_uInt32 i = 0; i < m_aCustomProperties.size(); i++ )
477 CustomProperty* pProp = new CustomProperty( m_aCustomProperties[i]->m_sName,
478 m_aCustomProperties[i]->m_aValue );
479 aRet.push_back( pProp );
482 return aRet;
485 void SfxDocumentInfoItem::ClearCustomProperties()
487 for ( sal_uInt32 i = 0; i < m_aCustomProperties.size(); i++ )
488 delete m_aCustomProperties[i];
489 m_aCustomProperties.clear();
492 void SfxDocumentInfoItem::AddCustomProperty( const ::rtl::OUString& sName, const Any& rValue )
494 CustomProperty* pProp = new CustomProperty( sName, rValue );
495 m_aCustomProperties.push_back( pProp );
498 bool SfxDocumentInfoItem::QueryValue( Any& rVal, sal_uInt8 nMemberId ) const
500 String aValue;
501 sal_Int32 nValue = 0;
502 sal_Bool bValue = sal_False;
503 sal_Bool bIsInt = sal_False;
504 sal_Bool bIsString = sal_False;
505 nMemberId &= ~CONVERT_TWIPS;
506 switch ( nMemberId )
508 case MID_DOCINFO_USEUSERDATA:
509 bValue = IsUseUserData();
510 break;
511 case MID_DOCINFO_DELETEUSERDATA:
512 bValue = IsDeleteUserData();
513 break;
514 case MID_DOCINFO_AUTOLOADENABLED:
515 bValue = isAutoloadEnabled();
516 break;
517 case MID_DOCINFO_AUTOLOADSECS:
518 bIsInt = sal_True;
519 nValue = getAutoloadDelay();
520 break;
521 case MID_DOCINFO_AUTOLOADURL:
522 bIsString = sal_True;
523 aValue = getAutoloadURL();
524 break;
525 case MID_DOCINFO_DEFAULTTARGET:
526 bIsString = sal_True;
527 aValue = getDefaultTarget();
528 break;
529 case MID_DOCINFO_DESCRIPTION:
530 bIsString = sal_True;
531 aValue = getDescription();
532 break;
533 case MID_DOCINFO_KEYWORDS:
534 bIsString = sal_True;
535 aValue = getKeywords();
536 break;
537 case MID_DOCINFO_SUBJECT:
538 bIsString = sal_True;
539 aValue = getSubject();
540 break;
541 case MID_DOCINFO_TITLE:
542 bIsString = sal_True;
543 aValue = getTitle();
544 break;
545 default:
546 OSL_FAIL("Wrong MemberId!");
547 return sal_False;
550 if ( bIsString )
551 rVal <<= ::rtl::OUString( aValue );
552 else if ( bIsInt )
553 rVal <<= nValue;
554 else
555 rVal <<= bValue;
556 return true;
559 bool SfxDocumentInfoItem::PutValue( const Any& rVal, sal_uInt8 nMemberId )
561 ::rtl::OUString aValue;
562 sal_Int32 nValue=0;
563 sal_Bool bValue = sal_False;
564 bool bRet = false;
565 nMemberId &= ~CONVERT_TWIPS;
566 switch ( nMemberId )
568 case MID_DOCINFO_USEUSERDATA:
569 bRet = (rVal >>= bValue);
570 if ( bRet )
571 SetUseUserData( bValue );
572 break;
573 case MID_DOCINFO_DELETEUSERDATA:
574 // QUESTION: deleting user data was done here; seems to be superfluous!
575 bRet = (rVal >>= bValue);
576 if ( bRet )
577 SetDeleteUserData( bValue );
578 break;
579 case MID_DOCINFO_AUTOLOADENABLED:
580 bRet = (rVal >>= bValue);
581 if ( bRet )
582 setAutoloadEnabled(bValue);
583 break;
584 case MID_DOCINFO_AUTOLOADSECS:
585 bRet = (rVal >>= nValue);
586 if ( bRet )
587 setAutoloadDelay(nValue);
588 break;
589 case MID_DOCINFO_AUTOLOADURL:
590 bRet = (rVal >>= aValue);
591 if ( bRet )
592 setAutoloadURL(aValue);
593 break;
594 case MID_DOCINFO_DEFAULTTARGET:
595 bRet = (rVal >>= aValue);
596 if ( bRet )
597 setDefaultTarget(aValue);
598 break;
599 case MID_DOCINFO_DESCRIPTION:
600 bRet = (rVal >>= aValue);
601 if ( bRet )
602 setDescription(aValue);
603 break;
604 case MID_DOCINFO_KEYWORDS:
605 bRet = (rVal >>= aValue);
606 if ( bRet )
607 setKeywords(aValue);
608 break;
609 case MID_DOCINFO_SUBJECT:
610 bRet = (rVal >>= aValue);
611 if ( bRet )
612 setSubject(aValue);
613 break;
614 case MID_DOCINFO_TITLE:
615 bRet = (rVal >>= aValue);
616 if ( bRet )
617 setTitle(aValue);
618 break;
619 default:
620 OSL_FAIL("Wrong MemberId!");
621 return false;
624 return bRet;
627 //------------------------------------------------------------------------
628 SfxDocumentDescPage::SfxDocumentDescPage( Window * pParent, const SfxItemSet& rItemSet ) :
630 SfxTabPage( pParent, SfxResId( TP_DOCINFODESC ), rItemSet ),
632 aTitleFt ( this, SfxResId( FT_TITLE ) ),
633 aTitleEd ( this, SfxResId( ED_TITLE ) ),
634 aThemaFt ( this, SfxResId( FT_THEMA ) ),
635 aThemaEd ( this, SfxResId( ED_THEMA ) ),
636 aKeywordsFt ( this, SfxResId( FT_KEYWORDS ) ),
637 aKeywordsEd ( this, SfxResId( ED_KEYWORDS ) ),
638 aCommentFt ( this, SfxResId( FT_COMMENT ) ),
639 aCommentEd ( this, SfxResId( ED_COMMENT ) ),
641 pInfoItem ( NULL )
644 FreeResource();
647 //------------------------------------------------------------------------
648 SfxTabPage *SfxDocumentDescPage::Create(Window *pParent, const SfxItemSet &rItemSet)
650 return new SfxDocumentDescPage(pParent, rItemSet);
653 //------------------------------------------------------------------------
654 sal_Bool SfxDocumentDescPage::FillItemSet(SfxItemSet &rSet)
656 // Test whether a change is present
657 const sal_Bool bTitleMod = aTitleEd.IsModified();
658 const sal_Bool bThemeMod = aThemaEd.IsModified();
659 const sal_Bool bKeywordsMod = aKeywordsEd.IsModified();
660 const sal_Bool bCommentMod = aCommentEd.IsModified();
661 if ( !( bTitleMod || bThemeMod || bKeywordsMod || bCommentMod ) )
663 return sal_False;
666 // Generating the output data
667 const SfxPoolItem* pItem = NULL;
668 SfxDocumentInfoItem* pInfo = NULL;
669 SfxTabDialog* pDlg = GetTabDialog();
670 const SfxItemSet* pExSet = NULL;
672 if ( pDlg )
673 pExSet = pDlg->GetExampleSet();
675 if ( pExSet && SFX_ITEM_SET != pExSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
676 pInfo = pInfoItem;
677 else if ( pItem )
678 pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem *)pItem );
680 if ( !pInfo )
682 SAL_WARN( "sfx2.dialog", "SfxDocumentDescPage::FillItemSet(): no item found" );
683 return sal_False;
686 if ( bTitleMod )
688 pInfo->setTitle( aTitleEd.GetText() );
690 if ( bThemeMod )
692 pInfo->setSubject( aThemaEd.GetText() );
694 if ( bKeywordsMod )
696 pInfo->setKeywords( aKeywordsEd.GetText() );
698 if ( bCommentMod )
700 pInfo->setDescription( aCommentEd.GetText() );
702 rSet.Put( SfxDocumentInfoItem( *pInfo ) );
703 if ( pInfo != pInfoItem )
705 delete pInfo;
708 return sal_True;
711 //------------------------------------------------------------------------
712 void SfxDocumentDescPage::Reset(const SfxItemSet &rSet)
714 pInfoItem = &(SfxDocumentInfoItem &)rSet.Get(SID_DOCINFO);
716 aTitleEd.SetText( pInfoItem->getTitle() );
717 aThemaEd.SetText( pInfoItem->getSubject() );
718 aKeywordsEd.SetText( pInfoItem->getKeywords() );
719 aCommentEd.SetText( pInfoItem->getDescription() );
721 SFX_ITEMSET_ARG( &rSet, pROItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
722 if ( pROItem && pROItem->GetValue() )
724 aTitleEd.SetReadOnly( sal_True );
725 aThemaEd.SetReadOnly( sal_True );
726 aKeywordsEd.SetReadOnly( sal_True );
727 aCommentEd.SetReadOnly( sal_True );
731 //------------------------------------------------------------------------
732 namespace
734 String GetDateTimeString( sal_Int32 _nDate, sal_Int32 _nTime )
736 LocaleDataWrapper aWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
738 Date aDate( _nDate );
739 Time aTime( _nTime );
740 String aStr( aWrapper.getDate( aDate ) );
741 aStr.AppendAscii( ", " );
742 aStr += aWrapper.getTime( aTime );
743 return aStr;
746 // copy from xmlsecurity/source/dialog/resourcemanager.cxx
747 String GetContentPart( const String& _rRawString, const String& _rPartId )
749 String s;
751 xub_StrLen nContStart = _rRawString.Search( _rPartId );
752 if ( nContStart != STRING_NOTFOUND )
754 nContStart = nContStart + _rPartId.Len();
755 ++nContStart; // now it's start of content, directly after Id
757 xub_StrLen nContEnd = _rRawString.Search( sal_Unicode( ',' ), nContStart );
759 s = String( _rRawString, nContStart, nContEnd - nContStart );
762 return s;
766 SfxDocumentPage::SfxDocumentPage( Window* pParent, const SfxItemSet& rItemSet ) :
768 SfxTabPage( pParent, SfxResId( TP_DOCINFODOC ), rItemSet ),
770 aBmp1 ( this, SfxResId( BMP_FILE_1 ) ),
771 aNameED ( this, SfxResId( ED_FILE_NAME ) ),
772 aChangePassBtn ( this, SfxResId( BTN_CHANGE_PASS ) ),
774 aLine1FL ( this, SfxResId( FL_FILE_1 ) ),
775 aTypeFT ( this, SfxResId( FT_FILE_TYP ) ),
776 aShowTypeFT ( this, SfxResId( FT_FILE_SHOW_TYP ) ),
777 aReadOnlyCB ( this, SfxResId( CB_FILE_READONLY ) ),
778 aFileFt ( this, SfxResId( FT_FILE ) ),
779 aFileValFt ( this, SfxResId( FT_FILE_VAL ) ),
780 aSizeFT ( this, SfxResId( FT_FILE_SIZE ) ),
781 aShowSizeFT ( this, SfxResId( FT_FILE_SHOW_SIZE ) ),
783 aLine2FL ( this, SfxResId( FL_FILE_2 ) ),
784 aCreateFt ( this, SfxResId( FT_CREATE ) ),
785 aCreateValFt ( this, SfxResId( FT_CREATE_VAL ) ),
786 aChangeFt ( this, SfxResId( FT_CHANGE ) ),
787 aChangeValFt ( this, SfxResId( FT_CHANGE_VAL ) ),
788 aSignedFt ( this, SfxResId( FT_SIGNED ) ),
789 aSignedValFt ( this, SfxResId( FT_SIGNED_VAL ) ),
790 aSignatureBtn ( this, SfxResId( BTN_SIGNATURE ) ),
791 aPrintFt ( this, SfxResId( FT_PRINT ) ),
792 aPrintValFt ( this, SfxResId( FT_PRINT_VAL ) ),
793 aTimeLogFt ( this, SfxResId( FT_TIMELOG ) ),
794 aTimeLogValFt ( this, SfxResId( FT_TIMELOG_VAL ) ),
795 aDocNoFt ( this, SfxResId( FT_DOCNO ) ),
796 aDocNoValFt ( this, SfxResId( FT_DOCNO_VAL ) ),
797 aUseUserDataCB ( this, SfxResId( CB_USE_USERDATA ) ),
798 aDeleteBtn ( this, SfxResId( BTN_DELETE ) ),
800 aLine3FL ( this, SfxResId( FL_FILE_3 ) ),
801 aTemplFt ( this, SfxResId( FT_TEMPL ) ),
802 aTemplValFt ( this, SfxResId( FT_TEMPL_VAL ) ),
804 aUnknownSize ( SfxResId( STR_UNKNOWNSIZE ) ),
805 aMultiSignedStr ( SfxResId( STR_MULTSIGNED ) ),
807 bEnableUseUserData ( sal_False ),
808 bHandleDelete ( sal_False )
811 aNameED.SetAccessibleName( String( SfxResId( EDIT_FILE_NAME ) ) );
812 FreeResource();
813 ImplUpdateSignatures();
814 ImplCheckPasswordState();
815 aChangePassBtn.SetClickHdl( LINK( this, SfxDocumentPage, ChangePassHdl ) );
816 aSignatureBtn.SetClickHdl( LINK( this, SfxDocumentPage, SignatureHdl ) );
817 aDeleteBtn.SetClickHdl( LINK( this, SfxDocumentPage, DeleteHdl ) );
819 // Get the max size needed for the 'Change Password', 'Signature' and 'Delete' buttons
820 // and set their size according to this max size to get perfect aligment
821 long nTxtW = ( aChangePassBtn.GetTextWidth( aChangePassBtn.GetText() ) + IMPL_EXTRA_BUTTON_WIDTH );
822 nTxtW = Max( ( aSignatureBtn.GetTextWidth( aSignatureBtn.GetText() ) + IMPL_EXTRA_BUTTON_WIDTH ), nTxtW);
823 nTxtW = Max( ( aDeleteBtn.GetTextWidth( aDeleteBtn.GetText() ) + IMPL_EXTRA_BUTTON_WIDTH ), nTxtW);
825 // New size and position for the 'Change Password' button
826 Size aNewSize = aChangePassBtn.GetSizePixel();
827 long nDelta = nTxtW - aNewSize.Width();
828 aNewSize.Width() = nTxtW;
829 aChangePassBtn.SetSizePixel( aNewSize );
830 Point aNewPos = aChangePassBtn.GetPosPixel();
831 aNewPos.X() -= nDelta;
832 aChangePassBtn.SetPosPixel( aNewPos );
834 // Calculate the space between the bmp image and the 'Change password' button
835 nDelta = aNewPos.X() - IMPL_EXTRA_BUTTON_WIDTH / 2 \
836 - ( aBmp1.GetPosPixel().X() + aBmp1.GetSizePixel().Width() );
838 // Reduces the filename field size if space size is not large enough
839 aNewSize = aNameED.GetSizePixel();
840 if ( nDelta - aNewSize.Width() < IMPL_EXTRA_BUTTON_WIDTH )
842 aNewSize.Width() -= IMPL_EXTRA_BUTTON_WIDTH - ( nDelta - aNewSize.Width() );
843 aNameED.SetSizePixel( aNewSize );
846 // Centers the filename field in the space
847 aNewPos = aNameED.GetPosPixel();
848 nDelta -= aNewSize.Width();
849 aNewPos.X() = aBmp1.GetPosPixel().X() + aBmp1.GetSizePixel().Width() + nDelta / 2;
850 aNameED.SetPosPixel( aNewPos );
852 // New size and position for the 'Signature' button
853 aNewSize = aSignatureBtn.GetSizePixel();
854 nDelta = nTxtW - aNewSize.Width();
855 aNewSize.Width() = nTxtW;
856 aSignatureBtn.SetSizePixel( aNewSize );
857 aNewPos = aSignatureBtn.GetPosPixel();
858 aNewPos.X() -= nDelta;
859 aSignatureBtn.SetPosPixel( aNewPos );
861 // New size for the signature field
862 aNewSize = aSignedValFt.GetSizePixel();
863 aNewSize.Width() -= nDelta;
864 aSignedValFt.SetSizePixel( aNewSize );
866 // New size and position for the 'Delete' button
867 aNewSize = aDeleteBtn.GetSizePixel();
868 nDelta = nTxtW - aNewSize.Width();
869 aNewSize.Width() = nTxtW;
870 aDeleteBtn.SetSizePixel( aNewSize );
871 aNewPos = aDeleteBtn.GetPosPixel();
872 aNewPos.X() -= nDelta;
873 aDeleteBtn.SetPosPixel( aNewPos );
875 // [i96288] Check if the document signature command is enabled
876 // on the main list enable/disable the pushbutton accordingly
877 SvtCommandOptions aCmdOptions;
878 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
879 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( DOCUMENT_SIGNATURE_MENU_CMD ) ) ) )
880 aSignatureBtn.Disable();
883 //------------------------------------------------------------------------
885 IMPL_LINK_NOARG(SfxDocumentPage, DeleteHdl)
887 String aName;
888 if ( bEnableUseUserData && aUseUserDataCB.IsChecked() )
889 aName = SvtUserOptions().GetFullName();
890 LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
891 DateTime now( DateTime::SYSTEM );
892 util::DateTime uDT(
893 now.Get100Sec(), now.GetSec(), now.GetMin(), now.GetHour(),
894 now.GetDay(), now.GetMonth(), now.GetYear() );
895 aCreateValFt.SetText( ConvertDateTime_Impl( aName, uDT, aLocaleWrapper ) );
896 XubString aEmpty;
897 aChangeValFt.SetText( aEmpty );
898 aPrintValFt.SetText( aEmpty );
899 const Time aTime( 0 );
900 aTimeLogValFt.SetText( aLocaleWrapper.getDuration( aTime ) );
901 aDocNoValFt.SetText( '1' );
902 bHandleDelete = sal_True;
903 return 0;
906 IMPL_LINK_NOARG(SfxDocumentPage, SignatureHdl)
908 SfxObjectShell* pDoc = SfxObjectShell::Current();
909 if( pDoc )
911 pDoc->SignDocumentContent();
913 ImplUpdateSignatures();
916 return 0;
919 IMPL_LINK_NOARG(SfxDocumentPage, ChangePassHdl)
921 SfxObjectShell* pShell = SfxObjectShell::Current();
924 if (!pShell)
925 break;
926 SfxItemSet* pMedSet = pShell->GetMedium()->GetItemSet();
927 if (!pMedSet)
928 break;
929 const SfxFilter* pFilter = pShell->GetMedium()->GetFilter();
930 if (!pFilter)
931 break;
933 rtl::OUString aDocName;
934 sfx2::RequestPassword(pFilter, aDocName, pMedSet);
935 pShell->SetModified(true);
937 while (false);
938 return 0;
941 void SfxDocumentPage::ImplUpdateSignatures()
943 SfxObjectShell* pDoc = SfxObjectShell::Current();
944 if ( pDoc )
946 SfxMedium* pMedium = pDoc->GetMedium();
947 if ( pMedium && pMedium->GetName().Len() && pMedium->GetStorage().is() )
949 Reference< security::XDocumentDigitalSignatures > xD(
950 comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), uno::UNO_QUERY );
952 if ( xD.is() )
954 String s;
955 Sequence< security::DocumentSignatureInformation > aInfos;
956 aInfos = xD->verifyDocumentContentSignatures( pMedium->GetZipStorageToSign_Impl(),
957 uno::Reference< io::XInputStream >() );
958 if ( aInfos.getLength() > 1 )
959 s = aMultiSignedStr;
960 else if ( aInfos.getLength() == 1 )
962 String aCN_Id( String::CreateFromAscii( "CN" ) );
963 const security::DocumentSignatureInformation& rInfo = aInfos[ 0 ];
964 s = GetDateTimeString( rInfo.SignatureDate, rInfo.SignatureTime );
965 s.AppendAscii( ", " );
966 s += GetContentPart( rInfo.Signer->getSubjectName(), aCN_Id );
968 aSignedValFt.SetText( s );
974 void SfxDocumentPage::ImplCheckPasswordState()
976 SfxObjectShell* pShell = SfxObjectShell::Current();
979 if (!pShell)
980 break;
981 SfxItemSet* pMedSet = pShell->GetMedium()->GetItemSet();
982 if (!pMedSet)
983 break;
984 SFX_ITEMSET_ARG( pMedSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False);
985 uno::Sequence< beans::NamedValue > aEncryptionData;
986 if (pEncryptionDataItem)
987 pEncryptionDataItem->GetValue() >>= aEncryptionData;
988 else
989 break;
991 if (!aEncryptionData.getLength())
992 break;
993 aChangePassBtn.Enable();
994 return;
996 while (false);
997 aChangePassBtn.Disable();
1000 //------------------------------------------------------------------------
1002 SfxTabPage* SfxDocumentPage::Create( Window* pParent, const SfxItemSet& rItemSet )
1004 return new SfxDocumentPage( pParent, rItemSet );
1007 //------------------------------------------------------------------------
1009 void SfxDocumentPage::EnableUseUserData()
1011 bEnableUseUserData = sal_True;
1012 aUseUserDataCB.Show();
1013 aDeleteBtn.Show();
1016 //------------------------------------------------------------------------
1018 sal_Bool SfxDocumentPage::FillItemSet( SfxItemSet& rSet )
1020 sal_Bool bRet = sal_False;
1022 if ( !bHandleDelete && bEnableUseUserData &&
1023 aUseUserDataCB.GetState() != aUseUserDataCB.GetSavedValue() &&
1024 GetTabDialog() && GetTabDialog()->GetExampleSet() )
1026 const SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet();
1027 const SfxPoolItem* pItem;
1029 if ( pExpSet && SFX_ITEM_SET == pExpSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
1031 SfxDocumentInfoItem* pInfoItem = (SfxDocumentInfoItem*)pItem;
1032 sal_Bool bUseData = ( STATE_CHECK == aUseUserDataCB.GetState() );
1033 pInfoItem->SetUseUserData( bUseData );
1034 rSet.Put( SfxDocumentInfoItem( *pInfoItem ) );
1035 bRet = sal_True;
1039 if ( bHandleDelete )
1041 const SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet();
1042 const SfxPoolItem* pItem;
1043 if ( pExpSet && SFX_ITEM_SET == pExpSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
1045 SfxDocumentInfoItem* pInfoItem = (SfxDocumentInfoItem*)pItem;
1046 sal_Bool bUseAuthor = bEnableUseUserData && aUseUserDataCB.IsChecked();
1047 SfxDocumentInfoItem newItem( *pInfoItem );
1048 newItem.resetUserData( bUseAuthor
1049 ? SvtUserOptions().GetFullName()
1050 : ::rtl::OUString() );
1051 pInfoItem->SetUseUserData( STATE_CHECK == aUseUserDataCB.GetState() );
1052 newItem.SetUseUserData( STATE_CHECK == aUseUserDataCB.GetState() );
1054 newItem.SetDeleteUserData( sal_True );
1055 rSet.Put( newItem );
1056 bRet = sal_True;
1060 if ( aNameED.IsModified() && aNameED.GetText().Len() )
1062 rSet.Put( SfxStringItem( ID_FILETP_TITLE, aNameED.GetText() ) );
1063 bRet = sal_True;
1066 if ( /* aReadOnlyCB.IsModified() */ sal_True )
1068 rSet.Put( SfxBoolItem( ID_FILETP_READONLY, aReadOnlyCB.IsChecked() ) );
1069 bRet = sal_True;
1072 return bRet;
1075 //------------------------------------------------------------------------
1077 void SfxDocumentPage::Reset( const SfxItemSet& rSet )
1079 // Determine the document information
1080 const SfxDocumentInfoItem *pInfoItem =
1081 &(const SfxDocumentInfoItem &)rSet.Get(SID_DOCINFO);
1083 // template data
1084 if ( pInfoItem->HasTemplate() )
1085 aTemplValFt.SetText( pInfoItem->getTemplateName() );
1086 else
1088 aTemplFt.Hide();
1089 aTemplValFt.Hide();
1092 // determine file name
1093 String aFile( pInfoItem->GetValue() );
1094 String aFactory( aFile );
1095 if ( aFile.Len() > 2 && aFile.GetChar(0) == '[' )
1097 sal_uInt16 nPos = aFile.Search( ']' );
1098 aFactory = aFile.Copy( 1, nPos-1 );
1099 aFile = aFile.Copy( nPos+1 );
1102 // determine name
1103 String aName;
1104 const SfxPoolItem* pItem = 0;
1105 if ( SFX_ITEM_SET != rSet.GetItemState( ID_FILETP_TITLE, sal_False, &pItem ) )
1107 INetURLObject aURL(aFile);
1108 aName = aURL.GetName( INetURLObject::DECODE_WITH_CHARSET );
1109 if ( !aName.Len() || aURL.GetProtocol() == INET_PROT_PRIVATE )
1110 aName = String( SfxResId( STR_NONAME ) );
1111 aNameED.SetReadOnly( sal_True );
1113 else
1115 DBG_ASSERT( pItem->IsA( TYPE( SfxStringItem ) ), "SfxDocumentPage:<SfxStringItem> expected" );
1116 aName = ( ( SfxStringItem* ) pItem )->GetValue();
1118 aNameED.SetText( aName );
1119 aNameED.ClearModifyFlag();
1121 // determine RO-Flag
1122 if ( SFX_ITEM_UNKNOWN == rSet.GetItemState( ID_FILETP_READONLY, sal_False, &pItem )
1123 || !pItem )
1124 aReadOnlyCB.Hide();
1125 else
1126 aReadOnlyCB.Check( ( (SfxBoolItem*)pItem )->GetValue() );
1128 // determine context symbol
1129 INetURLObject aURL;
1130 aURL.SetSmartProtocol( INET_PROT_FILE );
1131 aURL.SetSmartURL( aFactory);
1132 const String& rMainURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
1133 aBmp1.SetImage( SvFileInformationManager::GetImage( aURL, sal_True ) );
1135 // determine size and type
1136 String aSizeText( aUnknownSize );
1137 if ( aURL.GetProtocol() == INET_PROT_FILE )
1138 aSizeText = CreateSizeText( SfxContentHelper::GetSize( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
1139 aShowSizeFT.SetText( aSizeText );
1141 String aDescription = SvFileInformationManager::GetDescription( INetURLObject(rMainURL) );
1142 if ( aDescription.Len() == 0 )
1143 aDescription = String( SfxResId( STR_SFX_NEWOFFICEDOC ) );
1144 aShowTypeFT.SetText( aDescription );
1146 // determine location
1147 aURL.SetSmartURL( aFile);
1148 if ( aURL.GetProtocol() == INET_PROT_FILE )
1150 INetURLObject aPath( aURL );
1151 aPath.setFinalSlash();
1152 aPath.removeSegment();
1153 // we know it's a folder -> don't need the final slash, but it's better for WB_PATHELLIPSIS
1154 aPath.removeFinalSlash();
1155 String aText( aPath.PathToFileName() ); //! (pb) MaxLen?
1156 aFileValFt.SetText( aText );
1158 else if ( aURL.GetProtocol() != INET_PROT_PRIVATE )
1159 aFileValFt.SetText( aURL.GetPartBeforeLastName() );
1161 // handle access data
1162 sal_Bool m_bUseUserData = pInfoItem->IsUseUserData();
1163 LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
1164 aCreateValFt.SetText( ConvertDateTime_Impl( pInfoItem->getAuthor(),
1165 pInfoItem->getCreationDate(), aLocaleWrapper ) );
1166 util::DateTime aTime( pInfoItem->getModificationDate() );
1167 if ( aTime.Month > 0 )
1168 aChangeValFt.SetText( ConvertDateTime_Impl(
1169 pInfoItem->getModifiedBy(), aTime, aLocaleWrapper ) );
1170 aTime = pInfoItem->getPrintDate();
1171 if ( aTime.Month > 0 )
1172 aPrintValFt.SetText( ConvertDateTime_Impl( pInfoItem->getPrintedBy(),
1173 aTime, aLocaleWrapper ) );
1174 const long nTime = pInfoItem->getEditingDuration();
1175 if ( m_bUseUserData )
1177 const Time aT( nTime/3600, (nTime%3600)/60, nTime%60 );
1178 aTimeLogValFt.SetText( aLocaleWrapper.getDuration( aT ) );
1179 aDocNoValFt.SetText( String::CreateFromInt32(
1180 pInfoItem->getEditingCycles() ) );
1183 TriState eState = (TriState)m_bUseUserData;
1185 if ( STATE_DONTKNOW == eState )
1186 aUseUserDataCB.EnableTriState( sal_True );
1188 aUseUserDataCB.SetState( eState );
1189 aUseUserDataCB.SaveValue();
1190 aUseUserDataCB.Enable( bEnableUseUserData );
1191 bHandleDelete = sal_False;
1192 aDeleteBtn.Enable( bEnableUseUserData );
1195 //------------------------------------------------------------------------
1196 SfxInternetPage::SfxInternetPage( Window* pParent, const SfxItemSet& rItemSet ) :
1198 SfxTabPage( pParent, SfxResId( TP_DOCINFORELOAD ), rItemSet ),
1200 aRBNoAutoUpdate ( this, SfxResId( RB_NOAUTOUPDATE ) ),
1202 aRBReloadUpdate ( this, SfxResId( RB_RELOADUPDATE ) ),
1204 aRBForwardUpdate ( this, SfxResId( RB_FORWARDUPDATE ) ),
1205 aFTEvery ( this, SfxResId( FT_EVERY ) ),
1206 aNFReload ( this, SfxResId( ED_RELOAD ) ),
1207 aFTReloadSeconds ( this, SfxResId( FT_RELOADSECS ) ),
1208 aFTAfter ( this, SfxResId( FT_AFTER ) ),
1209 aNFAfter ( this, SfxResId( ED_FORWARD ) ),
1210 aFTAfterSeconds ( this, SfxResId( FT_FORWARDSECS ) ),
1211 aFTURL ( this, SfxResId( FT_URL ) ),
1212 aEDForwardURL ( this, SfxResId( ED_URL ) ),
1213 aPBBrowseURL ( this, SfxResId( PB_BROWSEURL ) ),
1214 aFTFrame ( this, SfxResId( FT_FRAME ) ),
1215 aCBFrame ( this, SfxResId( CB_FRAME ) ),
1217 aForwardErrorMessg ( SfxResId( STR_FORWARD_ERRMSSG ) ),
1218 pInfoItem ( NULL ),
1219 pFileDlg ( NULL ),
1220 eState ( S_Init )
1223 FreeResource();
1224 pInfoItem = &( SfxDocumentInfoItem& ) rItemSet.Get( SID_DOCINFO );
1225 TargetList aList;
1226 SfxViewFrame* pFrame = SfxViewFrame::Current();
1227 if ( pFrame )
1229 pFrame = pFrame->GetTopViewFrame();
1230 if ( pFrame )
1232 pFrame->GetTargetList( aList );
1234 String* pObj;
1235 for ( size_t nPos = aList.size() ; nPos ; )
1237 pObj = aList[ --nPos ];
1238 aCBFrame.InsertEntry( *pObj );
1239 delete pObj;
1244 aRBNoAutoUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlNoUpdate ) );
1245 aRBReloadUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlReload ) );
1246 aRBForwardUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlForward ) );
1247 aPBBrowseURL.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlBrowseURL ) );
1249 aForwardErrorMessg.SearchAndReplaceAscii( "%PLACEHOLDER%", aRBForwardUpdate.GetText() );
1251 ChangeState( S_NoUpdate );
1254 //------------------------------------------------------------------------
1255 SfxInternetPage::~SfxInternetPage()
1257 delete pFileDlg;
1260 //------------------------------------------------------------------------
1261 void SfxInternetPage::ChangeState( STATE eNewState )
1263 DBG_ASSERT( eNewState != S_Init, "*SfxInternetPage::ChangeState(): new state init is supposed to not work here!" );
1265 if ( eState == eNewState )
1266 return;
1268 switch ( eState )
1270 case S_Init:
1271 EnableNoUpdate( sal_True );
1272 EnableReload( sal_False );
1273 EnableForward( sal_False );
1274 break;
1275 case S_NoUpdate:
1276 EnableNoUpdate( sal_False );
1277 if( eNewState == S_Reload )
1278 EnableReload( sal_True );
1279 else
1280 EnableForward( sal_True );
1281 break;
1282 case S_Reload:
1283 EnableReload( sal_False );
1284 if( eNewState == S_NoUpdate )
1285 EnableNoUpdate( sal_True );
1286 else
1287 EnableForward( sal_True );
1288 break;
1289 case S_Forward:
1290 EnableForward( sal_False );
1291 if( eNewState == S_NoUpdate )
1292 EnableNoUpdate( sal_True );
1293 else
1294 EnableReload( sal_True );
1295 break;
1296 default:
1297 OSL_FAIL( "*SfxInternetPage::SetState(): unhandled state!" );
1300 eState = eNewState;
1303 //------------------------------------------------------------------------
1305 void SfxInternetPage::EnableNoUpdate( sal_Bool bEnable )
1307 if ( bEnable )
1308 aRBNoAutoUpdate.Check();
1311 //------------------------------------------------------------------------
1313 void SfxInternetPage::EnableReload( sal_Bool bEnable )
1315 aFTEvery.Enable( bEnable );
1316 aNFReload.Enable( bEnable );
1317 aFTReloadSeconds.Enable( bEnable );
1319 if ( bEnable )
1320 aRBReloadUpdate.Check();
1323 //------------------------------------------------------------------------
1325 void SfxInternetPage::EnableForward( sal_Bool bEnable )
1327 aFTAfter.Enable( bEnable );
1328 aNFAfter.Enable( bEnable );
1329 aFTAfterSeconds.Enable( bEnable );
1330 aFTURL.Enable( bEnable );
1331 aEDForwardURL.Enable( bEnable );
1332 aPBBrowseURL.Enable( bEnable );
1333 aFTFrame.Enable( bEnable );
1334 aCBFrame.Enable( bEnable );
1336 if ( bEnable )
1337 aRBForwardUpdate.Check();
1340 //------------------------------------------------------------------------
1342 IMPL_LINK( SfxInternetPage, ClickHdlNoUpdate, Control*, pCtrl )
1344 (void)pCtrl; //unused
1345 ChangeState( S_NoUpdate );
1346 return 0;
1349 //------------------------------------------------------------------------
1351 IMPL_LINK( SfxInternetPage, ClickHdlReload, Control*, pCtrl )
1353 (void)pCtrl; //unused
1354 ChangeState( S_Reload );
1355 return 0;
1358 //------------------------------------------------------------------------
1360 IMPL_LINK( SfxInternetPage, ClickHdlForward, Control*, pCtrl )
1362 (void)pCtrl; //unused
1363 ChangeState( S_Forward );
1364 return 0;
1367 //------------------------------------------------------------------------
1369 IMPL_LINK_NOARG(SfxInternetPage, ClickHdlBrowseURL)
1371 if ( !pFileDlg )
1372 pFileDlg = new sfx2::FileDialogHelper(
1373 TemplateDescription::FILEOPEN_SIMPLE, 0 );
1374 pFileDlg->SetDisplayDirectory( aEDForwardURL.GetText() );
1375 pFileDlg->StartExecuteModal( LINK( this, SfxInternetPage, DialogClosedHdl ) );
1377 return 0;
1380 //------------------------------------------------------------------------
1382 IMPL_LINK_NOARG(SfxInternetPage, DialogClosedHdl)
1384 DBG_ASSERT( pFileDlg, "SfxInternetPage::DialogClosedHdl(): no file dialog" );
1386 if ( ERRCODE_NONE == pFileDlg->GetError() )
1387 aEDForwardURL.SetText( pFileDlg->GetPath() );
1389 return 0;
1392 //------------------------------------------------------------------------
1394 sal_Bool SfxInternetPage::FillItemSet( SfxItemSet& rSet )
1396 const SfxPoolItem* pItem = NULL;
1397 SfxDocumentInfoItem* pInfo = NULL;
1398 SfxTabDialog* pDlg = GetTabDialog();
1399 const SfxItemSet* pExSet = NULL;
1401 if ( pDlg )
1402 pExSet = pDlg->GetExampleSet();
1404 if ( pExSet && SFX_ITEM_SET != pExSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
1405 pInfo = pInfoItem;
1406 else if ( pItem )
1407 pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem*)pItem );
1409 if ( !pInfo )
1411 SAL_WARN( "sfx2.dialog", "SfxInternetPage::FillItemSet(): no item found" );
1412 return sal_False;
1415 DBG_ASSERT( eState != S_Init, "*SfxInternetPage::FillItemSet(): state init is not acceptable at this point!" );
1417 sal_Bool bEnableReload = sal_False;
1418 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1419 ::std::auto_ptr< String > aURL( NULL );
1420 ::std::auto_ptr< String > aFrame( NULL );
1421 SAL_WNODEPRECATED_DECLARATIONS_POP
1422 sal_uIntPtr nDelay = 0;
1424 switch ( eState )
1426 case S_NoUpdate:
1427 break;
1428 case S_Reload:
1429 bEnableReload = sal_True;
1430 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1431 aURL = ::std::auto_ptr< String >( new String() );
1432 aFrame = ::std::auto_ptr< String >( new String() );
1433 SAL_WNODEPRECATED_DECLARATIONS_POP
1434 nDelay = static_cast<sal_uIntPtr>(aNFReload.GetValue());
1435 break;
1436 case S_Forward:
1437 DBG_ASSERT( aEDForwardURL.GetText().Len(), "+SfxInternetPage::FillItemSet(): empty URL should be not possible for forward option!" );
1439 bEnableReload = sal_True;
1440 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1441 aURL = ::std::auto_ptr< String >( new String( URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), aEDForwardURL.GetText(), URIHelper::GetMaybeFileHdl(), true ) ) );
1442 aFrame = ::std::auto_ptr< String >( new String( aCBFrame.GetText() ) );
1443 SAL_WNODEPRECATED_DECLARATIONS_POP
1444 nDelay = static_cast<sal_uIntPtr>(aNFAfter.GetValue());
1445 break;
1446 default:
1447 break;
1450 pInfo->setAutoloadEnabled( bEnableReload );
1452 if ( bEnableReload )
1454 pInfo->setAutoloadURL( *aURL.get() );
1455 pInfo->setDefaultTarget( *aFrame.get() );
1456 pInfo->setAutoloadDelay( nDelay );
1459 rSet.Put( *pInfo );
1460 if ( pInfo != pInfoItem )
1461 delete pInfo;
1462 return sal_True;
1465 //------------------------------------------------------------------------
1466 SfxTabPage *SfxInternetPage::Create( Window* pParent, const SfxItemSet& rItemSet )
1468 return new SfxInternetPage(pParent, rItemSet);
1471 //------------------------------------------------------------------------
1472 void SfxInternetPage::Reset( const SfxItemSet& rSet )
1474 pInfoItem = &( SfxDocumentInfoItem& ) rSet.Get( SID_DOCINFO );
1475 SFX_ITEMSET_ARG( &rSet, pURLItem, SfxStringItem, SID_BASEURL, sal_False );
1476 DBG_ASSERT( pURLItem, "No BaseURL provided for InternetTabPage!" );
1477 if ( pURLItem )
1478 aBaseURL = pURLItem->GetValue();
1480 STATE eNewState = S_NoUpdate;
1482 if ( pInfoItem->isAutoloadEnabled() )
1484 const String& rURL = pInfoItem->getAutoloadURL();
1486 if( rURL.Len() )
1488 aNFAfter.SetValue( pInfoItem->getAutoloadDelay() );
1489 aEDForwardURL.SetText( rURL );
1490 aCBFrame.SetText( pInfoItem->getDefaultTarget() );
1491 eNewState = S_Forward;
1493 else
1495 aNFReload.SetValue( pInfoItem->getAutoloadDelay() );
1496 eNewState = S_Reload;
1500 ChangeState( eNewState );
1502 SFX_ITEMSET_ARG( &rSet, pROItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
1503 if ( pROItem && pROItem->GetValue() )
1505 aRBNoAutoUpdate.Disable();
1506 aRBReloadUpdate.Disable();
1507 aRBForwardUpdate.Disable();
1508 aNFReload.Disable();
1509 aNFAfter.Disable();
1510 aEDForwardURL.Disable();
1511 aPBBrowseURL.Disable();
1512 aCBFrame.Disable();
1513 aFTEvery.Disable();
1514 aFTReloadSeconds.Disable();
1515 aFTAfter.Disable();
1516 aFTAfterSeconds.Disable();
1517 aFTURL.Disable();
1518 aFTFrame.Disable();
1522 //------------------------------------------------------------------------
1523 int SfxInternetPage::DeactivatePage( SfxItemSet* /*pSet*/ )
1525 int nRet = LEAVE_PAGE;
1527 if ( eState == S_Forward && !aEDForwardURL.GetText().Len() )
1529 ErrorBox aErrBox( this, WB_OK, aForwardErrorMessg );
1530 aErrBox.Execute();
1532 nRet = KEEP_PAGE;
1535 return nRet;
1538 //------------------------------------------------------------------------
1539 SfxDocumentInfoDialog::SfxDocumentInfoDialog( Window* pParent,
1540 const SfxItemSet& rItemSet ) :
1542 SfxTabDialog( 0, pParent, SfxResId( SID_DOCINFO ), &rItemSet )
1545 FreeResource();
1547 const SfxDocumentInfoItem* pInfoItem =
1548 &(const SfxDocumentInfoItem &)rItemSet.Get( SID_DOCINFO );
1550 #ifdef DBG_UTIL
1551 SFX_ITEMSET_ARG( &rItemSet, pURLItem, SfxStringItem, SID_BASEURL, sal_False );
1552 DBG_ASSERT( pURLItem, "No BaseURL provided for InternetTabPage!" );
1553 #endif
1555 // Determine the Titels
1556 const SfxPoolItem* pItem = 0;
1557 String aTitle( GetText() );
1558 if ( SFX_ITEM_SET !=
1559 rItemSet.GetItemState( SID_EXPLORER_PROPS_START, sal_False, &pItem ) )
1561 // File name
1562 String aFile( pInfoItem->GetValue() );
1564 INetURLObject aURL;
1565 aURL.SetSmartProtocol( INET_PROT_FILE );
1566 aURL.SetSmartURL( aFile);
1567 if ( INET_PROT_PRIV_SOFFICE != aURL.GetProtocol() )
1569 String aLastName( aURL.GetLastName() );
1570 if ( aLastName.Len() )
1571 aTitle += aLastName;
1572 else
1573 aTitle += aFile;
1575 else
1576 aTitle += String( SfxResId( STR_NONAME ) );
1578 else
1580 DBG_ASSERT( pItem->IsA( TYPE( SfxStringItem ) ),
1581 "SfxDocumentInfoDialog:<SfxStringItem> expected" );
1582 aTitle += ( ( SfxStringItem* ) pItem )->GetValue();
1584 SetText( aTitle );
1586 // Property Pages
1587 AddTabPage(TP_DOCINFODESC, SfxDocumentDescPage::Create, 0);
1588 AddTabPage(TP_DOCINFODOC, SfxDocumentPage::Create, 0);
1589 AddTabPage(TP_CUSTOMPROPERTIES, SfxCustomPropertiesPage::Create, 0);
1590 AddTabPage(TP_DOCINFORELOAD, SfxInternetPage::Create, 0);
1591 AddTabPage(TP_DOCINFOSECURITY, SfxSecurityPage::Create, 0);
1594 // -----------------------------------------------------------------------
1596 void SfxDocumentInfoDialog::PageCreated( sal_uInt16 nId, SfxTabPage &rPage )
1598 if ( TP_DOCINFODOC == nId )
1599 ( (SfxDocumentPage&)rPage ).EnableUseUserData();
1602 // class CustomPropertiesYesNoButton -------------------------------------
1604 CustomPropertiesYesNoButton::CustomPropertiesYesNoButton( Window* pParent, const ResId& rResId ) :
1605 Control( pParent, rResId ),
1606 m_aYesButton( this, ResId( RB_PROPERTY_YES, *rResId.GetResMgr() ) ),
1607 m_aNoButton ( this, ResId( RB_PROPERTY_NO, *rResId.GetResMgr() ) )
1609 FreeResource();
1610 Wallpaper aWall( Color( COL_TRANSPARENT ) );
1611 SetBackground( aWall );
1612 SetBorderStyle( WINDOW_BORDER_MONO );
1613 CheckNo();
1614 m_aYesButton.SetBackground( aWall );
1615 m_aNoButton.SetBackground( aWall );
1617 class DurationDialog_Impl : public ModalDialog
1619 FixedLine aDurationFL;
1621 OKButton aOKPB;
1622 CancelButton aCancelPB;
1623 HelpButton aHelpPB;
1625 CheckBox aNegativeCB;
1626 FixedText aYearFT;
1627 NumericField aYearNF;
1628 FixedText aMonthFT;
1629 NumericField aMonthNF;
1630 FixedText aDayFT;
1631 NumericField aDayNF;
1632 FixedText aHourFT;
1633 NumericField aHourNF;
1634 FixedText aMinuteFT;
1635 NumericField aMinuteNF;
1636 FixedText aSecondFT;
1637 NumericField aSecondNF;
1638 FixedText aMSecondFT;
1639 NumericField aMSecondNF;
1641 public:
1643 DurationDialog_Impl( Window* pParent, const util::Duration& rDuration );
1644 ~DurationDialog_Impl();
1646 util::Duration GetDuration() const;
1649 DurationDialog_Impl::DurationDialog_Impl(
1650 Window* pParent, const util::Duration& rDuration)
1651 : ModalDialog( pParent, SfxResId( RID_EDIT_DURATIONS ) ),
1652 aDurationFL(this, SfxResId( FL_DURATION )),
1653 aOKPB( this, SfxResId( PB_OK )),
1654 aCancelPB( this, SfxResId( PB_CANCEL )),
1655 aHelpPB( this, SfxResId( PB_HELP )),
1656 aNegativeCB(this, SfxResId( CB_NEGATIVE )),
1657 aYearFT( this, SfxResId( FT_YEAR )),
1658 aYearNF( this, SfxResId( ED_YEAR )),
1659 aMonthFT( this, SfxResId( FT_MONTH )),
1660 aMonthNF( this, SfxResId( ED_MONTH )),
1661 aDayFT( this, SfxResId( FT_DAY )),
1662 aDayNF( this, SfxResId( ED_DAY )),
1663 aHourFT( this, SfxResId( FT_HOUR )),
1664 aHourNF( this, SfxResId( ED_HOUR )),
1665 aMinuteFT( this, SfxResId( FT_MINUTE )),
1666 aMinuteNF( this, SfxResId( ED_MINUTE )),
1667 aSecondFT( this, SfxResId( FT_SECOND )),
1668 aSecondNF( this, SfxResId( ED_SECOND )),
1669 aMSecondFT( this, SfxResId( FT_MSECOND )),
1670 aMSecondNF( this, SfxResId( ED_MSECOND ))
1672 FreeResource();
1673 aNegativeCB.Check(rDuration.Negative);
1674 aYearNF.SetValue(rDuration.Years);
1675 aMonthNF.SetValue(rDuration.Months );
1676 aDayNF.SetValue(rDuration.Days );
1677 aHourNF.SetValue(rDuration.Hours );
1678 aMinuteNF.SetValue(rDuration.Minutes);
1679 aSecondNF.SetValue(rDuration.Seconds);
1680 aMSecondNF.SetValue(rDuration.MilliSeconds);
1683 DurationDialog_Impl::~DurationDialog_Impl()
1687 util::Duration DurationDialog_Impl::GetDuration() const
1689 util::Duration aRet;
1690 aRet.Negative = aNegativeCB.IsChecked();
1691 aRet.Years = aYearNF.GetValue();
1692 aRet.Months = aMonthNF.GetValue( );
1693 aRet.Days = aDayNF.GetValue( );
1694 aRet.Hours = aHourNF.GetValue( );
1695 aRet.Minutes = aMinuteNF.GetValue();
1696 aRet.Seconds = aSecondNF.GetValue();
1697 aRet.MilliSeconds = aMSecondNF.GetValue();
1698 return aRet;
1701 CustomPropertiesDurationField::CustomPropertiesDurationField( Window* pParent, const ResId& rResId, CustomPropertyLine* pLine ) :
1702 Edit( pParent, rResId ), m_pLine( pLine )
1705 SetDuration( util::Duration(false, 0, 0, 0, 0, 0, 0, 0) );
1708 CustomPropertiesDurationField::~CustomPropertiesDurationField()
1712 void CustomPropertiesDurationField::RequestHelp( const HelpEvent& rHEvt )
1714 if ( rHEvt.GetMode() & HELPMODE_QUICK )
1716 Size aSize( GetSizePixel() );
1717 Rectangle aItemRect( rHEvt.GetMousePosPixel(), aSize );
1718 if (Help::IsBalloonHelpEnabled())
1719 Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), GetText() );
1720 else
1721 Help::ShowQuickHelp( this, aItemRect, GetText(),
1722 QUICKHELP_LEFT|QUICKHELP_VCENTER );
1726 void CustomPropertiesDurationField::SetDuration( const util::Duration& rDuration )
1728 m_aDuration = rDuration;
1729 String sText(rDuration.Negative ? '-' : '+');
1730 sText += m_pLine->m_sDurationFormat;
1731 sText.SearchAndReplace(String::CreateFromAscii( "%1"), String::CreateFromInt32( rDuration.Years ) );
1732 sText.SearchAndReplace(String::CreateFromAscii( "%2"), String::CreateFromInt32( rDuration.Months ) );
1733 sText.SearchAndReplace(String::CreateFromAscii( "%3"), String::CreateFromInt32( rDuration.Days ) );
1734 sText.SearchAndReplace(String::CreateFromAscii( "%4"), String::CreateFromInt32( rDuration.Hours ) );
1735 sText.SearchAndReplace(String::CreateFromAscii( "%5"), String::CreateFromInt32( rDuration.Minutes) );
1736 sText.SearchAndReplace(String::CreateFromAscii( "%6"), String::CreateFromInt32( rDuration.Seconds) );
1737 SetText( sText );
1740 CustomPropertiesEditButton::CustomPropertiesEditButton( Window* pParent, const ResId& rResId, CustomPropertyLine* pLine ) :
1741 PushButton( pParent, rResId ), m_pLine( pLine )
1743 SetClickHdl( LINK( this, CustomPropertiesEditButton, ClickHdl ));
1746 CustomPropertiesEditButton::~CustomPropertiesEditButton()
1750 IMPL_LINK_NOARG(CustomPropertiesEditButton, ClickHdl)
1752 DurationDialog_Impl* pDurationDlg = new DurationDialog_Impl( this, m_pLine->m_aDurationField.GetDuration() );
1753 if ( RET_OK == pDurationDlg->Execute() )
1754 m_pLine->m_aDurationField.SetDuration( pDurationDlg->GetDuration() );
1755 delete pDurationDlg;
1756 return 1;
1758 //--------------------------------------------------------------------------
1759 void CustomPropertiesYesNoButton::Resize()
1761 const long nWidth = GetSizePixel().Width();
1762 const long n3Width = LogicToPixel( Size( 3, 3 ), MAP_APPFONT ).Width();
1763 const long nNewWidth = ( nWidth / 2 ) - n3Width - 2;
1764 Size aSize = m_aYesButton.GetSizePixel();
1765 const long nDelta = aSize.Width() - nNewWidth;
1766 aSize.Width() = nNewWidth;
1767 m_aYesButton.SetSizePixel( aSize );
1768 Point aPos = m_aNoButton.GetPosPixel();
1769 aPos.X() -= nDelta;
1770 m_aNoButton.SetPosSizePixel( aPos, aSize );
1773 // struct CustomPropertyLine ---------------------------------------------
1774 CustomPropertyLine::CustomPropertyLine( Window* pParent ) :
1775 m_aNameBox ( pParent, SfxResId( SFX_CB_PROPERTY_NAME ) ),
1776 m_aTypeBox ( pParent, SfxResId( SFX_LB_PROPERTY_TYPE ), this ),
1777 m_aValueEdit ( pParent, SfxResId( SFX_ED_PROPERTY_VALUE ), this ),
1778 m_aDateField ( pParent, SfxResId( SFX_FLD_DATE), this),
1779 m_aTimeField ( pParent, SfxResId( SFX_FLD_TIME), this),
1780 m_sDurationFormat( SfxResId( SFX_ST_DURATION_FORMAT )),
1781 m_aDurationField( pParent, SfxResId( SFX_FLD_DURATION), this),
1782 m_aEditButton( pParent, SfxResId( SFX_PB_EDIT ), this),
1783 m_aYesNoButton ( pParent, SfxResId( SFX_WIN_PROPERTY_YESNO ) ),
1784 m_aRemoveButton ( pParent, SfxResId( SFX_PB_PROPERTY_REMOVE ), this ),
1785 m_bIsRemoved ( false ),
1786 m_bTypeLostFocus( false )
1789 m_aTimeField.SetExtFormat( EXTTIMEF_24H_LONG );
1790 m_aDateField.SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY );
1792 m_aRemoveButton.SetModeImage( SfxResId( SFX_IMG_PROPERTY_REMOVE ) );
1795 void CustomPropertyLine::SetRemoved()
1797 DBG_ASSERT( !m_bIsRemoved, "CustomPropertyLine::SetRemoved(): line already removed" );
1798 m_bIsRemoved = true;
1799 m_aNameBox.Hide();
1800 m_aTypeBox.Hide();
1801 m_aValueEdit.Hide();
1802 m_aDateField.Hide();
1803 m_aTimeField.Hide();
1804 m_aDurationField.Hide();
1805 m_aEditButton.Hide();
1806 m_aYesNoButton.Hide();
1807 m_aRemoveButton.Hide();
1810 // class CustomPropertiesWindow ------------------------------------------
1811 CustomPropertiesWindow::CustomPropertiesWindow( Window* pParent, const ResId& rResId ) :
1813 Window( pParent, rResId ),
1814 m_aNameBox ( this, SfxResId( SFX_CB_PROPERTY_NAME ) ),
1815 m_aTypeBox ( this, SfxResId( SFX_LB_PROPERTY_TYPE ) ),
1816 m_aValueEdit ( this, SfxResId( SFX_ED_PROPERTY_VALUE ) ),
1817 m_aDateField ( this, SfxResId( SFX_FLD_DATE) ),
1818 m_aTimeField ( this, SfxResId( SFX_FLD_TIME) ),
1819 m_aDurationField( this, SfxResId( SFX_FLD_DURATION) ),
1820 m_aEditButton( this, SfxResId( SFX_PB_EDIT )),
1821 m_aYesNoButton ( this, SfxResId( SFX_WIN_PROPERTY_YESNO ) ),
1822 m_aRemoveButton ( this, SfxResId( SFX_PB_PROPERTY_REMOVE ) ),
1823 m_nScrollPos (0),
1824 m_aNumberFormatter( ::comphelper::getProcessServiceFactory(),
1825 Application::GetSettings().GetLanguage() )
1828 m_aEditLoseFocusTimer.SetTimeout( 300 );
1829 m_aEditLoseFocusTimer.SetTimeoutHdl( LINK( this, CustomPropertiesWindow, EditTimeoutHdl ) );
1830 m_aBoxLoseFocusTimer.SetTimeout( 300 );
1831 m_aBoxLoseFocusTimer.SetTimeoutHdl( LINK( this, CustomPropertiesWindow, BoxTimeoutHdl ) );
1833 ResMgr* pResMgr = rResId.GetResMgr();
1834 m_aNameBox.SetAccessibleName( String( ResId( STR_HEADER_NAME, *pResMgr ) ) );
1835 m_aTypeBox.SetAccessibleName( String( ResId( STR_HEADER_TYPE, *pResMgr ) ) );
1836 m_aValueEdit.SetAccessibleName( String( ResId( STR_HEADER_VALUE, *pResMgr ) ) );
1839 CustomPropertiesWindow::~CustomPropertiesWindow()
1841 m_aEditLoseFocusTimer.Stop();
1842 m_aBoxLoseFocusTimer.Stop();
1843 ClearAllLines();
1846 IMPL_LINK( CustomPropertiesWindow, TypeHdl, CustomPropertiesTypeBox*, pBox )
1848 sal_Int64 nType = sal_Int64( (long)pBox->GetEntryData( pBox->GetSelectEntryPos() ) );
1849 CustomPropertyLine* pLine = pBox->GetLine();
1850 pLine->m_aValueEdit.Show( (CUSTOM_TYPE_TEXT == nType) || (CUSTOM_TYPE_NUMBER == nType) );
1851 pLine->m_aDateField.Show( (CUSTOM_TYPE_DATE == nType) || (CUSTOM_TYPE_DATETIME == nType) );
1852 pLine->m_aTimeField.Show( CUSTOM_TYPE_DATETIME == nType );
1853 pLine->m_aDurationField.Show( CUSTOM_TYPE_DURATION == nType );
1854 pLine->m_aEditButton.Show( CUSTOM_TYPE_DURATION == nType );
1855 pLine->m_aYesNoButton.Show( CUSTOM_TYPE_BOOLEAN == nType );
1856 //adjust positions of date and time controls
1857 if ( nType == CUSTOM_TYPE_DATE )
1858 pLine->m_aDateField.SetPosSizePixel(pLine->m_aValueEdit.GetPosPixel(), pLine->m_aValueEdit.GetSizePixel());
1859 else if ( nType == CUSTOM_TYPE_DATETIME)
1861 pLine->m_aDateField.SetPosSizePixel( pLine->m_aDatePos, pLine->m_aDateTimeSize );
1862 pLine->m_aTimeField.SetPosSizePixel(pLine->m_aTimePos, pLine->m_aDateTimeSize );
1865 return 0;
1868 IMPL_LINK( CustomPropertiesWindow, RemoveHdl, CustomPropertiesRemoveButton*, pButton )
1870 CustomPropertyLine* pLine = pButton->GetLine();
1871 std::vector< CustomPropertyLine* >::iterator pFound =
1872 std::find( m_aCustomPropertiesLines.begin(), m_aCustomPropertiesLines.end(), pLine );
1873 if ( pFound != m_aCustomPropertiesLines.end() )
1875 pLine = *pFound;
1876 pLine->SetRemoved();
1877 std::vector< CustomPropertyLine* >::iterator pIter = pFound + 1;
1878 const long nDelta = GetLineHeight();
1879 for ( ; pIter != m_aCustomPropertiesLines.end(); ++pIter )
1881 pLine = *pIter;
1882 if ( pLine->m_bIsRemoved )
1883 continue;
1885 Window* pWindows[] = { &pLine->m_aNameBox, &pLine->m_aTypeBox, &pLine->m_aValueEdit,
1886 &pLine->m_aDateField, &pLine->m_aTimeField,
1887 &pLine->m_aDurationField, &pLine->m_aEditButton,
1888 &pLine->m_aYesNoButton, &pLine->m_aRemoveButton, NULL };
1889 Window** pCurrent = pWindows;
1890 while ( *pCurrent )
1892 Point aPos = (*pCurrent)->GetPosPixel();
1893 aPos.Y() -= nDelta;
1894 (*pCurrent)->SetPosPixel( aPos );
1895 pCurrent++;
1900 m_aRemovedHdl.Call(0);
1901 return 0;
1904 IMPL_LINK( CustomPropertiesWindow, EditLoseFocusHdl, CustomPropertiesEdit*, pEdit )
1906 if ( pEdit )
1908 CustomPropertyLine* pLine = pEdit->GetLine();
1909 if ( !pLine->m_bTypeLostFocus )
1911 m_pCurrentLine = pLine;
1912 m_aEditLoseFocusTimer.Start();
1914 else
1915 pLine->m_bTypeLostFocus = false;
1917 return 0;
1920 IMPL_LINK( CustomPropertiesWindow, BoxLoseFocusHdl, CustomPropertiesTypeBox*, pBox )
1922 if ( pBox )
1924 m_pCurrentLine = pBox->GetLine();
1925 m_aBoxLoseFocusTimer.Start();
1928 return 0;
1931 IMPL_LINK_NOARG(CustomPropertiesWindow, EditTimeoutHdl)
1933 ValidateLine( m_pCurrentLine, false );
1934 return 0;
1937 IMPL_LINK_NOARG(CustomPropertiesWindow, BoxTimeoutHdl)
1939 ValidateLine( m_pCurrentLine, true );
1940 return 0;
1943 bool CustomPropertiesWindow::IsLineValid( CustomPropertyLine* pLine ) const
1945 bool bIsValid = true;
1946 pLine->m_bTypeLostFocus = false;
1947 sal_Int64 nType = sal_Int64(
1948 (long)pLine->m_aTypeBox.GetEntryData( pLine->m_aTypeBox.GetSelectEntryPos() ) );
1949 String sValue = pLine->m_aValueEdit.GetText();
1950 if ( sValue.Len() == 0 )
1951 return true;
1953 sal_uInt32 nIndex = 0xFFFFFFFF;
1954 if ( CUSTOM_TYPE_NUMBER == nType )
1955 nIndex = const_cast< SvNumberFormatter& >(
1956 m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
1957 else if ( CUSTOM_TYPE_DATE == nType )
1958 nIndex = const_cast< SvNumberFormatter& >(
1959 m_aNumberFormatter).GetFormatIndex( NF_DATE_SYS_DDMMYYYY );
1961 if ( nIndex != 0xFFFFFFFF )
1963 sal_uInt32 nTemp = nIndex;
1964 double fDummy = 0.0;
1965 bIsValid = const_cast< SvNumberFormatter& >(
1966 m_aNumberFormatter ).IsNumberFormat( sValue, nIndex, fDummy ) != sal_False;
1967 if ( bIsValid && nTemp != nIndex )
1968 // sValue is a number but the format doesn't match the index
1969 bIsValid = false;
1972 return bIsValid;
1975 void CustomPropertiesWindow::ValidateLine( CustomPropertyLine* pLine, bool bIsFromTypeBox )
1977 if ( !IsLineValid( pLine ) )
1979 if ( bIsFromTypeBox ) // LoseFocus of TypeBox
1980 pLine->m_bTypeLostFocus = true;
1981 Window* pParent = GetParent()->GetParent();
1982 if ( QueryBox( pParent, SfxResId( SFX_QB_WRONG_TYPE ) ).Execute() == RET_OK )
1983 pLine->m_aTypeBox.SelectEntryPos( m_aTypeBox.GetEntryPos( (void*)CUSTOM_TYPE_TEXT ) );
1984 else
1985 pLine->m_aValueEdit.GrabFocus();
1989 void CustomPropertiesWindow::InitControls( HeaderBar* pHeaderBar, const ScrollBar* pScrollBar )
1991 DBG_ASSERT( pHeaderBar, "CustomPropertiesWindow::InitControls(): invalid headerbar" );
1992 DBG_ASSERT( pScrollBar, "CustomPropertiesWindow::InitControls(): invalid scrollbar" );
1994 m_aNameBox.Hide();
1995 m_aTypeBox.Hide();
1996 m_aValueEdit.Hide();
1997 m_aDateField.Hide();
1998 m_aTimeField.Hide();
1999 m_aDurationField.Hide();
2000 m_aEditButton.Hide();
2001 m_aYesNoButton.Hide();
2002 m_aRemoveButton.Hide();
2004 const long nOffset = 4;
2005 const long nScrollBarWidth = pScrollBar->GetSizePixel().Width();
2006 const long nButtonWidth = m_aRemoveButton.GetSizePixel().Width() + nScrollBarWidth + nOffset;
2007 long nTypeWidth = m_aTypeBox.CalcMinimumSize().Width() + ( 2 * nOffset );
2008 long nFullWidth = pHeaderBar->GetSizePixel().Width();
2009 long nItemWidth = ( nFullWidth - nTypeWidth - nButtonWidth ) / 2;
2010 pHeaderBar->SetItemSize( HI_NAME, nItemWidth );
2011 pHeaderBar->SetItemSize( HI_TYPE, nTypeWidth );
2012 pHeaderBar->SetItemSize( HI_VALUE, nItemWidth );
2013 pHeaderBar->SetItemSize( HI_ACTION, nButtonWidth );
2015 Window* pWindows[] = { &m_aNameBox, &m_aTypeBox, &m_aValueEdit, &m_aRemoveButton, NULL };
2016 Window** pCurrent = pWindows;
2017 sal_uInt16 nPos = 0;
2018 while ( *pCurrent )
2020 Rectangle aRect = pHeaderBar->GetItemRect( pHeaderBar->GetItemId( nPos++ ) );
2021 Size aSize = (*pCurrent)->GetSizePixel();
2022 Point aPos = (*pCurrent)->GetPosPixel();
2023 long nWidth = aRect.getWidth() - nOffset;
2024 if ( *pCurrent == &m_aRemoveButton )
2025 nWidth -= pScrollBar->GetSizePixel().Width();
2026 aSize.Width() = nWidth;
2027 aPos.X() = aRect.getX() + ( nOffset / 2 );
2028 (*pCurrent)->SetPosSizePixel( aPos, aSize );
2030 if ( *pCurrent == &m_aValueEdit )
2032 Point aDurationPos( aPos );
2033 m_aDurationField.SetPosPixel( aDurationPos );
2034 Size aDurationSize(aSize);
2035 aDurationSize.Width() -= (m_aEditButton.GetSizePixel().Width() + 3 );
2036 m_aDurationField.SetSizePixel(aDurationSize);
2037 aDurationPos.X() = aPos.X() - m_aEditButton.GetSizePixel().Width() + aSize.Width();
2038 m_aEditButton.SetPosPixel(aDurationPos);
2039 aSize = m_aYesNoButton.GetSizePixel();
2040 aPos = m_aYesNoButton.GetPosPixel();
2041 aSize.Width() = nWidth;
2042 aPos.X() = aRect.getX() + ( nOffset / 2 );
2043 m_aYesNoButton.SetPosSizePixel( aPos, aSize );
2044 aSize.Width() /= 2;
2045 aSize.Width() -= 2;
2046 m_aDateField.SetPosSizePixel( aPos, aSize );
2047 aPos.X() += aSize.Width() + 4;
2048 m_aTimeField.SetPosSizePixel( aPos, aSize );
2051 pCurrent++;
2054 m_nLineHeight =
2055 ( m_aRemoveButton.GetPosPixel().Y() * 2 ) + m_aRemoveButton.GetSizePixel().Height();
2058 sal_uInt16 CustomPropertiesWindow::GetVisibleLineCount() const
2060 sal_uInt16 nCount = 0;
2061 std::vector< CustomPropertyLine* >::const_iterator pIter;
2062 for ( pIter = m_aCustomPropertiesLines.begin();
2063 pIter != m_aCustomPropertiesLines.end(); ++pIter )
2065 CustomPropertyLine* pLine = *pIter;
2066 if ( !pLine->m_bIsRemoved )
2067 nCount++;
2069 return nCount;
2072 void CustomPropertiesWindow::AddLine( const ::rtl::OUString& sName, Any& rAny )
2074 CustomPropertyLine* pNewLine = new CustomPropertyLine( this );
2075 pNewLine->m_aTypeBox.SetSelectHdl( LINK( this, CustomPropertiesWindow, TypeHdl ) );
2076 pNewLine->m_aRemoveButton.SetClickHdl( LINK( this, CustomPropertiesWindow, RemoveHdl ) );
2077 pNewLine->m_aValueEdit.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, EditLoseFocusHdl ) );
2078 //add lose focus handlers of date/time fields
2080 pNewLine->m_aTypeBox.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, BoxLoseFocusHdl ) );
2082 pNewLine->m_aNameBox.SetAccessibleName(m_aNameBox.GetAccessibleName());
2083 pNewLine->m_aTypeBox.SetAccessibleName(m_aTypeBox.GetAccessibleName());
2084 pNewLine->m_aValueEdit.SetAccessibleName(m_aValueEdit.GetAccessibleName());
2086 long nPos = GetVisibleLineCount() * GetLineHeight();
2087 m_aCustomPropertiesLines.push_back( pNewLine );
2088 Window* pWindows[] = { &m_aNameBox, &m_aTypeBox, &m_aValueEdit,
2089 &m_aDateField, &m_aTimeField,
2090 &m_aDurationField, &m_aEditButton,
2091 &m_aYesNoButton, &m_aRemoveButton, NULL };
2092 Window* pNewWindows[] =
2093 { &pNewLine->m_aNameBox, &pNewLine->m_aTypeBox, &pNewLine->m_aValueEdit,
2094 &pNewLine->m_aDateField, &pNewLine->m_aTimeField,
2095 &pNewLine->m_aDurationField, &pNewLine->m_aEditButton,
2096 &pNewLine->m_aYesNoButton, &pNewLine->m_aRemoveButton, NULL };
2097 Window** pCurrent = pWindows;
2098 Window** pNewCurrent = pNewWindows;
2099 while ( *pCurrent )
2101 Size aSize = (*pCurrent)->GetSizePixel();
2102 Point aPos = (*pCurrent)->GetPosPixel();
2103 aPos.Y() += nPos;
2104 aPos.Y() += m_nScrollPos;
2105 (*pNewCurrent)->SetPosSizePixel( aPos, aSize );
2106 (*pNewCurrent)->Show();
2107 pCurrent++;
2108 pNewCurrent++;
2111 pNewLine->m_aDatePos = pNewLine->m_aDateField.GetPosPixel();
2112 pNewLine->m_aTimePos = pNewLine->m_aTimeField.GetPosPixel();
2113 pNewLine->m_aDateTimeSize = pNewLine->m_aDateField.GetSizePixel();
2115 double nTmpValue = 0;
2116 bool bTmpValue = false;
2117 ::rtl::OUString sTmpValue;
2118 util::DateTime aTmpDateTime;
2119 util::Date aTmpDate;
2120 util::Duration aTmpDuration;
2121 SvtSysLocale aSysLocale;
2122 const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData();
2123 pNewLine->m_aNameBox.SetText( sName );
2124 sal_IntPtr nType = CUSTOM_TYPE_UNKNOWN;
2125 String sValue;
2127 if ( rAny >>= nTmpValue )
2129 sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM );
2130 m_aNumberFormatter.GetInputLineString( nTmpValue, nIndex, sValue );
2131 pNewLine->m_aValueEdit.SetText( sValue );
2132 nType = CUSTOM_TYPE_NUMBER;
2134 else if ( rAny >>= bTmpValue )
2136 sValue = ( bTmpValue ? rLocaleWrapper.getTrueWord() : rLocaleWrapper.getFalseWord() );
2137 nType = CUSTOM_TYPE_BOOLEAN;
2139 else if ( rAny >>= sTmpValue )
2141 pNewLine->m_aValueEdit.SetText( sTmpValue );
2142 nType = CUSTOM_TYPE_TEXT;
2144 else if ( rAny >>= aTmpDate )
2146 nType = CUSTOM_TYPE_DATE;
2147 pNewLine->m_aDateField.SetDate( Date( aTmpDate.Day, aTmpDate.Month, aTmpDate.Year ) );
2150 else if ( rAny >>= aTmpDuration )
2152 nType = CUSTOM_TYPE_DURATION;
2153 pNewLine->m_aDurationField.SetDuration( aTmpDuration );
2155 else if ( rAny >>= aTmpDateTime )
2157 pNewLine->m_aDateField.SetDate( Date( aTmpDateTime.Day, aTmpDateTime.Month, aTmpDateTime.Year ) );
2158 pNewLine->m_aTimeField.SetTime( Time( aTmpDateTime.Hours, aTmpDateTime.Minutes, aTmpDateTime.Seconds, aTmpDateTime.HundredthSeconds ) );
2160 nType = CUSTOM_TYPE_DATETIME;
2163 if ( nType != CUSTOM_TYPE_UNKNOWN )
2165 if ( CUSTOM_TYPE_BOOLEAN == nType )
2167 if ( bTmpValue )
2168 pNewLine->m_aYesNoButton.CheckYes();
2169 else
2170 pNewLine->m_aYesNoButton.CheckNo();
2172 pNewLine->m_aTypeBox.SelectEntryPos( m_aTypeBox.GetEntryPos( (void*)nType ) );
2175 TypeHdl( &pNewLine->m_aTypeBox );
2176 pNewLine->m_aNameBox.GrabFocus();
2179 bool CustomPropertiesWindow::AreAllLinesValid() const
2181 bool bRet = true;
2182 std::vector< CustomPropertyLine* >::const_iterator pIter;
2183 for ( pIter = m_aCustomPropertiesLines.begin();
2184 pIter != m_aCustomPropertiesLines.end(); ++pIter )
2186 CustomPropertyLine* pLine = *pIter;
2187 if ( !IsLineValid( pLine ) )
2189 bRet = false;
2190 break;
2194 return bRet;
2197 void CustomPropertiesWindow::ClearAllLines()
2199 std::vector< CustomPropertyLine* >::iterator pIter;
2200 for ( pIter = m_aCustomPropertiesLines.begin();
2201 pIter != m_aCustomPropertiesLines.end(); ++pIter )
2203 CustomPropertyLine* pLine = *pIter;
2204 pLine->SetRemoved();
2205 delete pLine;
2207 m_aCustomPropertiesLines.clear();
2208 m_nScrollPos = 0;
2211 void CustomPropertiesWindow::DoScroll( sal_Int32 nNewPos )
2213 m_nScrollPos += nNewPos;
2214 std::vector< CustomPropertyLine* >::iterator pIter;
2215 for ( pIter = m_aCustomPropertiesLines.begin();
2216 pIter != m_aCustomPropertiesLines.end(); ++pIter )
2218 CustomPropertyLine* pLine = *pIter;
2219 if ( pLine->m_bIsRemoved )
2220 continue;
2222 Window* pWindows[] = { &pLine->m_aNameBox, &pLine->m_aTypeBox, &pLine->m_aValueEdit, &pLine->m_aDateField, &pLine->m_aTimeField,
2223 &pLine->m_aDurationField, &pLine->m_aEditButton, &pLine->m_aYesNoButton, &pLine->m_aRemoveButton, NULL };
2224 Window** pCurrent = pWindows;
2225 while ( *pCurrent )
2227 Point aPos = (*pCurrent)->GetPosPixel();
2228 aPos.Y() += nNewPos;
2229 (*pCurrent)->SetPosPixel( aPos );
2230 pCurrent++;
2235 Sequence< beans::PropertyValue > CustomPropertiesWindow::GetCustomProperties() const
2237 Sequence< beans::PropertyValue > aPropertiesSeq( m_aCustomPropertiesLines.size() );
2238 sal_Int32 i = 0;
2239 std::vector< CustomPropertyLine* >::const_iterator pIter;
2240 for ( pIter = m_aCustomPropertiesLines.begin();
2241 pIter != m_aCustomPropertiesLines.end(); ++pIter, ++i )
2243 CustomPropertyLine* pLine = *pIter;
2244 if ( pLine->m_bIsRemoved )
2245 continue;
2247 String sPropertyName = pLine->m_aNameBox.GetText();
2248 if ( sPropertyName.Len() > 0 )
2250 aPropertiesSeq[i].Name = sPropertyName;
2251 sal_Int64 nType = sal_Int64(
2252 (long)pLine->m_aTypeBox.GetEntryData( pLine->m_aTypeBox.GetSelectEntryPos() ) );
2253 if ( CUSTOM_TYPE_NUMBER == nType )
2255 double nValue = 0;
2256 sal_uInt32 nIndex = const_cast< SvNumberFormatter& >(
2257 m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
2258 sal_Bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ).
2259 IsNumberFormat( pLine->m_aValueEdit.GetText(), nIndex, nValue );
2260 if ( bIsNum )
2261 aPropertiesSeq[i].Value <<= makeAny( nValue );
2263 else if ( CUSTOM_TYPE_BOOLEAN == nType )
2265 bool bValue = pLine->m_aYesNoButton.IsYesChecked();
2266 aPropertiesSeq[i].Value <<= makeAny( bValue );
2268 else if ( CUSTOM_TYPE_DATETIME == nType )
2270 Date aTmpDate = pLine->m_aDateField.GetDate();
2271 Time aTmpTime = pLine->m_aTimeField.GetTime();
2272 util::DateTime aDateTime(aTmpTime.Get100Sec(), aTmpTime.GetSec(), aTmpTime.GetMin(), aTmpTime.GetHour(),
2273 aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear() );
2274 aPropertiesSeq[i].Value <<= aDateTime;
2276 else if ( CUSTOM_TYPE_DURATION == nType )
2278 aPropertiesSeq[i].Value <<= pLine->m_aDurationField.GetDuration();
2280 else if ( CUSTOM_TYPE_DATE == nType )
2282 Date aTmpDate = pLine->m_aDateField.GetDate();
2283 util::Date aDate(aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear());
2284 aPropertiesSeq[i].Value <<= aDate;
2287 else
2289 ::rtl::OUString sValue( pLine->m_aValueEdit.GetText() );
2290 aPropertiesSeq[i].Value <<= makeAny( sValue );
2295 return aPropertiesSeq;
2298 // class CustomPropertiesControl -----------------------------------------
2299 CustomPropertiesControl::CustomPropertiesControl( Window* pParent, const ResId& rResId ) :
2301 Control( pParent, rResId ),
2303 m_aHeaderBar ( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER ),
2304 m_aPropertiesWin( this, ResId( WIN_PROPERTIES, *rResId.GetResMgr() ) ),
2305 m_aVertScroll ( this, ResId( SB_VERTICAL, *rResId.GetResMgr() ) ),
2307 m_nThumbPos ( 0 )
2310 m_aPropertiesWin.SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
2311 m_aVertScroll.EnableDrag();
2312 m_aVertScroll.Show();
2313 long nWidth = GetOutputSizePixel().Width();
2314 m_aHeaderBar.SetPosSizePixel( Point(), Size( nWidth, m_aVertScroll.GetPosPixel().Y() ) );
2315 const HeaderBarItemBits nHeadBits = HIB_VCENTER | HIB_FIXED | HIB_FIXEDPOS | HIB_LEFT;
2316 nWidth = nWidth / 4;
2317 ResMgr* pResMgr = rResId.GetResMgr();
2318 m_aHeaderBar.InsertItem( HI_NAME, String( ResId( STR_HEADER_NAME, *pResMgr ) ), nWidth, nHeadBits );
2319 m_aHeaderBar.InsertItem( HI_TYPE, String( ResId( STR_HEADER_TYPE, *pResMgr ) ), nWidth, nHeadBits );
2320 m_aHeaderBar.InsertItem( HI_VALUE, String( ResId( STR_HEADER_VALUE, *pResMgr ) ), nWidth, nHeadBits );
2321 m_aHeaderBar.InsertItem( HI_ACTION, String( ResId( STR_HEADER_ACTION, *pResMgr ) ), nWidth, nHeadBits );
2322 m_aHeaderBar.Show();
2324 FreeResource();
2326 XubString sTEST = m_aHeaderBar.GetItemText( HI_NAME );
2328 m_aPropertiesWin.InitControls( &m_aHeaderBar, &m_aVertScroll );
2329 m_aPropertiesWin.SetRemovedHdl( LINK( this, CustomPropertiesControl, RemovedHdl ) );
2331 m_aVertScroll.SetRangeMin( 0 );
2332 sal_Int32 nScrollOffset = m_aPropertiesWin.GetLineHeight();
2333 sal_Int32 nVisibleEntries = m_aPropertiesWin.GetSizePixel().Height() / nScrollOffset;
2334 m_aVertScroll.SetRangeMax( nVisibleEntries );
2335 m_aVertScroll.SetPageSize( nVisibleEntries - 1 );
2336 m_aVertScroll.SetVisibleSize( nVisibleEntries );
2338 Point aPos = m_aHeaderBar.GetPosPixel();
2339 Size aSize = m_aHeaderBar.GetSizePixel();
2340 aPos = m_aVertScroll.GetPosPixel();
2341 aSize = m_aVertScroll.GetSizePixel();
2343 Link aScrollLink = LINK( this, CustomPropertiesControl, ScrollHdl );
2344 m_aVertScroll.SetScrollHdl( aScrollLink );
2347 CustomPropertiesControl::~CustomPropertiesControl()
2351 IMPL_LINK( CustomPropertiesControl, ScrollHdl, ScrollBar*, pScrollBar )
2353 sal_Int32 nOffset = m_aPropertiesWin.GetLineHeight();
2354 nOffset *= ( m_nThumbPos - pScrollBar->GetThumbPos() );
2355 m_nThumbPos = pScrollBar->GetThumbPos();
2356 m_aPropertiesWin.DoScroll( nOffset );
2357 return 0;
2360 IMPL_LINK_NOARG(CustomPropertiesControl, RemovedHdl)
2362 m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 );
2363 if ( m_aPropertiesWin.GetOutputSizePixel().Height() < m_aPropertiesWin.GetVisibleLineCount() * m_aPropertiesWin.GetLineHeight() )
2364 m_aVertScroll.DoScrollAction ( SCROLL_LINEUP );
2365 return 0;
2368 void CustomPropertiesControl::AddLine( const ::rtl::OUString& sName, Any& rAny, bool bInteractive )
2370 m_aPropertiesWin.AddLine( sName, rAny );
2371 m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 );
2372 if ( bInteractive && m_aPropertiesWin.GetOutputSizePixel().Height() < m_aPropertiesWin.GetVisibleLineCount() * m_aPropertiesWin.GetLineHeight() )
2373 m_aVertScroll.DoScroll( m_aPropertiesWin.GetVisibleLineCount() + 1 );
2376 // class SfxCustomPropertiesPage -----------------------------------------
2377 SfxCustomPropertiesPage::SfxCustomPropertiesPage( Window* pParent, const SfxItemSet& rItemSet ) :
2379 SfxTabPage( pParent, SfxResId( TP_CUSTOMPROPERTIES ), rItemSet ),
2380 m_aPropertiesCtrl ( this, SfxResId( CTRL_PROPERTIES ) ),
2381 m_aAddBtn ( this, SfxResId( BTN_ADD ) ),
2382 m_aPropertiesFT ( this, SfxResId( FT_PROPERTIES ) )
2385 FreeResource();
2387 m_aAddBtn.SetClickHdl( LINK( this, SfxCustomPropertiesPage, AddHdl ) );
2390 IMPL_LINK_NOARG(SfxCustomPropertiesPage, AddHdl)
2392 Any aAny;
2393 m_aPropertiesCtrl.AddLine( ::rtl::OUString(), aAny, true );
2394 return 0;
2397 sal_Bool SfxCustomPropertiesPage::FillItemSet( SfxItemSet& rSet )
2399 sal_Bool bModified = sal_False;
2400 const SfxPoolItem* pItem = NULL;
2401 SfxDocumentInfoItem* pInfo = NULL;
2402 bool bMustDelete = false;
2404 if ( GetTabDialog() && GetTabDialog()->GetExampleSet() )
2406 if ( SFX_ITEM_SET !=
2407 GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
2408 pInfo = &( SfxDocumentInfoItem& )rSet.Get( SID_DOCINFO );
2409 else
2411 bMustDelete = true;
2412 pInfo = new SfxDocumentInfoItem( *( const SfxDocumentInfoItem* ) pItem );
2416 if ( pInfo )
2418 pInfo->ClearCustomProperties();
2419 Sequence< beans::PropertyValue > aPropertySeq = m_aPropertiesCtrl.GetCustomProperties();
2420 sal_Int32 i = 0, nCount = aPropertySeq.getLength();
2421 for ( ; i < nCount; ++i )
2423 if ( !aPropertySeq[i].Name.isEmpty() )
2424 pInfo->AddCustomProperty( aPropertySeq[i].Name, aPropertySeq[i].Value );
2428 bModified = sal_True; //!!!
2429 if ( bModified )
2430 rSet.Put( *pInfo );
2431 if ( bMustDelete )
2432 delete pInfo;
2433 return bModified;
2436 void SfxCustomPropertiesPage::Reset( const SfxItemSet& rItemSet )
2438 m_aPropertiesCtrl.ClearAllLines();
2439 const SfxDocumentInfoItem* pInfoItem = &(const SfxDocumentInfoItem &)rItemSet.Get(SID_DOCINFO);
2440 std::vector< CustomProperty* > aCustomProps = pInfoItem->GetCustomProperties();
2441 for ( sal_uInt32 i = 0; i < aCustomProps.size(); i++ )
2443 m_aPropertiesCtrl.AddLine( aCustomProps[i]->m_sName, aCustomProps[i]->m_aValue, false );
2447 int SfxCustomPropertiesPage::DeactivatePage( SfxItemSet* /*pSet*/ )
2449 int nRet = LEAVE_PAGE;
2450 if ( !m_aPropertiesCtrl.AreAllLinesValid() )
2451 nRet = KEEP_PAGE;
2452 return nRet;
2455 SfxTabPage* SfxCustomPropertiesPage::Create( Window* pParent, const SfxItemSet& rItemSet )
2457 return new SfxCustomPropertiesPage( pParent, rItemSet );
2460 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */