1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/urlobj.hxx>
21 #include <vcl/msgbox.hxx>
22 #include <svl/eitem.hxx>
23 #include <vcl/svapp.hxx>
24 #include <unotools/localedatawrapper.hxx>
25 #include <unotools/cmdoptions.hxx>
26 #include <comphelper/processfactory.hxx>
27 #include <svl/urihelper.hxx>
28 #include <unotools/useroptions.hxx>
29 #include <svtools/imagemgr.hxx>
30 #include <tools/datetime.hxx>
34 #include <comphelper/string.hxx>
35 #include <com/sun/star/security/DocumentSignatureInformation.hpp>
36 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
37 #include <unotools/syslocale.hxx>
38 #include <rtl/math.hxx>
39 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/beans/XPropertyContainer.hpp>
42 #include <com/sun/star/util/DateTime.hpp>
43 #include <com/sun/star/util/Date.hpp>
44 #include <com/sun/star/util/Time.hpp>
45 #include <com/sun/star/util/Duration.hpp>
46 #include <com/sun/star/document/XDocumentProperties.hpp>
48 #include <vcl/timer.hxx>
49 #include "sfx2/dinfdlg.hxx"
50 #include "sfx2/securitypage.hxx"
51 #include "sfxresid.hxx"
52 #include "dinfedt.hxx"
53 #include <sfx2/frame.hxx>
54 #include <sfx2/viewfrm.hxx>
55 #include <sfx2/request.hxx>
56 #include <sfx2/passwd.hxx>
57 #include <sfx2/filedlghelper.hxx>
59 #include <sfx2/objsh.hxx>
60 #include <sfx2/docfile.hxx>
61 #include <comphelper/storagehelper.hxx>
63 #include "documentfontsdialog.hxx"
64 #include <sfx2/sfx.hrc>
65 #include "dinfdlg.hrc"
66 #include "../appl/app.hrc"
67 #include "sfxlocal.hrc"
69 #include <vcl/help.hxx>
73 using namespace ::com::sun::star
;
74 using namespace ::com::sun::star::lang
;
75 using namespace ::com::sun::star::ui::dialogs
;
76 using namespace ::com::sun::star::uno
;
78 const sal_uInt16 FONT_PAGE_ID
= 99;
83 com::sun::star::uno::Any m_aValue
;
85 CustomProperty( const OUString
& sName
,
86 const com::sun::star::uno::Any
& rValue
) :
87 m_sName( sName
), m_aValue( rValue
) {}
89 inline bool operator==( const CustomProperty
& rProp
)
90 { return m_sName
.equals( rProp
.m_sName
) && m_aValue
== rProp
.m_aValue
; }
94 bool operator==(const util::DateTime
&i_rLeft
, const util::DateTime
&i_rRight
)
96 return i_rLeft
.Year
== i_rRight
.Year
97 && i_rLeft
.Month
== i_rRight
.Month
98 && i_rLeft
.Day
== i_rRight
.Day
99 && i_rLeft
.Hours
== i_rRight
.Hours
100 && i_rLeft
.Minutes
== i_rRight
.Minutes
101 && i_rLeft
.Seconds
== i_rRight
.Seconds
102 && i_rLeft
.NanoSeconds
== i_rRight
.NanoSeconds
103 && i_rLeft
.IsUTC
== i_rRight
.IsUTC
;
106 // STATIC DATA -----------------------------------------------------------
107 TYPEINIT1_AUTOFACTORY(SfxDocumentInfoItem
, SfxStringItem
);
109 const sal_uInt16 HI_NAME
= 1;
110 const sal_uInt16 HI_TYPE
= 2;
111 const sal_uInt16 HI_VALUE
= 3;
112 const sal_uInt16 HI_ACTION
= 4;
114 static const char DOCUMENT_SIGNATURE_MENU_CMD
[] = "Signature";
116 //------------------------------------------------------------------------
119 String
CreateSizeText( sal_Int64 nSize
)
121 String aUnitStr
= OUString(' ');
122 aUnitStr
+= SfxResId(STR_BYTES
).toString();
123 sal_Int64 nSize1
= nSize
;
124 sal_Int64 nSize2
= nSize1
;
125 sal_Int64 nMega
= 1024 * 1024;
126 sal_Int64 nGiga
= nMega
* 1024;
127 double fSize
= nSize
;
130 if ( nSize1
>= 10000 && nSize1
< nMega
)
134 aUnitStr
+= SfxResId(STR_KB
).toString();
138 else if ( nSize1
>= nMega
&& nSize1
< nGiga
)
142 aUnitStr
+= SfxResId(STR_MB
).toString();
146 else if ( nSize1
>= nGiga
)
150 aUnitStr
+= SfxResId(STR_GB
).toString();
154 const SvtSysLocale aSysLocale
;
155 const LocaleDataWrapper
& rLocaleWrapper
= aSysLocale
.GetLocaleData();
156 String
aSizeStr( rLocaleWrapper
.getNum( nSize1
, 0 ) );
157 aSizeStr
+= aUnitStr
;
158 if ( nSize1
< nSize2
)
160 aSizeStr
= ::rtl::math::doubleToUString( fSize
,
161 rtl_math_StringFormat_F
, nDec
,
162 rLocaleWrapper
.getNumDecimalSep()[0] );
163 aSizeStr
+= aUnitStr
;
166 aSizeStr
+= rLocaleWrapper
.getNum( nSize2
, 0 );
168 aSizeStr
+= SfxResId(STR_BYTES
).toString();
174 String
ConvertDateTime_Impl( const String
& rName
,
175 const util::DateTime
& uDT
, const LocaleDataWrapper
& rWrapper
)
177 Date
aD(uDT
.Day
, uDT
.Month
, uDT
.Year
);
178 Time
aT(uDT
.Hours
, uDT
.Minutes
, uDT
.Seconds
, uDT
.NanoSeconds
);
179 const String
pDelim ( ", " );
180 String
aStr( rWrapper
.getDate( aD
) );
182 aStr
+= rWrapper
.getTime( aT
, sal_True
, sal_False
);
183 OUString aAuthor
= comphelper::string::stripStart(rName
, ' ');
184 if (!aAuthor
.isEmpty())
193 //------------------------------------------------------------------------
195 SfxDocumentInfoItem::SfxDocumentInfoItem()
199 , m_isAutoloadEnabled(sal_False
)
205 , m_ModificationDate()
209 , m_EditingDuration(0)
214 , m_bHasTemplate( sal_True
)
215 , m_bDeleteUserData( sal_False
)
216 , m_bUseUserData( sal_True
)
220 //------------------------------------------------------------------------
222 SfxDocumentInfoItem::SfxDocumentInfoItem( const String
& rFile
,
223 const uno::Reference
<document::XDocumentProperties
>& i_xDocProps
,
225 : SfxStringItem( SID_DOCINFO
, rFile
)
226 , m_AutoloadDelay( i_xDocProps
->getAutoloadSecs() )
227 , m_AutoloadURL( i_xDocProps
->getAutoloadURL() )
228 , m_isAutoloadEnabled( (m_AutoloadDelay
> 0) || !m_AutoloadURL
.isEmpty() )
229 , m_DefaultTarget( i_xDocProps
->getDefaultTarget() )
230 , m_TemplateName( i_xDocProps
->getTemplateName() )
231 , m_Author( i_xDocProps
->getAuthor() )
232 , m_CreationDate( i_xDocProps
->getCreationDate() )
233 , m_ModifiedBy( i_xDocProps
->getModifiedBy() )
234 , m_ModificationDate( i_xDocProps
->getModificationDate() )
235 , m_PrintedBy( i_xDocProps
->getPrintedBy() )
236 , m_PrintDate( i_xDocProps
->getPrintDate() )
237 , m_EditingCycles( i_xDocProps
->getEditingCycles() )
238 , m_EditingDuration( i_xDocProps
->getEditingDuration() )
239 , m_Description( i_xDocProps
->getDescription() )
240 , m_Keywords( ::comphelper::string::convertCommaSeparated(
241 i_xDocProps
->getKeywords()) )
242 , m_Subject( i_xDocProps
->getSubject() )
243 , m_Title( i_xDocProps
->getTitle() )
244 , m_bHasTemplate( sal_True
)
245 , m_bDeleteUserData( sal_False
)
246 , m_bUseUserData( bIs
)
250 Reference
< beans::XPropertyContainer
> xContainer
= i_xDocProps
->getUserDefinedProperties();
251 if ( xContainer
.is() )
253 Reference
< beans::XPropertySet
> xSet( xContainer
, UNO_QUERY
);
254 const Sequence
< beans::Property
> lProps
= xSet
->getPropertySetInfo()->getProperties();
255 const beans::Property
* pProps
= lProps
.getConstArray();
256 sal_Int32 nCount
= lProps
.getLength();
257 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
259 // "fix" property? => not a custom property => ignore it!
260 if (!(pProps
[i
].Attributes
&
261 ::com::sun::star::beans::PropertyAttribute::REMOVABLE
))
263 DBG_ASSERT(false, "non-removable user-defined property?");
267 uno::Any aValue
= xSet
->getPropertyValue(pProps
[i
].Name
);
268 CustomProperty
* pProp
= new CustomProperty( pProps
[i
].Name
, aValue
);
269 m_aCustomProperties
.push_back( pProp
);
273 catch ( Exception
& ) {}
276 //------------------------------------------------------------------------
278 SfxDocumentInfoItem::SfxDocumentInfoItem( const SfxDocumentInfoItem
& rItem
)
279 : SfxStringItem( rItem
)
280 , m_AutoloadDelay( rItem
.getAutoloadDelay() )
281 , m_AutoloadURL( rItem
.getAutoloadURL() )
282 , m_isAutoloadEnabled( rItem
.isAutoloadEnabled() )
283 , m_DefaultTarget( rItem
.getDefaultTarget() )
284 , m_TemplateName( rItem
.getTemplateName() )
285 , m_Author( rItem
.getAuthor() )
286 , m_CreationDate( rItem
.getCreationDate() )
287 , m_ModifiedBy( rItem
.getModifiedBy() )
288 , m_ModificationDate( rItem
.getModificationDate() )
289 , m_PrintedBy( rItem
.getPrintedBy() )
290 , m_PrintDate( rItem
.getPrintDate() )
291 , m_EditingCycles( rItem
.getEditingCycles() )
292 , m_EditingDuration( rItem
.getEditingDuration() )
293 , m_Description( rItem
.getDescription() )
294 , m_Keywords( rItem
.getKeywords() )
295 , m_Subject( rItem
.getSubject() )
296 , m_Title( rItem
.getTitle() )
297 , m_bHasTemplate( rItem
.m_bHasTemplate
)
298 , m_bDeleteUserData( rItem
.m_bDeleteUserData
)
299 , m_bUseUserData( rItem
.m_bUseUserData
)
301 for ( sal_uInt32 i
= 0; i
< rItem
.m_aCustomProperties
.size(); i
++ )
303 CustomProperty
* pProp
= new CustomProperty( rItem
.m_aCustomProperties
[i
]->m_sName
,
304 rItem
.m_aCustomProperties
[i
]->m_aValue
);
305 m_aCustomProperties
.push_back( pProp
);
309 //------------------------------------------------------------------------
310 SfxDocumentInfoItem::~SfxDocumentInfoItem()
312 ClearCustomProperties();
315 //------------------------------------------------------------------------
316 SfxPoolItem
* SfxDocumentInfoItem::Clone( SfxItemPool
* ) const
318 return new SfxDocumentInfoItem( *this );
321 //------------------------------------------------------------------------
322 int SfxDocumentInfoItem::operator==( const SfxPoolItem
& rItem
) const
324 if (!(rItem
.Type() == Type() && SfxStringItem::operator==(rItem
)))
326 const SfxDocumentInfoItem
& rInfoItem(static_cast<const SfxDocumentInfoItem
&>(rItem
));
329 m_AutoloadDelay
== rInfoItem
.m_AutoloadDelay
&&
330 m_AutoloadURL
== rInfoItem
.m_AutoloadURL
&&
331 m_isAutoloadEnabled
== rInfoItem
.m_isAutoloadEnabled
&&
332 m_DefaultTarget
== rInfoItem
.m_DefaultTarget
&&
333 m_Author
== rInfoItem
.m_Author
&&
334 m_CreationDate
== rInfoItem
.m_CreationDate
&&
335 m_ModifiedBy
== rInfoItem
.m_ModifiedBy
&&
336 m_ModificationDate
== rInfoItem
.m_ModificationDate
&&
337 m_PrintedBy
== rInfoItem
.m_PrintedBy
&&
338 m_PrintDate
== rInfoItem
.m_PrintDate
&&
339 m_EditingCycles
== rInfoItem
.m_EditingCycles
&&
340 m_EditingDuration
== rInfoItem
.m_EditingDuration
&&
341 m_Description
== rInfoItem
.m_Description
&&
342 m_Keywords
== rInfoItem
.m_Keywords
&&
343 m_Subject
== rInfoItem
.m_Subject
&&
344 m_Title
== rInfoItem
.m_Title
&&
345 m_aCustomProperties
.size() == rInfoItem
.m_aCustomProperties
.size() &&
346 std::equal(m_aCustomProperties
.begin(), m_aCustomProperties
.end(),
347 rInfoItem
.m_aCustomProperties
.begin());
350 //------------------------------------------------------------------------
351 void SfxDocumentInfoItem::resetUserData(const OUString
& i_rAuthor
)
353 setAuthor(i_rAuthor
);
354 DateTime
now( DateTime::SYSTEM
);
355 setCreationDate( util::DateTime(
356 now
.GetNanoSec(), now
.GetSec(), now
.GetMin(), now
.GetHour(),
357 now
.GetDay(), now
.GetMonth(), now
.GetYear(), false) );
358 setModifiedBy(OUString());
359 setPrintedBy(OUString());
360 setModificationDate(util::DateTime());
361 setPrintDate(util::DateTime());
362 setEditingDuration(0);
366 //------------------------------------------------------------------------
367 void SfxDocumentInfoItem::UpdateDocumentInfo(
368 const uno::Reference
<document::XDocumentProperties
>& i_xDocProps
,
369 bool i_bDoNotUpdateUserDefined
) const
371 if (isAutoloadEnabled()) {
372 i_xDocProps
->setAutoloadSecs(getAutoloadDelay());
373 i_xDocProps
->setAutoloadURL(getAutoloadURL());
375 i_xDocProps
->setAutoloadSecs(0);
376 i_xDocProps
->setAutoloadURL(OUString());
378 i_xDocProps
->setDefaultTarget(getDefaultTarget());
379 i_xDocProps
->setAuthor(getAuthor());
380 i_xDocProps
->setCreationDate(getCreationDate());
381 i_xDocProps
->setModifiedBy(getModifiedBy());
382 i_xDocProps
->setModificationDate(getModificationDate());
383 i_xDocProps
->setPrintedBy(getPrintedBy());
384 i_xDocProps
->setPrintDate(getPrintDate());
385 i_xDocProps
->setEditingCycles(getEditingCycles());
386 i_xDocProps
->setEditingDuration(getEditingDuration());
387 i_xDocProps
->setDescription(getDescription());
388 i_xDocProps
->setKeywords(
389 ::comphelper::string::convertCommaSeparated(getKeywords()));
390 i_xDocProps
->setSubject(getSubject());
391 i_xDocProps
->setTitle(getTitle());
393 // this is necessary in case of replaying a recorded macro:
394 // in this case, the macro may contain the 4 old user-defined DocumentInfo
395 // fields, but not any of the DocumentInfo properties;
396 // as a consequence, most of the UserDefined properties of the
397 // DocumentProperties would be summarily deleted here, which does not
398 // seem like a good idea.
399 if (i_bDoNotUpdateUserDefined
)
404 Reference
< beans::XPropertyContainer
> xContainer
= i_xDocProps
->getUserDefinedProperties();
405 Reference
< beans::XPropertySet
> xSet( xContainer
, UNO_QUERY
);
406 Reference
< beans::XPropertySetInfo
> xSetInfo
= xSet
->getPropertySetInfo();
407 const Sequence
< beans::Property
> lProps
= xSetInfo
->getProperties();
408 const beans::Property
* pProps
= lProps
.getConstArray();
409 sal_Int32 nCount
= lProps
.getLength();
410 for ( sal_Int32 j
= 0; j
< nCount
; ++j
)
412 if ((pProps
[j
].Attributes
&
413 ::com::sun::star::beans::PropertyAttribute::REMOVABLE
))
415 xContainer
->removeProperty( pProps
[j
].Name
);
419 for ( sal_uInt32 k
= 0; k
< m_aCustomProperties
.size(); ++k
)
423 xContainer
->addProperty( m_aCustomProperties
[k
]->m_sName
,
424 beans::PropertyAttribute::REMOVABLE
, m_aCustomProperties
[k
]->m_aValue
);
428 SAL_WARN( "sfx2.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while adding custom properties" );
434 SAL_WARN( "sfx2.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while removing custom properties" );
438 //------------------------------------------------------------------------
439 sal_Bool
SfxDocumentInfoItem::IsDeleteUserData() const
441 return m_bDeleteUserData
;
444 void SfxDocumentInfoItem::SetDeleteUserData( sal_Bool bSet
)
446 m_bDeleteUserData
= bSet
;
449 sal_Bool
SfxDocumentInfoItem::IsUseUserData() const
451 return m_bUseUserData
;
454 void SfxDocumentInfoItem::SetUseUserData( sal_Bool bSet
)
456 m_bUseUserData
= bSet
;
459 std::vector
< CustomProperty
* > SfxDocumentInfoItem::GetCustomProperties() const
461 std::vector
< CustomProperty
* > aRet
;
462 for ( sal_uInt32 i
= 0; i
< m_aCustomProperties
.size(); i
++ )
464 CustomProperty
* pProp
= new CustomProperty( m_aCustomProperties
[i
]->m_sName
,
465 m_aCustomProperties
[i
]->m_aValue
);
466 aRet
.push_back( pProp
);
472 void SfxDocumentInfoItem::ClearCustomProperties()
474 for ( sal_uInt32 i
= 0; i
< m_aCustomProperties
.size(); i
++ )
475 delete m_aCustomProperties
[i
];
476 m_aCustomProperties
.clear();
479 void SfxDocumentInfoItem::AddCustomProperty( const OUString
& sName
, const Any
& rValue
)
481 CustomProperty
* pProp
= new CustomProperty( sName
, rValue
);
482 m_aCustomProperties
.push_back( pProp
);
485 bool SfxDocumentInfoItem::QueryValue( Any
& rVal
, sal_uInt8 nMemberId
) const
488 sal_Int32 nValue
= 0;
489 sal_Bool bValue
= sal_False
;
490 sal_Bool bIsInt
= sal_False
;
491 sal_Bool bIsString
= sal_False
;
492 nMemberId
&= ~CONVERT_TWIPS
;
495 case MID_DOCINFO_USEUSERDATA
:
496 bValue
= IsUseUserData();
498 case MID_DOCINFO_DELETEUSERDATA
:
499 bValue
= IsDeleteUserData();
501 case MID_DOCINFO_AUTOLOADENABLED
:
502 bValue
= isAutoloadEnabled();
504 case MID_DOCINFO_AUTOLOADSECS
:
506 nValue
= getAutoloadDelay();
508 case MID_DOCINFO_AUTOLOADURL
:
509 bIsString
= sal_True
;
510 aValue
= getAutoloadURL();
512 case MID_DOCINFO_DEFAULTTARGET
:
513 bIsString
= sal_True
;
514 aValue
= getDefaultTarget();
516 case MID_DOCINFO_DESCRIPTION
:
517 bIsString
= sal_True
;
518 aValue
= getDescription();
520 case MID_DOCINFO_KEYWORDS
:
521 bIsString
= sal_True
;
522 aValue
= getKeywords();
524 case MID_DOCINFO_SUBJECT
:
525 bIsString
= sal_True
;
526 aValue
= getSubject();
528 case MID_DOCINFO_TITLE
:
529 bIsString
= sal_True
;
533 OSL_FAIL("Wrong MemberId!");
538 rVal
<<= OUString( aValue
);
546 bool SfxDocumentInfoItem::PutValue( const Any
& rVal
, sal_uInt8 nMemberId
)
550 sal_Bool bValue
= sal_False
;
552 nMemberId
&= ~CONVERT_TWIPS
;
555 case MID_DOCINFO_USEUSERDATA
:
556 bRet
= (rVal
>>= bValue
);
558 SetUseUserData( bValue
);
560 case MID_DOCINFO_DELETEUSERDATA
:
561 // QUESTION: deleting user data was done here; seems to be superfluous!
562 bRet
= (rVal
>>= bValue
);
564 SetDeleteUserData( bValue
);
566 case MID_DOCINFO_AUTOLOADENABLED
:
567 bRet
= (rVal
>>= bValue
);
569 setAutoloadEnabled(bValue
);
571 case MID_DOCINFO_AUTOLOADSECS
:
572 bRet
= (rVal
>>= nValue
);
574 setAutoloadDelay(nValue
);
576 case MID_DOCINFO_AUTOLOADURL
:
577 bRet
= (rVal
>>= aValue
);
579 setAutoloadURL(aValue
);
581 case MID_DOCINFO_DEFAULTTARGET
:
582 bRet
= (rVal
>>= aValue
);
584 setDefaultTarget(aValue
);
586 case MID_DOCINFO_DESCRIPTION
:
587 bRet
= (rVal
>>= aValue
);
589 setDescription(aValue
);
591 case MID_DOCINFO_KEYWORDS
:
592 bRet
= (rVal
>>= aValue
);
596 case MID_DOCINFO_SUBJECT
:
597 bRet
= (rVal
>>= aValue
);
601 case MID_DOCINFO_TITLE
:
602 bRet
= (rVal
>>= aValue
);
607 OSL_FAIL("Wrong MemberId!");
614 //------------------------------------------------------------------------
615 SfxDocumentDescPage::SfxDocumentDescPage( Window
* pParent
, const SfxItemSet
& rItemSet
)
616 : SfxTabPage(pParent
, "DescriptionInfoPage", "sfx/ui/descriptioninfopage.ui", rItemSet
)
617 , m_pInfoItem ( NULL
)
620 get(m_pTitleEd
, "title");
621 get(m_pThemaEd
, "subject");
622 get(m_pKeywordsEd
, "keywords");
623 get(m_pCommentEd
, "comments");
626 //------------------------------------------------------------------------
627 SfxTabPage
*SfxDocumentDescPage::Create(Window
*pParent
, const SfxItemSet
&rItemSet
)
629 return new SfxDocumentDescPage(pParent
, rItemSet
);
632 //------------------------------------------------------------------------
633 sal_Bool
SfxDocumentDescPage::FillItemSet(SfxItemSet
&rSet
)
635 // Test whether a change is present
636 const sal_Bool bTitleMod
= m_pTitleEd
->IsModified();
637 const sal_Bool bThemeMod
= m_pThemaEd
->IsModified();
638 const sal_Bool bKeywordsMod
= m_pKeywordsEd
->IsModified();
639 const sal_Bool bCommentMod
= m_pCommentEd
->IsModified();
640 if ( !( bTitleMod
|| bThemeMod
|| bKeywordsMod
|| bCommentMod
) )
645 // Generating the output data
646 const SfxPoolItem
* pItem
= NULL
;
647 SfxDocumentInfoItem
* pInfo
= NULL
;
648 SfxTabDialog
* pDlg
= GetTabDialog();
649 const SfxItemSet
* pExSet
= NULL
;
652 pExSet
= pDlg
->GetExampleSet();
654 if ( pExSet
&& SFX_ITEM_SET
!= pExSet
->GetItemState( SID_DOCINFO
, sal_True
, &pItem
) )
657 pInfo
= new SfxDocumentInfoItem( *(const SfxDocumentInfoItem
*)pItem
);
661 SAL_WARN( "sfx2.dialog", "SfxDocumentDescPage::FillItemSet(): no item found" );
667 pInfo
->setTitle( m_pTitleEd
->GetText() );
671 pInfo
->setSubject( m_pThemaEd
->GetText() );
675 pInfo
->setKeywords( m_pKeywordsEd
->GetText() );
679 pInfo
->setDescription( m_pCommentEd
->GetText() );
681 rSet
.Put( SfxDocumentInfoItem( *pInfo
) );
682 if ( pInfo
!= m_pInfoItem
)
690 //------------------------------------------------------------------------
691 void SfxDocumentDescPage::Reset(const SfxItemSet
&rSet
)
693 m_pInfoItem
= &(SfxDocumentInfoItem
&)rSet
.Get(SID_DOCINFO
);
695 m_pTitleEd
->SetText( m_pInfoItem
->getTitle() );
696 m_pThemaEd
->SetText( m_pInfoItem
->getSubject() );
697 m_pKeywordsEd
->SetText( m_pInfoItem
->getKeywords() );
698 m_pCommentEd
->SetText( m_pInfoItem
->getDescription() );
700 SFX_ITEMSET_ARG( &rSet
, pROItem
, SfxBoolItem
, SID_DOC_READONLY
, sal_False
);
701 if ( pROItem
&& pROItem
->GetValue() )
703 m_pTitleEd
->SetReadOnly( sal_True
);
704 m_pThemaEd
->SetReadOnly( sal_True
);
705 m_pKeywordsEd
->SetReadOnly( sal_True
);
706 m_pCommentEd
->SetReadOnly( sal_True
);
710 //------------------------------------------------------------------------
713 String
GetDateTimeString( sal_Int32 _nDate
, sal_Int32 _nTime
)
715 const LocaleDataWrapper
& rWrapper( Application::GetSettings().GetLocaleDataWrapper() );
717 Date
aDate( _nDate
);
718 Time
aTime( _nTime
);
719 String
aStr( rWrapper
.getDate( aDate
) );
720 aStr
.AppendAscii( ", " );
721 aStr
+= rWrapper
.getTime( aTime
);
725 // copy from xmlsecurity/source/dialog/resourcemanager.cxx
726 String
GetContentPart( const String
& _rRawString
, const String
& _rPartId
)
730 xub_StrLen nContStart
= _rRawString
.Search( _rPartId
);
731 if ( nContStart
!= STRING_NOTFOUND
)
733 nContStart
= nContStart
+ _rPartId
.Len();
734 ++nContStart
; // now it's start of content, directly after Id
736 xub_StrLen nContEnd
= _rRawString
.Search( sal_Unicode( ',' ), nContStart
);
738 s
= String( _rRawString
, nContStart
, nContEnd
- nContStart
);
745 SfxDocumentPage::SfxDocumentPage(Window
* pParent
, const SfxItemSet
& rItemSet
)
746 : SfxTabPage(pParent
, "DocumentInfoPage", "sfx/ui/documentinfopage.ui", rItemSet
)
747 , bEnableUseUserData( sal_False
)
748 , bHandleDelete( sal_False
)
751 get(m_pNameED
, "nameed");
752 //FIXME m_pNameED->SetAccessibleName( SfxResId( EDIT_FILE_NAME ).toString() );
753 get(m_pChangePassBtn
, "changepass");
755 get(m_pShowTypeFT
, "showtype");
756 get(m_pReadOnlyCB
, "readonlycb");
757 get(m_pFileValFt
, "showlocation");
758 get(m_pShowSizeFT
, "showsize");
759 m_aUnknownSize
= m_pShowSizeFT
->GetText();
760 m_pShowSizeFT
->SetText(OUString());
762 get(m_pCreateValFt
, "showcreate");
763 get(m_pChangeValFt
, "showmodify");
764 get(m_pSignedValFt
, "showsigned");
765 m_aMultiSignedStr
= m_pSignedValFt
->GetText();
766 m_pSignedValFt
->SetText(OUString());
767 get(m_pSignatureBtn
, "signature");
768 get(m_pPrintValFt
, "showprint");
769 get(m_pTimeLogValFt
, "showedittime");
770 get(m_pDocNoValFt
, "showrevision");
772 get(m_pUseUserDataCB
, "userdatacb");
773 get(m_pDeleteBtn
, "reset");
775 get(m_pTemplFt
, "templateft");
776 get(m_pTemplValFt
, "showtemplate");
778 ImplUpdateSignatures();
779 ImplCheckPasswordState();
780 m_pChangePassBtn
->SetClickHdl( LINK( this, SfxDocumentPage
, ChangePassHdl
) );
781 m_pSignatureBtn
->SetClickHdl( LINK( this, SfxDocumentPage
, SignatureHdl
) );
782 m_pDeleteBtn
->SetClickHdl( LINK( this, SfxDocumentPage
, DeleteHdl
) );
784 // [i96288] Check if the document signature command is enabled
785 // on the main list enable/disable the pushbutton accordingly
786 SvtCommandOptions aCmdOptions
;
787 if ( aCmdOptions
.Lookup( SvtCommandOptions::CMDOPTION_DISABLED
,
788 OUString( RTL_CONSTASCII_USTRINGPARAM( DOCUMENT_SIGNATURE_MENU_CMD
) ) ) )
789 m_pSignatureBtn
->Disable();
792 //------------------------------------------------------------------------
794 IMPL_LINK_NOARG(SfxDocumentPage
, DeleteHdl
)
797 if ( bEnableUseUserData
&& m_pUseUserDataCB
->IsChecked() )
798 aName
= SvtUserOptions().GetFullName();
799 const LocaleDataWrapper
& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
800 DateTime
now( DateTime::SYSTEM
);
802 now
.GetNanoSec(), now
.GetSec(), now
.GetMin(), now
.GetHour(),
803 now
.GetDay(), now
.GetMonth(), now
.GetYear(), false);
804 m_pCreateValFt
->SetText( ConvertDateTime_Impl( aName
, uDT
, rLocaleWrapper
) );
806 m_pChangeValFt
->SetText( aEmpty
);
807 m_pPrintValFt
->SetText( aEmpty
);
808 const Time
aTime( 0 );
809 m_pTimeLogValFt
->SetText( rLocaleWrapper
.getDuration( aTime
) );
810 m_pDocNoValFt
->SetText(OUString('1'));
811 bHandleDelete
= sal_True
;
815 IMPL_LINK_NOARG(SfxDocumentPage
, SignatureHdl
)
817 SfxObjectShell
* pDoc
= SfxObjectShell::Current();
820 pDoc
->SignDocumentContent();
822 ImplUpdateSignatures();
828 IMPL_LINK_NOARG(SfxDocumentPage
, ChangePassHdl
)
830 SfxObjectShell
* pShell
= SfxObjectShell::Current();
835 SfxItemSet
* pMedSet
= pShell
->GetMedium()->GetItemSet();
838 const SfxFilter
* pFilter
= pShell
->GetMedium()->GetFilter();
843 sfx2::RequestPassword(pFilter
, aDocName
, pMedSet
);
844 pShell
->SetModified(true);
850 void SfxDocumentPage::ImplUpdateSignatures()
852 SfxObjectShell
* pDoc
= SfxObjectShell::Current();
855 SfxMedium
* pMedium
= pDoc
->GetMedium();
856 if ( pMedium
&& !pMedium
->GetName().isEmpty() && pMedium
->GetStorage().is() )
858 Reference
< security::XDocumentDigitalSignatures
> xD(
859 security::DocumentDigitalSignatures::createDefault(comphelper::getProcessComponentContext()) );
862 Sequence
< security::DocumentSignatureInformation
> aInfos
;
863 aInfos
= xD
->verifyDocumentContentSignatures( pMedium
->GetZipStorageToSign_Impl(),
864 uno::Reference
< io::XInputStream
>() );
865 if ( aInfos
.getLength() > 1 )
866 s
= m_aMultiSignedStr
;
867 else if ( aInfos
.getLength() == 1 )
869 OUString
aCN_Id("CN");
870 const security::DocumentSignatureInformation
& rInfo
= aInfos
[ 0 ];
871 s
= GetDateTimeString( rInfo
.SignatureDate
, rInfo
.SignatureTime
);
872 s
.AppendAscii( ", " );
873 s
+= GetContentPart( rInfo
.Signer
->getSubjectName(), aCN_Id
);
875 m_pSignedValFt
->SetText( s
);
880 void SfxDocumentPage::ImplCheckPasswordState()
882 SfxObjectShell
* pShell
= SfxObjectShell::Current();
887 SfxItemSet
* pMedSet
= pShell
->GetMedium()->GetItemSet();
890 SFX_ITEMSET_ARG( pMedSet
, pEncryptionDataItem
, SfxUnoAnyItem
, SID_ENCRYPTIONDATA
, sal_False
);
891 uno::Sequence
< beans::NamedValue
> aEncryptionData
;
892 if (pEncryptionDataItem
)
893 pEncryptionDataItem
->GetValue() >>= aEncryptionData
;
897 if (!aEncryptionData
.getLength())
899 m_pChangePassBtn
->Enable();
903 m_pChangePassBtn
->Disable();
906 //------------------------------------------------------------------------
908 SfxTabPage
* SfxDocumentPage::Create( Window
* pParent
, const SfxItemSet
& rItemSet
)
910 return new SfxDocumentPage( pParent
, rItemSet
);
913 //------------------------------------------------------------------------
915 void SfxDocumentPage::EnableUseUserData()
917 bEnableUseUserData
= sal_True
;
918 m_pUseUserDataCB
->Show();
919 m_pDeleteBtn
->Show();
922 //------------------------------------------------------------------------
924 sal_Bool
SfxDocumentPage::FillItemSet( SfxItemSet
& rSet
)
926 sal_Bool bRet
= sal_False
;
928 if ( !bHandleDelete
&& bEnableUseUserData
&&
929 m_pUseUserDataCB
->GetState() != m_pUseUserDataCB
->GetSavedValue() &&
930 GetTabDialog() && GetTabDialog()->GetExampleSet() )
932 const SfxItemSet
* pExpSet
= GetTabDialog()->GetExampleSet();
933 const SfxPoolItem
* pItem
;
935 if ( pExpSet
&& SFX_ITEM_SET
== pExpSet
->GetItemState( SID_DOCINFO
, sal_True
, &pItem
) )
937 SfxDocumentInfoItem
* m_pInfoItem
= (SfxDocumentInfoItem
*)pItem
;
938 sal_Bool bUseData
= ( STATE_CHECK
== m_pUseUserDataCB
->GetState() );
939 m_pInfoItem
->SetUseUserData( bUseData
);
940 rSet
.Put( SfxDocumentInfoItem( *m_pInfoItem
) );
947 const SfxItemSet
* pExpSet
= GetTabDialog()->GetExampleSet();
948 const SfxPoolItem
* pItem
;
949 if ( pExpSet
&& SFX_ITEM_SET
== pExpSet
->GetItemState( SID_DOCINFO
, sal_True
, &pItem
) )
951 SfxDocumentInfoItem
* m_pInfoItem
= (SfxDocumentInfoItem
*)pItem
;
952 sal_Bool bUseAuthor
= bEnableUseUserData
&& m_pUseUserDataCB
->IsChecked();
953 SfxDocumentInfoItem
newItem( *m_pInfoItem
);
954 newItem
.resetUserData( bUseAuthor
955 ? SvtUserOptions().GetFullName()
957 m_pInfoItem
->SetUseUserData( STATE_CHECK
== m_pUseUserDataCB
->GetState() );
958 newItem
.SetUseUserData( STATE_CHECK
== m_pUseUserDataCB
->GetState() );
960 newItem
.SetDeleteUserData( sal_True
);
966 if ( m_pNameED
->IsModified() && !m_pNameED
->GetText().isEmpty() )
968 rSet
.Put( SfxStringItem( ID_FILETP_TITLE
, m_pNameED
->GetText() ) );
972 if ( /* m_pReadOnlyCB->IsModified() */ sal_True
)
974 rSet
.Put( SfxBoolItem( ID_FILETP_READONLY
, m_pReadOnlyCB
->IsChecked() ) );
981 //------------------------------------------------------------------------
983 void SfxDocumentPage::Reset( const SfxItemSet
& rSet
)
985 // Determine the document information
986 const SfxDocumentInfoItem
*m_pInfoItem
=
987 &(const SfxDocumentInfoItem
&)rSet
.Get(SID_DOCINFO
);
990 if ( m_pInfoItem
->HasTemplate() )
991 m_pTemplValFt
->SetText( m_pInfoItem
->getTemplateName() );
995 m_pTemplValFt
->Hide();
998 // determine file name
999 String
aFile( m_pInfoItem
->GetValue() );
1000 String
aFactory( aFile
);
1001 if ( aFile
.Len() > 2 && aFile
.GetChar(0) == '[' )
1003 sal_uInt16 nPos
= aFile
.Search( ']' );
1004 aFactory
= aFile
.Copy( 1, nPos
-1 );
1005 aFile
= aFile
.Copy( nPos
+1 );
1010 const SfxPoolItem
* pItem
= 0;
1011 if ( SFX_ITEM_SET
!= rSet
.GetItemState( ID_FILETP_TITLE
, sal_False
, &pItem
) )
1013 INetURLObject
aURL(aFile
);
1014 aName
= aURL
.GetName( INetURLObject::DECODE_WITH_CHARSET
);
1015 if ( !aName
.Len() || aURL
.GetProtocol() == INET_PROT_PRIVATE
)
1016 aName
= SfxResId( STR_NONAME
).toString();
1017 m_pNameED
->SetReadOnly( sal_True
);
1021 DBG_ASSERT( pItem
->IsA( TYPE( SfxStringItem
) ), "SfxDocumentPage:<SfxStringItem> expected" );
1022 aName
= ( ( SfxStringItem
* ) pItem
)->GetValue();
1024 m_pNameED
->SetText( aName
);
1025 m_pNameED
->ClearModifyFlag();
1027 // determine RO-Flag
1028 if ( SFX_ITEM_UNKNOWN
== rSet
.GetItemState( ID_FILETP_READONLY
, sal_False
, &pItem
)
1030 m_pReadOnlyCB
->Hide();
1032 m_pReadOnlyCB
->Check( ( (SfxBoolItem
*)pItem
)->GetValue() );
1034 // determine context symbol
1036 aURL
.SetSmartProtocol( INET_PROT_FILE
);
1037 aURL
.SetSmartURL( aFactory
);
1038 const String
& rMainURL
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
1039 m_pBmp
->SetImage( SvFileInformationManager::GetImage( aURL
, sal_True
) );
1041 // determine size and type
1042 String
aSizeText( m_aUnknownSize
);
1043 if ( aURL
.GetProtocol() == INET_PROT_FILE
)
1044 aSizeText
= CreateSizeText( SfxContentHelper::GetSize( aURL
.GetMainURL( INetURLObject::NO_DECODE
) ) );
1045 m_pShowSizeFT
->SetText( aSizeText
);
1047 String aDescription
= SvFileInformationManager::GetDescription( INetURLObject(rMainURL
) );
1048 if ( aDescription
.Len() == 0 )
1049 aDescription
= SfxResId( STR_SFX_NEWOFFICEDOC
).toString();
1050 m_pShowTypeFT
->SetText( aDescription
);
1052 // determine location
1053 aURL
.SetSmartURL( aFile
);
1054 if ( aURL
.GetProtocol() == INET_PROT_FILE
)
1056 INetURLObject
aPath( aURL
);
1057 aPath
.setFinalSlash();
1058 aPath
.removeSegment();
1059 // we know it's a folder -> don't need the final slash, but it's better for WB_PATHELLIPSIS
1060 aPath
.removeFinalSlash();
1061 String
aText( aPath
.PathToFileName() ); //! (pb) MaxLen?
1062 m_pFileValFt
->SetText( aText
);
1064 else if ( aURL
.GetProtocol() != INET_PROT_PRIVATE
)
1065 m_pFileValFt
->SetText( aURL
.GetPartBeforeLastName() );
1067 // handle access data
1068 sal_Bool m_bUseUserData
= m_pInfoItem
->IsUseUserData();
1069 const LocaleDataWrapper
& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
1070 m_pCreateValFt
->SetText( ConvertDateTime_Impl( m_pInfoItem
->getAuthor(),
1071 m_pInfoItem
->getCreationDate(), rLocaleWrapper
) );
1072 util::DateTime
aTime( m_pInfoItem
->getModificationDate() );
1073 if ( aTime
.Month
> 0 )
1074 m_pChangeValFt
->SetText( ConvertDateTime_Impl(
1075 m_pInfoItem
->getModifiedBy(), aTime
, rLocaleWrapper
) );
1076 aTime
= m_pInfoItem
->getPrintDate();
1077 if ( aTime
.Month
> 0 )
1078 m_pPrintValFt
->SetText( ConvertDateTime_Impl( m_pInfoItem
->getPrintedBy(),
1079 aTime
, rLocaleWrapper
) );
1080 const long nTime
= m_pInfoItem
->getEditingDuration();
1081 if ( m_bUseUserData
)
1083 const Time
aT( nTime
/3600, (nTime
%3600)/60, nTime
%60 );
1084 m_pTimeLogValFt
->SetText( rLocaleWrapper
.getDuration( aT
) );
1085 m_pDocNoValFt
->SetText( OUString::number(
1086 m_pInfoItem
->getEditingCycles() ) );
1089 TriState eState
= (TriState
)m_bUseUserData
;
1091 if ( STATE_DONTKNOW
== eState
)
1092 m_pUseUserDataCB
->EnableTriState( sal_True
);
1094 m_pUseUserDataCB
->SetState( eState
);
1095 m_pUseUserDataCB
->SaveValue();
1096 m_pUseUserDataCB
->Enable( bEnableUseUserData
);
1097 bHandleDelete
= sal_False
;
1098 m_pDeleteBtn
->Enable( bEnableUseUserData
);
1101 //------------------------------------------------------------------------
1102 SfxDocumentInfoDialog::SfxDocumentInfoDialog( Window
* pParent
,
1103 const SfxItemSet
& rItemSet
)
1104 : SfxTabDialog(0, pParent
, "DocumentPropertiesDialog",
1105 "sfx/ui/documentpropertiesdialog.ui", &rItemSet
)
1108 const SfxDocumentInfoItem
* m_pInfoItem
=
1109 &(const SfxDocumentInfoItem
&)rItemSet
.Get( SID_DOCINFO
);
1112 SFX_ITEMSET_ARG( &rItemSet
, pURLItem
, SfxStringItem
, SID_BASEURL
, sal_False
);
1113 DBG_ASSERT( pURLItem
, "No BaseURL provided for InternetTabPage!" );
1116 // Determine the Titels
1117 const SfxPoolItem
* pItem
= 0;
1118 String
aTitle( GetText() );
1119 if ( SFX_ITEM_SET
!=
1120 rItemSet
.GetItemState( SID_EXPLORER_PROPS_START
, sal_False
, &pItem
) )
1123 String
aFile( m_pInfoItem
->GetValue() );
1126 aURL
.SetSmartProtocol( INET_PROT_FILE
);
1127 aURL
.SetSmartURL( aFile
);
1128 if ( INET_PROT_PRIV_SOFFICE
!= aURL
.GetProtocol() )
1130 String
aLastName( aURL
.GetLastName() );
1131 if ( aLastName
.Len() )
1132 aTitle
+= aLastName
;
1137 aTitle
+= SfxResId( STR_NONAME
).toString();
1141 DBG_ASSERT( pItem
->IsA( TYPE( SfxStringItem
) ),
1142 "SfxDocumentInfoDialog:<SfxStringItem> expected" );
1143 aTitle
+= ( ( SfxStringItem
* ) pItem
)->GetValue();
1148 m_nDocInfoId
= AddTabPage("general", SfxDocumentPage::Create
, 0);
1149 AddTabPage("description", SfxDocumentDescPage::Create
, 0);
1150 AddTabPage("customprops", SfxCustomPropertiesPage::Create
, 0);
1151 AddTabPage("security", SfxSecurityPage::Create
, 0);
1154 // -----------------------------------------------------------------------
1156 void SfxDocumentInfoDialog::PageCreated( sal_uInt16 nId
, SfxTabPage
&rPage
)
1158 if ( m_nDocInfoId
== nId
)
1159 ( (SfxDocumentPage
&)rPage
).EnableUseUserData();
1162 void SfxDocumentInfoDialog::AddFontTabPage()
1164 AddTabPage( FONT_PAGE_ID
, SfxResId( STR_FONT_TABPAGE
).toString(), SfxDocumentFontsPage::Create
, 0);
1167 // class CustomPropertiesYesNoButton -------------------------------------
1169 CustomPropertiesYesNoButton::CustomPropertiesYesNoButton( Window
* pParent
, const ResId
& rResId
) :
1170 Control( pParent
, rResId
),
1171 m_aYesButton( this, ResId( RB_PROPERTY_YES
, *rResId
.GetResMgr() ) ),
1172 m_aNoButton ( this, ResId( RB_PROPERTY_NO
, *rResId
.GetResMgr() ) )
1175 Wallpaper
aWall( Color( COL_TRANSPARENT
) );
1176 SetBackground( aWall
);
1177 SetBorderStyle( WINDOW_BORDER_MONO
);
1179 m_aYesButton
.SetBackground( aWall
);
1180 m_aNoButton
.SetBackground( aWall
);
1182 class DurationDialog_Impl
: public ModalDialog
1184 FixedLine aDurationFL
;
1187 CancelButton aCancelPB
;
1190 CheckBox aNegativeCB
;
1192 NumericField aYearNF
;
1194 NumericField aMonthNF
;
1196 NumericField aDayNF
;
1198 NumericField aHourNF
;
1199 FixedText aMinuteFT
;
1200 NumericField aMinuteNF
;
1201 FixedText aSecondFT
;
1202 NumericField aSecondNF
;
1203 FixedText aMSecondFT
;
1204 NumericField aMSecondNF
;
1208 DurationDialog_Impl( Window
* pParent
, const util::Duration
& rDuration
);
1209 ~DurationDialog_Impl();
1211 util::Duration
GetDuration() const;
1214 DurationDialog_Impl::DurationDialog_Impl(
1215 Window
* pParent
, const util::Duration
& rDuration
)
1216 : ModalDialog( pParent
, SfxResId( RID_EDIT_DURATIONS
) ),
1217 aDurationFL(this, SfxResId( FL_DURATION
)),
1218 aOKPB( this, SfxResId( PB_OK
)),
1219 aCancelPB( this, SfxResId( PB_CANCEL
)),
1220 aHelpPB( this, SfxResId( PB_HELP
)),
1221 aNegativeCB(this, SfxResId( CB_NEGATIVE
)),
1222 aYearFT( this, SfxResId( FT_YEAR
)),
1223 aYearNF( this, SfxResId( ED_YEAR
)),
1224 aMonthFT( this, SfxResId( FT_MONTH
)),
1225 aMonthNF( this, SfxResId( ED_MONTH
)),
1226 aDayFT( this, SfxResId( FT_DAY
)),
1227 aDayNF( this, SfxResId( ED_DAY
)),
1228 aHourFT( this, SfxResId( FT_HOUR
)),
1229 aHourNF( this, SfxResId( ED_HOUR
)),
1230 aMinuteFT( this, SfxResId( FT_MINUTE
)),
1231 aMinuteNF( this, SfxResId( ED_MINUTE
)),
1232 aSecondFT( this, SfxResId( FT_SECOND
)),
1233 aSecondNF( this, SfxResId( ED_SECOND
)),
1234 aMSecondFT( this, SfxResId( FT_MSECOND
)),
1235 aMSecondNF( this, SfxResId( ED_MSECOND
))
1238 aNegativeCB
.Check(rDuration
.Negative
);
1239 aYearNF
.SetValue(rDuration
.Years
);
1240 aMonthNF
.SetValue(rDuration
.Months
);
1241 aDayNF
.SetValue(rDuration
.Days
);
1242 aHourNF
.SetValue(rDuration
.Hours
);
1243 aMinuteNF
.SetValue(rDuration
.Minutes
);
1244 aSecondNF
.SetValue(rDuration
.Seconds
);
1245 aMSecondNF
.SetValue(rDuration
.NanoSeconds
);
1248 DurationDialog_Impl::~DurationDialog_Impl()
1252 util::Duration
DurationDialog_Impl::GetDuration() const
1254 util::Duration aRet
;
1255 aRet
.Negative
= aNegativeCB
.IsChecked();
1256 aRet
.Years
= aYearNF
.GetValue();
1257 aRet
.Months
= aMonthNF
.GetValue( );
1258 aRet
.Days
= aDayNF
.GetValue( );
1259 aRet
.Hours
= aHourNF
.GetValue( );
1260 aRet
.Minutes
= aMinuteNF
.GetValue();
1261 aRet
.Seconds
= aSecondNF
.GetValue();
1262 aRet
.NanoSeconds
= aMSecondNF
.GetValue();
1266 CustomPropertiesDurationField::CustomPropertiesDurationField( Window
* pParent
, const ResId
& rResId
, CustomPropertyLine
* pLine
) :
1267 Edit( pParent
, rResId
), m_pLine( pLine
)
1270 SetDuration( util::Duration(false, 0, 0, 0, 0, 0, 0, 0) );
1273 CustomPropertiesDurationField::~CustomPropertiesDurationField()
1277 void CustomPropertiesDurationField::RequestHelp( const HelpEvent
& rHEvt
)
1279 if ( rHEvt
.GetMode() & HELPMODE_QUICK
)
1281 Size
aSize( GetSizePixel() );
1282 Rectangle
aItemRect( rHEvt
.GetMousePosPixel(), aSize
);
1283 if (Help::IsBalloonHelpEnabled())
1284 Help::ShowBalloon( this, rHEvt
.GetMousePosPixel(), GetText() );
1286 Help::ShowQuickHelp( this, aItemRect
, GetText(),
1287 QUICKHELP_LEFT
|QUICKHELP_VCENTER
);
1291 void CustomPropertiesDurationField::SetDuration( const util::Duration
& rDuration
)
1293 m_aDuration
= rDuration
;
1294 String
sText(rDuration
.Negative
? OUString('-') : OUString('+'));
1295 sText
+= m_pLine
->m_sDurationFormat
;
1296 sText
.SearchAndReplace(OUString("%1"), OUString::number( rDuration
.Years
) );
1297 sText
.SearchAndReplace(OUString("%2"), OUString::number( rDuration
.Months
) );
1298 sText
.SearchAndReplace(OUString("%3"), OUString::number( rDuration
.Days
) );
1299 sText
.SearchAndReplace(OUString("%4"), OUString::number( rDuration
.Hours
) );
1300 sText
.SearchAndReplace(OUString("%5"), OUString::number( rDuration
.Minutes
) );
1301 sText
.SearchAndReplace(OUString("%6"), OUString::number( rDuration
.Seconds
) );
1305 CustomPropertiesEditButton::CustomPropertiesEditButton( Window
* pParent
, const ResId
& rResId
, CustomPropertyLine
* pLine
) :
1306 PushButton( pParent
, rResId
), m_pLine( pLine
)
1308 SetClickHdl( LINK( this, CustomPropertiesEditButton
, ClickHdl
));
1311 CustomPropertiesEditButton::~CustomPropertiesEditButton()
1315 IMPL_LINK_NOARG(CustomPropertiesEditButton
, ClickHdl
)
1317 DurationDialog_Impl
* pDurationDlg
= new DurationDialog_Impl( this, m_pLine
->m_aDurationField
.GetDuration() );
1318 if ( RET_OK
== pDurationDlg
->Execute() )
1319 m_pLine
->m_aDurationField
.SetDuration( pDurationDlg
->GetDuration() );
1320 delete pDurationDlg
;
1323 //--------------------------------------------------------------------------
1324 void CustomPropertiesYesNoButton::Resize()
1326 const long nWidth
= GetSizePixel().Width();
1327 const long n3Width
= LogicToPixel( Size( 3, 3 ), MAP_APPFONT
).Width();
1328 const long nNewWidth
= ( nWidth
/ 2 ) - n3Width
- 2;
1329 Size aSize
= m_aYesButton
.GetSizePixel();
1330 const long nDelta
= aSize
.Width() - nNewWidth
;
1331 aSize
.Width() = nNewWidth
;
1332 m_aYesButton
.SetSizePixel( aSize
);
1333 Point aPos
= m_aNoButton
.GetPosPixel();
1335 m_aNoButton
.SetPosSizePixel( aPos
, aSize
);
1338 // struct CustomPropertyLine ---------------------------------------------
1339 CustomPropertyLine::CustomPropertyLine( Window
* pParent
) :
1340 m_aNameBox ( pParent
, SfxResId( SFX_CB_PROPERTY_NAME
) ),
1341 m_aTypeBox ( pParent
, SfxResId( SFX_LB_PROPERTY_TYPE
), this ),
1342 m_aValueEdit ( pParent
, SfxResId( SFX_ED_PROPERTY_VALUE
), this ),
1343 m_aDateField ( pParent
, SfxResId( SFX_FLD_DATE
), this),
1344 m_aTimeField ( pParent
, SfxResId( SFX_FLD_TIME
), this),
1345 m_sDurationFormat( SfxResId( SFX_ST_DURATION_FORMAT
).toString() ),
1346 m_aDurationField( pParent
, SfxResId( SFX_FLD_DURATION
), this),
1347 m_aEditButton( pParent
, SfxResId( SFX_PB_EDIT
), this),
1348 m_aYesNoButton ( pParent
, SfxResId( SFX_WIN_PROPERTY_YESNO
) ),
1349 m_aRemoveButton ( pParent
, SfxResId( SFX_PB_PROPERTY_REMOVE
), this ),
1350 m_bIsRemoved ( false ),
1351 m_bTypeLostFocus( false )
1354 m_aTimeField
.SetExtFormat( EXTTIMEF_24H_LONG
);
1355 m_aDateField
.SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY
);
1357 m_aRemoveButton
.SetModeImage( SfxResId( SFX_IMG_PROPERTY_REMOVE
) );
1360 void CustomPropertyLine::SetRemoved()
1362 DBG_ASSERT( !m_bIsRemoved
, "CustomPropertyLine::SetRemoved(): line already removed" );
1363 m_bIsRemoved
= true;
1366 m_aValueEdit
.Hide();
1367 m_aDateField
.Hide();
1368 m_aTimeField
.Hide();
1369 m_aDurationField
.Hide();
1370 m_aEditButton
.Hide();
1371 m_aYesNoButton
.Hide();
1372 m_aRemoveButton
.Hide();
1375 CustomPropertiesWindow::CustomPropertiesWindow(Window
* pParent
,
1376 const OUString
&rHeaderAccName
,
1377 const OUString
&rHeaderAccType
,
1378 const OUString
&rHeaderAccValue
) :
1380 m_aNameBox ( this, SfxResId( SFX_CB_PROPERTY_NAME
) ),
1381 m_aTypeBox ( this, SfxResId( SFX_LB_PROPERTY_TYPE
) ),
1382 m_aValueEdit ( this, SfxResId( SFX_ED_PROPERTY_VALUE
) ),
1383 m_aDateField ( this, SfxResId( SFX_FLD_DATE
) ),
1384 m_aTimeField ( this, SfxResId( SFX_FLD_TIME
) ),
1385 m_aDurationField( this, SfxResId( SFX_FLD_DURATION
) ),
1386 m_aEditButton( this, SfxResId( SFX_PB_EDIT
)),
1387 m_aYesNoButton ( this, SfxResId( SFX_WIN_PROPERTY_YESNO
) ),
1388 m_aRemoveButton ( this, SfxResId( SFX_PB_PROPERTY_REMOVE
) ),
1390 m_aNumberFormatter( ::comphelper::getProcessComponentContext(),
1391 Application::GetSettings().GetLanguageTag().getLanguageType() )
1394 m_aEditLoseFocusTimer
.SetTimeout( 300 );
1395 m_aEditLoseFocusTimer
.SetTimeoutHdl( LINK( this, CustomPropertiesWindow
, EditTimeoutHdl
) );
1396 m_aBoxLoseFocusTimer
.SetTimeout( 300 );
1397 m_aBoxLoseFocusTimer
.SetTimeoutHdl( LINK( this, CustomPropertiesWindow
, BoxTimeoutHdl
) );
1399 m_aNameBox
.SetAccessibleName(rHeaderAccName
);
1400 m_aTypeBox
.SetAccessibleName(rHeaderAccType
);
1401 m_aValueEdit
.SetAccessibleName(rHeaderAccValue
);
1405 m_aValueEdit
.Hide();
1406 m_aDateField
.Hide();
1407 m_aTimeField
.Hide();
1408 m_aDurationField
.Hide();
1409 m_aEditButton
.Hide();
1410 m_aYesNoButton
.Hide();
1411 m_aRemoveButton
.Hide();
1414 ( m_aRemoveButton
.GetPosPixel().Y() * 2 ) + m_aRemoveButton
.GetSizePixel().Height();
1417 CustomPropertiesWindow::~CustomPropertiesWindow()
1419 m_aEditLoseFocusTimer
.Stop();
1420 m_aBoxLoseFocusTimer
.Stop();
1424 IMPL_LINK( CustomPropertiesWindow
, TypeHdl
, CustomPropertiesTypeBox
*, pBox
)
1426 sal_Int64 nType
= sal_Int64( (long)pBox
->GetEntryData( pBox
->GetSelectEntryPos() ) );
1427 CustomPropertyLine
* pLine
= pBox
->GetLine();
1428 pLine
->m_aValueEdit
.Show( (CUSTOM_TYPE_TEXT
== nType
) || (CUSTOM_TYPE_NUMBER
== nType
) );
1429 pLine
->m_aDateField
.Show( (CUSTOM_TYPE_DATE
== nType
) || (CUSTOM_TYPE_DATETIME
== nType
) );
1430 pLine
->m_aTimeField
.Show( CUSTOM_TYPE_DATETIME
== nType
);
1431 pLine
->m_aDurationField
.Show( CUSTOM_TYPE_DURATION
== nType
);
1432 pLine
->m_aEditButton
.Show( CUSTOM_TYPE_DURATION
== nType
);
1433 pLine
->m_aYesNoButton
.Show( CUSTOM_TYPE_BOOLEAN
== nType
);
1434 //adjust positions of date and time controls
1435 if ( nType
== CUSTOM_TYPE_DATE
)
1436 pLine
->m_aDateField
.SetPosSizePixel(pLine
->m_aValueEdit
.GetPosPixel(), pLine
->m_aValueEdit
.GetSizePixel());
1437 else if ( nType
== CUSTOM_TYPE_DATETIME
)
1439 pLine
->m_aDateField
.SetPosSizePixel( pLine
->m_aDatePos
, pLine
->m_aDateTimeSize
);
1440 pLine
->m_aTimeField
.SetPosSizePixel(pLine
->m_aTimePos
, pLine
->m_aDateTimeSize
);
1446 IMPL_LINK( CustomPropertiesWindow
, RemoveHdl
, CustomPropertiesRemoveButton
*, pButton
)
1448 CustomPropertyLine
* pLine
= pButton
->GetLine();
1449 std::vector
< CustomPropertyLine
* >::iterator pFound
=
1450 std::find( m_aCustomPropertiesLines
.begin(), m_aCustomPropertiesLines
.end(), pLine
);
1451 if ( pFound
!= m_aCustomPropertiesLines
.end() )
1454 pLine
->SetRemoved();
1455 std::vector
< CustomPropertyLine
* >::iterator pIter
= pFound
+ 1;
1456 const long nDelta
= GetLineHeight();
1457 for ( ; pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1460 if ( pLine
->m_bIsRemoved
)
1463 Window
* pWindows
[] = { &pLine
->m_aNameBox
, &pLine
->m_aTypeBox
, &pLine
->m_aValueEdit
,
1464 &pLine
->m_aDateField
, &pLine
->m_aTimeField
,
1465 &pLine
->m_aDurationField
, &pLine
->m_aEditButton
,
1466 &pLine
->m_aYesNoButton
, &pLine
->m_aRemoveButton
, NULL
};
1467 Window
** pCurrent
= pWindows
;
1470 Point aPos
= (*pCurrent
)->GetPosPixel();
1472 (*pCurrent
)->SetPosPixel( aPos
);
1478 m_aRemovedHdl
.Call(0);
1482 IMPL_LINK( CustomPropertiesWindow
, EditLoseFocusHdl
, CustomPropertiesEdit
*, pEdit
)
1486 CustomPropertyLine
* pLine
= pEdit
->GetLine();
1487 if ( !pLine
->m_bTypeLostFocus
)
1489 m_pCurrentLine
= pLine
;
1490 m_aEditLoseFocusTimer
.Start();
1493 pLine
->m_bTypeLostFocus
= false;
1498 IMPL_LINK( CustomPropertiesWindow
, BoxLoseFocusHdl
, CustomPropertiesTypeBox
*, pBox
)
1502 m_pCurrentLine
= pBox
->GetLine();
1503 m_aBoxLoseFocusTimer
.Start();
1509 IMPL_LINK_NOARG(CustomPropertiesWindow
, EditTimeoutHdl
)
1511 ValidateLine( m_pCurrentLine
, false );
1515 IMPL_LINK_NOARG(CustomPropertiesWindow
, BoxTimeoutHdl
)
1517 ValidateLine( m_pCurrentLine
, true );
1521 bool CustomPropertiesWindow::IsLineValid( CustomPropertyLine
* pLine
) const
1523 bool bIsValid
= true;
1524 pLine
->m_bTypeLostFocus
= false;
1525 sal_Int64 nType
= sal_Int64(
1526 (long)pLine
->m_aTypeBox
.GetEntryData( pLine
->m_aTypeBox
.GetSelectEntryPos() ) );
1527 String sValue
= pLine
->m_aValueEdit
.GetText();
1528 if ( sValue
.Len() == 0 )
1531 sal_uInt32 nIndex
= 0xFFFFFFFF;
1532 if ( CUSTOM_TYPE_NUMBER
== nType
)
1533 nIndex
= const_cast< SvNumberFormatter
& >(
1534 m_aNumberFormatter
).GetFormatIndex( NF_NUMBER_SYSTEM
);
1535 else if ( CUSTOM_TYPE_DATE
== nType
)
1536 nIndex
= const_cast< SvNumberFormatter
& >(
1537 m_aNumberFormatter
).GetFormatIndex( NF_DATE_SYS_DDMMYYYY
);
1539 if ( nIndex
!= 0xFFFFFFFF )
1541 sal_uInt32 nTemp
= nIndex
;
1542 double fDummy
= 0.0;
1543 bIsValid
= const_cast< SvNumberFormatter
& >(
1544 m_aNumberFormatter
).IsNumberFormat( sValue
, nIndex
, fDummy
) != sal_False
;
1545 if ( bIsValid
&& nTemp
!= nIndex
)
1546 // sValue is a number but the format doesn't match the index
1553 void CustomPropertiesWindow::ValidateLine( CustomPropertyLine
* pLine
, bool bIsFromTypeBox
)
1555 if ( !IsLineValid( pLine
) )
1557 if ( bIsFromTypeBox
) // LoseFocus of TypeBox
1558 pLine
->m_bTypeLostFocus
= true;
1559 Window
* pParent
= GetParent()->GetParent();
1560 if ( QueryBox( pParent
, SfxResId( SFX_QB_WRONG_TYPE
) ).Execute() == RET_OK
)
1561 pLine
->m_aTypeBox
.SelectEntryPos( m_aTypeBox
.GetEntryPos( (void*)CUSTOM_TYPE_TEXT
) );
1563 pLine
->m_aValueEdit
.GrabFocus();
1567 void CustomPropertiesWindow::InitControls( HeaderBar
* pHeaderBar
, const ScrollBar
* pScrollBar
)
1569 DBG_ASSERT( pHeaderBar
, "CustomPropertiesWindow::InitControls(): invalid headerbar" );
1570 DBG_ASSERT( pScrollBar
, "CustomPropertiesWindow::InitControls(): invalid scrollbar" );
1572 const long nOffset
= 4;
1573 const long nScrollBarWidth
= pScrollBar
->GetSizePixel().Width();
1574 const long nButtonWidth
= m_aRemoveButton
.GetSizePixel().Width() + nScrollBarWidth
+ nOffset
;
1575 long nTypeWidth
= m_aTypeBox
.CalcMinimumSize().Width() + ( 2 * nOffset
);
1576 long nFullWidth
= pHeaderBar
->GetSizePixel().Width();
1577 long nItemWidth
= ( nFullWidth
- nTypeWidth
- nButtonWidth
) / 2;
1578 pHeaderBar
->SetItemSize( HI_NAME
, nItemWidth
);
1579 pHeaderBar
->SetItemSize( HI_TYPE
, nTypeWidth
);
1580 pHeaderBar
->SetItemSize( HI_VALUE
, nItemWidth
);
1581 pHeaderBar
->SetItemSize( HI_ACTION
, nButtonWidth
);
1583 Window
* pWindows
[] = { &m_aNameBox
, &m_aTypeBox
, &m_aValueEdit
, &m_aRemoveButton
, NULL
};
1584 Window
** pCurrent
= pWindows
;
1585 sal_uInt16 nPos
= 0;
1588 Rectangle aRect
= pHeaderBar
->GetItemRect( pHeaderBar
->GetItemId( nPos
++ ) );
1589 Size aSize
= (*pCurrent
)->GetSizePixel();
1590 Point aPos
= (*pCurrent
)->GetPosPixel();
1591 long nWidth
= aRect
.GetWidth() - nOffset
;
1592 if ( *pCurrent
== &m_aRemoveButton
)
1593 nWidth
-= pScrollBar
->GetSizePixel().Width();
1594 aSize
.Width() = nWidth
;
1595 aPos
.X() = aRect
.getX() + ( nOffset
/ 2 );
1596 (*pCurrent
)->SetPosSizePixel( aPos
, aSize
);
1598 if ( *pCurrent
== &m_aValueEdit
)
1600 Point
aDurationPos( aPos
);
1601 m_aDurationField
.SetPosPixel( aDurationPos
);
1602 Size
aDurationSize(aSize
);
1603 aDurationSize
.Width() -= (m_aEditButton
.GetSizePixel().Width() + 3 );
1604 m_aDurationField
.SetSizePixel(aDurationSize
);
1605 aDurationPos
.X() = aPos
.X() - m_aEditButton
.GetSizePixel().Width() + aSize
.Width();
1606 m_aEditButton
.SetPosPixel(aDurationPos
);
1607 aSize
= m_aYesNoButton
.GetSizePixel();
1608 aPos
= m_aYesNoButton
.GetPosPixel();
1609 aSize
.Width() = nWidth
;
1610 aPos
.X() = aRect
.getX() + ( nOffset
/ 2 );
1611 m_aYesNoButton
.SetPosSizePixel( aPos
, aSize
);
1614 m_aDateField
.SetPosSizePixel( aPos
, aSize
);
1615 aPos
.X() += aSize
.Width() + 4;
1616 m_aTimeField
.SetPosSizePixel( aPos
, aSize
);
1623 sal_uInt16
CustomPropertiesWindow::GetVisibleLineCount() const
1625 sal_uInt16 nCount
= 0;
1626 std::vector
< CustomPropertyLine
* >::const_iterator pIter
;
1627 for ( pIter
= m_aCustomPropertiesLines
.begin();
1628 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1630 CustomPropertyLine
* pLine
= *pIter
;
1631 if ( !pLine
->m_bIsRemoved
)
1637 void CustomPropertiesWindow::updateLineWidth()
1639 Window
* pWindows
[] = { &m_aNameBox
, &m_aTypeBox
, &m_aValueEdit
,
1640 &m_aDateField
, &m_aTimeField
,
1641 &m_aDurationField
, &m_aEditButton
,
1642 &m_aYesNoButton
, &m_aRemoveButton
, NULL
};
1644 for (std::vector
< CustomPropertyLine
* >::iterator aI
=
1645 m_aCustomPropertiesLines
.begin(), aEnd
= m_aCustomPropertiesLines
.end();
1648 CustomPropertyLine
* pNewLine
= *aI
;
1650 Window
* pNewWindows
[] =
1651 { &pNewLine
->m_aNameBox
, &pNewLine
->m_aTypeBox
, &pNewLine
->m_aValueEdit
,
1652 &pNewLine
->m_aDateField
, &pNewLine
->m_aTimeField
,
1653 &pNewLine
->m_aDurationField
, &pNewLine
->m_aEditButton
,
1654 &pNewLine
->m_aYesNoButton
, &pNewLine
->m_aRemoveButton
, NULL
};
1656 Window
** pCurrent
= pWindows
;
1657 Window
** pNewCurrent
= pNewWindows
;
1660 Size aSize
= (*pCurrent
)->GetSizePixel();
1661 Point aPos
= (*pCurrent
)->GetPosPixel();
1662 aPos
.Y() = (*pNewCurrent
)->GetPosPixel().Y();
1663 (*pNewCurrent
)->SetPosSizePixel( aPos
, aSize
);
1670 void CustomPropertiesWindow::AddLine( const OUString
& sName
, Any
& rAny
)
1672 CustomPropertyLine
* pNewLine
= new CustomPropertyLine( this );
1673 pNewLine
->m_aTypeBox
.SetSelectHdl( LINK( this, CustomPropertiesWindow
, TypeHdl
) );
1674 pNewLine
->m_aRemoveButton
.SetClickHdl( LINK( this, CustomPropertiesWindow
, RemoveHdl
) );
1675 pNewLine
->m_aValueEdit
.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow
, EditLoseFocusHdl
) );
1676 //add lose focus handlers of date/time fields
1678 pNewLine
->m_aTypeBox
.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow
, BoxLoseFocusHdl
) );
1680 pNewLine
->m_aNameBox
.SetAccessibleName(m_aNameBox
.GetAccessibleName());
1681 pNewLine
->m_aTypeBox
.SetAccessibleName(m_aTypeBox
.GetAccessibleName());
1682 pNewLine
->m_aValueEdit
.SetAccessibleName(m_aValueEdit
.GetAccessibleName());
1684 long nPos
= GetVisibleLineCount() * GetLineHeight();
1685 m_aCustomPropertiesLines
.push_back( pNewLine
);
1686 Window
* pWindows
[] = { &m_aNameBox
, &m_aTypeBox
, &m_aValueEdit
,
1687 &m_aDateField
, &m_aTimeField
,
1688 &m_aDurationField
, &m_aEditButton
,
1689 &m_aYesNoButton
, &m_aRemoveButton
, NULL
};
1690 Window
* pNewWindows
[] =
1691 { &pNewLine
->m_aNameBox
, &pNewLine
->m_aTypeBox
, &pNewLine
->m_aValueEdit
,
1692 &pNewLine
->m_aDateField
, &pNewLine
->m_aTimeField
,
1693 &pNewLine
->m_aDurationField
, &pNewLine
->m_aEditButton
,
1694 &pNewLine
->m_aYesNoButton
, &pNewLine
->m_aRemoveButton
, NULL
};
1695 Window
** pCurrent
= pWindows
;
1696 Window
** pNewCurrent
= pNewWindows
;
1699 Size aSize
= (*pCurrent
)->GetSizePixel();
1700 Point aPos
= (*pCurrent
)->GetPosPixel();
1702 aPos
.Y() += m_nScrollPos
;
1703 (*pNewCurrent
)->SetPosSizePixel( aPos
, aSize
);
1704 (*pNewCurrent
)->Show();
1709 pNewLine
->m_aDatePos
= pNewLine
->m_aDateField
.GetPosPixel();
1710 pNewLine
->m_aTimePos
= pNewLine
->m_aTimeField
.GetPosPixel();
1711 pNewLine
->m_aDateTimeSize
= pNewLine
->m_aDateField
.GetSizePixel();
1713 double nTmpValue
= 0;
1714 bool bTmpValue
= false;
1716 util::DateTime aTmpDateTime
;
1717 util::Date aTmpDate
;
1718 util::Duration aTmpDuration
;
1719 SvtSysLocale aSysLocale
;
1720 const LocaleDataWrapper
& rLocaleWrapper
= aSysLocale
.GetLocaleData();
1721 pNewLine
->m_aNameBox
.SetText( sName
);
1722 sal_IntPtr nType
= CUSTOM_TYPE_UNKNOWN
;
1725 if ( rAny
>>= nTmpValue
)
1727 sal_uInt32 nIndex
= m_aNumberFormatter
.GetFormatIndex( NF_NUMBER_SYSTEM
);
1728 m_aNumberFormatter
.GetInputLineString( nTmpValue
, nIndex
, sValue
);
1729 pNewLine
->m_aValueEdit
.SetText( sValue
);
1730 nType
= CUSTOM_TYPE_NUMBER
;
1732 else if ( rAny
>>= bTmpValue
)
1734 sValue
= ( bTmpValue
? rLocaleWrapper
.getTrueWord() : rLocaleWrapper
.getFalseWord() );
1735 nType
= CUSTOM_TYPE_BOOLEAN
;
1737 else if ( rAny
>>= sTmpValue
)
1739 pNewLine
->m_aValueEdit
.SetText( sTmpValue
);
1740 nType
= CUSTOM_TYPE_TEXT
;
1742 else if ( rAny
>>= aTmpDate
)
1744 nType
= CUSTOM_TYPE_DATE
;
1745 pNewLine
->m_aDateField
.SetDate( Date( aTmpDate
.Day
, aTmpDate
.Month
, aTmpDate
.Year
) );
1748 else if ( rAny
>>= aTmpDuration
)
1750 nType
= CUSTOM_TYPE_DURATION
;
1751 pNewLine
->m_aDurationField
.SetDuration( aTmpDuration
);
1753 else if ( rAny
>>= aTmpDateTime
)
1755 pNewLine
->m_aDateField
.SetDate( Date( aTmpDateTime
.Day
, aTmpDateTime
.Month
, aTmpDateTime
.Year
) );
1756 pNewLine
->m_aTimeField
.SetTime( Time( aTmpDateTime
.Hours
, aTmpDateTime
.Minutes
, aTmpDateTime
.Seconds
, aTmpDateTime
.NanoSeconds
) );
1758 nType
= CUSTOM_TYPE_DATETIME
;
1761 if ( nType
!= CUSTOM_TYPE_UNKNOWN
)
1763 if ( CUSTOM_TYPE_BOOLEAN
== nType
)
1766 pNewLine
->m_aYesNoButton
.CheckYes();
1768 pNewLine
->m_aYesNoButton
.CheckNo();
1770 pNewLine
->m_aTypeBox
.SelectEntryPos( m_aTypeBox
.GetEntryPos( (void*)nType
) );
1773 TypeHdl( &pNewLine
->m_aTypeBox
);
1774 pNewLine
->m_aNameBox
.GrabFocus();
1777 bool CustomPropertiesWindow::AreAllLinesValid() const
1780 std::vector
< CustomPropertyLine
* >::const_iterator pIter
;
1781 for ( pIter
= m_aCustomPropertiesLines
.begin();
1782 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1784 CustomPropertyLine
* pLine
= *pIter
;
1785 if ( !IsLineValid( pLine
) )
1795 void CustomPropertiesWindow::ClearAllLines()
1797 std::vector
< CustomPropertyLine
* >::iterator pIter
;
1798 for ( pIter
= m_aCustomPropertiesLines
.begin();
1799 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1801 CustomPropertyLine
* pLine
= *pIter
;
1802 pLine
->SetRemoved();
1805 m_aCustomPropertiesLines
.clear();
1809 void CustomPropertiesWindow::DoScroll( sal_Int32 nNewPos
)
1811 m_nScrollPos
+= nNewPos
;
1812 std::vector
< CustomPropertyLine
* >::iterator pIter
;
1813 for ( pIter
= m_aCustomPropertiesLines
.begin();
1814 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1816 CustomPropertyLine
* pLine
= *pIter
;
1817 if ( pLine
->m_bIsRemoved
)
1820 Window
* pWindows
[] = { &pLine
->m_aNameBox
, &pLine
->m_aTypeBox
, &pLine
->m_aValueEdit
, &pLine
->m_aDateField
, &pLine
->m_aTimeField
,
1821 &pLine
->m_aDurationField
, &pLine
->m_aEditButton
, &pLine
->m_aYesNoButton
, &pLine
->m_aRemoveButton
, NULL
};
1822 Window
** pCurrent
= pWindows
;
1825 Point aPos
= (*pCurrent
)->GetPosPixel();
1826 aPos
.Y() += nNewPos
;
1827 (*pCurrent
)->SetPosPixel( aPos
);
1833 Sequence
< beans::PropertyValue
> CustomPropertiesWindow::GetCustomProperties() const
1835 Sequence
< beans::PropertyValue
> aPropertiesSeq( m_aCustomPropertiesLines
.size() );
1837 std::vector
< CustomPropertyLine
* >::const_iterator pIter
;
1838 for ( pIter
= m_aCustomPropertiesLines
.begin();
1839 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
, ++i
)
1841 CustomPropertyLine
* pLine
= *pIter
;
1842 if ( pLine
->m_bIsRemoved
)
1845 String sPropertyName
= pLine
->m_aNameBox
.GetText();
1846 if ( sPropertyName
.Len() > 0 )
1848 aPropertiesSeq
[i
].Name
= sPropertyName
;
1849 sal_Int64 nType
= sal_Int64(
1850 (long)pLine
->m_aTypeBox
.GetEntryData( pLine
->m_aTypeBox
.GetSelectEntryPos() ) );
1851 if ( CUSTOM_TYPE_NUMBER
== nType
)
1854 sal_uInt32 nIndex
= const_cast< SvNumberFormatter
& >(
1855 m_aNumberFormatter
).GetFormatIndex( NF_NUMBER_SYSTEM
);
1856 sal_Bool bIsNum
= const_cast< SvNumberFormatter
& >( m_aNumberFormatter
).
1857 IsNumberFormat( pLine
->m_aValueEdit
.GetText(), nIndex
, nValue
);
1859 aPropertiesSeq
[i
].Value
<<= makeAny( nValue
);
1861 else if ( CUSTOM_TYPE_BOOLEAN
== nType
)
1863 bool bValue
= pLine
->m_aYesNoButton
.IsYesChecked();
1864 aPropertiesSeq
[i
].Value
<<= makeAny( bValue
);
1866 else if ( CUSTOM_TYPE_DATETIME
== nType
)
1868 Date aTmpDate
= pLine
->m_aDateField
.GetDate();
1869 Time aTmpTime
= pLine
->m_aTimeField
.GetTime();
1870 util::DateTime
const aDateTime(aTmpTime
.GetNanoSec(),
1871 aTmpTime
.GetSec(), aTmpTime
.GetMin(), aTmpTime
.GetHour(),
1872 aTmpDate
.GetDay(), aTmpDate
.GetMonth(), aTmpDate
.GetYear(),
1874 aPropertiesSeq
[i
].Value
<<= aDateTime
;
1876 else if ( CUSTOM_TYPE_DURATION
== nType
)
1878 aPropertiesSeq
[i
].Value
<<= pLine
->m_aDurationField
.GetDuration();
1880 else if ( CUSTOM_TYPE_DATE
== nType
)
1882 Date aTmpDate
= pLine
->m_aDateField
.GetDate();
1883 util::Date
const aDate(aTmpDate
.GetDay(), aTmpDate
.GetMonth(),
1884 aTmpDate
.GetYear());
1885 aPropertiesSeq
[i
].Value
<<= aDate
;
1890 OUString
sValue( pLine
->m_aValueEdit
.GetText() );
1891 aPropertiesSeq
[i
].Value
<<= makeAny( sValue
);
1896 return aPropertiesSeq
;
1899 CustomPropertiesControl::CustomPropertiesControl(Window
* pParent
)
1905 void CustomPropertiesControl::Init(VclBuilderContainer
& rBuilder
)
1907 m_pHeaderBar
= new HeaderBar(this, WB_BUTTONSTYLE
| WB_BOTTOMBORDER
);
1908 m_pBody
= new VclHBox(this);
1909 OUString sName
= rBuilder
.get
<FixedText
>("name")->GetText();
1910 OUString sType
= rBuilder
.get
<FixedText
>("type")->GetText();
1911 OUString sValue
= rBuilder
.get
<FixedText
>("value")->GetText();
1912 m_pPropertiesWin
= new CustomPropertiesWindow(m_pBody
, sName
, sType
, sValue
);
1913 m_pVertScroll
= new ScrollBar(m_pBody
, WB_VERT
);
1920 m_pBody
->set_hexpand(true);
1921 m_pBody
->set_vexpand(true);
1922 m_pBody
->set_expand(true);
1923 m_pBody
->set_fill(true);
1926 m_pPropertiesWin
->set_hexpand(true);
1927 m_pPropertiesWin
->set_vexpand(true);
1928 m_pPropertiesWin
->set_expand(true);
1929 m_pPropertiesWin
->set_fill(true);
1930 m_pPropertiesWin
->Show();
1932 m_pPropertiesWin
->SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
1933 m_pVertScroll
->EnableDrag();
1934 m_pVertScroll
->Show();
1936 m_pHeaderBar
->set_height_request(GetTextHeight() + 6);
1938 const HeaderBarItemBits nHeadBits
= HIB_VCENTER
| HIB_FIXED
| HIB_FIXEDPOS
| HIB_LEFT
;
1940 m_pHeaderBar
->InsertItem( HI_NAME
, sName
, 0, nHeadBits
);
1941 m_pHeaderBar
->InsertItem( HI_TYPE
, sType
, 0, nHeadBits
);
1942 m_pHeaderBar
->InsertItem( HI_VALUE
, sValue
, 0, nHeadBits
);
1943 m_pHeaderBar
->InsertItem( HI_ACTION
, OUString(), 0, nHeadBits
);
1944 m_pHeaderBar
->Show();
1946 m_pPropertiesWin
->SetRemovedHdl( LINK( this, CustomPropertiesControl
, RemovedHdl
) );
1948 m_pVertScroll
->SetRangeMin( 0 );
1949 m_pVertScroll
->SetRangeMax( 0 );
1950 m_pVertScroll
->SetVisibleSize( 0xFFFF );
1952 Link aScrollLink
= LINK( this, CustomPropertiesControl
, ScrollHdl
);
1953 m_pVertScroll
->SetScrollHdl( aScrollLink
);
1956 void CustomPropertiesControl::setAllocation(const Size
&rAllocation
)
1958 VclVBox::setAllocation(rAllocation
);
1960 m_pPropertiesWin
->InitControls( m_pHeaderBar
, m_pVertScroll
);
1961 sal_Int32 nScrollOffset
= m_pPropertiesWin
->GetLineHeight();
1962 sal_Int32 nVisibleEntries
= m_pPropertiesWin
->GetSizePixel().Height() / nScrollOffset
;
1963 m_pVertScroll
->SetPageSize( nVisibleEntries
- 1 );
1964 m_pVertScroll
->SetVisibleSize( nVisibleEntries
);
1965 m_pPropertiesWin
->updateLineWidth();
1968 extern "C" SAL_DLLPUBLIC_EXPORT Window
* SAL_CALL
makeCustomPropertiesControl(Window
*pParent
,
1969 VclBuilder::stringmap
&)
1971 return new CustomPropertiesControl(pParent
);
1974 CustomPropertiesControl::~CustomPropertiesControl()
1976 delete m_pVertScroll
;
1977 delete m_pPropertiesWin
;
1979 delete m_pHeaderBar
;
1982 IMPL_LINK( CustomPropertiesControl
, ScrollHdl
, ScrollBar
*, pScrollBar
)
1984 sal_Int32 nOffset
= m_pPropertiesWin
->GetLineHeight();
1985 nOffset
*= ( m_nThumbPos
- pScrollBar
->GetThumbPos() );
1986 m_nThumbPos
= pScrollBar
->GetThumbPos();
1987 m_pPropertiesWin
->DoScroll( nOffset
);
1991 IMPL_LINK_NOARG(CustomPropertiesControl
, RemovedHdl
)
1993 m_pVertScroll
->SetRangeMax( m_pPropertiesWin
->GetVisibleLineCount() + 1 );
1994 if ( m_pPropertiesWin
->GetOutputSizePixel().Height() < m_pPropertiesWin
->GetVisibleLineCount() * m_pPropertiesWin
->GetLineHeight() )
1995 m_pVertScroll
->DoScrollAction ( SCROLL_LINEUP
);
1999 void CustomPropertiesControl::AddLine( const OUString
& sName
, Any
& rAny
, bool bInteractive
)
2001 m_pPropertiesWin
->AddLine( sName
, rAny
);
2002 m_pVertScroll
->SetRangeMax( m_pPropertiesWin
->GetVisibleLineCount() + 1 );
2003 if ( bInteractive
&& m_pPropertiesWin
->GetOutputSizePixel().Height() < m_pPropertiesWin
->GetVisibleLineCount() * m_pPropertiesWin
->GetLineHeight() )
2004 m_pVertScroll
->DoScroll( m_pPropertiesWin
->GetVisibleLineCount() + 1 );
2007 // class SfxCustomPropertiesPage -----------------------------------------
2008 SfxCustomPropertiesPage::SfxCustomPropertiesPage( Window
* pParent
, const SfxItemSet
& rItemSet
)
2009 : SfxTabPage(pParent
, "CustomInfoPage", "sfx/ui/custominfopage.ui", rItemSet
)
2011 get(m_pPropertiesCtrl
, "properties");
2012 m_pPropertiesCtrl
->Init(*this);
2013 get
<PushButton
>("add")->SetClickHdl(LINK(this, SfxCustomPropertiesPage
, AddHdl
));
2016 IMPL_LINK_NOARG(SfxCustomPropertiesPage
, AddHdl
)
2019 m_pPropertiesCtrl
->AddLine( OUString(), aAny
, true );
2023 sal_Bool
SfxCustomPropertiesPage::FillItemSet( SfxItemSet
& rSet
)
2025 sal_Bool bModified
= sal_False
;
2026 const SfxPoolItem
* pItem
= NULL
;
2027 SfxDocumentInfoItem
* pInfo
= NULL
;
2028 bool bMustDelete
= false;
2030 if ( GetTabDialog() && GetTabDialog()->GetExampleSet() )
2032 if ( SFX_ITEM_SET
!=
2033 GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO
, sal_True
, &pItem
) )
2034 pInfo
= &( SfxDocumentInfoItem
& )rSet
.Get( SID_DOCINFO
);
2038 pInfo
= new SfxDocumentInfoItem( *( const SfxDocumentInfoItem
* ) pItem
);
2044 pInfo
->ClearCustomProperties();
2045 Sequence
< beans::PropertyValue
> aPropertySeq
= m_pPropertiesCtrl
->GetCustomProperties();
2046 sal_Int32 i
= 0, nCount
= aPropertySeq
.getLength();
2047 for ( ; i
< nCount
; ++i
)
2049 if ( !aPropertySeq
[i
].Name
.isEmpty() )
2050 pInfo
->AddCustomProperty( aPropertySeq
[i
].Name
, aPropertySeq
[i
].Value
);
2054 bModified
= sal_True
; //!!!
2062 void SfxCustomPropertiesPage::Reset( const SfxItemSet
& rItemSet
)
2064 m_pPropertiesCtrl
->ClearAllLines();
2065 const SfxDocumentInfoItem
* m_pInfoItem
= &(const SfxDocumentInfoItem
&)rItemSet
.Get(SID_DOCINFO
);
2066 std::vector
< CustomProperty
* > aCustomProps
= m_pInfoItem
->GetCustomProperties();
2067 for ( sal_uInt32 i
= 0; i
< aCustomProps
.size(); i
++ )
2069 m_pPropertiesCtrl
->AddLine( aCustomProps
[i
]->m_sName
, aCustomProps
[i
]->m_aValue
, false );
2073 int SfxCustomPropertiesPage::DeactivatePage( SfxItemSet
* /*pSet*/ )
2075 int nRet
= LEAVE_PAGE
;
2076 if ( !m_pPropertiesCtrl
->AreAllLinesValid() )
2081 SfxTabPage
* SfxCustomPropertiesPage::Create( Window
* pParent
, const SfxItemSet
& rItemSet
)
2083 return new SfxCustomPropertiesPage( pParent
, rItemSet
);
2086 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */