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/layout.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/DateTimeWithTimezone.hpp>
45 #include <com/sun/star/util/DateWithTimezone.hpp>
46 #include <com/sun/star/util/Duration.hpp>
47 #include <com/sun/star/document/XDocumentProperties.hpp>
48 #include <com/sun/star/document/CmisProperty.hpp>
50 #include <vcl/timer.hxx>
51 #include <vcl/settings.hxx>
52 #include <sfx2/dinfdlg.hxx>
53 #include <sfx2/securitypage.hxx>
54 #include <sfx2/sfxresid.hxx>
55 #include <sfx2/dinfedt.hxx>
56 #include <sfx2/frame.hxx>
57 #include <sfx2/viewfrm.hxx>
58 #include <sfx2/request.hxx>
59 #include <sfx2/passwd.hxx>
60 #include <sfx2/filedlghelper.hxx>
62 #include <sfx2/objsh.hxx>
63 #include <sfx2/docfile.hxx>
64 #include <comphelper/storagehelper.hxx>
66 #include "documentfontsdialog.hxx"
67 #include <sfx2/sfx.hrc>
68 #include "dinfdlg.hrc"
69 #include "../appl/app.hrc"
70 #include "sfxlocal.hrc"
72 #include <vcl/help.hxx>
73 #include <vcl/builderfactory.hxx>
76 #include <boost/scoped_ptr.hpp>
78 using namespace ::com::sun::star
;
79 using namespace ::com::sun::star::lang
;
80 using namespace ::com::sun::star::ui::dialogs
;
81 using namespace ::com::sun::star::uno
;
83 const sal_uInt16 FONT_PAGE_ID
= 99;
88 com::sun::star::uno::Any m_aValue
;
90 CustomProperty( const OUString
& sName
,
91 const com::sun::star::uno::Any
& rValue
) :
92 m_sName( sName
), m_aValue( rValue
) {}
96 bool operator==(const util::DateTime
&i_rLeft
, const util::DateTime
&i_rRight
)
98 return i_rLeft
.Year
== i_rRight
.Year
99 && i_rLeft
.Month
== i_rRight
.Month
100 && i_rLeft
.Day
== i_rRight
.Day
101 && i_rLeft
.Hours
== i_rRight
.Hours
102 && i_rLeft
.Minutes
== i_rRight
.Minutes
103 && i_rLeft
.Seconds
== i_rRight
.Seconds
104 && i_rLeft
.NanoSeconds
== i_rRight
.NanoSeconds
105 && i_rLeft
.IsUTC
== i_rRight
.IsUTC
;
108 // STATIC DATA -----------------------------------------------------------
109 TYPEINIT1_AUTOFACTORY(SfxDocumentInfoItem
, SfxStringItem
);
111 const sal_uInt16 HI_NAME
= 1;
112 const sal_uInt16 HI_TYPE
= 2;
113 const sal_uInt16 HI_VALUE
= 3;
114 const sal_uInt16 HI_ACTION
= 4;
116 static const char DOCUMENT_SIGNATURE_MENU_CMD
[] = "Signature";
121 OUString
CreateSizeText( sal_Int64 nSize
)
123 OUString
aUnitStr(" ");
124 aUnitStr
+= SfxResId(STR_BYTES
).toString();
125 sal_Int64 nSize1
= nSize
;
126 sal_Int64 nSize2
= nSize1
;
127 sal_Int64 nMega
= 1024 * 1024;
128 sal_Int64 nGiga
= nMega
* 1024;
129 double fSize
= nSize
;
132 if ( nSize1
>= 10000 && nSize1
< nMega
)
136 aUnitStr
+= SfxResId(STR_KB
).toString();
140 else if ( nSize1
>= nMega
&& nSize1
< nGiga
)
144 aUnitStr
+= SfxResId(STR_MB
).toString();
148 else if ( nSize1
>= nGiga
)
152 aUnitStr
+= SfxResId(STR_GB
).toString();
156 const SvtSysLocale aSysLocale
;
157 const LocaleDataWrapper
& rLocaleWrapper
= aSysLocale
.GetLocaleData();
158 OUString
aSizeStr( rLocaleWrapper
.getNum( nSize1
, 0 ) );
159 aSizeStr
+= aUnitStr
;
160 if ( nSize1
< nSize2
)
162 aSizeStr
= ::rtl::math::doubleToUString( fSize
,
163 rtl_math_StringFormat_F
, nDec
,
164 rLocaleWrapper
.getNumDecimalSep()[0] );
165 aSizeStr
+= aUnitStr
;
168 aSizeStr
+= rLocaleWrapper
.getNum( nSize2
, 0 );
170 aSizeStr
+= SfxResId(STR_BYTES
).toString();
176 OUString
ConvertDateTime_Impl( const OUString
& rName
,
177 const util::DateTime
& uDT
, const LocaleDataWrapper
& rWrapper
)
181 const OUString
pDelim ( ", " );
182 OUString
aStr( rWrapper
.getDate( aD
) );
184 aStr
+= rWrapper
.getTime( aT
, true, false );
185 OUString aAuthor
= comphelper::string::stripStart(rName
, ' ');
186 if (!aAuthor
.isEmpty())
197 SfxDocumentInfoItem::SfxDocumentInfoItem()
201 , m_isAutoloadEnabled(false)
207 , m_ModificationDate()
211 , m_EditingDuration(0)
216 , m_bHasTemplate( true )
217 , m_bDeleteUserData( false )
218 , m_bUseUserData( true )
222 SfxDocumentInfoItem::SfxDocumentInfoItem( const OUString
& rFile
,
223 const uno::Reference
<document::XDocumentProperties
>& i_xDocProps
,
224 const uno::Sequence
<document::CmisProperty
>& i_cmisProps
,
226 : SfxStringItem( SID_DOCINFO
, rFile
)
227 , m_AutoloadDelay( i_xDocProps
->getAutoloadSecs() )
228 , m_AutoloadURL( i_xDocProps
->getAutoloadURL() )
229 , m_isAutoloadEnabled( (m_AutoloadDelay
> 0) || !m_AutoloadURL
.isEmpty() )
230 , m_DefaultTarget( i_xDocProps
->getDefaultTarget() )
231 , m_TemplateName( i_xDocProps
->getTemplateName() )
232 , m_Author( i_xDocProps
->getAuthor() )
233 , m_CreationDate( i_xDocProps
->getCreationDate() )
234 , m_ModifiedBy( i_xDocProps
->getModifiedBy() )
235 , m_ModificationDate( i_xDocProps
->getModificationDate() )
236 , m_PrintedBy( i_xDocProps
->getPrintedBy() )
237 , m_PrintDate( i_xDocProps
->getPrintDate() )
238 , m_EditingCycles( i_xDocProps
->getEditingCycles() )
239 , m_EditingDuration( i_xDocProps
->getEditingDuration() )
240 , m_Description( i_xDocProps
->getDescription() )
241 , m_Keywords( ::comphelper::string::convertCommaSeparated(
242 i_xDocProps
->getKeywords()) )
243 , m_Subject( i_xDocProps
->getSubject() )
244 , m_Title( i_xDocProps
->getTitle() )
245 , m_bHasTemplate( true )
246 , m_bDeleteUserData( false )
247 , m_bUseUserData( bIs
)
251 Reference
< beans::XPropertyContainer
> xContainer
= i_xDocProps
->getUserDefinedProperties();
252 if ( xContainer
.is() )
254 Reference
< beans::XPropertySet
> xSet( xContainer
, UNO_QUERY
);
255 const Sequence
< beans::Property
> lProps
= xSet
->getPropertySetInfo()->getProperties();
256 const beans::Property
* pProps
= lProps
.getConstArray();
257 sal_Int32 nCount
= lProps
.getLength();
258 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
260 // "fix" property? => not a custom property => ignore it!
261 if (!(pProps
[i
].Attributes
&
262 ::com::sun::star::beans::PropertyAttribute::REMOVABLE
))
264 DBG_ASSERT(false, "non-removable user-defined property?");
268 uno::Any aValue
= xSet
->getPropertyValue(pProps
[i
].Name
);
269 CustomProperty
* pProp
= new CustomProperty( pProps
[i
].Name
, aValue
);
270 m_aCustomProperties
.push_back( pProp
);
274 // get CMIS properties
275 m_aCmisProperties
= i_cmisProps
;
277 catch ( Exception
& ) {}
282 SfxDocumentInfoItem::SfxDocumentInfoItem( const SfxDocumentInfoItem
& rItem
)
283 : SfxStringItem( rItem
)
284 , m_AutoloadDelay( rItem
.getAutoloadDelay() )
285 , m_AutoloadURL( rItem
.getAutoloadURL() )
286 , m_isAutoloadEnabled( rItem
.isAutoloadEnabled() )
287 , m_DefaultTarget( rItem
.getDefaultTarget() )
288 , m_TemplateName( rItem
.getTemplateName() )
289 , m_Author( rItem
.getAuthor() )
290 , m_CreationDate( rItem
.getCreationDate() )
291 , m_ModifiedBy( rItem
.getModifiedBy() )
292 , m_ModificationDate( rItem
.getModificationDate() )
293 , m_PrintedBy( rItem
.getPrintedBy() )
294 , m_PrintDate( rItem
.getPrintDate() )
295 , m_EditingCycles( rItem
.getEditingCycles() )
296 , m_EditingDuration( rItem
.getEditingDuration() )
297 , m_Description( rItem
.getDescription() )
298 , m_Keywords( rItem
.getKeywords() )
299 , m_Subject( rItem
.getSubject() )
300 , m_Title( rItem
.getTitle() )
301 , m_bHasTemplate( rItem
.m_bHasTemplate
)
302 , m_bDeleteUserData( rItem
.m_bDeleteUserData
)
303 , m_bUseUserData( rItem
.m_bUseUserData
)
305 for ( sal_uInt32 i
= 0; i
< rItem
.m_aCustomProperties
.size(); i
++ )
307 CustomProperty
* pProp
= new CustomProperty( rItem
.m_aCustomProperties
[i
]->m_sName
,
308 rItem
.m_aCustomProperties
[i
]->m_aValue
);
309 m_aCustomProperties
.push_back( pProp
);
312 m_aCmisProperties
= rItem
.m_aCmisProperties
;
316 SfxDocumentInfoItem::~SfxDocumentInfoItem()
318 ClearCustomProperties();
322 SfxPoolItem
* SfxDocumentInfoItem::Clone( SfxItemPool
* ) const
324 return new SfxDocumentInfoItem( *this );
328 bool SfxDocumentInfoItem::operator==( const SfxPoolItem
& rItem
) const
330 if (!(rItem
.Type() == Type() && SfxStringItem::operator==(rItem
)))
332 const SfxDocumentInfoItem
& rInfoItem(static_cast<const SfxDocumentInfoItem
&>(rItem
));
335 m_AutoloadDelay
== rInfoItem
.m_AutoloadDelay
&&
336 m_AutoloadURL
== rInfoItem
.m_AutoloadURL
&&
337 m_isAutoloadEnabled
== rInfoItem
.m_isAutoloadEnabled
&&
338 m_DefaultTarget
== rInfoItem
.m_DefaultTarget
&&
339 m_Author
== rInfoItem
.m_Author
&&
340 m_CreationDate
== rInfoItem
.m_CreationDate
&&
341 m_ModifiedBy
== rInfoItem
.m_ModifiedBy
&&
342 m_ModificationDate
== rInfoItem
.m_ModificationDate
&&
343 m_PrintedBy
== rInfoItem
.m_PrintedBy
&&
344 m_PrintDate
== rInfoItem
.m_PrintDate
&&
345 m_EditingCycles
== rInfoItem
.m_EditingCycles
&&
346 m_EditingDuration
== rInfoItem
.m_EditingDuration
&&
347 m_Description
== rInfoItem
.m_Description
&&
348 m_Keywords
== rInfoItem
.m_Keywords
&&
349 m_Subject
== rInfoItem
.m_Subject
&&
350 m_Title
== rInfoItem
.m_Title
&&
351 m_aCustomProperties
.size() == rInfoItem
.m_aCustomProperties
.size() &&
352 std::equal(m_aCustomProperties
.begin(), m_aCustomProperties
.end(),
353 rInfoItem
.m_aCustomProperties
.begin()) &&
354 m_aCmisProperties
.getLength() == rInfoItem
.m_aCmisProperties
.getLength();
358 void SfxDocumentInfoItem::resetUserData(const OUString
& i_rAuthor
)
360 setAuthor(i_rAuthor
);
361 DateTime
now( DateTime::SYSTEM
);
362 setCreationDate( now
.GetUNODateTime() );
363 setModifiedBy(OUString());
364 setPrintedBy(OUString());
365 setModificationDate(util::DateTime());
366 setPrintDate(util::DateTime());
367 setEditingDuration(0);
372 void SfxDocumentInfoItem::UpdateDocumentInfo(
373 const uno::Reference
<document::XDocumentProperties
>& i_xDocProps
,
374 bool i_bDoNotUpdateUserDefined
) const
376 if (isAutoloadEnabled()) {
377 i_xDocProps
->setAutoloadSecs(getAutoloadDelay());
378 i_xDocProps
->setAutoloadURL(getAutoloadURL());
380 i_xDocProps
->setAutoloadSecs(0);
381 i_xDocProps
->setAutoloadURL(OUString());
383 i_xDocProps
->setDefaultTarget(getDefaultTarget());
384 i_xDocProps
->setAuthor(getAuthor());
385 i_xDocProps
->setCreationDate(getCreationDate());
386 i_xDocProps
->setModifiedBy(getModifiedBy());
387 i_xDocProps
->setModificationDate(getModificationDate());
388 i_xDocProps
->setPrintedBy(getPrintedBy());
389 i_xDocProps
->setPrintDate(getPrintDate());
390 i_xDocProps
->setEditingCycles(getEditingCycles());
391 i_xDocProps
->setEditingDuration(getEditingDuration());
392 i_xDocProps
->setDescription(getDescription());
393 i_xDocProps
->setKeywords(
394 ::comphelper::string::convertCommaSeparated(getKeywords()));
395 i_xDocProps
->setSubject(getSubject());
396 i_xDocProps
->setTitle(getTitle());
398 // this is necessary in case of replaying a recorded macro:
399 // in this case, the macro may contain the 4 old user-defined DocumentInfo
400 // fields, but not any of the DocumentInfo properties;
401 // as a consequence, most of the UserDefined properties of the
402 // DocumentProperties would be summarily deleted here, which does not
403 // seem like a good idea.
404 if (i_bDoNotUpdateUserDefined
)
409 Reference
< beans::XPropertyContainer
> xContainer
= i_xDocProps
->getUserDefinedProperties();
410 Reference
< beans::XPropertySet
> xSet( xContainer
, UNO_QUERY
);
411 Reference
< beans::XPropertySetInfo
> xSetInfo
= xSet
->getPropertySetInfo();
412 const Sequence
< beans::Property
> lProps
= xSetInfo
->getProperties();
413 const beans::Property
* pProps
= lProps
.getConstArray();
414 sal_Int32 nCount
= lProps
.getLength();
415 for ( sal_Int32 j
= 0; j
< nCount
; ++j
)
417 if ((pProps
[j
].Attributes
&
418 ::com::sun::star::beans::PropertyAttribute::REMOVABLE
))
420 xContainer
->removeProperty( pProps
[j
].Name
);
424 for ( sal_uInt32 k
= 0; k
< m_aCustomProperties
.size(); ++k
)
428 xContainer
->addProperty( m_aCustomProperties
[k
]->m_sName
,
429 beans::PropertyAttribute::REMOVABLE
, m_aCustomProperties
[k
]->m_aValue
);
433 SAL_WARN( "sfx.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while adding custom properties" );
439 SAL_WARN( "sfx.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while removing custom properties" );
445 void SfxDocumentInfoItem::SetDeleteUserData( bool bSet
)
447 m_bDeleteUserData
= bSet
;
451 void SfxDocumentInfoItem::SetUseUserData( bool bSet
)
453 m_bUseUserData
= bSet
;
456 std::vector
< CustomProperty
* > SfxDocumentInfoItem::GetCustomProperties() const
458 std::vector
< CustomProperty
* > aRet
;
459 for ( sal_uInt32 i
= 0; i
< m_aCustomProperties
.size(); i
++ )
461 CustomProperty
* pProp
= new CustomProperty( m_aCustomProperties
[i
]->m_sName
,
462 m_aCustomProperties
[i
]->m_aValue
);
463 aRet
.push_back( pProp
);
469 void SfxDocumentInfoItem::ClearCustomProperties()
471 for ( sal_uInt32 i
= 0; i
< m_aCustomProperties
.size(); i
++ )
472 delete m_aCustomProperties
[i
];
473 m_aCustomProperties
.clear();
476 void SfxDocumentInfoItem::AddCustomProperty( const OUString
& sName
, const Any
& rValue
)
478 CustomProperty
* pProp
= new CustomProperty( sName
, rValue
);
479 m_aCustomProperties
.push_back( pProp
);
483 void SfxDocumentInfoItem::SetCmisProperties( const Sequence
< document::CmisProperty
>& cmisProps
)
485 m_aCmisProperties
= cmisProps
;
488 bool SfxDocumentInfoItem::QueryValue( Any
& rVal
, sal_uInt8 nMemberId
) const
491 sal_Int32 nValue
= 0;
494 bool bIsString
= false;
495 nMemberId
&= ~CONVERT_TWIPS
;
498 case MID_DOCINFO_USEUSERDATA
:
499 bValue
= IsUseUserData();
501 case MID_DOCINFO_DELETEUSERDATA
:
502 bValue
= IsDeleteUserData();
504 case MID_DOCINFO_AUTOLOADENABLED
:
505 bValue
= isAutoloadEnabled();
507 case MID_DOCINFO_AUTOLOADSECS
:
509 nValue
= getAutoloadDelay();
511 case MID_DOCINFO_AUTOLOADURL
:
513 aValue
= getAutoloadURL();
515 case MID_DOCINFO_DEFAULTTARGET
:
517 aValue
= getDefaultTarget();
519 case MID_DOCINFO_DESCRIPTION
:
521 aValue
= getDescription();
523 case MID_DOCINFO_KEYWORDS
:
525 aValue
= getKeywords();
527 case MID_DOCINFO_SUBJECT
:
529 aValue
= getSubject();
531 case MID_DOCINFO_TITLE
:
536 OSL_FAIL("Wrong MemberId!");
541 rVal
<<= OUString( aValue
);
549 bool SfxDocumentInfoItem::PutValue( const Any
& rVal
, sal_uInt8 nMemberId
)
555 nMemberId
&= ~CONVERT_TWIPS
;
558 case MID_DOCINFO_USEUSERDATA
:
559 bRet
= (rVal
>>= bValue
);
561 SetUseUserData( bValue
);
563 case MID_DOCINFO_DELETEUSERDATA
:
564 // QUESTION: deleting user data was done here; seems to be superfluous!
565 bRet
= (rVal
>>= bValue
);
567 SetDeleteUserData( bValue
);
569 case MID_DOCINFO_AUTOLOADENABLED
:
570 bRet
= (rVal
>>= bValue
);
572 setAutoloadEnabled(bValue
);
574 case MID_DOCINFO_AUTOLOADSECS
:
575 bRet
= (rVal
>>= nValue
);
577 setAutoloadDelay(nValue
);
579 case MID_DOCINFO_AUTOLOADURL
:
580 bRet
= (rVal
>>= aValue
);
582 setAutoloadURL(aValue
);
584 case MID_DOCINFO_DEFAULTTARGET
:
585 bRet
= (rVal
>>= aValue
);
587 setDefaultTarget(aValue
);
589 case MID_DOCINFO_DESCRIPTION
:
590 bRet
= (rVal
>>= aValue
);
592 setDescription(aValue
);
594 case MID_DOCINFO_KEYWORDS
:
595 bRet
= (rVal
>>= aValue
);
599 case MID_DOCINFO_SUBJECT
:
600 bRet
= (rVal
>>= aValue
);
604 case MID_DOCINFO_TITLE
:
605 bRet
= (rVal
>>= aValue
);
610 OSL_FAIL("Wrong MemberId!");
617 SfxDocumentDescPage::SfxDocumentDescPage( vcl::Window
* pParent
, const SfxItemSet
& rItemSet
)
618 : SfxTabPage(pParent
, "DescriptionInfoPage", "sfx/ui/descriptioninfopage.ui", &rItemSet
)
619 , m_pInfoItem ( NULL
)
622 get(m_pTitleEd
, "title");
623 get(m_pThemaEd
, "subject");
624 get(m_pKeywordsEd
, "keywords");
625 get(m_pCommentEd
, "comments");
626 m_pCommentEd
->set_width_request(m_pKeywordsEd
->get_preferred_size().Width());
627 m_pCommentEd
->set_height_request(m_pCommentEd
->GetTextHeight() * 16);
630 SfxDocumentDescPage::~SfxDocumentDescPage()
635 void SfxDocumentDescPage::dispose()
639 m_pKeywordsEd
.clear();
640 m_pCommentEd
.clear();
641 SfxTabPage::dispose();
644 VclPtr
<SfxTabPage
> SfxDocumentDescPage::Create(vcl::Window
*pParent
, const SfxItemSet
*rItemSet
)
646 return VclPtr
<SfxDocumentDescPage
>::Create(pParent
, *rItemSet
);
649 bool SfxDocumentDescPage::FillItemSet(SfxItemSet
*rSet
)
651 // Test whether a change is present
652 const bool bTitleMod
= m_pTitleEd
->IsModified();
653 const bool bThemeMod
= m_pThemaEd
->IsModified();
654 const bool bKeywordsMod
= m_pKeywordsEd
->IsModified();
655 const bool bCommentMod
= m_pCommentEd
->IsModified();
656 if ( !( bTitleMod
|| bThemeMod
|| bKeywordsMod
|| bCommentMod
) )
661 // Generating the output data
662 const SfxPoolItem
* pItem
= NULL
;
663 SfxDocumentInfoItem
* pInfo
= NULL
;
664 SfxTabDialog
* pDlg
= GetTabDialog();
665 const SfxItemSet
* pExSet
= NULL
;
668 pExSet
= pDlg
->GetExampleSet();
670 if ( pExSet
&& SfxItemState::SET
!= pExSet
->GetItemState( SID_DOCINFO
, true, &pItem
) )
673 pInfo
= new SfxDocumentInfoItem( *static_cast<const SfxDocumentInfoItem
*>(pItem
) );
677 SAL_WARN( "sfx.dialog", "SfxDocumentDescPage::FillItemSet(): no item found" );
683 pInfo
->setTitle( m_pTitleEd
->GetText() );
687 pInfo
->setSubject( m_pThemaEd
->GetText() );
691 pInfo
->setKeywords( m_pKeywordsEd
->GetText() );
695 pInfo
->setDescription( m_pCommentEd
->GetText() );
697 rSet
->Put( SfxDocumentInfoItem( *pInfo
) );
698 if ( pInfo
!= m_pInfoItem
)
707 void SfxDocumentDescPage::Reset(const SfxItemSet
*rSet
)
709 m_pInfoItem
= const_cast<SfxDocumentInfoItem
*>(&static_cast<const SfxDocumentInfoItem
&>(rSet
->Get(SID_DOCINFO
)));
711 m_pTitleEd
->SetText( m_pInfoItem
->getTitle() );
712 m_pThemaEd
->SetText( m_pInfoItem
->getSubject() );
713 m_pKeywordsEd
->SetText( m_pInfoItem
->getKeywords() );
714 m_pCommentEd
->SetText( m_pInfoItem
->getDescription() );
716 SFX_ITEMSET_ARG( rSet
, pROItem
, SfxBoolItem
, SID_DOC_READONLY
, false );
717 if ( pROItem
&& pROItem
->GetValue() )
719 m_pTitleEd
->SetReadOnly( true );
720 m_pThemaEd
->SetReadOnly( true );
721 m_pKeywordsEd
->SetReadOnly( true );
722 m_pCommentEd
->SetReadOnly( true );
729 OUString
GetDateTimeString( sal_Int32 _nDate
, sal_Int32 _nTime
)
731 const LocaleDataWrapper
& rWrapper( Application::GetSettings().GetLocaleDataWrapper() );
733 Date
aDate( _nDate
);
734 tools::Time
aTime( _nTime
);
735 OUString
aStr( rWrapper
.getDate( aDate
) );
737 aStr
+= rWrapper
.getTime( aTime
);
741 // copy from xmlsecurity/source/dialog/resourcemanager.cxx
742 OUString
GetContentPart( const OUString
& _rRawString
, const OUString
& _rPartId
)
746 sal_Int32 nContStart
= _rRawString
.indexOf( _rPartId
);
747 if ( nContStart
!= -1 )
749 nContStart
= nContStart
+ _rPartId
.getLength();
750 ++nContStart
; // now its start of content, directly after Id
752 sal_Int32 nContEnd
= _rRawString
.indexOf( ',', nContStart
);
754 s
= _rRawString
.copy( nContStart
, nContEnd
- nContStart
);
761 SfxDocumentPage::SfxDocumentPage(vcl::Window
* pParent
, const SfxItemSet
& rItemSet
)
762 : SfxTabPage(pParent
, "DocumentInfoPage", "sfx/ui/documentinfopage.ui", &rItemSet
)
763 , bEnableUseUserData( false )
764 , bHandleDelete( false )
767 get(m_pNameED
, "nameed");
768 get(m_pChangePassBtn
, "changepass");
770 get(m_pShowTypeFT
, "showtype");
771 get(m_pFileValEd
, "showlocation");
772 get(m_pShowSizeFT
, "showsize");
773 m_aUnknownSize
= m_pShowSizeFT
->GetText();
774 m_pShowSizeFT
->SetText(OUString());
776 get(m_pCreateValFt
, "showcreate");
777 get(m_pChangeValFt
, "showmodify");
778 get(m_pSignedValFt
, "showsigned");
779 m_aMultiSignedStr
= m_pSignedValFt
->GetText();
780 m_pSignedValFt
->SetText(OUString());
781 get(m_pSignatureBtn
, "signature");
782 get(m_pPrintValFt
, "showprint");
783 get(m_pTimeLogValFt
, "showedittime");
784 get(m_pDocNoValFt
, "showrevision");
786 get(m_pUseUserDataCB
, "userdatacb");
787 get(m_pDeleteBtn
, "reset");
789 get(m_pTemplFt
, "templateft");
790 get(m_pTemplValFt
, "showtemplate");
792 ImplUpdateSignatures();
793 ImplCheckPasswordState();
794 m_pChangePassBtn
->SetClickHdl( LINK( this, SfxDocumentPage
, ChangePassHdl
) );
795 m_pSignatureBtn
->SetClickHdl( LINK( this, SfxDocumentPage
, SignatureHdl
) );
796 m_pDeleteBtn
->SetClickHdl( LINK( this, SfxDocumentPage
, DeleteHdl
) );
798 // [i96288] Check if the document signature command is enabled
799 // on the main list enable/disable the pushbutton accordingly
800 SvtCommandOptions aCmdOptions
;
801 if ( aCmdOptions
.Lookup( SvtCommandOptions::CMDOPTION_DISABLED
,
802 OUString( DOCUMENT_SIGNATURE_MENU_CMD
) ) )
803 m_pSignatureBtn
->Disable();
806 SfxDocumentPage::~SfxDocumentPage()
811 void SfxDocumentPage::dispose()
815 m_pChangePassBtn
.clear();
816 m_pShowTypeFT
.clear();
817 m_pFileValEd
.clear();
818 m_pShowSizeFT
.clear();
819 m_pCreateValFt
.clear();
820 m_pChangeValFt
.clear();
821 m_pSignedValFt
.clear();
822 m_pSignatureBtn
.clear();
823 m_pPrintValFt
.clear();
824 m_pTimeLogValFt
.clear();
825 m_pDocNoValFt
.clear();
826 m_pUseUserDataCB
.clear();
827 m_pDeleteBtn
.clear();
829 m_pTemplValFt
.clear();
830 SfxTabPage::dispose();
834 IMPL_LINK_NOARG(SfxDocumentPage
, DeleteHdl
)
837 if ( bEnableUseUserData
&& m_pUseUserDataCB
->IsChecked() )
838 aName
= SvtUserOptions().GetFullName();
839 const LocaleDataWrapper
& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
840 DateTime
now( DateTime::SYSTEM
);
841 util::DateTime
uDT( now
.GetUNODateTime() );
842 m_pCreateValFt
->SetText( ConvertDateTime_Impl( aName
, uDT
, rLocaleWrapper
) );
844 m_pChangeValFt
->SetText( aEmpty
);
845 m_pPrintValFt
->SetText( aEmpty
);
846 const tools::Time
aTime( 0 );
847 m_pTimeLogValFt
->SetText( rLocaleWrapper
.getDuration( aTime
) );
848 m_pDocNoValFt
->SetText(OUString('1'));
849 bHandleDelete
= true;
853 IMPL_LINK_NOARG(SfxDocumentPage
, SignatureHdl
)
855 SfxObjectShell
* pDoc
= SfxObjectShell::Current();
858 pDoc
->SignDocumentContent();
860 ImplUpdateSignatures();
866 IMPL_STATIC_LINK_NOARG(SfxDocumentPage
, ChangePassHdl
)
868 SfxObjectShell
* pShell
= SfxObjectShell::Current();
873 SfxItemSet
* pMedSet
= pShell
->GetMedium()->GetItemSet();
876 const SfxFilter
* pFilter
= pShell
->GetMedium()->GetFilter();
881 sfx2::RequestPassword(pFilter
, aDocName
, pMedSet
);
882 pShell
->SetModified(true);
888 void SfxDocumentPage::ImplUpdateSignatures()
890 SfxObjectShell
* pDoc
= SfxObjectShell::Current();
893 SfxMedium
* pMedium
= pDoc
->GetMedium();
894 if ( pMedium
&& !pMedium
->GetName().isEmpty() && pMedium
->GetStorage().is() )
896 Reference
< security::XDocumentDigitalSignatures
> xD(
897 security::DocumentDigitalSignatures::createDefault(comphelper::getProcessComponentContext()) );
900 Sequence
< security::DocumentSignatureInformation
> aInfos
;
901 aInfos
= xD
->verifyDocumentContentSignatures( pMedium
->GetZipStorageToSign_Impl(),
902 uno::Reference
< io::XInputStream
>() );
903 if ( aInfos
.getLength() > 1 )
904 s
= m_aMultiSignedStr
;
905 else if ( aInfos
.getLength() == 1 )
907 OUString
aCN_Id("CN");
908 const security::DocumentSignatureInformation
& rInfo
= aInfos
[ 0 ];
909 s
= GetDateTimeString( rInfo
.SignatureDate
, rInfo
.SignatureTime
);
911 s
+= GetContentPart( rInfo
.Signer
->getSubjectName(), aCN_Id
);
913 m_pSignedValFt
->SetText( s
);
918 void SfxDocumentPage::ImplCheckPasswordState()
920 SfxObjectShell
* pShell
= SfxObjectShell::Current();
925 SfxItemSet
* pMedSet
= pShell
->GetMedium()->GetItemSet();
928 SFX_ITEMSET_ARG( pMedSet
, pEncryptionDataItem
, SfxUnoAnyItem
, SID_ENCRYPTIONDATA
, false);
929 uno::Sequence
< beans::NamedValue
> aEncryptionData
;
930 if (pEncryptionDataItem
)
931 pEncryptionDataItem
->GetValue() >>= aEncryptionData
;
935 if (!aEncryptionData
.getLength())
937 m_pChangePassBtn
->Enable();
941 m_pChangePassBtn
->Disable();
944 VclPtr
<SfxTabPage
> SfxDocumentPage::Create( vcl::Window
* pParent
, const SfxItemSet
* rItemSet
)
946 return VclPtr
<SfxDocumentPage
>::Create( pParent
, *rItemSet
);
949 void SfxDocumentPage::EnableUseUserData()
951 bEnableUseUserData
= true;
952 m_pUseUserDataCB
->Show();
953 m_pDeleteBtn
->Show();
956 bool SfxDocumentPage::FillItemSet( SfxItemSet
* rSet
)
960 if ( !bHandleDelete
&& bEnableUseUserData
&&
961 m_pUseUserDataCB
->IsValueChangedFromSaved() &&
962 GetTabDialog() && GetTabDialog()->GetExampleSet() )
964 SfxItemSet
* pExpSet
= GetTabDialog()->GetExampleSet();
965 const SfxPoolItem
* pItem
;
967 if ( pExpSet
&& SfxItemState::SET
== pExpSet
->GetItemState( SID_DOCINFO
, true, &pItem
) )
969 const SfxDocumentInfoItem
* m_pInfoItem
= static_cast<const SfxDocumentInfoItem
*>(pItem
);
970 bool bUseData
= ( TRISTATE_TRUE
== m_pUseUserDataCB
->GetState() );
971 const_cast<SfxDocumentInfoItem
*>(m_pInfoItem
)->SetUseUserData( bUseData
);
972 rSet
->Put( SfxDocumentInfoItem( *m_pInfoItem
) );
979 SfxItemSet
* pExpSet
= GetTabDialog()->GetExampleSet();
980 const SfxPoolItem
* pItem
;
981 if ( pExpSet
&& SfxItemState::SET
== pExpSet
->GetItemState( SID_DOCINFO
, true, &pItem
) )
983 const SfxDocumentInfoItem
* pInfoItem
= static_cast<const SfxDocumentInfoItem
*>(pItem
);
984 bool bUseAuthor
= bEnableUseUserData
&& m_pUseUserDataCB
->IsChecked();
985 SfxDocumentInfoItem
newItem( *pInfoItem
);
986 newItem
.resetUserData( bUseAuthor
987 ? SvtUserOptions().GetFullName()
989 const_cast<SfxDocumentInfoItem
*>(pInfoItem
)->SetUseUserData( TRISTATE_TRUE
== m_pUseUserDataCB
->GetState() );
990 newItem
.SetUseUserData( TRISTATE_TRUE
== m_pUseUserDataCB
->GetState() );
992 newItem
.SetDeleteUserData( true );
993 rSet
->Put( newItem
);
1001 void SfxDocumentPage::Reset( const SfxItemSet
* rSet
)
1003 // Determine the document information
1004 const SfxDocumentInfoItem
& rInfoItem
=
1005 static_cast<const SfxDocumentInfoItem
&>(rSet
->Get(SID_DOCINFO
));
1008 if ( rInfoItem
.HasTemplate() )
1009 m_pTemplValFt
->SetText( rInfoItem
.getTemplateName() );
1013 m_pTemplValFt
->Hide();
1016 // determine file name
1017 OUString
aFile( rInfoItem
.GetValue() );
1018 OUString
aFactory( aFile
);
1019 if ( aFile
.getLength() > 2 && aFile
[0] == '[' )
1021 sal_Int32 nPos
= aFile
.indexOf( ']' );
1022 aFactory
= aFile
.copy( 1, nPos
-1 );
1023 aFile
= aFile
.copy( nPos
+1 );
1027 INetURLObject
aURL(aFile
);
1028 OUString aName
= aURL
.GetName( INetURLObject::DECODE_WITH_CHARSET
);
1029 if ( aName
.isEmpty() || aURL
.GetProtocol() == INetProtocol::PrivSoffice
)
1030 aName
= SfxResId( STR_NONAME
).toString();
1031 m_pNameED
->SetText( aName
);
1033 // determine context symbol
1034 aURL
.SetSmartProtocol( INetProtocol::File
);
1035 aURL
.SetSmartURL( aFactory
);
1036 const OUString
& rMainURL
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
1037 Image aImage
= SvFileInformationManager::GetImage( aURL
, true );
1039 if ( GetDPIScaleFactor() > 1)
1041 BitmapEx b
= aImage
.GetBitmapEx();
1042 b
.Scale(GetDPIScaleFactor(), GetDPIScaleFactor());
1046 m_pBmp
->SetImage( aImage
);
1048 // determine size and type
1049 OUString
aSizeText( m_aUnknownSize
);
1050 if ( aURL
.GetProtocol() == INetProtocol::File
)
1051 aSizeText
= CreateSizeText( SfxContentHelper::GetSize( aURL
.GetMainURL( INetURLObject::NO_DECODE
) ) );
1052 m_pShowSizeFT
->SetText( aSizeText
);
1054 OUString aDescription
= SvFileInformationManager::GetDescription( INetURLObject(rMainURL
) );
1055 if ( aDescription
.isEmpty() )
1056 aDescription
= SfxResId( STR_SFX_NEWOFFICEDOC
).toString();
1057 m_pShowTypeFT
->SetText( aDescription
);
1059 // determine location
1060 aURL
.SetSmartURL( aFile
);
1061 if ( aURL
.GetProtocol() == INetProtocol::File
)
1063 INetURLObject
aPath( aURL
);
1064 aPath
.setFinalSlash();
1065 aPath
.removeSegment();
1066 // we know it's a folder -> don't need the final slash, but it's better for WB_PATHELLIPSIS
1067 aPath
.removeFinalSlash();
1068 OUString
aText( aPath
.PathToFileName() ); //! (pb) MaxLen?
1069 m_pFileValEd
->SetText( aText
);
1071 else if ( aURL
.GetProtocol() != INetProtocol::PrivSoffice
)
1072 m_pFileValEd
->SetText( aURL
.GetPartBeforeLastName() );
1074 // handle access data
1075 bool m_bUseUserData
= rInfoItem
.IsUseUserData();
1076 const LocaleDataWrapper
& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
1077 m_pCreateValFt
->SetText( ConvertDateTime_Impl( rInfoItem
.getAuthor(),
1078 rInfoItem
.getCreationDate(), rLocaleWrapper
) );
1079 util::DateTime
aTime( rInfoItem
.getModificationDate() );
1080 if ( aTime
.Month
> 0 )
1081 m_pChangeValFt
->SetText( ConvertDateTime_Impl(
1082 rInfoItem
.getModifiedBy(), aTime
, rLocaleWrapper
) );
1083 aTime
= rInfoItem
.getPrintDate();
1084 if ( aTime
.Month
> 0 )
1085 m_pPrintValFt
->SetText( ConvertDateTime_Impl( rInfoItem
.getPrintedBy(),
1086 aTime
, rLocaleWrapper
) );
1087 const long nTime
= rInfoItem
.getEditingDuration();
1088 if ( m_bUseUserData
)
1090 const tools::Time
aT( nTime
/3600, (nTime
%3600)/60, nTime
%60 );
1091 m_pTimeLogValFt
->SetText( rLocaleWrapper
.getDuration( aT
) );
1092 m_pDocNoValFt
->SetText( OUString::number(
1093 rInfoItem
.getEditingCycles() ) );
1096 // Check for cmis properties where otherwise unavailable
1097 if ( rInfoItem
.isCmisDocument( ) )
1099 uno::Sequence
< document::CmisProperty
> aCmisProps
= rInfoItem
.GetCmisProperties();
1100 for ( sal_Int32 i
= 0; i
< aCmisProps
.getLength(); i
++ )
1102 if ( aCmisProps
[i
].Id
== "cmis:contentStreamLength" &&
1103 aSizeText
== m_aUnknownSize
)
1105 Sequence
< sal_Int64
> seqValue
;
1106 aCmisProps
[i
].Value
>>= seqValue
;
1107 SvNumberFormatter
m_aNumberFormatter( ::comphelper::getProcessComponentContext(),
1108 Application::GetSettings().GetLanguageTag().getLanguageType() );
1109 sal_uInt32 nIndex
= m_aNumberFormatter
.GetFormatIndex( NF_NUMBER_SYSTEM
);
1110 if ( seqValue
.getLength( ) > 0 )
1113 m_aNumberFormatter
.GetInputLineString( seqValue
[0], nIndex
, sValue
);
1114 m_pShowSizeFT
->SetText( CreateSizeText( sValue
.toInt64( ) ) );
1119 OUString emptyDate
= ConvertDateTime_Impl( "", uDT
, rLocaleWrapper
);
1120 if ( aCmisProps
[i
].Id
== "cmis:creationDate" &&
1121 (m_pCreateValFt
->GetText() == emptyDate
||
1122 m_pCreateValFt
->GetText().isEmpty()))
1124 Sequence
< util::DateTime
> seqValue
;
1125 aCmisProps
[i
].Value
>>= seqValue
;
1126 if ( seqValue
.getLength( ) > 0 )
1128 m_pCreateValFt
->SetText( ConvertDateTime_Impl( "", seqValue
[0], rLocaleWrapper
) );
1131 if ( aCmisProps
[i
].Id
== "cmis:lastModificationDate" &&
1132 (m_pChangeValFt
->GetText() == emptyDate
||
1133 m_pChangeValFt
->GetText().isEmpty()))
1135 Sequence
< util::DateTime
> seqValue
;
1136 aCmisProps
[i
].Value
>>= seqValue
;
1137 if ( seqValue
.getLength( ) > 0 )
1139 m_pChangeValFt
->SetText( ConvertDateTime_Impl( "", seqValue
[0], rLocaleWrapper
) );
1145 m_pUseUserDataCB
->SetState( static_cast<TriState
>(m_bUseUserData
) );
1146 m_pUseUserDataCB
->SaveValue();
1147 m_pUseUserDataCB
->Enable( bEnableUseUserData
);
1148 bHandleDelete
= false;
1149 m_pDeleteBtn
->Enable( bEnableUseUserData
);
1153 SfxDocumentInfoDialog::SfxDocumentInfoDialog( vcl::Window
* pParent
,
1154 const SfxItemSet
& rItemSet
)
1155 : SfxTabDialog(0, pParent
, "DocumentPropertiesDialog",
1156 "sfx/ui/documentpropertiesdialog.ui", &rItemSet
)
1159 const SfxDocumentInfoItem
& rInfoItem
=
1160 static_cast<const SfxDocumentInfoItem
&>(rItemSet
.Get( SID_DOCINFO
));
1163 SFX_ITEMSET_ARG( &rItemSet
, pURLItem
, SfxStringItem
, SID_BASEURL
, false );
1164 DBG_ASSERT( pURLItem
, "No BaseURL provided for InternetTabPage!" );
1167 // Determine the Titels
1168 const SfxPoolItem
* pItem
= 0;
1169 OUString
aTitle( GetText() );
1170 if ( SfxItemState::SET
!=
1171 rItemSet
.GetItemState( SID_EXPLORER_PROPS_START
, false, &pItem
) )
1174 OUString
aFile( rInfoItem
.GetValue() );
1177 aURL
.SetSmartProtocol( INetProtocol::File
);
1178 aURL
.SetSmartURL( aFile
);
1179 if ( INetProtocol::PrivSoffice
!= aURL
.GetProtocol() )
1181 OUString
aLastName( aURL
.GetLastName() );
1182 if ( !aLastName
.isEmpty() )
1183 aTitle
+= aLastName
;
1188 aTitle
+= SfxResId( STR_NONAME
).toString();
1192 DBG_ASSERT( pItem
->IsA( TYPE( SfxStringItem
) ),
1193 "SfxDocumentInfoDialog:<SfxStringItem> expected" );
1194 aTitle
+= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
1199 m_nDocInfoId
= AddTabPage("general", SfxDocumentPage::Create
, 0);
1200 AddTabPage("description", SfxDocumentDescPage::Create
, 0);
1201 AddTabPage("customprops", SfxCustomPropertiesPage::Create
, 0);
1202 AddTabPage("cmisprops", SfxCmisPropertiesPage::Create
, 0);
1203 AddTabPage("security", SfxSecurityPage::Create
, 0);
1208 void SfxDocumentInfoDialog::PageCreated( sal_uInt16 nId
, SfxTabPage
&rPage
)
1210 if ( m_nDocInfoId
== nId
)
1211 static_cast<SfxDocumentPage
&>(rPage
).EnableUseUserData();
1214 void SfxDocumentInfoDialog::AddFontTabPage()
1216 AddTabPage( FONT_PAGE_ID
, SfxResId( STR_FONT_TABPAGE
).toString(), SfxDocumentFontsPage::Create
, 0);
1219 // class CustomPropertiesYesNoButton -------------------------------------
1221 CustomPropertiesYesNoButton::CustomPropertiesYesNoButton( vcl::Window
* pParent
, const ResId
& rResId
) :
1222 Control( pParent
, rResId
),
1223 m_aYesButton( VclPtr
<RadioButton
>::Create(this, ResId( RB_PROPERTY_YES
, *rResId
.GetResMgr() )) ),
1224 m_aNoButton ( VclPtr
<RadioButton
>::Create(this, ResId( RB_PROPERTY_NO
, *rResId
.GetResMgr() )) )
1227 Wallpaper
aWall( Color( COL_TRANSPARENT
) );
1228 SetBackground( aWall
);
1229 SetBorderStyle( WindowBorderStyle::MONO
);
1231 m_aYesButton
->SetBackground( aWall
);
1232 m_aNoButton
->SetBackground( aWall
);
1236 CustomPropertiesYesNoButton::~CustomPropertiesYesNoButton()
1241 void CustomPropertiesYesNoButton::dispose()
1243 m_aYesButton
.disposeAndClear();
1244 m_aNoButton
.disposeAndClear();
1248 class DurationDialog_Impl
: public ModalDialog
1250 VclPtr
<CheckBox
> m_pNegativeCB
;
1251 VclPtr
<NumericField
> m_pYearNF
;
1252 VclPtr
<NumericField
> m_pMonthNF
;
1253 VclPtr
<NumericField
> m_pDayNF
;
1254 VclPtr
<NumericField
> m_pHourNF
;
1255 VclPtr
<NumericField
> m_pMinuteNF
;
1256 VclPtr
<NumericField
> m_pSecondNF
;
1257 VclPtr
<NumericField
> m_pMSecondNF
;
1261 DurationDialog_Impl( vcl::Window
* pParent
, const util::Duration
& rDuration
);
1262 virtual ~DurationDialog_Impl();
1263 virtual void dispose() SAL_OVERRIDE
;
1264 util::Duration
GetDuration() const;
1267 DurationDialog_Impl::DurationDialog_Impl(vcl::Window
* pParent
,
1268 const util::Duration
& rDuration
)
1269 : ModalDialog(pParent
, "EditDurationDialog",
1270 "sfx/ui/editdurationdialog.ui")
1272 get(m_pNegativeCB
, "negative");
1273 get(m_pYearNF
, "years");
1274 get(m_pMonthNF
, "months");
1275 get(m_pDayNF
, "days");
1276 get(m_pHourNF
, "hours");
1277 get(m_pMinuteNF
, "minutes");
1278 get(m_pSecondNF
, "seconds");
1279 get(m_pMSecondNF
, "milliseconds");
1281 m_pNegativeCB
->Check(rDuration
.Negative
);
1282 m_pYearNF
->SetValue(rDuration
.Years
);
1283 m_pMonthNF
->SetValue(rDuration
.Months
);
1284 m_pDayNF
->SetValue(rDuration
.Days
);
1285 m_pHourNF
->SetValue(rDuration
.Hours
);
1286 m_pMinuteNF
->SetValue(rDuration
.Minutes
);
1287 m_pSecondNF
->SetValue(rDuration
.Seconds
);
1288 m_pMSecondNF
->SetValue(rDuration
.NanoSeconds
);
1291 DurationDialog_Impl::~DurationDialog_Impl()
1296 void DurationDialog_Impl::dispose()
1298 m_pNegativeCB
.clear();
1303 m_pMinuteNF
.clear();
1304 m_pSecondNF
.clear();
1305 m_pMSecondNF
.clear();
1306 ModalDialog::dispose();
1309 util::Duration
DurationDialog_Impl::GetDuration() const
1311 util::Duration aRet
;
1312 aRet
.Negative
= m_pNegativeCB
->IsChecked();
1313 aRet
.Years
= m_pYearNF
->GetValue();
1314 aRet
.Months
= m_pMonthNF
->GetValue( );
1315 aRet
.Days
= m_pDayNF
->GetValue( );
1316 aRet
.Hours
= m_pHourNF
->GetValue( );
1317 aRet
.Minutes
= m_pMinuteNF
->GetValue();
1318 aRet
.Seconds
= m_pSecondNF
->GetValue();
1319 aRet
.NanoSeconds
= m_pMSecondNF
->GetValue();
1323 CustomPropertiesDurationField::CustomPropertiesDurationField(vcl::Window
* pParent
, WinBits nStyle
,
1324 CustomPropertyLine
* pLine
)
1325 : Edit(pParent
, nStyle
)
1329 SetDuration( util::Duration(false, 0, 0, 0, 0, 0, 0, 0) );
1332 void CustomPropertiesDurationField::RequestHelp( const HelpEvent
& rHEvt
)
1334 if ( rHEvt
.GetMode() & HelpEventMode::QUICK
)
1336 Size
aSize( GetSizePixel() );
1337 Rectangle
aItemRect( rHEvt
.GetMousePosPixel(), aSize
);
1338 if (Help::IsBalloonHelpEnabled())
1339 Help::ShowBalloon( this, rHEvt
.GetMousePosPixel(), GetText() );
1341 Help::ShowQuickHelp( this, aItemRect
, GetText(),
1342 QuickHelpFlags::Left
|QuickHelpFlags::VCenter
);
1346 void CustomPropertiesDurationField::SetDuration( const util::Duration
& rDuration
)
1348 m_aDuration
= rDuration
;
1349 OUString
sText(rDuration
.Negative
? OUString('-') : OUString('+'));
1350 sText
+= m_pLine
->m_sDurationFormat
;
1351 sText
= sText
.replaceFirst( "%1", OUString::number( rDuration
.Years
) );
1352 sText
= sText
.replaceFirst( "%2", OUString::number( rDuration
.Months
) );
1353 sText
= sText
.replaceFirst( "%3", OUString::number( rDuration
.Days
) );
1354 sText
= sText
.replaceFirst( "%4", OUString::number( rDuration
.Hours
) );
1355 sText
= sText
.replaceFirst( "%5", OUString::number( rDuration
.Minutes
) );
1356 sText
= sText
.replaceFirst( "%6", OUString::number( rDuration
.Seconds
) );
1360 CustomPropertiesEditButton::CustomPropertiesEditButton(vcl::Window
* pParent
, WinBits nStyle
,
1361 CustomPropertyLine
* pLine
)
1362 : PushButton(pParent
, nStyle
)
1365 SetClickHdl( LINK( this, CustomPropertiesEditButton
, ClickHdl
));
1368 IMPL_LINK_NOARG(CustomPropertiesEditButton
, ClickHdl
)
1370 VclPtrInstance
< DurationDialog_Impl
> pDurationDlg( this, m_pLine
->m_aDurationField
->GetDuration() );
1371 if ( RET_OK
== pDurationDlg
->Execute() )
1372 m_pLine
->m_aDurationField
->SetDuration( pDurationDlg
->GetDuration() );
1376 void CustomPropertiesYesNoButton::Resize()
1378 const long nWidth
= GetSizePixel().Width();
1379 const long n3Width
= LogicToPixel( Size( 3, 3 ), MAP_APPFONT
).Width();
1380 const long nNewWidth
= ( nWidth
/ 2 ) - n3Width
- 2;
1381 Size aSize
= m_aYesButton
->GetSizePixel();
1382 const long nDelta
= aSize
.Width() - nNewWidth
;
1383 aSize
.Width() = nNewWidth
;
1384 m_aYesButton
->SetSizePixel( aSize
);
1385 Point aPos
= m_aNoButton
->GetPosPixel();
1387 m_aNoButton
->SetPosSizePixel( aPos
, aSize
);
1390 // struct CustomPropertyLine ---------------------------------------------
1391 CustomPropertyLine::CustomPropertyLine( vcl::Window
* pParent
) :
1392 m_aNameBox ( VclPtr
<ComboBox
>::Create(pParent
, SfxResId( SFX_CB_PROPERTY_NAME
)) ),
1393 m_aTypeBox ( VclPtr
<CustomPropertiesTypeBox
>::Create(pParent
, SfxResId( SFX_LB_PROPERTY_TYPE
), this) ),
1394 m_aValueEdit ( VclPtr
<CustomPropertiesEdit
>::Create(pParent
, WB_BORDER
|WB_TABSTOP
|WB_LEFT
, this ) ),
1395 m_aDateField ( VclPtr
<CustomPropertiesDateField
>::Create(pParent
, WB_BORDER
|WB_TABSTOP
|WB_SPIN
|WB_LEFT
, this ) ),
1396 m_aTimeField ( VclPtr
<CustomPropertiesTimeField
>::Create(pParent
, WB_BORDER
|WB_TABSTOP
|WB_SPIN
|WB_LEFT
, this ) ),
1397 m_sDurationFormat( SfxResId( SFX_ST_DURATION_FORMAT
).toString() ),
1398 m_aDurationField( VclPtr
<CustomPropertiesDurationField
>::Create(pParent
, WB_BORDER
|WB_TABSTOP
|WB_READONLY
, this ) ),
1399 m_aEditButton ( VclPtr
<CustomPropertiesEditButton
>::Create(pParent
, WB_TABSTOP
, this) ),
1400 m_aYesNoButton ( VclPtr
<CustomPropertiesYesNoButton
>::Create(pParent
, SfxResId( SFX_WIN_PROPERTY_YESNO
)) ),
1401 m_aRemoveButton ( VclPtr
<CustomPropertiesRemoveButton
>::Create(pParent
, 0, this) ),
1402 m_bIsDate ( false ),
1403 m_bIsRemoved ( false ),
1404 m_bTypeLostFocus( false )
1407 m_aTimeField
->SetExtFormat( EXTTIMEF_24H_LONG
);
1408 m_aDateField
->SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY
);
1410 m_aRemoveButton
->SetModeImage(Image(SfxResId(SFX_IMG_PROPERTY_REMOVE
)));
1411 m_aRemoveButton
->SetQuickHelpText(SfxResId(STR_SFX_REMOVE_PROPERTY
).toString());
1413 m_aEditButton
->SetText(SfxResId(SFX_ST_EDIT
).toString());
1416 void CustomPropertyLine::SetRemoved()
1418 DBG_ASSERT( !m_bIsRemoved
, "CustomPropertyLine::SetRemoved(): line already removed" );
1419 m_bIsRemoved
= true;
1422 m_aValueEdit
->Hide();
1423 m_aDateField
->Hide();
1424 m_aTimeField
->Hide();
1425 m_aDurationField
->Hide();
1426 m_aEditButton
->Hide();
1427 m_aYesNoButton
->Hide();
1428 m_aRemoveButton
->Hide();
1431 CustomPropertiesWindow::CustomPropertiesWindow(vcl::Window
* pParent
,
1432 FixedText
*pHeaderAccName
,
1433 FixedText
*pHeaderAccType
,
1434 FixedText
*pHeaderAccValue
) :
1435 Window(pParent
, WB_HIDE
| WB_CLIPCHILDREN
| WB_TABSTOP
| WB_DIALOGCONTROL
),
1436 m_pHeaderAccName(pHeaderAccName
),
1437 m_pHeaderAccType(pHeaderAccType
),
1438 m_pHeaderAccValue(pHeaderAccValue
),
1439 m_aNameBox ( VclPtr
<ComboBox
>::Create( this, SfxResId( SFX_CB_PROPERTY_NAME
) ) ),
1440 m_aTypeBox ( VclPtr
<ListBox
>::Create( this, SfxResId( SFX_LB_PROPERTY_TYPE
) ) ),
1441 m_aValueEdit ( VclPtr
<Edit
>::Create( this, WB_BORDER
|WB_TABSTOP
|WB_LEFT
) ),
1442 m_aDateField ( VclPtr
<DateField
>::Create( this, WB_BORDER
|WB_TABSTOP
|WB_SPIN
|WB_LEFT
) ),
1443 m_aTimeField ( VclPtr
<TimeField
>::Create( this, WB_BORDER
|WB_TABSTOP
|WB_SPIN
|WB_LEFT
) ),
1444 m_aDurationField( VclPtr
<Edit
>::Create( this, WB_BORDER
|WB_TABSTOP
|WB_READONLY
) ),
1445 m_aEditButton ( VclPtr
<PushButton
>::Create( this, WB_TABSTOP
) ),
1446 m_aYesNoButton ( VclPtr
<CustomPropertiesYesNoButton
>::Create( this, SfxResId( SFX_WIN_PROPERTY_YESNO
)) ),
1447 m_aRemoveButton ( VclPtr
<ImageButton
>::Create( this, 0 ) ),
1449 m_pCurrentLine (NULL
),
1450 m_aNumberFormatter( ::comphelper::getProcessComponentContext(),
1451 Application::GetSettings().GetLanguageTag().getLanguageType() )
1454 m_aEditButton
->SetPosSizePixel(
1455 LogicToPixel(Point(159, 2), MAP_APPFONT
),
1456 LogicToPixel(Size(RSC_CD_TEXTBOX_HEIGHT
, RSC_CD_TEXTBOX_HEIGHT
), MAP_APPFONT
));
1457 m_aRemoveButton
->SetSizePixel(LogicToPixel(Size(RSC_CD_PUSHBUTTON_HEIGHT
, RSC_CD_PUSHBUTTON_HEIGHT
), MAP_APPFONT
));
1459 m_aValueEdit
->SetPosSizePixel(
1460 LogicToPixel(Point(159, 2), MAP_APPFONT
),
1461 LogicToPixel(Size(61, RSC_CD_TEXTBOX_HEIGHT
), MAP_APPFONT
));
1463 m_aEditLoseFocusIdle
.SetPriority( SchedulerPriority::LOWEST
);
1464 m_aEditLoseFocusIdle
.SetIdleHdl( LINK( this, CustomPropertiesWindow
, EditTimeoutHdl
) );
1465 m_aBoxLoseFocusIdle
.SetPriority( SchedulerPriority::LOWEST
);
1466 m_aBoxLoseFocusIdle
.SetIdleHdl( LINK( this, CustomPropertiesWindow
, BoxTimeoutHdl
) );
1468 m_aNameBox
->add_mnemonic_label(m_pHeaderAccName
);
1469 m_aNameBox
->SetAccessibleName(m_pHeaderAccName
->GetText());
1470 m_aTypeBox
->add_mnemonic_label(m_pHeaderAccType
);
1471 m_aTypeBox
->SetAccessibleName(m_pHeaderAccType
->GetText());
1472 m_aValueEdit
->add_mnemonic_label(m_pHeaderAccValue
);
1473 m_aValueEdit
->SetAccessibleName(m_pHeaderAccValue
->GetText());
1477 m_aValueEdit
->Hide();
1478 m_aDateField
->Hide();
1479 m_aTimeField
->Hide();
1480 m_aDurationField
->Hide();
1481 m_aEditButton
->Hide();
1482 m_aYesNoButton
->Hide();
1483 m_aRemoveButton
->Hide();
1486 ( m_aRemoveButton
->GetPosPixel().Y() * 2 ) + m_aRemoveButton
->GetSizePixel().Height();
1489 CustomPropertiesWindow::~CustomPropertiesWindow()
1494 void CustomPropertiesWindow::dispose()
1496 m_aEditLoseFocusIdle
.Stop();
1497 m_aBoxLoseFocusIdle
.Stop();
1499 m_aNameBox
.disposeAndClear();
1500 m_aTypeBox
.disposeAndClear();
1501 m_aValueEdit
.disposeAndClear();
1502 m_aDateField
.disposeAndClear();
1503 m_aTimeField
.disposeAndClear();
1504 m_aDurationField
.disposeAndClear();
1505 m_aEditButton
.disposeAndClear();
1506 m_aYesNoButton
.disposeAndClear();
1507 m_aRemoveButton
.disposeAndClear();
1508 m_pHeaderAccName
.clear();
1509 m_pHeaderAccType
.clear();
1510 m_pHeaderAccValue
.clear();
1511 vcl::Window::dispose();
1515 CustomPropertiesWindow
, TypeHdl
, CustomPropertiesTypeBox
*, pBox
)
1517 long nType
= reinterpret_cast<long>( pBox
->GetSelectEntryData() );
1518 CustomPropertyLine
* pLine
= pBox
->GetLine();
1519 pLine
->m_aValueEdit
->Show( (CUSTOM_TYPE_TEXT
== nType
) || (CUSTOM_TYPE_NUMBER
== nType
) );
1520 pLine
->m_aDateField
->Show( (CUSTOM_TYPE_DATE
== nType
) || (CUSTOM_TYPE_DATETIME
== nType
) );
1521 pLine
->m_aTimeField
->Show( CUSTOM_TYPE_DATETIME
== nType
);
1522 pLine
->m_aDurationField
->Show( CUSTOM_TYPE_DURATION
== nType
);
1523 pLine
->m_aEditButton
->Show( CUSTOM_TYPE_DURATION
== nType
);
1524 pLine
->m_aYesNoButton
->Show( CUSTOM_TYPE_BOOLEAN
== nType
);
1526 //adjust positions of date and time controls
1527 if ( nType
== CUSTOM_TYPE_DATE
)
1529 pLine
->m_bIsDate
= true;
1530 pLine
->m_aDateField
->SetSizePixel( pLine
->m_aValueEdit
->GetSizePixel() );
1532 else if ( nType
== CUSTOM_TYPE_DATETIME
)
1534 // because m_aDateField and m_aTimeField have the same size for type "DateTime",
1535 // we just rely on m_aTimeField here.
1536 pLine
->m_bIsDate
= false;
1537 pLine
->m_aDateField
->SetSizePixel( pLine
->m_aTimeField
->GetSizePixel() );
1543 IMPL_LINK( CustomPropertiesWindow
, RemoveHdl
, CustomPropertiesRemoveButton
*, pButton
)
1545 CustomPropertyLine
* pLine
= pButton
->GetLine();
1546 std::vector
< CustomPropertyLine
* >::iterator pFound
=
1547 std::find( m_aCustomPropertiesLines
.begin(), m_aCustomPropertiesLines
.end(), pLine
);
1548 if ( pFound
!= m_aCustomPropertiesLines
.end() )
1551 pLine
->SetRemoved();
1552 std::vector
< CustomPropertyLine
* >::iterator pIter
= pFound
+ 1;
1553 const long nDelta
= GetLineHeight();
1554 for ( ; pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1557 if ( pLine
->m_bIsRemoved
)
1560 vcl::Window
* pWindows
[] = { pLine
->m_aNameBox
.get(), pLine
->m_aTypeBox
.get(), pLine
->m_aValueEdit
.get(),
1561 pLine
->m_aDateField
.get(), pLine
->m_aTimeField
.get(),
1562 pLine
->m_aDurationField
.get(), pLine
->m_aEditButton
.get(),
1563 pLine
->m_aYesNoButton
.get(), pLine
->m_aRemoveButton
.get(), NULL
};
1564 vcl::Window
** pCurrent
= pWindows
;
1567 Point aPos
= (*pCurrent
)->GetPosPixel();
1569 (*pCurrent
)->SetPosPixel( aPos
);
1575 m_aRemovedHdl
.Call(0);
1579 IMPL_LINK( CustomPropertiesWindow
, EditLoseFocusHdl
, CustomPropertiesEdit
*, pEdit
)
1583 CustomPropertyLine
* pLine
= pEdit
->GetLine();
1584 if ( !pLine
->m_bTypeLostFocus
)
1586 m_pCurrentLine
= pLine
;
1587 m_aEditLoseFocusIdle
.Start();
1590 pLine
->m_bTypeLostFocus
= false;
1595 IMPL_LINK( CustomPropertiesWindow
, BoxLoseFocusHdl
, CustomPropertiesTypeBox
*, pBox
)
1599 m_pCurrentLine
= pBox
->GetLine();
1600 m_aBoxLoseFocusIdle
.Start();
1606 IMPL_LINK_NOARG_TYPED(CustomPropertiesWindow
, EditTimeoutHdl
, Idle
*, void)
1608 ValidateLine( m_pCurrentLine
, false );
1611 IMPL_LINK_NOARG_TYPED(CustomPropertiesWindow
, BoxTimeoutHdl
, Idle
*, void)
1613 ValidateLine( m_pCurrentLine
, true );
1616 bool CustomPropertiesWindow::IsLineValid( CustomPropertyLine
* pLine
) const
1618 bool bIsValid
= true;
1619 pLine
->m_bTypeLostFocus
= false;
1620 long nType
= reinterpret_cast<long>(
1621 pLine
->m_aTypeBox
->GetSelectEntryData() );
1622 OUString sValue
= pLine
->m_aValueEdit
->GetText();
1623 if ( sValue
.isEmpty() )
1626 sal_uInt32 nIndex
= 0xFFFFFFFF;
1627 if ( CUSTOM_TYPE_NUMBER
== nType
)
1628 nIndex
= const_cast< SvNumberFormatter
& >(
1629 m_aNumberFormatter
).GetFormatIndex( NF_NUMBER_SYSTEM
);
1630 else if ( CUSTOM_TYPE_DATE
== nType
)
1631 nIndex
= const_cast< SvNumberFormatter
& >(
1632 m_aNumberFormatter
).GetFormatIndex( NF_DATE_SYS_DDMMYYYY
);
1634 if ( nIndex
!= 0xFFFFFFFF )
1636 sal_uInt32 nTemp
= nIndex
;
1637 double fDummy
= 0.0;
1638 bIsValid
= const_cast< SvNumberFormatter
& >(
1639 m_aNumberFormatter
).IsNumberFormat( sValue
, nIndex
, fDummy
);
1640 if ( bIsValid
&& nTemp
!= nIndex
)
1641 // sValue is a number but the format doesn't match the index
1648 void CustomPropertiesWindow::ValidateLine( CustomPropertyLine
* pLine
, bool bIsFromTypeBox
)
1650 if ( !IsLineValid( pLine
) )
1652 if ( bIsFromTypeBox
) // LoseFocus of TypeBox
1653 pLine
->m_bTypeLostFocus
= true;
1654 vcl::Window
* pParent
= GetParent()->GetParent();
1655 if (ScopedVclPtrInstance
<MessageDialog
>::Create(pParent
, SfxResId(STR_SFX_QUERY_WRONG_TYPE
), VCL_MESSAGE_QUESTION
, VCL_BUTTONS_OK_CANCEL
)->Execute() == RET_OK
)
1656 pLine
->m_aTypeBox
->SelectEntryPos( m_aTypeBox
->GetEntryPos( reinterpret_cast<void*>(CUSTOM_TYPE_TEXT
) ) );
1658 pLine
->m_aValueEdit
->GrabFocus();
1662 bool CustomPropertiesWindow::InitControls( HeaderBar
* pHeaderBar
, const ScrollBar
* pScrollBar
)
1664 bool bChanged
= false;
1666 DBG_ASSERT( pHeaderBar
, "CustomPropertiesWindow::InitControls(): invalid headerbar" );
1667 DBG_ASSERT( pScrollBar
, "CustomPropertiesWindow::InitControls(): invalid scrollbar" );
1669 const long nOffset
= 4;
1670 const long nScrollBarWidth
= pScrollBar
->GetSizePixel().Width();
1671 const long nButtonWidth
= m_aRemoveButton
->GetSizePixel().Width() + nScrollBarWidth
+ nOffset
;
1672 long nTypeWidth
= m_aTypeBox
->CalcMinimumSize().Width() + ( 2 * nOffset
);
1673 long nFullWidth
= pHeaderBar
->GetSizePixel().Width();
1674 long nItemWidth
= ( nFullWidth
- nTypeWidth
- nButtonWidth
) / 2;
1675 pHeaderBar
->SetItemSize( HI_NAME
, nItemWidth
);
1676 pHeaderBar
->SetItemSize( HI_TYPE
, nTypeWidth
);
1677 pHeaderBar
->SetItemSize( HI_VALUE
, nItemWidth
);
1678 pHeaderBar
->SetItemSize( HI_ACTION
, nButtonWidth
);
1680 vcl::Window
* pWindows
[] = { m_aNameBox
.get(), m_aTypeBox
.get(), m_aValueEdit
.get(), m_aRemoveButton
.get(), NULL
};
1681 vcl::Window
** pCurrent
= pWindows
;
1682 sal_uInt16 nPos
= 0;
1685 Rectangle aRect
= pHeaderBar
->GetItemRect( pHeaderBar
->GetItemId( nPos
++ ) );
1686 Size aOrigSize
= (*pCurrent
)->GetSizePixel();
1687 Point aOrigPos
= (*pCurrent
)->GetPosPixel();
1688 Size
aSize(aOrigSize
);
1689 Point
aPos(aOrigPos
);
1690 long nWidth
= aRect
.GetWidth() - nOffset
;
1691 if ( *pCurrent
== m_aRemoveButton
.get() )
1692 nWidth
-= pScrollBar
->GetSizePixel().Width();
1693 aSize
.Width() = nWidth
;
1694 aPos
.X() = aRect
.getX() + ( nOffset
/ 2 );
1696 if (aOrigSize
!= aSize
|| aOrigPos
!= aPos
)
1698 (*pCurrent
)->SetPosSizePixel(aPos
, aSize
);
1702 if ( *pCurrent
== m_aValueEdit
.get() )
1704 Point
aDurationPos( aPos
);
1705 m_aDurationField
->SetPosPixel( aDurationPos
);
1706 Size
aDurationSize(aSize
);
1707 aDurationSize
.Width() -= (m_aEditButton
->GetSizePixel().Width() + 3 );
1708 m_aDurationField
->SetSizePixel(aDurationSize
);
1709 aDurationPos
.X() = aPos
.X() - m_aEditButton
->GetSizePixel().Width() + aSize
.Width();
1710 m_aEditButton
->SetPosPixel(aDurationPos
);
1712 m_aYesNoButton
->SetPosSizePixel( aPos
, aSize
);
1716 m_aDateField
->SetPosSizePixel( aPos
, aSize
);
1717 aPos
.X() += aSize
.Width() + 4;
1718 m_aTimeField
->SetPosSizePixel( aPos
, aSize
);
1726 sal_uInt16
CustomPropertiesWindow::GetVisibleLineCount() const
1728 sal_uInt16 nCount
= 0;
1729 std::vector
< CustomPropertyLine
* >::const_iterator pIter
;
1730 for ( pIter
= m_aCustomPropertiesLines
.begin();
1731 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1733 CustomPropertyLine
* pLine
= *pIter
;
1734 if ( !pLine
->m_bIsRemoved
)
1740 void CustomPropertiesWindow::updateLineWidth()
1742 vcl::Window
* pWindows
[] = { m_aNameBox
.get(), m_aTypeBox
.get(), m_aValueEdit
.get(),
1743 m_aDateField
.get(), m_aTimeField
.get(),
1744 m_aDurationField
.get(), m_aEditButton
.get(),
1745 m_aYesNoButton
.get(), m_aRemoveButton
.get(), NULL
};
1747 for (std::vector
< CustomPropertyLine
* >::iterator aI
=
1748 m_aCustomPropertiesLines
.begin(), aEnd
= m_aCustomPropertiesLines
.end();
1751 CustomPropertyLine
* pNewLine
= *aI
;
1753 vcl::Window
* pNewWindows
[] =
1754 { pNewLine
->m_aNameBox
.get(), pNewLine
->m_aTypeBox
.get(), pNewLine
->m_aValueEdit
.get(),
1755 pNewLine
->m_aDateField
.get(), pNewLine
->m_aTimeField
.get(),
1756 pNewLine
->m_aDurationField
.get(), pNewLine
->m_aEditButton
.get(),
1757 pNewLine
->m_aYesNoButton
.get(), pNewLine
->m_aRemoveButton
.get(), NULL
};
1759 vcl::Window
** pCurrent
= pWindows
;
1760 vcl::Window
** pNewCurrent
= pNewWindows
;
1763 Size aSize
= (*pCurrent
)->GetSizePixel();
1764 Point aPos
= (*pCurrent
)->GetPosPixel();
1765 aPos
.Y() = (*pNewCurrent
)->GetPosPixel().Y();
1766 (*pNewCurrent
)->SetPosSizePixel( aPos
, aSize
);
1771 // if we have type "Date", we use the full width, not only the half
1772 if (pNewLine
->m_bIsDate
)
1773 pNewLine
->m_aDateField
->SetSizePixel( pNewLine
->m_aValueEdit
->GetSizePixel() );
1777 void CustomPropertiesWindow::AddLine( const OUString
& sName
, Any
& rAny
)
1779 CustomPropertyLine
* pNewLine
= new CustomPropertyLine( this );
1780 pNewLine
->m_aTypeBox
->SetSelectHdl( LINK( this, CustomPropertiesWindow
, TypeHdl
) );
1781 pNewLine
->m_aRemoveButton
->SetClickHdl( LINK( this, CustomPropertiesWindow
, RemoveHdl
) );
1782 pNewLine
->m_aValueEdit
->SetLoseFocusHdl( LINK( this, CustomPropertiesWindow
, EditLoseFocusHdl
) );
1783 //add lose focus handlers of date/time fields
1785 pNewLine
->m_aTypeBox
->SetLoseFocusHdl( LINK( this, CustomPropertiesWindow
, BoxLoseFocusHdl
) );
1787 pNewLine
->m_aNameBox
->add_mnemonic_label(m_pHeaderAccName
);
1788 pNewLine
->m_aNameBox
->SetAccessibleName(m_pHeaderAccName
->GetText());
1789 pNewLine
->m_aTypeBox
->add_mnemonic_label(m_pHeaderAccType
);
1790 pNewLine
->m_aTypeBox
->SetAccessibleName(m_pHeaderAccType
->GetText());
1791 pNewLine
->m_aValueEdit
->add_mnemonic_label(m_pHeaderAccValue
);
1792 pNewLine
->m_aValueEdit
->SetAccessibleName(m_pHeaderAccValue
->GetText());
1794 sal_Int32 nPos
= GetVisibleLineCount() * GetLineHeight();
1795 m_aCustomPropertiesLines
.push_back( pNewLine
);
1796 vcl::Window
* pWindows
[] = { m_aNameBox
.get(), m_aTypeBox
.get(), m_aValueEdit
.get(),
1797 m_aDateField
.get(), m_aTimeField
.get(),
1798 m_aDurationField
.get(), m_aEditButton
.get(),
1799 m_aYesNoButton
.get(), m_aRemoveButton
.get(), NULL
};
1800 vcl::Window
* pNewWindows
[] =
1801 { pNewLine
->m_aNameBox
.get(), pNewLine
->m_aTypeBox
.get(), pNewLine
->m_aValueEdit
.get(),
1802 pNewLine
->m_aDateField
.get(), pNewLine
->m_aTimeField
.get(),
1803 pNewLine
->m_aDurationField
.get(), pNewLine
->m_aEditButton
.get(),
1804 pNewLine
->m_aYesNoButton
.get(), pNewLine
->m_aRemoveButton
.get(), NULL
};
1805 vcl::Window
** pCurrent
= pWindows
;
1806 vcl::Window
** pNewCurrent
= pNewWindows
;
1809 Size aSize
= (*pCurrent
)->GetSizePixel();
1810 Point aPos
= (*pCurrent
)->GetPosPixel();
1812 aPos
.Y() += m_nScrollPos
;
1813 (*pNewCurrent
)->SetPosSizePixel( aPos
, aSize
);
1814 (*pNewCurrent
)->Show();
1819 double nTmpValue
= 0;
1820 bool bTmpValue
= false;
1822 util::DateTime aTmpDateTime
;
1823 util::Date aTmpDate
;
1824 util::DateTimeWithTimezone aTmpDateTimeTZ
;
1825 util::DateWithTimezone aTmpDateTZ
;
1826 util::Duration aTmpDuration
;
1827 SvtSysLocale aSysLocale
;
1828 const LocaleDataWrapper
& rLocaleWrapper
= aSysLocale
.GetLocaleData();
1829 pNewLine
->m_aNameBox
->SetText( sName
);
1830 sal_IntPtr nType
= CUSTOM_TYPE_UNKNOWN
;
1833 if ( rAny
>>= nTmpValue
)
1835 sal_uInt32 nIndex
= m_aNumberFormatter
.GetFormatIndex( NF_NUMBER_SYSTEM
);
1836 m_aNumberFormatter
.GetInputLineString( nTmpValue
, nIndex
, sValue
);
1837 pNewLine
->m_aValueEdit
->SetText( sValue
);
1838 nType
= CUSTOM_TYPE_NUMBER
;
1840 else if ( rAny
>>= bTmpValue
)
1842 sValue
= ( bTmpValue
? rLocaleWrapper
.getTrueWord() : rLocaleWrapper
.getFalseWord() );
1843 nType
= CUSTOM_TYPE_BOOLEAN
;
1845 else if ( rAny
>>= sTmpValue
)
1847 pNewLine
->m_aValueEdit
->SetText( sTmpValue
);
1848 nType
= CUSTOM_TYPE_TEXT
;
1850 else if ( rAny
>>= aTmpDate
)
1852 pNewLine
->m_aDateField
->SetDate( Date( aTmpDate
) );
1853 nType
= CUSTOM_TYPE_DATE
;
1855 else if ( rAny
>>= aTmpDateTime
)
1857 pNewLine
->m_aDateField
->SetDate( Date( aTmpDateTime
) );
1858 pNewLine
->m_aTimeField
->SetTime( tools::Time( aTmpDateTime
) );
1859 pNewLine
->m_aTimeField
->m_isUTC
= aTmpDateTime
.IsUTC
;
1860 nType
= CUSTOM_TYPE_DATETIME
;
1862 else if ( rAny
>>= aTmpDateTZ
)
1864 pNewLine
->m_aDateField
->SetDate( Date( aTmpDateTZ
.DateInTZ
.Day
,
1865 aTmpDateTZ
.DateInTZ
.Month
, aTmpDateTZ
.DateInTZ
.Year
) );
1866 pNewLine
->m_aDateField
->m_TZ
= aTmpDateTZ
.Timezone
;
1867 nType
= CUSTOM_TYPE_DATE
;
1869 else if ( rAny
>>= aTmpDateTimeTZ
)
1871 util::DateTime
const& rDT(aTmpDateTimeTZ
.DateTimeInTZ
);
1872 pNewLine
->m_aDateField
->SetDate( Date( rDT
) );
1873 pNewLine
->m_aTimeField
->SetTime( tools::Time( rDT
) );
1874 pNewLine
->m_aTimeField
->m_isUTC
= rDT
.IsUTC
;
1875 pNewLine
->m_aDateField
->m_TZ
= aTmpDateTimeTZ
.Timezone
;
1876 nType
= CUSTOM_TYPE_DATETIME
;
1878 else if ( rAny
>>= aTmpDuration
)
1880 nType
= CUSTOM_TYPE_DURATION
;
1881 pNewLine
->m_aDurationField
->SetDuration( aTmpDuration
);
1884 if ( nType
!= CUSTOM_TYPE_UNKNOWN
)
1886 if ( CUSTOM_TYPE_BOOLEAN
== nType
)
1889 pNewLine
->m_aYesNoButton
->CheckYes();
1891 pNewLine
->m_aYesNoButton
->CheckNo();
1893 pNewLine
->m_aTypeBox
->SelectEntryPos( m_aTypeBox
->GetEntryPos( reinterpret_cast<void*>(nType
) ) );
1896 TypeHdl( nullptr, pNewLine
->m_aTypeBox
.get() );
1897 pNewLine
->m_aNameBox
->GrabFocus();
1900 bool CustomPropertiesWindow::AreAllLinesValid() const
1903 std::vector
< CustomPropertyLine
* >::const_iterator pIter
;
1904 for ( pIter
= m_aCustomPropertiesLines
.begin();
1905 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1907 CustomPropertyLine
* pLine
= *pIter
;
1908 if ( !IsLineValid( pLine
) )
1918 void CustomPropertiesWindow::ClearAllLines()
1920 std::vector
< CustomPropertyLine
* >::iterator pIter
;
1921 for ( pIter
= m_aCustomPropertiesLines
.begin();
1922 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1924 CustomPropertyLine
* pLine
= *pIter
;
1925 pLine
->SetRemoved();
1928 m_aCustomPropertiesLines
.clear();
1932 void CustomPropertiesWindow::DoScroll( sal_Int32 nNewPos
)
1934 m_nScrollPos
+= nNewPos
;
1935 std::vector
< CustomPropertyLine
* >::iterator pIter
;
1936 for ( pIter
= m_aCustomPropertiesLines
.begin();
1937 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
)
1939 CustomPropertyLine
* pLine
= *pIter
;
1940 if ( pLine
->m_bIsRemoved
)
1943 vcl::Window
* pWindows
[] = { pLine
->m_aNameBox
.get(), pLine
->m_aTypeBox
.get(), pLine
->m_aValueEdit
.get(), pLine
->m_aDateField
.get(), pLine
->m_aTimeField
.get(),
1944 pLine
->m_aDurationField
.get(), pLine
->m_aEditButton
.get(), pLine
->m_aYesNoButton
.get(), pLine
->m_aRemoveButton
.get(), NULL
};
1945 vcl::Window
** pCurrent
= pWindows
;
1948 Point aPos
= (*pCurrent
)->GetPosPixel();
1949 aPos
.Y() += nNewPos
;
1950 (*pCurrent
)->SetPosPixel( aPos
);
1956 Sequence
< beans::PropertyValue
> CustomPropertiesWindow::GetCustomProperties() const
1958 Sequence
< beans::PropertyValue
> aPropertiesSeq( m_aCustomPropertiesLines
.size() );
1960 std::vector
< CustomPropertyLine
* >::const_iterator pIter
;
1961 for ( pIter
= m_aCustomPropertiesLines
.begin();
1962 pIter
!= m_aCustomPropertiesLines
.end(); ++pIter
, ++i
)
1964 CustomPropertyLine
* pLine
= *pIter
;
1965 if ( pLine
->m_bIsRemoved
)
1968 OUString sPropertyName
= pLine
->m_aNameBox
->GetText();
1969 if ( !sPropertyName
.isEmpty() )
1971 aPropertiesSeq
[i
].Name
= sPropertyName
;
1972 long nType
= reinterpret_cast<long>(
1973 pLine
->m_aTypeBox
->GetSelectEntryData() );
1974 if ( CUSTOM_TYPE_NUMBER
== nType
)
1977 sal_uInt32 nIndex
= const_cast< SvNumberFormatter
& >(
1978 m_aNumberFormatter
).GetFormatIndex( NF_NUMBER_SYSTEM
);
1979 bool bIsNum
= const_cast< SvNumberFormatter
& >( m_aNumberFormatter
).
1980 IsNumberFormat( pLine
->m_aValueEdit
->GetText(), nIndex
, nValue
);
1982 aPropertiesSeq
[i
].Value
<<= makeAny( nValue
);
1984 else if ( CUSTOM_TYPE_BOOLEAN
== nType
)
1986 bool bValue
= pLine
->m_aYesNoButton
->IsYesChecked();
1987 aPropertiesSeq
[i
].Value
<<= makeAny( bValue
);
1989 else if ( CUSTOM_TYPE_DATETIME
== nType
)
1991 Date aTmpDate
= pLine
->m_aDateField
->GetDate();
1992 tools::Time aTmpTime
= pLine
->m_aTimeField
->GetTime();
1993 util::DateTime
const aDateTime(aTmpTime
.GetNanoSec(),
1994 aTmpTime
.GetSec(), aTmpTime
.GetMin(), aTmpTime
.GetHour(),
1995 aTmpDate
.GetDay(), aTmpDate
.GetMonth(), aTmpDate
.GetYear(),
1996 pLine
->m_aTimeField
->m_isUTC
);
1997 if (pLine
->m_aDateField
->m_TZ
.is_initialized())
1999 aPropertiesSeq
[i
].Value
<<= util::DateTimeWithTimezone(
2000 aDateTime
, pLine
->m_aDateField
->m_TZ
.get());
2004 aPropertiesSeq
[i
].Value
<<= aDateTime
;
2007 else if ( CUSTOM_TYPE_DATE
== nType
)
2009 Date aTmpDate
= pLine
->m_aDateField
->GetDate();
2010 util::Date
const aDate(aTmpDate
.GetDay(), aTmpDate
.GetMonth(),
2011 aTmpDate
.GetYear());
2012 if (pLine
->m_aDateField
->m_TZ
.is_initialized())
2014 aPropertiesSeq
[i
].Value
<<= util::DateWithTimezone(
2015 aDate
, pLine
->m_aDateField
->m_TZ
.get());
2019 aPropertiesSeq
[i
].Value
<<= aDate
;
2022 else if ( CUSTOM_TYPE_DURATION
== nType
)
2024 aPropertiesSeq
[i
].Value
<<= pLine
->m_aDurationField
->GetDuration();
2028 OUString
sValue( pLine
->m_aValueEdit
->GetText() );
2029 aPropertiesSeq
[i
].Value
<<= makeAny( sValue
);
2034 return aPropertiesSeq
;
2037 CustomPropertiesControl::CustomPropertiesControl(vcl::Window
* pParent
)
2038 : Window(pParent
, WB_HIDE
| WB_CLIPCHILDREN
| WB_TABSTOP
| WB_DIALOGCONTROL
| WB_BORDER
)
2040 , m_pHeaderBar(NULL
)
2042 , m_pPropertiesWin(NULL
)
2043 , m_pVertScroll(NULL
)
2048 void CustomPropertiesControl::Init(VclBuilderContainer
& rBuilder
)
2050 m_pVBox
= VclPtr
<VclVBox
>::Create(this);
2051 m_pHeaderBar
= VclPtr
<HeaderBar
>::Create(m_pVBox
, WB_BUTTONSTYLE
| WB_BOTTOMBORDER
);
2052 m_pBody
= VclPtr
<VclHBox
>::Create(m_pVBox
);
2053 FixedText
* pName
= rBuilder
.get
<FixedText
>("name");
2054 FixedText
* pType
= rBuilder
.get
<FixedText
>("type");
2055 FixedText
* pValue
= rBuilder
.get
<FixedText
>("value");
2056 OUString sName
= pName
->GetText();
2057 OUString sType
= pType
->GetText();
2058 OUString sValue
= pValue
->GetText();
2059 m_pPropertiesWin
= VclPtr
<CustomPropertiesWindow
>::Create(m_pBody
, pName
, pType
, pValue
);
2060 m_pVertScroll
= VclPtr
<ScrollBar
>::Create(m_pBody
, WB_VERT
);
2067 m_pVBox
->set_hexpand(true);
2068 m_pVBox
->set_vexpand(true);
2069 m_pVBox
->set_expand(true);
2070 m_pVBox
->set_fill(true);
2073 m_pBody
->set_hexpand(true);
2074 m_pBody
->set_vexpand(true);
2075 m_pBody
->set_expand(true);
2076 m_pBody
->set_fill(true);
2079 m_pPropertiesWin
->set_hexpand(true);
2080 m_pPropertiesWin
->set_vexpand(true);
2081 m_pPropertiesWin
->set_expand(true);
2082 m_pPropertiesWin
->set_fill(true);
2083 m_pPropertiesWin
->Show();
2085 m_pPropertiesWin
->SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
2086 m_pVertScroll
->EnableDrag();
2087 m_pVertScroll
->Show();
2089 m_pHeaderBar
->set_height_request(GetTextHeight() + 6);
2091 const HeaderBarItemBits nHeadBits
= HeaderBarItemBits::VCENTER
| HeaderBarItemBits::FIXED
| HeaderBarItemBits::FIXEDPOS
| HeaderBarItemBits::LEFT
;
2093 m_pHeaderBar
->InsertItem( HI_NAME
, sName
, 0, nHeadBits
);
2094 m_pHeaderBar
->InsertItem( HI_TYPE
, sType
, 0, nHeadBits
);
2095 m_pHeaderBar
->InsertItem( HI_VALUE
, sValue
, 0, nHeadBits
);
2096 m_pHeaderBar
->InsertItem( HI_ACTION
, OUString(), 0, nHeadBits
);
2097 m_pHeaderBar
->Show();
2099 m_pPropertiesWin
->SetRemovedHdl( LINK( this, CustomPropertiesControl
, RemovedHdl
) );
2101 m_pVertScroll
->SetRangeMin( 0 );
2102 m_pVertScroll
->SetRangeMax( 0 );
2103 m_pVertScroll
->SetVisibleSize( 0xFFFF );
2105 Link
<> aScrollLink
= LINK( this, CustomPropertiesControl
, ScrollHdl
);
2106 m_pVertScroll
->SetScrollHdl( aScrollLink
);
2109 void CustomPropertiesControl::Resize()
2116 m_pVBox
->SetSizePixel(GetSizePixel());
2118 bool bWidgetsResized
= m_pPropertiesWin
->InitControls( m_pHeaderBar
, m_pVertScroll
);
2119 sal_Int32 nScrollOffset
= m_pPropertiesWin
->GetLineHeight();
2120 sal_Int32 nVisibleEntries
= m_pPropertiesWin
->GetSizePixel().Height() / nScrollOffset
;
2121 m_pVertScroll
->SetPageSize( nVisibleEntries
- 1 );
2122 m_pVertScroll
->SetVisibleSize( nVisibleEntries
);
2123 if (bWidgetsResized
)
2125 m_pPropertiesWin
->updateLineWidth();
2129 VCL_BUILDER_FACTORY(CustomPropertiesControl
)
2131 CustomPropertiesControl::~CustomPropertiesControl()
2136 void CustomPropertiesControl::dispose()
2138 m_pVertScroll
.disposeAndClear();
2139 m_pPropertiesWin
.disposeAndClear();
2140 m_pBody
.disposeAndClear();
2141 m_pHeaderBar
.disposeAndClear();
2142 m_pVBox
.disposeAndClear();
2143 vcl::Window::dispose();
2146 IMPL_LINK( CustomPropertiesControl
, ScrollHdl
, ScrollBar
*, pScrollBar
)
2148 sal_Int32 nOffset
= m_pPropertiesWin
->GetLineHeight();
2149 nOffset
*= ( m_nThumbPos
- pScrollBar
->GetThumbPos() );
2150 m_nThumbPos
= pScrollBar
->GetThumbPos();
2151 m_pPropertiesWin
->DoScroll( nOffset
);
2155 IMPL_LINK_NOARG(CustomPropertiesControl
, RemovedHdl
)
2157 long nLineCount
= m_pPropertiesWin
->GetVisibleLineCount();
2158 m_pVertScroll
->SetRangeMax(nLineCount
+ 1);
2159 if ( m_pPropertiesWin
->GetOutputSizePixel().Height() < nLineCount
* m_pPropertiesWin
->GetLineHeight() )
2160 m_pVertScroll
->DoScrollAction ( SCROLL_LINEUP
);
2164 void CustomPropertiesControl::AddLine( const OUString
& sName
, Any
& rAny
, bool bInteractive
)
2166 m_pPropertiesWin
->AddLine( sName
, rAny
);
2167 long nLineCount
= m_pPropertiesWin
->GetVisibleLineCount();
2168 m_pVertScroll
->SetRangeMax(nLineCount
+ 1);
2169 if ( bInteractive
&& m_pPropertiesWin
->GetOutputSizePixel().Height() < nLineCount
* m_pPropertiesWin
->GetLineHeight() )
2170 m_pVertScroll
->DoScroll(nLineCount
+ 1);
2173 // class SfxCustomPropertiesPage -----------------------------------------
2174 SfxCustomPropertiesPage::SfxCustomPropertiesPage( vcl::Window
* pParent
, const SfxItemSet
& rItemSet
)
2175 : SfxTabPage(pParent
, "CustomInfoPage", "sfx/ui/custominfopage.ui", &rItemSet
)
2177 get(m_pPropertiesCtrl
, "properties");
2178 m_pPropertiesCtrl
->Init(*this);
2179 get
<PushButton
>("add")->SetClickHdl(LINK(this, SfxCustomPropertiesPage
, AddHdl
));
2182 SfxCustomPropertiesPage::~SfxCustomPropertiesPage()
2187 void SfxCustomPropertiesPage::dispose()
2189 m_pPropertiesCtrl
.clear();
2190 SfxTabPage::dispose();
2193 IMPL_LINK_NOARG(SfxCustomPropertiesPage
, AddHdl
)
2196 m_pPropertiesCtrl
->AddLine( OUString(), aAny
, true );
2200 bool SfxCustomPropertiesPage::FillItemSet( SfxItemSet
* rSet
)
2202 bool bModified
= false;
2203 const SfxPoolItem
* pItem
= NULL
;
2204 SfxDocumentInfoItem
* pInfo
= NULL
;
2205 bool bMustDelete
= false;
2207 if ( GetTabDialog() && GetTabDialog()->GetExampleSet() )
2209 if ( SfxItemState::SET
!=
2210 GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO
, true, &pItem
) )
2211 pInfo
= const_cast<SfxDocumentInfoItem
*>(&static_cast<const SfxDocumentInfoItem
& >(rSet
->Get( SID_DOCINFO
)));
2215 pInfo
= new SfxDocumentInfoItem( *static_cast<const SfxDocumentInfoItem
*>(pItem
) );
2221 // If it's a CMIS document, we can't save custom properties
2222 if ( pInfo
->isCmisDocument( ) )
2229 pInfo
->ClearCustomProperties();
2230 Sequence
< beans::PropertyValue
> aPropertySeq
= m_pPropertiesCtrl
->GetCustomProperties();
2231 sal_Int32 i
= 0, nCount
= aPropertySeq
.getLength();
2232 for ( ; i
< nCount
; ++i
)
2234 if ( !aPropertySeq
[i
].Name
.isEmpty() )
2235 pInfo
->AddCustomProperty( aPropertySeq
[i
].Name
, aPropertySeq
[i
].Value
);
2239 bModified
= true; //!!!
2244 rSet
->Put( *pInfo
);
2251 void SfxCustomPropertiesPage::Reset( const SfxItemSet
* rItemSet
)
2253 m_pPropertiesCtrl
->ClearAllLines();
2254 const SfxDocumentInfoItem
& rInfoItem
= static_cast<const SfxDocumentInfoItem
&>(rItemSet
->Get(SID_DOCINFO
));
2255 std::vector
< CustomProperty
* > aCustomProps
= rInfoItem
.GetCustomProperties();
2256 for ( sal_uInt32 i
= 0; i
< aCustomProps
.size(); i
++ )
2258 m_pPropertiesCtrl
->AddLine( aCustomProps
[i
]->m_sName
, aCustomProps
[i
]->m_aValue
, false );
2262 SfxTabPage::sfxpg
SfxCustomPropertiesPage::DeactivatePage( SfxItemSet
* /*pSet*/ )
2264 sfxpg nRet
= LEAVE_PAGE
;
2265 if ( !m_pPropertiesCtrl
->AreAllLinesValid() )
2270 VclPtr
<SfxTabPage
> SfxCustomPropertiesPage::Create( vcl::Window
* pParent
, const SfxItemSet
* rItemSet
)
2272 return VclPtr
<SfxCustomPropertiesPage
>::Create( pParent
, *rItemSet
);
2275 CmisValue::CmisValue( vcl::Window
* pParent
, const OUString
& aStr
)
2277 m_pUIBuilder
= new VclBuilder( pParent
, getUIRootDir(), "sfx/ui/cmisline.ui");
2278 get( m_aValueEdit
, "value");
2279 m_aValueEdit
->Show( true );
2280 m_aValueEdit
->SetText( aStr
);
2283 CmisDateTime::CmisDateTime( vcl::Window
* pParent
, const util::DateTime
& aDateTime
)
2285 m_pUIBuilder
= new VclBuilder( pParent
, getUIRootDir(), "sfx/ui/cmisline.ui");
2286 get( m_aDateField
, "date");
2287 get( m_aTimeField
, "time");
2288 m_aDateField
->Show( true );
2289 m_aTimeField
->Show( true );
2290 m_aDateField
->SetDate( Date( aDateTime
) );
2291 m_aTimeField
->SetTime( tools::Time( aDateTime
) );
2294 CmisYesNo::CmisYesNo( vcl::Window
* pParent
, bool bValue
)
2296 m_pUIBuilder
= new VclBuilder( pParent
, getUIRootDir(), "sfx/ui/cmisline.ui");
2297 get( m_aYesButton
, "yes");
2298 get( m_aNoButton
, "no");
2299 m_aYesButton
->Show( true );
2300 m_aNoButton
->Show( true );
2302 m_aYesButton
->Check( );
2304 m_aNoButton
->Check( );
2307 // struct CmisPropertyLine ---------------------------------------------
2308 CmisPropertyLine::CmisPropertyLine(vcl::Window
* pParent
)
2309 : m_sType(CMIS_TYPE_STRING
)
2310 , m_bUpdatable(false)
2311 , m_bRequired(false)
2312 , m_bMultiValued(false)
2313 , m_bOpenChoice(false)
2316 m_pUIBuilder
= new VclBuilder( pParent
, getUIRootDir(), "sfx/ui/cmisline.ui");
2317 get( m_pFrame
, "CmisFrame" );
2318 get( m_aName
, "name" );
2319 get( m_aType
, "type" );
2323 CmisPropertyLine::~CmisPropertyLine( )
2325 std::vector
< CmisValue
* >::iterator pIter
;
2326 for ( pIter
= m_aValues
.begin();
2327 pIter
!= m_aValues
.end(); ++pIter
)
2329 CmisValue
* pValue
= *pIter
;
2334 std::vector
< CmisYesNo
* >::iterator pIterYesNo
;
2335 for ( pIterYesNo
= m_aYesNos
.begin();
2336 pIterYesNo
!= m_aYesNos
.end(); ++pIterYesNo
)
2338 CmisYesNo
* pYesNo
= *pIterYesNo
;
2343 std::vector
< CmisDateTime
* >::iterator pIterDateTime
;
2344 for ( pIterDateTime
= m_aDateTimes
.begin();
2345 pIterDateTime
!= m_aDateTimes
.end(); ++pIterDateTime
)
2347 CmisDateTime
* pDateTime
= *pIterDateTime
;
2350 m_aDateTimes
.clear();
2354 long CmisPropertyLine::getItemHeight() const
2356 return VclContainer::getLayoutRequisition(*m_pFrame
).Height();
2359 // class CmisPropertiesWindow -----------------------------------------
2361 CmisPropertiesWindow::CmisPropertiesWindow(SfxTabPage
* pParent
):
2362 m_aNumberFormatter( ::comphelper::getProcessComponentContext(),
2363 Application::GetSettings().GetLanguageTag().getLanguageType() )
2366 pParent
->get(m_pBox
, "CmisWindow");
2367 CmisPropertyLine
aTemp( m_pBox
);
2368 m_nItemHeight
= aTemp
.getItemHeight();
2371 CmisPropertiesWindow::~CmisPropertiesWindow()
2376 void CmisPropertiesWindow::ClearAllLines()
2378 std::vector
< CmisPropertyLine
* >::iterator pIter
;
2379 for ( pIter
= m_aCmisPropertiesLines
.begin();
2380 pIter
!= m_aCmisPropertiesLines
.end(); ++pIter
)
2382 CmisPropertyLine
* pLine
= *pIter
;
2385 m_aCmisPropertiesLines
.clear();
2388 sal_uInt16
CmisPropertiesWindow::GetLineCount() const
2390 sal_uInt16 nCount
= 0;
2391 std::vector
< CmisPropertyLine
* >::const_iterator pIter
;
2392 for ( pIter
= m_aCmisPropertiesLines
.begin();
2393 pIter
!= m_aCmisPropertiesLines
.end(); ++pIter
)
2394 nCount
+= ( (*pIter
)->m_nNumValue
+ 1 );
2398 void CmisPropertiesWindow::AddLine( const OUString
& sId
, const OUString
& sName
,
2399 const OUString
& sType
, const bool bUpdatable
,
2400 const bool bRequired
, const bool bMultiValued
,
2401 const bool bOpenChoice
, Any
& /*aChoices*/, Any
& rAny
)
2403 CmisPropertyLine
* pNewLine
= new CmisPropertyLine( m_pBox
);
2405 pNewLine
->m_sId
= sId
;
2406 pNewLine
->m_sType
= sType
;
2407 pNewLine
->m_bUpdatable
= bUpdatable
;
2408 pNewLine
->m_bRequired
= bRequired
;
2409 pNewLine
->m_bMultiValued
= bMultiValued
;
2410 pNewLine
->m_bOpenChoice
= bOpenChoice
;
2412 if ( sType
== CMIS_TYPE_INTEGER
)
2414 Sequence
< sal_Int64
> seqValue
;
2416 sal_uInt32 nIndex
= m_aNumberFormatter
.GetFormatIndex( NF_NUMBER_SYSTEM
);
2417 sal_Int32 m_nNumValue
= seqValue
.getLength( );
2418 for ( sal_Int32 i
= 0; i
< m_nNumValue
; ++i
)
2421 m_aNumberFormatter
.GetInputLineString( seqValue
[i
], nIndex
, sValue
);
2422 CmisValue
* pValue
= new CmisValue( m_pBox
, sValue
);
2423 pValue
->m_aValueEdit
->SetReadOnly( !bUpdatable
);
2424 pNewLine
->m_aValues
.push_back( pValue
);
2427 else if ( sType
== CMIS_TYPE_DECIMAL
)
2429 Sequence
< double > seqValue
;
2431 sal_uInt32 nIndex
= m_aNumberFormatter
.GetFormatIndex( NF_NUMBER_SYSTEM
);
2432 sal_Int32 m_nNumValue
= seqValue
.getLength( );
2433 for ( sal_Int32 i
= 0; i
< m_nNumValue
; ++i
)
2436 m_aNumberFormatter
.GetInputLineString( seqValue
[i
], nIndex
, sValue
);
2437 CmisValue
* pValue
= new CmisValue( m_pBox
, sValue
);
2438 pValue
->m_aValueEdit
->SetReadOnly( !bUpdatable
);
2439 pNewLine
->m_aValues
.push_back( pValue
);
2443 else if ( sType
== CMIS_TYPE_BOOL
)
2445 Sequence
<sal_Bool
> seqValue
;
2447 sal_Int32 m_nNumValue
= seqValue
.getLength( );
2448 for ( sal_Int32 i
= 0; i
< m_nNumValue
; ++i
)
2450 CmisYesNo
* pYesNo
= new CmisYesNo( m_pBox
, seqValue
[i
] );
2451 pYesNo
->m_aYesButton
->Enable( bUpdatable
);
2452 pYesNo
->m_aNoButton
->Enable( bUpdatable
);
2453 pNewLine
->m_aYesNos
.push_back( pYesNo
);
2456 else if ( sType
== CMIS_TYPE_STRING
)
2458 Sequence
< OUString
> seqValue
;
2460 sal_Int32 m_nNumValue
= seqValue
.getLength( );
2461 for ( sal_Int32 i
= 0; i
< m_nNumValue
; ++i
)
2463 CmisValue
* pValue
= new CmisValue( m_pBox
, seqValue
[i
] );
2464 pValue
->m_aValueEdit
->SetReadOnly( !bUpdatable
);
2465 pNewLine
->m_aValues
.push_back( pValue
);
2468 else if ( sType
== CMIS_TYPE_DATETIME
)
2470 Sequence
< util::DateTime
> seqValue
;
2472 sal_Int32 m_nNumValue
= seqValue
.getLength( );
2473 for ( sal_Int32 i
= 0; i
< m_nNumValue
; ++i
)
2475 CmisDateTime
* pDateTime
= new CmisDateTime( m_pBox
, seqValue
[i
]);
2476 pDateTime
->m_aDateField
->SetReadOnly( !bUpdatable
);
2477 pDateTime
->m_aTimeField
->SetReadOnly( !bUpdatable
);
2478 pNewLine
->m_aDateTimes
.push_back( pDateTime
);
2482 pNewLine
->m_aName
->SetText( sName
);
2483 pNewLine
->m_aName
->Show( true );
2484 pNewLine
->m_aType
->SetText( sType
);
2485 pNewLine
->m_aType
->Show( true );
2487 m_aCmisPropertiesLines
.push_back( pNewLine
);
2490 void CmisPropertiesWindow::DoScroll( sal_Int32 nNewPos
)
2492 m_pBox
->SetPosPixel(Point(0, nNewPos
));
2495 Sequence
< document::CmisProperty
> CmisPropertiesWindow::GetCmisProperties() const
2497 Sequence
< document::CmisProperty
> aPropertiesSeq( m_aCmisPropertiesLines
.size() );
2499 std::vector
< CmisPropertyLine
* >::const_iterator pIter
;
2500 for ( pIter
= m_aCmisPropertiesLines
.begin();
2501 pIter
!= m_aCmisPropertiesLines
.end(); ++pIter
, ++i
)
2503 CmisPropertyLine
* pLine
= *pIter
;
2505 aPropertiesSeq
[i
].Id
= pLine
->m_sId
;
2506 aPropertiesSeq
[i
].Type
= pLine
->m_sType
;
2507 aPropertiesSeq
[i
].Updatable
= pLine
->m_bUpdatable
;
2508 aPropertiesSeq
[i
].Required
= pLine
->m_bRequired
;
2509 aPropertiesSeq
[i
].OpenChoice
= pLine
->m_bOpenChoice
;
2510 aPropertiesSeq
[i
].MultiValued
= pLine
->m_bMultiValued
;
2512 OUString sPropertyName
= pLine
->m_aName
->GetText();
2513 if ( !sPropertyName
.isEmpty() )
2515 aPropertiesSeq
[i
].Name
= sPropertyName
;
2516 OUString sType
= pLine
->m_aType
->GetText( );
2517 if ( CMIS_TYPE_DECIMAL
== sType
)
2519 sal_uInt32 nIndex
= const_cast< SvNumberFormatter
& >(
2520 m_aNumberFormatter
).GetFormatIndex( NF_NUMBER_SYSTEM
);
2521 Sequence
< double > seqValue( pLine
->m_aValues
.size( ) );
2523 for ( std::vector
< CmisValue
*>::const_iterator it
= pLine
->m_aValues
.begin();
2524 it
!= pLine
->m_aValues
.end(); ++it
, ++k
)
2526 double dValue
= 0.0;
2527 OUString
sValue( (*it
)->m_aValueEdit
->GetText() );
2528 bool bIsNum
= const_cast< SvNumberFormatter
& >( m_aNumberFormatter
).
2529 IsNumberFormat( sValue
, nIndex
, dValue
);
2531 seqValue
[k
] = dValue
;
2533 aPropertiesSeq
[i
].Value
<<= makeAny( seqValue
);
2535 else if ( CMIS_TYPE_INTEGER
== sType
)
2537 sal_uInt32 nIndex
= const_cast< SvNumberFormatter
& >(
2538 m_aNumberFormatter
).GetFormatIndex( NF_NUMBER_SYSTEM
);
2539 Sequence
< sal_Int64
> seqValue( pLine
->m_aValues
.size( ) );
2541 for ( std::vector
< CmisValue
*>::const_iterator it
= pLine
->m_aValues
.begin();
2542 it
!= pLine
->m_aValues
.end(); ++it
, ++k
)
2545 OUString
sValue( (*it
)->m_aValueEdit
->GetText() );
2546 bool bIsNum
= const_cast< SvNumberFormatter
& >( m_aNumberFormatter
).
2547 IsNumberFormat( sValue
, nIndex
, dValue
);
2549 seqValue
[k
] = (sal_Int64
) dValue
;
2551 aPropertiesSeq
[i
].Value
<<= makeAny( seqValue
);
2553 else if ( CMIS_TYPE_BOOL
== sType
)
2555 Sequence
<sal_Bool
> seqValue( pLine
->m_aYesNos
.size( ) );
2557 for ( std::vector
< CmisYesNo
*>::const_iterator it
= pLine
->m_aYesNos
.begin();
2558 it
!= pLine
->m_aYesNos
.end(); ++it
, ++k
)
2560 bool bValue
= (*it
)->m_aYesButton
->IsChecked();
2561 seqValue
[k
] = bValue
;
2563 aPropertiesSeq
[i
].Value
<<= makeAny( seqValue
);
2566 else if ( CMIS_TYPE_DATETIME
== sType
)
2568 Sequence
< util::DateTime
> seqValue( pLine
->m_aDateTimes
.size( ) );
2570 for ( std::vector
< CmisDateTime
*>::const_iterator it
= pLine
->m_aDateTimes
.begin();
2571 it
!= pLine
->m_aDateTimes
.end(); ++it
, ++k
)
2573 Date aTmpDate
= (*it
)->m_aDateField
->GetDate();
2574 tools::Time aTmpTime
= (*it
)->m_aTimeField
->GetTime();
2575 util::DateTime
aDateTime( aTmpTime
.GetNanoSec(), aTmpTime
.GetSec(),
2576 aTmpTime
.GetMin(), aTmpTime
.GetHour(),
2577 aTmpDate
.GetDay(), aTmpDate
.GetMonth(),
2578 aTmpDate
.GetYear(), sal_True
);
2579 seqValue
[k
] = aDateTime
;
2581 aPropertiesSeq
[i
].Value
<<= makeAny( seqValue
);
2585 Sequence
< OUString
> seqValue( pLine
->m_aValues
.size( ) );
2587 for ( std::vector
< CmisValue
*>::const_iterator it
= pLine
->m_aValues
.begin();
2588 it
!= pLine
->m_aValues
.end(); ++it
, ++k
)
2590 OUString
sValue( (*it
)->m_aValueEdit
->GetText() );
2591 seqValue
[k
] = sValue
;
2593 aPropertiesSeq
[i
].Value
<<= makeAny( seqValue
);
2598 return aPropertiesSeq
;
2601 CmisPropertiesControl::CmisPropertiesControl(SfxTabPage
* pParent
)
2602 : m_pPropertiesWin( pParent
)
2603 , m_rScrolledWindow( *pParent
->get
<VclScrolledWindow
>("CmisScroll"))
2604 , m_rVertScroll( m_rScrolledWindow
.getVertScrollBar())
2606 m_rScrolledWindow
.setUserManagedScrolling(true);
2607 m_rVertScroll
.EnableDrag();
2608 m_rVertScroll
.Show( m_rScrolledWindow
.GetStyle() & WB_VSCROLL
);
2609 m_rVertScroll
.SetRangeMin(0);
2610 m_rVertScroll
.SetVisibleSize( 0xFFFF );
2612 Link
<> aScrollLink
= LINK( this, CmisPropertiesControl
, ScrollHdl
);
2613 m_rVertScroll
.SetScrollHdl( aScrollLink
);
2616 void CmisPropertiesControl::ClearAllLines()
2618 m_pPropertiesWin
.ClearAllLines();
2621 IMPL_LINK( CmisPropertiesControl
, ScrollHdl
, ScrollBar
*, pScrollBar
)
2623 sal_Int32 nOffset
= m_pPropertiesWin
.GetItemHeight();
2624 nOffset
*= ( pScrollBar
->GetThumbPos() );
2625 m_pPropertiesWin
.DoScroll( -nOffset
);
2629 void CmisPropertiesControl::checkAutoVScroll()
2631 WinBits nBits
= m_rScrolledWindow
.GetStyle();
2632 if (nBits
& WB_VSCROLL
)
2634 if (nBits
& WB_AUTOVSCROLL
)
2636 bool bShow
= m_rVertScroll
.GetRangeMax() > m_rVertScroll
.GetVisibleSize();
2637 if (bShow
!= m_rVertScroll
.IsVisible())
2638 m_rVertScroll
.Show(bShow
);
2642 void CmisPropertiesControl::setScrollRange()
2644 sal_Int32 nScrollOffset
= m_pPropertiesWin
.GetItemHeight();
2645 sal_Int32 nVisibleItems
= m_rScrolledWindow
.getVisibleChildSize().Height() / nScrollOffset
;
2646 m_rVertScroll
.SetPageSize( nVisibleItems
- 1 );
2647 m_rVertScroll
.SetVisibleSize( nVisibleItems
);
2648 m_rVertScroll
.Scroll();
2652 void CmisPropertiesControl::AddLine( const OUString
& sId
, const OUString
& sName
,
2653 const OUString
& sType
, const bool bUpdatable
,
2654 const bool bRequired
, const bool bMultiValued
,
2655 const bool bOpenChoice
, Any
& aChoices
, Any
& rAny
2658 m_rVertScroll
.SetRangeMax( m_pPropertiesWin
.GetLineCount() + 1 );
2659 m_rVertScroll
.DoScroll( m_pPropertiesWin
.GetLineCount() + 1 );
2660 m_pPropertiesWin
.AddLine( sId
, sName
, sType
, bUpdatable
, bRequired
, bMultiValued
,
2661 bOpenChoice
, aChoices
, rAny
);
2665 // class SfxCmisPropertiesPage -----------------------------------------
2666 SfxCmisPropertiesPage::SfxCmisPropertiesPage( vcl::Window
* pParent
, const SfxItemSet
& rItemSet
)
2667 : SfxTabPage(pParent
, "CmisInfoPage", "sfx/ui/cmisinfopage.ui", &rItemSet
)
2668 , m_pPropertiesCtrl( this )
2672 bool SfxCmisPropertiesPage::FillItemSet( SfxItemSet
* rSet
)
2674 const SfxPoolItem
* pItem
= NULL
;
2675 SfxDocumentInfoItem
* pInfo
= NULL
;
2676 bool bMustDelete
= false;
2678 if ( GetTabDialog() && GetTabDialog()->GetExampleSet() )
2680 if ( SfxItemState::SET
!=
2681 GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO
, true, &pItem
) )
2682 pInfo
= const_cast<SfxDocumentInfoItem
*>(&static_cast<const SfxDocumentInfoItem
& >(rSet
->Get( SID_DOCINFO
)));
2686 pInfo
= new SfxDocumentInfoItem( *static_cast<const SfxDocumentInfoItem
*>(pItem
) );
2690 sal_Int32 modifiedNum
= 0;
2693 Sequence
< document::CmisProperty
> aOldProps
= pInfo
->GetCmisProperties( );
2694 Sequence
< document::CmisProperty
> aNewProps
= m_pPropertiesCtrl
.GetCmisProperties();
2696 std::vector
< document::CmisProperty
> changedProps
;
2697 for ( sal_Int32 i
= 0; i
< aNewProps
.getLength( ); ++i
)
2699 if ( aOldProps
[i
].Updatable
&& !aNewProps
[i
].Id
.isEmpty( ) )
2701 if ( aOldProps
[i
].Type
== CMIS_TYPE_DATETIME
)
2703 Sequence
< util::DateTime
> oldValue
;
2704 aOldProps
[i
].Value
>>= oldValue
;
2705 // We only edit hours and minutes
2706 // don't compare NanoSeconds and Seconds
2707 for ( sal_Int32 ii
= 0; ii
< oldValue
.getLength( ); ++ii
)
2709 oldValue
[ii
].NanoSeconds
= 0;
2710 oldValue
[ii
].Seconds
= 0;
2712 Sequence
< util::DateTime
> newValue
;
2713 aNewProps
[i
].Value
>>= newValue
;
2714 if ( oldValue
!= newValue
)
2717 changedProps
.push_back( aNewProps
[i
] );
2720 else if ( aOldProps
[i
].Value
!= aNewProps
[i
].Value
)
2723 changedProps
.push_back( aNewProps
[i
] );
2727 Sequence
< document::CmisProperty
> aModifiedProps( modifiedNum
);
2728 sal_Int32 nCount
= 0;
2729 for( std::vector
< document::CmisProperty
>::const_iterator pIter
= changedProps
.begin();
2730 pIter
!= changedProps
.end( ); ++pIter
)
2731 aModifiedProps
[ nCount
++ ] = *pIter
;
2732 pInfo
->SetCmisProperties( aModifiedProps
);
2733 rSet
->Put( *pInfo
);
2741 void SfxCmisPropertiesPage::Reset( const SfxItemSet
* rItemSet
)
2743 m_pPropertiesCtrl
.ClearAllLines();
2744 const SfxDocumentInfoItem
& rInfoItem
= static_cast<const SfxDocumentInfoItem
& >(rItemSet
->Get(SID_DOCINFO
));
2745 uno::Sequence
< document::CmisProperty
> aCmisProps
= rInfoItem
.GetCmisProperties();
2746 for ( sal_Int32 i
= 0; i
< aCmisProps
.getLength(); i
++ )
2748 m_pPropertiesCtrl
.AddLine( aCmisProps
[i
].Id
,
2751 aCmisProps
[i
].Updatable
,
2752 aCmisProps
[i
].Required
,
2753 aCmisProps
[i
].MultiValued
,
2754 aCmisProps
[i
].OpenChoice
,
2755 aCmisProps
[i
].Choices
,
2756 aCmisProps
[i
].Value
);
2758 m_pPropertiesCtrl
.setScrollRange();
2761 SfxTabPage::sfxpg
SfxCmisPropertiesPage::DeactivatePage( SfxItemSet
* /*pSet*/ )
2766 VclPtr
<SfxTabPage
> SfxCmisPropertiesPage::Create( vcl::Window
* pParent
, const SfxItemSet
* rItemSet
)
2768 return VclPtr
<SfxCmisPropertiesPage
>::Create( pParent
, *rItemSet
);
2771 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */