Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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>
31 :
32 : #include <memory>
33 :
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>
49 :
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>
61 : #include "helper.hxx"
62 : #include <sfx2/objsh.hxx>
63 : #include <sfx2/docfile.hxx>
64 : #include <comphelper/storagehelper.hxx>
65 :
66 : #include "documentfontsdialog.hxx"
67 : #include <sfx2/sfx.hrc>
68 : #include "dinfdlg.hrc"
69 : #include "../appl/app.hrc"
70 : #include "sfxlocal.hrc"
71 : #include <dialog.hrc>
72 : #include <vcl/help.hxx>
73 : #include <vcl/builderfactory.hxx>
74 :
75 : #include <algorithm>
76 : #include <boost/scoped_ptr.hpp>
77 :
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;
82 :
83 : const sal_uInt16 FONT_PAGE_ID = 99;
84 :
85 0 : struct CustomProperty
86 : {
87 : OUString m_sName;
88 : com::sun::star::uno::Any m_aValue;
89 :
90 0 : CustomProperty( const OUString& sName,
91 : const com::sun::star::uno::Any& rValue ) :
92 0 : m_sName( sName ), m_aValue( rValue ) {}
93 : };
94 :
95 : static
96 0 : bool operator==(const util::DateTime &i_rLeft, const util::DateTime &i_rRight)
97 : {
98 0 : return i_rLeft.Year == i_rRight.Year
99 0 : && i_rLeft.Month == i_rRight.Month
100 0 : && i_rLeft.Day == i_rRight.Day
101 0 : && i_rLeft.Hours == i_rRight.Hours
102 0 : && i_rLeft.Minutes == i_rRight.Minutes
103 0 : && i_rLeft.Seconds == i_rRight.Seconds
104 0 : && i_rLeft.NanoSeconds == i_rRight.NanoSeconds
105 0 : && i_rLeft.IsUTC == i_rRight.IsUTC;
106 : }
107 :
108 : // STATIC DATA -----------------------------------------------------------
109 216 : TYPEINIT1_AUTOFACTORY(SfxDocumentInfoItem, SfxStringItem);
110 :
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;
115 :
116 : static const char DOCUMENT_SIGNATURE_MENU_CMD[] = "Signature";
117 :
118 :
119 : namespace {
120 :
121 0 : OUString CreateSizeText( sal_Int64 nSize )
122 : {
123 0 : OUString aUnitStr(" ");
124 0 : aUnitStr += SfxResId(STR_BYTES).toString();
125 0 : sal_Int64 nSize1 = nSize;
126 0 : sal_Int64 nSize2 = nSize1;
127 0 : sal_Int64 nMega = 1024 * 1024;
128 0 : sal_Int64 nGiga = nMega * 1024;
129 0 : double fSize = nSize;
130 0 : int nDec = 0;
131 :
132 0 : if ( nSize1 >= 10000 && nSize1 < nMega )
133 : {
134 0 : nSize1 /= 1024;
135 0 : aUnitStr = " ";
136 0 : aUnitStr += SfxResId(STR_KB).toString();
137 0 : fSize /= 1024;
138 0 : nDec = 0;
139 : }
140 0 : else if ( nSize1 >= nMega && nSize1 < nGiga )
141 : {
142 0 : nSize1 /= nMega;
143 0 : aUnitStr = " ";
144 0 : aUnitStr += SfxResId(STR_MB).toString();
145 0 : fSize /= nMega;
146 0 : nDec = 2;
147 : }
148 0 : else if ( nSize1 >= nGiga )
149 : {
150 0 : nSize1 /= nGiga;
151 0 : aUnitStr = " ";
152 0 : aUnitStr += SfxResId(STR_GB).toString();
153 0 : fSize /= nGiga;
154 0 : nDec = 3;
155 : }
156 0 : const SvtSysLocale aSysLocale;
157 0 : const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData();
158 0 : OUString aSizeStr( rLocaleWrapper.getNum( nSize1, 0 ) );
159 0 : aSizeStr += aUnitStr;
160 0 : if ( nSize1 < nSize2 )
161 : {
162 0 : aSizeStr = ::rtl::math::doubleToUString( fSize,
163 : rtl_math_StringFormat_F, nDec,
164 0 : rLocaleWrapper.getNumDecimalSep()[0] );
165 0 : aSizeStr += aUnitStr;
166 :
167 0 : aSizeStr += " (";
168 0 : aSizeStr += rLocaleWrapper.getNum( nSize2, 0 );
169 0 : aSizeStr += " ";
170 0 : aSizeStr += SfxResId(STR_BYTES).toString();
171 0 : aSizeStr += ")";
172 : }
173 0 : return aSizeStr;
174 : }
175 :
176 0 : OUString ConvertDateTime_Impl( const OUString& rName,
177 : const util::DateTime& uDT, const LocaleDataWrapper& rWrapper )
178 : {
179 0 : Date aD(uDT);
180 0 : tools::Time aT(uDT);
181 0 : const OUString pDelim ( ", " );
182 0 : OUString aStr( rWrapper.getDate( aD ) );
183 0 : aStr += pDelim;
184 0 : aStr += rWrapper.getTime( aT, true, false );
185 0 : OUString aAuthor = comphelper::string::stripStart(rName, ' ');
186 0 : if (!aAuthor.isEmpty())
187 : {
188 0 : aStr += pDelim;
189 0 : aStr += aAuthor;
190 : }
191 0 : return aStr;
192 : }
193 :
194 : }
195 :
196 :
197 0 : SfxDocumentInfoItem::SfxDocumentInfoItem()
198 : : SfxStringItem()
199 : , m_AutoloadDelay(0)
200 : , m_AutoloadURL()
201 : , m_isAutoloadEnabled(false)
202 : , m_DefaultTarget()
203 : , m_TemplateName()
204 : , m_Author()
205 : , m_CreationDate()
206 : , m_ModifiedBy()
207 : , m_ModificationDate()
208 : , m_PrintedBy()
209 : , m_PrintDate()
210 : , m_EditingCycles(0)
211 : , m_EditingDuration(0)
212 : , m_Description()
213 : , m_Keywords()
214 : , m_Subject()
215 : , m_Title()
216 : , m_bHasTemplate( true )
217 : , m_bDeleteUserData( false )
218 0 : , m_bUseUserData( true )
219 : {
220 0 : }
221 :
222 0 : SfxDocumentInfoItem::SfxDocumentInfoItem( const OUString& rFile,
223 : const uno::Reference<document::XDocumentProperties>& i_xDocProps,
224 : const uno::Sequence<document::CmisProperty>& i_cmisProps,
225 : bool bIs )
226 : : SfxStringItem( SID_DOCINFO, rFile )
227 0 : , m_AutoloadDelay( i_xDocProps->getAutoloadSecs() )
228 0 : , m_AutoloadURL( i_xDocProps->getAutoloadURL() )
229 0 : , m_isAutoloadEnabled( (m_AutoloadDelay > 0) || !m_AutoloadURL.isEmpty() )
230 0 : , m_DefaultTarget( i_xDocProps->getDefaultTarget() )
231 0 : , m_TemplateName( i_xDocProps->getTemplateName() )
232 0 : , m_Author( i_xDocProps->getAuthor() )
233 0 : , m_CreationDate( i_xDocProps->getCreationDate() )
234 0 : , m_ModifiedBy( i_xDocProps->getModifiedBy() )
235 0 : , m_ModificationDate( i_xDocProps->getModificationDate() )
236 0 : , m_PrintedBy( i_xDocProps->getPrintedBy() )
237 0 : , m_PrintDate( i_xDocProps->getPrintDate() )
238 0 : , m_EditingCycles( i_xDocProps->getEditingCycles() )
239 0 : , m_EditingDuration( i_xDocProps->getEditingDuration() )
240 0 : , m_Description( i_xDocProps->getDescription() )
241 : , m_Keywords( ::comphelper::string::convertCommaSeparated(
242 0 : i_xDocProps->getKeywords()) )
243 0 : , m_Subject( i_xDocProps->getSubject() )
244 0 : , m_Title( i_xDocProps->getTitle() )
245 : , m_bHasTemplate( true )
246 : , m_bDeleteUserData( false )
247 0 : , m_bUseUserData( bIs )
248 : {
249 : try
250 : {
251 0 : Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties();
252 0 : if ( xContainer.is() )
253 : {
254 0 : Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY );
255 0 : const Sequence< beans::Property > lProps = xSet->getPropertySetInfo()->getProperties();
256 0 : const beans::Property* pProps = lProps.getConstArray();
257 0 : sal_Int32 nCount = lProps.getLength();
258 0 : for ( sal_Int32 i = 0; i < nCount; ++i )
259 : {
260 : // "fix" property? => not a custom property => ignore it!
261 0 : if (!(pProps[i].Attributes &
262 : ::com::sun::star::beans::PropertyAttribute::REMOVABLE))
263 : {
264 : DBG_ASSERT(false, "non-removable user-defined property?");
265 0 : continue;
266 : }
267 :
268 0 : uno::Any aValue = xSet->getPropertyValue(pProps[i].Name);
269 0 : CustomProperty* pProp = new CustomProperty( pProps[i].Name, aValue );
270 0 : m_aCustomProperties.push_back( pProp );
271 0 : }
272 : }
273 :
274 : // get CMIS properties
275 0 : m_aCmisProperties = i_cmisProps;
276 : }
277 0 : catch ( Exception& ) {}
278 0 : }
279 :
280 :
281 :
282 0 : SfxDocumentInfoItem::SfxDocumentInfoItem( const SfxDocumentInfoItem& rItem )
283 : : SfxStringItem( rItem )
284 0 : , m_AutoloadDelay( rItem.getAutoloadDelay() )
285 : , m_AutoloadURL( rItem.getAutoloadURL() )
286 0 : , 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 0 : , m_EditingCycles( rItem.getEditingCycles() )
296 0 : , 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 0 : , m_bUseUserData( rItem.m_bUseUserData )
304 : {
305 0 : for ( size_t i = 0; i < rItem.m_aCustomProperties.size(); i++ )
306 : {
307 0 : CustomProperty* pProp = new CustomProperty( rItem.m_aCustomProperties[i]->m_sName,
308 0 : rItem.m_aCustomProperties[i]->m_aValue );
309 0 : m_aCustomProperties.push_back( pProp );
310 : }
311 :
312 0 : m_aCmisProperties = rItem.m_aCmisProperties;
313 0 : }
314 :
315 :
316 0 : SfxDocumentInfoItem::~SfxDocumentInfoItem()
317 : {
318 0 : ClearCustomProperties();
319 0 : }
320 :
321 :
322 0 : SfxPoolItem* SfxDocumentInfoItem::Clone( SfxItemPool * ) const
323 : {
324 0 : return new SfxDocumentInfoItem( *this );
325 : }
326 :
327 :
328 0 : bool SfxDocumentInfoItem::operator==( const SfxPoolItem& rItem) const
329 : {
330 0 : if (!(rItem.Type() == Type() && SfxStringItem::operator==(rItem)))
331 0 : return false;
332 0 : const SfxDocumentInfoItem& rInfoItem(static_cast<const SfxDocumentInfoItem&>(rItem));
333 :
334 : return
335 0 : m_AutoloadDelay == rInfoItem.m_AutoloadDelay &&
336 0 : m_AutoloadURL == rInfoItem.m_AutoloadURL &&
337 0 : m_isAutoloadEnabled == rInfoItem.m_isAutoloadEnabled &&
338 0 : m_DefaultTarget == rInfoItem.m_DefaultTarget &&
339 0 : m_Author == rInfoItem.m_Author &&
340 0 : m_CreationDate == rInfoItem.m_CreationDate &&
341 0 : m_ModifiedBy == rInfoItem.m_ModifiedBy &&
342 0 : m_ModificationDate == rInfoItem.m_ModificationDate &&
343 0 : m_PrintedBy == rInfoItem.m_PrintedBy &&
344 0 : m_PrintDate == rInfoItem.m_PrintDate &&
345 0 : m_EditingCycles == rInfoItem.m_EditingCycles &&
346 0 : m_EditingDuration == rInfoItem.m_EditingDuration &&
347 0 : m_Description == rInfoItem.m_Description &&
348 0 : m_Keywords == rInfoItem.m_Keywords &&
349 0 : m_Subject == rInfoItem.m_Subject &&
350 0 : m_Title == rInfoItem.m_Title &&
351 0 : m_aCustomProperties.size() == rInfoItem.m_aCustomProperties.size() &&
352 : std::equal(m_aCustomProperties.begin(), m_aCustomProperties.end(),
353 0 : rInfoItem.m_aCustomProperties.begin()) &&
354 0 : m_aCmisProperties.getLength() == rInfoItem.m_aCmisProperties.getLength();
355 : }
356 :
357 :
358 0 : void SfxDocumentInfoItem::resetUserData(const OUString & i_rAuthor)
359 : {
360 0 : setAuthor(i_rAuthor);
361 0 : DateTime now( DateTime::SYSTEM );
362 0 : setCreationDate( now.GetUNODateTime() );
363 0 : setModifiedBy(OUString());
364 0 : setPrintedBy(OUString());
365 0 : setModificationDate(util::DateTime());
366 0 : setPrintDate(util::DateTime());
367 0 : setEditingDuration(0);
368 0 : setEditingCycles(1);
369 0 : }
370 :
371 :
372 0 : void SfxDocumentInfoItem::UpdateDocumentInfo(
373 : const uno::Reference<document::XDocumentProperties>& i_xDocProps,
374 : bool i_bDoNotUpdateUserDefined) const
375 : {
376 0 : if (isAutoloadEnabled()) {
377 0 : i_xDocProps->setAutoloadSecs(getAutoloadDelay());
378 0 : i_xDocProps->setAutoloadURL(getAutoloadURL());
379 : } else {
380 0 : i_xDocProps->setAutoloadSecs(0);
381 0 : i_xDocProps->setAutoloadURL(OUString());
382 : }
383 0 : i_xDocProps->setDefaultTarget(getDefaultTarget());
384 0 : i_xDocProps->setAuthor(getAuthor());
385 0 : i_xDocProps->setCreationDate(getCreationDate());
386 0 : i_xDocProps->setModifiedBy(getModifiedBy());
387 0 : i_xDocProps->setModificationDate(getModificationDate());
388 0 : i_xDocProps->setPrintedBy(getPrintedBy());
389 0 : i_xDocProps->setPrintDate(getPrintDate());
390 0 : i_xDocProps->setEditingCycles(getEditingCycles());
391 0 : i_xDocProps->setEditingDuration(getEditingDuration());
392 0 : i_xDocProps->setDescription(getDescription());
393 0 : i_xDocProps->setKeywords(
394 0 : ::comphelper::string::convertCommaSeparated(getKeywords()));
395 0 : i_xDocProps->setSubject(getSubject());
396 0 : i_xDocProps->setTitle(getTitle());
397 :
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 0 : if (i_bDoNotUpdateUserDefined)
405 0 : return;
406 :
407 : try
408 : {
409 0 : Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties();
410 0 : Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY );
411 0 : Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
412 0 : const Sequence< beans::Property > lProps = xSetInfo->getProperties();
413 0 : const beans::Property* pProps = lProps.getConstArray();
414 0 : sal_Int32 nCount = lProps.getLength();
415 0 : for ( sal_Int32 j = 0; j < nCount; ++j )
416 : {
417 0 : if ((pProps[j].Attributes &
418 : ::com::sun::star::beans::PropertyAttribute::REMOVABLE))
419 : {
420 0 : xContainer->removeProperty( pProps[j].Name );
421 : }
422 : }
423 :
424 0 : for ( size_t k = 0; k < m_aCustomProperties.size(); ++k )
425 : {
426 : try
427 : {
428 0 : xContainer->addProperty( m_aCustomProperties[k]->m_sName,
429 0 : beans::PropertyAttribute::REMOVABLE, m_aCustomProperties[k]->m_aValue );
430 : }
431 0 : catch ( Exception& )
432 : {
433 : SAL_WARN( "sfx.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while adding custom properties" );
434 : }
435 0 : }
436 : }
437 0 : catch ( Exception& )
438 : {
439 : SAL_WARN( "sfx.dialog", "SfxDocumentInfoItem::updateDocumentInfo(): exception while removing custom properties" );
440 : }
441 : }
442 :
443 :
444 :
445 0 : void SfxDocumentInfoItem::SetDeleteUserData( bool bSet )
446 : {
447 0 : m_bDeleteUserData = bSet;
448 0 : }
449 :
450 :
451 0 : void SfxDocumentInfoItem::SetUseUserData( bool bSet )
452 : {
453 0 : m_bUseUserData = bSet;
454 0 : }
455 :
456 0 : std::vector< CustomProperty* > SfxDocumentInfoItem::GetCustomProperties() const
457 : {
458 0 : std::vector< CustomProperty* > aRet;
459 0 : for ( size_t i = 0; i < m_aCustomProperties.size(); i++ )
460 : {
461 0 : CustomProperty* pProp = new CustomProperty( m_aCustomProperties[i]->m_sName,
462 0 : m_aCustomProperties[i]->m_aValue );
463 0 : aRet.push_back( pProp );
464 : }
465 :
466 0 : return aRet;
467 : }
468 :
469 0 : void SfxDocumentInfoItem::ClearCustomProperties()
470 : {
471 0 : for ( size_t i = 0; i < m_aCustomProperties.size(); i++ )
472 0 : delete m_aCustomProperties[i];
473 0 : m_aCustomProperties.clear();
474 0 : }
475 :
476 0 : void SfxDocumentInfoItem::AddCustomProperty( const OUString& sName, const Any& rValue )
477 : {
478 0 : CustomProperty* pProp = new CustomProperty( sName, rValue );
479 0 : m_aCustomProperties.push_back( pProp );
480 0 : }
481 :
482 :
483 0 : void SfxDocumentInfoItem::SetCmisProperties( const Sequence< document::CmisProperty >& cmisProps)
484 : {
485 0 : m_aCmisProperties = cmisProps;
486 0 : }
487 :
488 0 : bool SfxDocumentInfoItem::QueryValue( Any& rVal, sal_uInt8 nMemberId ) const
489 : {
490 0 : OUString aValue;
491 0 : sal_Int32 nValue = 0;
492 0 : bool bValue = false;
493 0 : bool bIsInt = false;
494 0 : bool bIsString = false;
495 0 : nMemberId &= ~CONVERT_TWIPS;
496 0 : switch ( nMemberId )
497 : {
498 : case MID_DOCINFO_USEUSERDATA:
499 0 : bValue = IsUseUserData();
500 0 : break;
501 : case MID_DOCINFO_DELETEUSERDATA:
502 0 : bValue = IsDeleteUserData();
503 0 : break;
504 : case MID_DOCINFO_AUTOLOADENABLED:
505 0 : bValue = isAutoloadEnabled();
506 0 : break;
507 : case MID_DOCINFO_AUTOLOADSECS:
508 0 : bIsInt = true;
509 0 : nValue = getAutoloadDelay();
510 0 : break;
511 : case MID_DOCINFO_AUTOLOADURL:
512 0 : bIsString = true;
513 0 : aValue = getAutoloadURL();
514 0 : break;
515 : case MID_DOCINFO_DEFAULTTARGET:
516 0 : bIsString = true;
517 0 : aValue = getDefaultTarget();
518 0 : break;
519 : case MID_DOCINFO_DESCRIPTION:
520 0 : bIsString = true;
521 0 : aValue = getDescription();
522 0 : break;
523 : case MID_DOCINFO_KEYWORDS:
524 0 : bIsString = true;
525 0 : aValue = getKeywords();
526 0 : break;
527 : case MID_DOCINFO_SUBJECT:
528 0 : bIsString = true;
529 0 : aValue = getSubject();
530 0 : break;
531 : case MID_DOCINFO_TITLE:
532 0 : bIsString = true;
533 0 : aValue = getTitle();
534 0 : break;
535 : default:
536 : OSL_FAIL("Wrong MemberId!");
537 0 : return false;
538 : }
539 :
540 0 : if ( bIsString )
541 0 : rVal <<= OUString( aValue );
542 0 : else if ( bIsInt )
543 0 : rVal <<= nValue;
544 : else
545 0 : rVal <<= bValue;
546 0 : return true;
547 : }
548 :
549 0 : bool SfxDocumentInfoItem::PutValue( const Any& rVal, sal_uInt8 nMemberId )
550 : {
551 0 : OUString aValue;
552 0 : sal_Int32 nValue=0;
553 0 : bool bValue = false;
554 0 : bool bRet = false;
555 0 : nMemberId &= ~CONVERT_TWIPS;
556 0 : switch ( nMemberId )
557 : {
558 : case MID_DOCINFO_USEUSERDATA:
559 0 : bRet = (rVal >>= bValue);
560 0 : if ( bRet )
561 0 : SetUseUserData( bValue );
562 0 : break;
563 : case MID_DOCINFO_DELETEUSERDATA:
564 : // QUESTION: deleting user data was done here; seems to be superfluous!
565 0 : bRet = (rVal >>= bValue);
566 0 : if ( bRet )
567 0 : SetDeleteUserData( bValue );
568 0 : break;
569 : case MID_DOCINFO_AUTOLOADENABLED:
570 0 : bRet = (rVal >>= bValue);
571 0 : if ( bRet )
572 0 : setAutoloadEnabled(bValue);
573 0 : break;
574 : case MID_DOCINFO_AUTOLOADSECS:
575 0 : bRet = (rVal >>= nValue);
576 0 : if ( bRet )
577 0 : setAutoloadDelay(nValue);
578 0 : break;
579 : case MID_DOCINFO_AUTOLOADURL:
580 0 : bRet = (rVal >>= aValue);
581 0 : if ( bRet )
582 0 : setAutoloadURL(aValue);
583 0 : break;
584 : case MID_DOCINFO_DEFAULTTARGET:
585 0 : bRet = (rVal >>= aValue);
586 0 : if ( bRet )
587 0 : setDefaultTarget(aValue);
588 0 : break;
589 : case MID_DOCINFO_DESCRIPTION:
590 0 : bRet = (rVal >>= aValue);
591 0 : if ( bRet )
592 0 : setDescription(aValue);
593 0 : break;
594 : case MID_DOCINFO_KEYWORDS:
595 0 : bRet = (rVal >>= aValue);
596 0 : if ( bRet )
597 0 : setKeywords(aValue);
598 0 : break;
599 : case MID_DOCINFO_SUBJECT:
600 0 : bRet = (rVal >>= aValue);
601 0 : if ( bRet )
602 0 : setSubject(aValue);
603 0 : break;
604 : case MID_DOCINFO_TITLE:
605 0 : bRet = (rVal >>= aValue);
606 0 : if ( bRet )
607 0 : setTitle(aValue);
608 0 : break;
609 : default:
610 : OSL_FAIL("Wrong MemberId!");
611 0 : return false;
612 : }
613 :
614 0 : return bRet;
615 : }
616 :
617 0 : SfxDocumentDescPage::SfxDocumentDescPage( vcl::Window * pParent, const SfxItemSet& rItemSet )
618 : : SfxTabPage(pParent, "DescriptionInfoPage", "sfx/ui/descriptioninfopage.ui", &rItemSet)
619 0 : , m_pInfoItem ( NULL )
620 :
621 : {
622 0 : get(m_pTitleEd, "title");
623 0 : get(m_pThemaEd, "subject");
624 0 : get(m_pKeywordsEd, "keywords");
625 0 : get(m_pCommentEd, "comments");
626 0 : m_pCommentEd->set_width_request(m_pKeywordsEd->get_preferred_size().Width());
627 0 : m_pCommentEd->set_height_request(m_pCommentEd->GetTextHeight() * 16);
628 0 : }
629 :
630 0 : SfxDocumentDescPage::~SfxDocumentDescPage()
631 : {
632 0 : disposeOnce();
633 0 : }
634 :
635 0 : void SfxDocumentDescPage::dispose()
636 : {
637 0 : m_pTitleEd.clear();
638 0 : m_pThemaEd.clear();
639 0 : m_pKeywordsEd.clear();
640 0 : m_pCommentEd.clear();
641 0 : SfxTabPage::dispose();
642 0 : }
643 :
644 0 : VclPtr<SfxTabPage> SfxDocumentDescPage::Create(vcl::Window *pParent, const SfxItemSet *rItemSet)
645 : {
646 0 : return VclPtr<SfxDocumentDescPage>::Create(pParent, *rItemSet);
647 : }
648 :
649 0 : bool SfxDocumentDescPage::FillItemSet(SfxItemSet *rSet)
650 : {
651 : // Test whether a change is present
652 0 : const bool bTitleMod = m_pTitleEd->IsModified();
653 0 : const bool bThemeMod = m_pThemaEd->IsModified();
654 0 : const bool bKeywordsMod = m_pKeywordsEd->IsModified();
655 0 : const bool bCommentMod = m_pCommentEd->IsModified();
656 0 : if ( !( bTitleMod || bThemeMod || bKeywordsMod || bCommentMod ) )
657 : {
658 0 : return false;
659 : }
660 :
661 : // Generating the output data
662 0 : const SfxPoolItem* pItem = NULL;
663 0 : SfxDocumentInfoItem* pInfo = NULL;
664 0 : SfxTabDialog* pDlg = GetTabDialog();
665 0 : const SfxItemSet* pExSet = NULL;
666 :
667 0 : if ( pDlg )
668 0 : pExSet = pDlg->GetExampleSet();
669 :
670 0 : if ( pExSet && SfxItemState::SET != pExSet->GetItemState( SID_DOCINFO, true, &pItem ) )
671 0 : pInfo = m_pInfoItem;
672 0 : else if ( pItem )
673 0 : pInfo = new SfxDocumentInfoItem( *static_cast<const SfxDocumentInfoItem *>(pItem) );
674 :
675 0 : if ( !pInfo )
676 : {
677 : SAL_WARN( "sfx.dialog", "SfxDocumentDescPage::FillItemSet(): no item found" );
678 0 : return false;
679 : }
680 :
681 0 : if ( bTitleMod )
682 : {
683 0 : pInfo->setTitle( m_pTitleEd->GetText() );
684 : }
685 0 : if ( bThemeMod )
686 : {
687 0 : pInfo->setSubject( m_pThemaEd->GetText() );
688 : }
689 0 : if ( bKeywordsMod )
690 : {
691 0 : pInfo->setKeywords( m_pKeywordsEd->GetText() );
692 : }
693 0 : if ( bCommentMod )
694 : {
695 0 : pInfo->setDescription( m_pCommentEd->GetText() );
696 : }
697 0 : rSet->Put( SfxDocumentInfoItem( *pInfo ) );
698 0 : if ( pInfo != m_pInfoItem )
699 : {
700 0 : delete pInfo;
701 : }
702 :
703 0 : return true;
704 : }
705 :
706 :
707 0 : void SfxDocumentDescPage::Reset(const SfxItemSet *rSet)
708 : {
709 0 : m_pInfoItem = const_cast<SfxDocumentInfoItem*>(&static_cast<const SfxDocumentInfoItem &>(rSet->Get(SID_DOCINFO)));
710 :
711 0 : m_pTitleEd->SetText( m_pInfoItem->getTitle() );
712 0 : m_pThemaEd->SetText( m_pInfoItem->getSubject() );
713 0 : m_pKeywordsEd->SetText( m_pInfoItem->getKeywords() );
714 0 : m_pCommentEd->SetText( m_pInfoItem->getDescription() );
715 :
716 0 : SFX_ITEMSET_ARG( rSet, pROItem, SfxBoolItem, SID_DOC_READONLY, false );
717 0 : if ( pROItem && pROItem->GetValue() )
718 : {
719 0 : m_pTitleEd->SetReadOnly( true );
720 0 : m_pThemaEd->SetReadOnly( true );
721 0 : m_pKeywordsEd->SetReadOnly( true );
722 0 : m_pCommentEd->SetReadOnly( true );
723 : }
724 0 : }
725 :
726 :
727 : namespace
728 : {
729 0 : OUString GetDateTimeString( sal_Int32 _nDate, sal_Int32 _nTime )
730 : {
731 0 : const LocaleDataWrapper& rWrapper( Application::GetSettings().GetLocaleDataWrapper() );
732 :
733 0 : Date aDate( _nDate );
734 0 : tools::Time aTime( _nTime );
735 0 : OUString aStr( rWrapper.getDate( aDate ) );
736 0 : aStr += ", ";
737 0 : aStr += rWrapper.getTime( aTime );
738 0 : return aStr;
739 : }
740 :
741 : // copy from xmlsecurity/source/dialog/resourcemanager.cxx
742 0 : OUString GetContentPart( const OUString& _rRawString, const OUString& _rPartId )
743 : {
744 0 : OUString s;
745 :
746 0 : sal_Int32 nContStart = _rRawString.indexOf( _rPartId );
747 0 : if ( nContStart != -1 )
748 : {
749 0 : nContStart = nContStart + _rPartId.getLength();
750 0 : ++nContStart; // now its start of content, directly after Id
751 :
752 0 : sal_Int32 nContEnd = _rRawString.indexOf( ',', nContStart );
753 :
754 0 : s = _rRawString.copy( nContStart, nContEnd - nContStart );
755 : }
756 :
757 0 : return s;
758 : }
759 : }
760 :
761 0 : SfxDocumentPage::SfxDocumentPage(vcl::Window* pParent, const SfxItemSet& rItemSet)
762 : : SfxTabPage(pParent, "DocumentInfoPage", "sfx/ui/documentinfopage.ui", &rItemSet)
763 : , bEnableUseUserData( false )
764 0 : , bHandleDelete( false )
765 : {
766 0 : get(m_pBmp, "icon");
767 0 : get(m_pNameED, "nameed");
768 0 : get(m_pChangePassBtn, "changepass");
769 :
770 0 : get(m_pShowTypeFT, "showtype");
771 0 : get(m_pFileValEd, "showlocation");
772 0 : get(m_pShowSizeFT, "showsize");
773 0 : m_aUnknownSize = m_pShowSizeFT->GetText();
774 0 : m_pShowSizeFT->SetText(OUString());
775 :
776 0 : get(m_pCreateValFt, "showcreate");
777 0 : get(m_pChangeValFt, "showmodify");
778 0 : get(m_pSignedValFt, "showsigned");
779 0 : m_aMultiSignedStr = m_pSignedValFt->GetText();
780 0 : m_pSignedValFt->SetText(OUString());
781 0 : get(m_pSignatureBtn, "signature");
782 0 : get(m_pPrintValFt, "showprint");
783 0 : get(m_pTimeLogValFt, "showedittime");
784 0 : get(m_pDocNoValFt, "showrevision");
785 :
786 0 : get(m_pUseUserDataCB, "userdatacb");
787 0 : get(m_pDeleteBtn, "reset");
788 :
789 0 : get(m_pTemplFt, "templateft");
790 0 : get(m_pTemplValFt, "showtemplate");
791 :
792 0 : ImplUpdateSignatures();
793 0 : ImplCheckPasswordState();
794 0 : m_pChangePassBtn->SetClickHdl( LINK( this, SfxDocumentPage, ChangePassHdl ) );
795 0 : m_pSignatureBtn->SetClickHdl( LINK( this, SfxDocumentPage, SignatureHdl ) );
796 0 : m_pDeleteBtn->SetClickHdl( LINK( this, SfxDocumentPage, DeleteHdl ) );
797 :
798 : // [i96288] Check if the document signature command is enabled
799 : // on the main list enable/disable the pushbutton accordingly
800 0 : SvtCommandOptions aCmdOptions;
801 0 : if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
802 0 : OUString( DOCUMENT_SIGNATURE_MENU_CMD ) ) )
803 0 : m_pSignatureBtn->Disable();
804 0 : }
805 :
806 0 : SfxDocumentPage::~SfxDocumentPage()
807 : {
808 0 : disposeOnce();
809 0 : }
810 :
811 0 : void SfxDocumentPage::dispose()
812 : {
813 0 : m_pBmp.clear();
814 0 : m_pNameED.clear();
815 0 : m_pChangePassBtn.clear();
816 0 : m_pShowTypeFT.clear();
817 0 : m_pFileValEd.clear();
818 0 : m_pShowSizeFT.clear();
819 0 : m_pCreateValFt.clear();
820 0 : m_pChangeValFt.clear();
821 0 : m_pSignedValFt.clear();
822 0 : m_pSignatureBtn.clear();
823 0 : m_pPrintValFt.clear();
824 0 : m_pTimeLogValFt.clear();
825 0 : m_pDocNoValFt.clear();
826 0 : m_pUseUserDataCB.clear();
827 0 : m_pDeleteBtn.clear();
828 0 : m_pTemplFt.clear();
829 0 : m_pTemplValFt.clear();
830 0 : SfxTabPage::dispose();
831 0 : }
832 :
833 :
834 0 : IMPL_LINK_NOARG(SfxDocumentPage, DeleteHdl)
835 : {
836 0 : OUString aName;
837 0 : if ( bEnableUseUserData && m_pUseUserDataCB->IsChecked() )
838 0 : aName = SvtUserOptions().GetFullName();
839 0 : const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
840 0 : DateTime now( DateTime::SYSTEM );
841 0 : util::DateTime uDT( now.GetUNODateTime() );
842 0 : m_pCreateValFt->SetText( ConvertDateTime_Impl( aName, uDT, rLocaleWrapper ) );
843 0 : OUString aEmpty;
844 0 : m_pChangeValFt->SetText( aEmpty );
845 0 : m_pPrintValFt->SetText( aEmpty );
846 0 : const tools::Time aTime( 0 );
847 0 : m_pTimeLogValFt->SetText( rLocaleWrapper.getDuration( aTime ) );
848 0 : m_pDocNoValFt->SetText(OUString('1'));
849 0 : bHandleDelete = true;
850 0 : return 0;
851 : }
852 :
853 0 : IMPL_LINK_NOARG(SfxDocumentPage, SignatureHdl)
854 : {
855 0 : SfxObjectShell* pDoc = SfxObjectShell::Current();
856 0 : if( pDoc )
857 : {
858 0 : pDoc->SignDocumentContent();
859 :
860 0 : ImplUpdateSignatures();
861 : }
862 :
863 0 : return 0;
864 : }
865 :
866 0 : IMPL_STATIC_LINK_NOARG(SfxDocumentPage, ChangePassHdl)
867 : {
868 0 : SfxObjectShell* pShell = SfxObjectShell::Current();
869 : do
870 : {
871 0 : if (!pShell)
872 0 : break;
873 0 : SfxItemSet* pMedSet = pShell->GetMedium()->GetItemSet();
874 0 : if (!pMedSet)
875 0 : break;
876 0 : const SfxFilter* pFilter = pShell->GetMedium()->GetFilter();
877 0 : if (!pFilter)
878 0 : break;
879 :
880 0 : OUString aDocName;
881 0 : sfx2::RequestPassword(pFilter, aDocName, pMedSet);
882 0 : pShell->SetModified(true);
883 : }
884 : while (false);
885 0 : return 0;
886 : }
887 :
888 0 : void SfxDocumentPage::ImplUpdateSignatures()
889 : {
890 0 : SfxObjectShell* pDoc = SfxObjectShell::Current();
891 0 : if ( pDoc )
892 : {
893 0 : SfxMedium* pMedium = pDoc->GetMedium();
894 0 : if ( pMedium && !pMedium->GetName().isEmpty() && pMedium->GetStorage().is() )
895 : {
896 : Reference< security::XDocumentDigitalSignatures > xD(
897 0 : security::DocumentDigitalSignatures::createDefault(comphelper::getProcessComponentContext()) );
898 :
899 0 : OUString s;
900 0 : Sequence< security::DocumentSignatureInformation > aInfos;
901 0 : aInfos = xD->verifyDocumentContentSignatures( pMedium->GetZipStorageToSign_Impl(),
902 0 : uno::Reference< io::XInputStream >() );
903 0 : if ( aInfos.getLength() > 1 )
904 0 : s = m_aMultiSignedStr;
905 0 : else if ( aInfos.getLength() == 1 )
906 : {
907 0 : OUString aCN_Id("CN");
908 0 : const security::DocumentSignatureInformation& rInfo = aInfos[ 0 ];
909 0 : s = GetDateTimeString( rInfo.SignatureDate, rInfo.SignatureTime );
910 0 : s += ", ";
911 0 : s += GetContentPart( rInfo.Signer->getSubjectName(), aCN_Id );
912 : }
913 0 : m_pSignedValFt->SetText( s );
914 : }
915 : }
916 0 : }
917 :
918 0 : void SfxDocumentPage::ImplCheckPasswordState()
919 : {
920 0 : SfxObjectShell* pShell = SfxObjectShell::Current();
921 : do
922 : {
923 0 : if (!pShell)
924 0 : break;
925 0 : SfxItemSet* pMedSet = pShell->GetMedium()->GetItemSet();
926 0 : if (!pMedSet)
927 0 : break;
928 0 : SFX_ITEMSET_ARG( pMedSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false);
929 0 : uno::Sequence< beans::NamedValue > aEncryptionData;
930 0 : if (pEncryptionDataItem)
931 0 : pEncryptionDataItem->GetValue() >>= aEncryptionData;
932 : else
933 0 : break;
934 :
935 0 : if (!aEncryptionData.getLength())
936 0 : break;
937 0 : m_pChangePassBtn->Enable();
938 0 : return;
939 : }
940 : while (false);
941 0 : m_pChangePassBtn->Disable();
942 : }
943 :
944 0 : VclPtr<SfxTabPage> SfxDocumentPage::Create( vcl::Window* pParent, const SfxItemSet* rItemSet )
945 : {
946 0 : return VclPtr<SfxDocumentPage>::Create( pParent, *rItemSet );
947 : }
948 :
949 0 : void SfxDocumentPage::EnableUseUserData()
950 : {
951 0 : bEnableUseUserData = true;
952 0 : m_pUseUserDataCB->Show();
953 0 : m_pDeleteBtn->Show();
954 0 : }
955 :
956 0 : bool SfxDocumentPage::FillItemSet( SfxItemSet* rSet )
957 : {
958 0 : bool bRet = false;
959 :
960 0 : if ( !bHandleDelete && bEnableUseUserData &&
961 0 : m_pUseUserDataCB->IsValueChangedFromSaved() &&
962 0 : GetTabDialog() && GetTabDialog()->GetExampleSet() )
963 : {
964 0 : SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet();
965 : const SfxPoolItem* pItem;
966 :
967 0 : if ( pExpSet && SfxItemState::SET == pExpSet->GetItemState( SID_DOCINFO, true, &pItem ) )
968 : {
969 0 : const SfxDocumentInfoItem* m_pInfoItem = static_cast<const SfxDocumentInfoItem*>(pItem);
970 0 : bool bUseData = ( TRISTATE_TRUE == m_pUseUserDataCB->GetState() );
971 0 : const_cast<SfxDocumentInfoItem*>(m_pInfoItem)->SetUseUserData( bUseData );
972 0 : rSet->Put( SfxDocumentInfoItem( *m_pInfoItem ) );
973 0 : bRet = true;
974 : }
975 : }
976 :
977 0 : if ( bHandleDelete )
978 : {
979 0 : SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet();
980 : const SfxPoolItem* pItem;
981 0 : if ( pExpSet && SfxItemState::SET == pExpSet->GetItemState( SID_DOCINFO, true, &pItem ) )
982 : {
983 0 : const SfxDocumentInfoItem* pInfoItem = static_cast<const SfxDocumentInfoItem*>(pItem);
984 0 : bool bUseAuthor = bEnableUseUserData && m_pUseUserDataCB->IsChecked();
985 0 : SfxDocumentInfoItem newItem( *pInfoItem );
986 : newItem.resetUserData( bUseAuthor
987 : ? SvtUserOptions().GetFullName()
988 0 : : OUString() );
989 0 : const_cast<SfxDocumentInfoItem*>(pInfoItem)->SetUseUserData( TRISTATE_TRUE == m_pUseUserDataCB->GetState() );
990 0 : newItem.SetUseUserData( TRISTATE_TRUE == m_pUseUserDataCB->GetState() );
991 :
992 0 : newItem.SetDeleteUserData( true );
993 0 : rSet->Put( newItem );
994 0 : bRet = true;
995 : }
996 : }
997 :
998 0 : return bRet;
999 : }
1000 :
1001 0 : void SfxDocumentPage::Reset( const SfxItemSet* rSet )
1002 : {
1003 : // Determine the document information
1004 : const SfxDocumentInfoItem& rInfoItem =
1005 0 : static_cast<const SfxDocumentInfoItem &>(rSet->Get(SID_DOCINFO));
1006 :
1007 : // template data
1008 0 : if ( rInfoItem.HasTemplate() )
1009 0 : m_pTemplValFt->SetText( rInfoItem.getTemplateName() );
1010 : else
1011 : {
1012 0 : m_pTemplFt->Hide();
1013 0 : m_pTemplValFt->Hide();
1014 : }
1015 :
1016 : // determine file name
1017 0 : OUString aFile( rInfoItem.GetValue() );
1018 0 : OUString aFactory( aFile );
1019 0 : if ( aFile.getLength() > 2 && aFile[0] == '[' )
1020 : {
1021 0 : sal_Int32 nPos = aFile.indexOf( ']' );
1022 0 : aFactory = aFile.copy( 1, nPos-1 );
1023 0 : aFile = aFile.copy( nPos+1 );
1024 : }
1025 :
1026 : // determine name
1027 0 : INetURLObject aURL(aFile);
1028 0 : OUString aName = aURL.GetName( INetURLObject::DECODE_WITH_CHARSET );
1029 0 : if ( aName.isEmpty() || aURL.GetProtocol() == INetProtocol::PrivSoffice )
1030 0 : aName = SfxResId( STR_NONAME ).toString();
1031 0 : m_pNameED->SetText( aName );
1032 :
1033 : // determine context symbol
1034 0 : aURL.SetSmartProtocol( INetProtocol::File );
1035 0 : aURL.SetSmartURL( aFactory);
1036 0 : const OUString& rMainURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
1037 0 : Image aImage = SvFileInformationManager::GetImage( aURL, true );
1038 :
1039 0 : if ( GetDPIScaleFactor() > 1)
1040 : {
1041 0 : BitmapEx b = aImage.GetBitmapEx();
1042 0 : b.Scale(GetDPIScaleFactor(), GetDPIScaleFactor());
1043 0 : aImage = Image(b);
1044 : }
1045 :
1046 0 : m_pBmp->SetImage( aImage );
1047 :
1048 : // determine size and type
1049 0 : OUString aSizeText( m_aUnknownSize );
1050 0 : if ( aURL.GetProtocol() == INetProtocol::File )
1051 0 : aSizeText = CreateSizeText( SfxContentHelper::GetSize( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
1052 0 : m_pShowSizeFT->SetText( aSizeText );
1053 :
1054 0 : OUString aDescription = SvFileInformationManager::GetDescription( INetURLObject(rMainURL) );
1055 0 : if ( aDescription.isEmpty() )
1056 0 : aDescription = SfxResId( STR_SFX_NEWOFFICEDOC ).toString();
1057 0 : m_pShowTypeFT->SetText( aDescription );
1058 :
1059 : // determine location
1060 0 : aURL.SetSmartURL( aFile);
1061 0 : if ( aURL.GetProtocol() == INetProtocol::File )
1062 : {
1063 0 : INetURLObject aPath( aURL );
1064 0 : aPath.setFinalSlash();
1065 0 : aPath.removeSegment();
1066 : // we know it's a folder -> don't need the final slash, but it's better for WB_PATHELLIPSIS
1067 0 : aPath.removeFinalSlash();
1068 0 : OUString aText( aPath.PathToFileName() ); //! (pb) MaxLen?
1069 0 : m_pFileValEd->SetText( aText );
1070 : }
1071 0 : else if ( aURL.GetProtocol() != INetProtocol::PrivSoffice )
1072 0 : m_pFileValEd->SetText( aURL.GetPartBeforeLastName() );
1073 :
1074 : // handle access data
1075 0 : bool m_bUseUserData = rInfoItem.IsUseUserData();
1076 0 : const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
1077 0 : m_pCreateValFt->SetText( ConvertDateTime_Impl( rInfoItem.getAuthor(),
1078 0 : rInfoItem.getCreationDate(), rLocaleWrapper ) );
1079 0 : util::DateTime aTime( rInfoItem.getModificationDate() );
1080 0 : if ( aTime.Month > 0 )
1081 0 : m_pChangeValFt->SetText( ConvertDateTime_Impl(
1082 0 : rInfoItem.getModifiedBy(), aTime, rLocaleWrapper ) );
1083 0 : aTime = rInfoItem.getPrintDate();
1084 0 : if ( aTime.Month > 0 )
1085 0 : m_pPrintValFt->SetText( ConvertDateTime_Impl( rInfoItem.getPrintedBy(),
1086 0 : aTime, rLocaleWrapper ) );
1087 0 : const long nTime = rInfoItem.getEditingDuration();
1088 0 : if ( m_bUseUserData )
1089 : {
1090 0 : const tools::Time aT( nTime/3600, (nTime%3600)/60, nTime%60 );
1091 0 : m_pTimeLogValFt->SetText( rLocaleWrapper.getDuration( aT ) );
1092 0 : m_pDocNoValFt->SetText( OUString::number(
1093 0 : rInfoItem.getEditingCycles() ) );
1094 : }
1095 :
1096 : // Check for cmis properties where otherwise unavailable
1097 0 : if ( rInfoItem.isCmisDocument( ) )
1098 : {
1099 0 : uno::Sequence< document::CmisProperty > aCmisProps = rInfoItem.GetCmisProperties();
1100 0 : for ( sal_Int32 i = 0; i < aCmisProps.getLength(); i++ )
1101 : {
1102 0 : if ( aCmisProps[i].Id == "cmis:contentStreamLength" &&
1103 0 : aSizeText == m_aUnknownSize )
1104 : {
1105 0 : Sequence< sal_Int64 > seqValue;
1106 0 : aCmisProps[i].Value >>= seqValue;
1107 : SvNumberFormatter m_aNumberFormatter( ::comphelper::getProcessComponentContext(),
1108 0 : Application::GetSettings().GetLanguageTag().getLanguageType() );
1109 0 : sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM );
1110 0 : if ( seqValue.getLength( ) > 0 )
1111 : {
1112 0 : OUString sValue;
1113 0 : m_aNumberFormatter.GetInputLineString( seqValue[0], nIndex, sValue );
1114 0 : m_pShowSizeFT->SetText( CreateSizeText( sValue.toInt64( ) ) );
1115 0 : }
1116 : }
1117 :
1118 0 : util::DateTime uDT;
1119 0 : OUString emptyDate = ConvertDateTime_Impl( "", uDT, rLocaleWrapper );
1120 0 : if ( aCmisProps[i].Id == "cmis:creationDate" &&
1121 0 : (m_pCreateValFt->GetText() == emptyDate ||
1122 0 : m_pCreateValFt->GetText().isEmpty()))
1123 : {
1124 0 : Sequence< util::DateTime > seqValue;
1125 0 : aCmisProps[i].Value >>= seqValue;
1126 0 : if ( seqValue.getLength( ) > 0 )
1127 : {
1128 0 : m_pCreateValFt->SetText( ConvertDateTime_Impl( "", seqValue[0], rLocaleWrapper ) );
1129 0 : }
1130 : }
1131 0 : if ( aCmisProps[i].Id == "cmis:lastModificationDate" &&
1132 0 : (m_pChangeValFt->GetText() == emptyDate ||
1133 0 : m_pChangeValFt->GetText().isEmpty()))
1134 : {
1135 0 : Sequence< util::DateTime > seqValue;
1136 0 : aCmisProps[i].Value >>= seqValue;
1137 0 : if ( seqValue.getLength( ) > 0 )
1138 : {
1139 0 : m_pChangeValFt->SetText( ConvertDateTime_Impl( "", seqValue[0], rLocaleWrapper ) );
1140 0 : }
1141 : }
1142 0 : }
1143 : }
1144 :
1145 0 : m_pUseUserDataCB->SetState( static_cast<TriState>(m_bUseUserData) );
1146 0 : m_pUseUserDataCB->SaveValue();
1147 0 : m_pUseUserDataCB->Enable( bEnableUseUserData );
1148 0 : bHandleDelete = false;
1149 0 : m_pDeleteBtn->Enable( bEnableUseUserData );
1150 0 : }
1151 :
1152 :
1153 0 : SfxDocumentInfoDialog::SfxDocumentInfoDialog( vcl::Window* pParent,
1154 : const SfxItemSet& rItemSet )
1155 : : SfxTabDialog(0, pParent, "DocumentPropertiesDialog",
1156 : "sfx/ui/documentpropertiesdialog.ui", &rItemSet)
1157 0 : , m_nDocInfoId(0)
1158 : {
1159 : const SfxDocumentInfoItem& rInfoItem =
1160 0 : static_cast<const SfxDocumentInfoItem &>(rItemSet.Get( SID_DOCINFO ));
1161 :
1162 : #ifdef DBG_UTIL
1163 : SFX_ITEMSET_ARG( &rItemSet, pURLItem, SfxStringItem, SID_BASEURL, false );
1164 : DBG_ASSERT( pURLItem, "No BaseURL provided for InternetTabPage!" );
1165 : #endif
1166 :
1167 : // Determine the Titels
1168 0 : const SfxPoolItem* pItem = 0;
1169 0 : OUString aTitle( GetText() );
1170 0 : if ( SfxItemState::SET !=
1171 0 : rItemSet.GetItemState( SID_EXPLORER_PROPS_START, false, &pItem ) )
1172 : {
1173 : // File name
1174 0 : OUString aFile( rInfoItem.GetValue() );
1175 :
1176 0 : INetURLObject aURL;
1177 0 : aURL.SetSmartProtocol( INetProtocol::File );
1178 0 : aURL.SetSmartURL( aFile);
1179 0 : if ( INetProtocol::PrivSoffice != aURL.GetProtocol() )
1180 : {
1181 0 : OUString aLastName( aURL.GetLastName() );
1182 0 : if ( !aLastName.isEmpty() )
1183 0 : aTitle += aLastName;
1184 : else
1185 0 : aTitle += aFile;
1186 : }
1187 : else
1188 0 : aTitle += SfxResId( STR_NONAME ).toString();
1189 : }
1190 : else
1191 : {
1192 : DBG_ASSERT( pItem->IsA( TYPE( SfxStringItem ) ),
1193 : "SfxDocumentInfoDialog:<SfxStringItem> expected" );
1194 0 : aTitle += static_cast<const SfxStringItem*>(pItem)->GetValue();
1195 : }
1196 0 : SetText( aTitle );
1197 :
1198 : // Property Pages
1199 0 : m_nDocInfoId = AddTabPage("general", SfxDocumentPage::Create, 0);
1200 0 : AddTabPage("description", SfxDocumentDescPage::Create, 0);
1201 0 : AddTabPage("customprops", SfxCustomPropertiesPage::Create, 0);
1202 0 : AddTabPage("cmisprops", SfxCmisPropertiesPage::Create, 0);
1203 0 : AddTabPage("security", SfxSecurityPage::Create, 0);
1204 0 : }
1205 :
1206 :
1207 :
1208 0 : void SfxDocumentInfoDialog::PageCreated( sal_uInt16 nId, SfxTabPage &rPage )
1209 : {
1210 0 : if ( m_nDocInfoId == nId )
1211 0 : static_cast<SfxDocumentPage&>(rPage).EnableUseUserData();
1212 0 : }
1213 :
1214 0 : void SfxDocumentInfoDialog::AddFontTabPage()
1215 : {
1216 0 : AddTabPage( FONT_PAGE_ID, SfxResId( STR_FONT_TABPAGE ).toString(), SfxDocumentFontsPage::Create, 0);
1217 0 : }
1218 :
1219 : // class CustomPropertiesYesNoButton -------------------------------------
1220 :
1221 0 : CustomPropertiesYesNoButton::CustomPropertiesYesNoButton( vcl::Window* pParent, const ResId& rResId ) :
1222 : Control( pParent, rResId ),
1223 0 : m_aYesButton( VclPtr<RadioButton>::Create(this, ResId( RB_PROPERTY_YES, *rResId.GetResMgr() )) ),
1224 0 : m_aNoButton ( VclPtr<RadioButton>::Create(this, ResId( RB_PROPERTY_NO, *rResId.GetResMgr() )) )
1225 : {
1226 0 : FreeResource();
1227 0 : Wallpaper aWall( Color( COL_TRANSPARENT ) );
1228 0 : SetBackground( aWall );
1229 0 : SetBorderStyle( WindowBorderStyle::MONO );
1230 0 : CheckNo();
1231 0 : m_aYesButton->SetBackground( aWall );
1232 0 : m_aNoButton->SetBackground( aWall );
1233 0 : }
1234 :
1235 :
1236 0 : CustomPropertiesYesNoButton::~CustomPropertiesYesNoButton()
1237 : {
1238 0 : disposeOnce();
1239 0 : }
1240 :
1241 0 : void CustomPropertiesYesNoButton::dispose()
1242 : {
1243 0 : m_aYesButton.disposeAndClear();
1244 0 : m_aNoButton.disposeAndClear();
1245 0 : Control::dispose();
1246 0 : }
1247 :
1248 : class DurationDialog_Impl : public ModalDialog
1249 : {
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;
1258 :
1259 : public:
1260 :
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;
1265 : };
1266 :
1267 0 : DurationDialog_Impl::DurationDialog_Impl(vcl::Window* pParent,
1268 : const util::Duration& rDuration)
1269 : : ModalDialog(pParent, "EditDurationDialog",
1270 0 : "sfx/ui/editdurationdialog.ui")
1271 : {
1272 0 : get(m_pNegativeCB, "negative");
1273 0 : get(m_pYearNF, "years");
1274 0 : get(m_pMonthNF, "months");
1275 0 : get(m_pDayNF, "days");
1276 0 : get(m_pHourNF, "hours");
1277 0 : get(m_pMinuteNF, "minutes");
1278 0 : get(m_pSecondNF, "seconds");
1279 0 : get(m_pMSecondNF, "milliseconds");
1280 :
1281 0 : m_pNegativeCB->Check(rDuration.Negative);
1282 0 : m_pYearNF->SetValue(rDuration.Years);
1283 0 : m_pMonthNF->SetValue(rDuration.Months);
1284 0 : m_pDayNF->SetValue(rDuration.Days);
1285 0 : m_pHourNF->SetValue(rDuration.Hours);
1286 0 : m_pMinuteNF->SetValue(rDuration.Minutes);
1287 0 : m_pSecondNF->SetValue(rDuration.Seconds);
1288 0 : m_pMSecondNF->SetValue(rDuration.NanoSeconds);
1289 0 : }
1290 :
1291 0 : DurationDialog_Impl::~DurationDialog_Impl()
1292 : {
1293 0 : disposeOnce();
1294 0 : }
1295 :
1296 0 : void DurationDialog_Impl::dispose()
1297 : {
1298 0 : m_pNegativeCB.clear();
1299 0 : m_pYearNF.clear();
1300 0 : m_pMonthNF.clear();
1301 0 : m_pDayNF.clear();
1302 0 : m_pHourNF.clear();
1303 0 : m_pMinuteNF.clear();
1304 0 : m_pSecondNF.clear();
1305 0 : m_pMSecondNF.clear();
1306 0 : ModalDialog::dispose();
1307 0 : }
1308 :
1309 0 : util::Duration DurationDialog_Impl::GetDuration() const
1310 : {
1311 0 : util::Duration aRet;
1312 0 : aRet.Negative = m_pNegativeCB->IsChecked();
1313 0 : aRet.Years = m_pYearNF->GetValue();
1314 0 : aRet.Months = m_pMonthNF->GetValue( );
1315 0 : aRet.Days = m_pDayNF->GetValue( );
1316 0 : aRet.Hours = m_pHourNF->GetValue( );
1317 0 : aRet.Minutes = m_pMinuteNF->GetValue();
1318 0 : aRet.Seconds = m_pSecondNF->GetValue();
1319 0 : aRet.NanoSeconds = m_pMSecondNF->GetValue();
1320 0 : return aRet;
1321 : }
1322 :
1323 0 : CustomPropertiesDurationField::CustomPropertiesDurationField(vcl::Window* pParent, WinBits nStyle,
1324 : CustomPropertyLine* pLine)
1325 : : Edit(pParent, nStyle)
1326 0 : , m_pLine(pLine)
1327 :
1328 : {
1329 0 : SetDuration( util::Duration(false, 0, 0, 0, 0, 0, 0, 0) );
1330 0 : }
1331 :
1332 0 : void CustomPropertiesDurationField::RequestHelp( const HelpEvent& rHEvt )
1333 : {
1334 0 : if ( rHEvt.GetMode() & HelpEventMode::QUICK )
1335 : {
1336 0 : Size aSize( GetSizePixel() );
1337 0 : Rectangle aItemRect( rHEvt.GetMousePosPixel(), aSize );
1338 0 : if (Help::IsBalloonHelpEnabled())
1339 0 : Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), GetText() );
1340 : else
1341 0 : Help::ShowQuickHelp( this, aItemRect, GetText(),
1342 0 : QuickHelpFlags::Left|QuickHelpFlags::VCenter );
1343 : }
1344 0 : }
1345 :
1346 0 : void CustomPropertiesDurationField::SetDuration( const util::Duration& rDuration )
1347 : {
1348 0 : m_aDuration = rDuration;
1349 0 : OUString sText(rDuration.Negative ? OUString('-') : OUString('+'));
1350 0 : sText += m_pLine->m_sDurationFormat;
1351 0 : sText = sText.replaceFirst( "%1", OUString::number( rDuration.Years ) );
1352 0 : sText = sText.replaceFirst( "%2", OUString::number( rDuration.Months ) );
1353 0 : sText = sText.replaceFirst( "%3", OUString::number( rDuration.Days ) );
1354 0 : sText = sText.replaceFirst( "%4", OUString::number( rDuration.Hours ) );
1355 0 : sText = sText.replaceFirst( "%5", OUString::number( rDuration.Minutes) );
1356 0 : sText = sText.replaceFirst( "%6", OUString::number( rDuration.Seconds) );
1357 0 : SetText( sText );
1358 0 : }
1359 :
1360 0 : CustomPropertiesEditButton::CustomPropertiesEditButton(vcl::Window* pParent, WinBits nStyle,
1361 : CustomPropertyLine* pLine)
1362 : : PushButton(pParent, nStyle)
1363 0 : , m_pLine(pLine)
1364 : {
1365 0 : SetClickHdl( LINK( this, CustomPropertiesEditButton, ClickHdl ));
1366 0 : }
1367 :
1368 0 : IMPL_LINK_NOARG(CustomPropertiesEditButton, ClickHdl)
1369 : {
1370 0 : VclPtrInstance< DurationDialog_Impl > pDurationDlg( this, m_pLine->m_aDurationField->GetDuration() );
1371 0 : if ( RET_OK == pDurationDlg->Execute() )
1372 0 : m_pLine->m_aDurationField->SetDuration( pDurationDlg->GetDuration() );
1373 0 : return 1;
1374 : }
1375 :
1376 0 : void CustomPropertiesYesNoButton::Resize()
1377 : {
1378 0 : const long nWidth = GetSizePixel().Width();
1379 0 : const long n3Width = LogicToPixel( Size( 3, 3 ), MAP_APPFONT ).Width();
1380 0 : const long nNewWidth = ( nWidth / 2 ) - n3Width - 2;
1381 0 : Size aSize = m_aYesButton->GetSizePixel();
1382 0 : const long nDelta = aSize.Width() - nNewWidth;
1383 0 : aSize.Width() = nNewWidth;
1384 0 : m_aYesButton->SetSizePixel( aSize );
1385 0 : Point aPos = m_aNoButton->GetPosPixel();
1386 0 : aPos.X() -= nDelta;
1387 0 : m_aNoButton->SetPosSizePixel( aPos, aSize );
1388 0 : }
1389 :
1390 : // struct CustomPropertyLine ---------------------------------------------
1391 0 : 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 0 : m_bTypeLostFocus( false )
1405 :
1406 : {
1407 0 : m_aTimeField->SetExtFormat( EXTTIMEF_24H_LONG );
1408 0 : m_aDateField->SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY );
1409 :
1410 0 : m_aRemoveButton->SetModeImage(Image(SfxResId(SFX_IMG_PROPERTY_REMOVE)));
1411 0 : m_aRemoveButton->SetQuickHelpText(SfxResId(STR_SFX_REMOVE_PROPERTY).toString());
1412 :
1413 0 : m_aEditButton->SetText(SfxResId(SFX_ST_EDIT).toString());
1414 0 : }
1415 :
1416 0 : void CustomPropertyLine::SetRemoved()
1417 : {
1418 : DBG_ASSERT( !m_bIsRemoved, "CustomPropertyLine::SetRemoved(): line already removed" );
1419 0 : m_bIsRemoved = true;
1420 0 : m_aNameBox->Hide();
1421 0 : m_aTypeBox->Hide();
1422 0 : m_aValueEdit->Hide();
1423 0 : m_aDateField->Hide();
1424 0 : m_aTimeField->Hide();
1425 0 : m_aDurationField->Hide();
1426 0 : m_aEditButton->Hide();
1427 0 : m_aYesNoButton->Hide();
1428 0 : m_aRemoveButton->Hide();
1429 0 : }
1430 :
1431 0 : 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 ) ),
1448 : m_nScrollPos (0),
1449 : m_pCurrentLine (NULL),
1450 : m_aNumberFormatter( ::comphelper::getProcessComponentContext(),
1451 0 : Application::GetSettings().GetLanguageTag().getLanguageType() )
1452 :
1453 : {
1454 0 : m_aEditButton->SetPosSizePixel(
1455 0 : LogicToPixel(Point(159, 2), MAP_APPFONT),
1456 0 : LogicToPixel(Size(RSC_CD_TEXTBOX_HEIGHT, RSC_CD_TEXTBOX_HEIGHT), MAP_APPFONT));
1457 0 : m_aRemoveButton->SetSizePixel(LogicToPixel(Size(RSC_CD_PUSHBUTTON_HEIGHT, RSC_CD_PUSHBUTTON_HEIGHT), MAP_APPFONT));
1458 :
1459 0 : m_aValueEdit->SetPosSizePixel(
1460 0 : LogicToPixel(Point(159, 2), MAP_APPFONT),
1461 0 : LogicToPixel(Size(61, RSC_CD_TEXTBOX_HEIGHT), MAP_APPFONT));
1462 :
1463 0 : m_aEditLoseFocusIdle.SetPriority( SchedulerPriority::LOWEST );
1464 0 : m_aEditLoseFocusIdle.SetIdleHdl( LINK( this, CustomPropertiesWindow, EditTimeoutHdl ) );
1465 0 : m_aBoxLoseFocusIdle.SetPriority( SchedulerPriority::LOWEST );
1466 0 : m_aBoxLoseFocusIdle.SetIdleHdl( LINK( this, CustomPropertiesWindow, BoxTimeoutHdl ) );
1467 :
1468 0 : m_aNameBox->add_mnemonic_label(m_pHeaderAccName);
1469 0 : m_aNameBox->SetAccessibleName(m_pHeaderAccName->GetText());
1470 0 : m_aTypeBox->add_mnemonic_label(m_pHeaderAccType);
1471 0 : m_aTypeBox->SetAccessibleName(m_pHeaderAccType->GetText());
1472 0 : m_aValueEdit->add_mnemonic_label(m_pHeaderAccValue);
1473 0 : m_aValueEdit->SetAccessibleName(m_pHeaderAccValue->GetText());
1474 :
1475 0 : m_aNameBox->Hide();
1476 0 : m_aTypeBox->Hide();
1477 0 : m_aValueEdit->Hide();
1478 0 : m_aDateField->Hide();
1479 0 : m_aTimeField->Hide();
1480 0 : m_aDurationField->Hide();
1481 0 : m_aEditButton->Hide();
1482 0 : m_aYesNoButton->Hide();
1483 0 : m_aRemoveButton->Hide();
1484 :
1485 : m_nLineHeight =
1486 0 : ( m_aRemoveButton->GetPosPixel().Y() * 2 ) + m_aRemoveButton->GetSizePixel().Height();
1487 0 : }
1488 :
1489 0 : CustomPropertiesWindow::~CustomPropertiesWindow()
1490 : {
1491 0 : disposeOnce();
1492 0 : }
1493 :
1494 0 : void CustomPropertiesWindow::dispose()
1495 : {
1496 0 : m_aEditLoseFocusIdle.Stop();
1497 0 : m_aBoxLoseFocusIdle.Stop();
1498 0 : ClearAllLines();
1499 0 : m_aNameBox.disposeAndClear();
1500 0 : m_aTypeBox.disposeAndClear();
1501 0 : m_aValueEdit.disposeAndClear();
1502 0 : m_aDateField.disposeAndClear();
1503 0 : m_aTimeField.disposeAndClear();
1504 0 : m_aDurationField.disposeAndClear();
1505 0 : m_aEditButton.disposeAndClear();
1506 0 : m_aYesNoButton.disposeAndClear();
1507 0 : m_aRemoveButton.disposeAndClear();
1508 0 : m_pHeaderAccName.clear();
1509 0 : m_pHeaderAccType.clear();
1510 0 : m_pHeaderAccValue.clear();
1511 0 : vcl::Window::dispose();
1512 0 : }
1513 :
1514 0 : IMPL_STATIC_LINK(
1515 : CustomPropertiesWindow, TypeHdl, CustomPropertiesTypeBox*, pBox )
1516 : {
1517 0 : long nType = reinterpret_cast<long>( pBox->GetSelectEntryData() );
1518 0 : CustomPropertyLine* pLine = pBox->GetLine();
1519 0 : pLine->m_aValueEdit->Show( (CUSTOM_TYPE_TEXT == nType) || (CUSTOM_TYPE_NUMBER == nType) );
1520 0 : pLine->m_aDateField->Show( (CUSTOM_TYPE_DATE == nType) || (CUSTOM_TYPE_DATETIME == nType) );
1521 0 : pLine->m_aTimeField->Show( CUSTOM_TYPE_DATETIME == nType );
1522 0 : pLine->m_aDurationField->Show( CUSTOM_TYPE_DURATION == nType );
1523 0 : pLine->m_aEditButton->Show( CUSTOM_TYPE_DURATION == nType );
1524 0 : pLine->m_aYesNoButton->Show( CUSTOM_TYPE_BOOLEAN == nType );
1525 :
1526 : //adjust positions of date and time controls
1527 0 : if ( nType == CUSTOM_TYPE_DATE )
1528 : {
1529 0 : pLine->m_bIsDate = true;
1530 0 : pLine->m_aDateField->SetSizePixel( pLine->m_aValueEdit->GetSizePixel() );
1531 : }
1532 0 : else if ( nType == CUSTOM_TYPE_DATETIME)
1533 : {
1534 : // because m_aDateField and m_aTimeField have the same size for type "DateTime",
1535 : // we just rely on m_aTimeField here.
1536 0 : pLine->m_bIsDate = false;
1537 0 : pLine->m_aDateField->SetSizePixel( pLine->m_aTimeField->GetSizePixel() );
1538 : }
1539 :
1540 0 : return 0;
1541 : }
1542 :
1543 0 : IMPL_LINK( CustomPropertiesWindow, RemoveHdl, CustomPropertiesRemoveButton*, pButton )
1544 : {
1545 0 : CustomPropertyLine* pLine = pButton->GetLine();
1546 : std::vector< CustomPropertyLine* >::iterator pFound =
1547 0 : std::find( m_aCustomPropertiesLines.begin(), m_aCustomPropertiesLines.end(), pLine );
1548 0 : if ( pFound != m_aCustomPropertiesLines.end() )
1549 : {
1550 0 : pLine = *pFound;
1551 0 : pLine->SetRemoved();
1552 0 : std::vector< CustomPropertyLine* >::iterator pIter = pFound + 1;
1553 0 : const long nDelta = GetLineHeight();
1554 0 : for ( ; pIter != m_aCustomPropertiesLines.end(); ++pIter )
1555 : {
1556 0 : pLine = *pIter;
1557 0 : if ( pLine->m_bIsRemoved )
1558 0 : continue;
1559 :
1560 0 : vcl::Window* pWindows[] = { pLine->m_aNameBox.get(), pLine->m_aTypeBox.get(), pLine->m_aValueEdit.get(),
1561 0 : pLine->m_aDateField.get(), pLine->m_aTimeField.get(),
1562 0 : pLine->m_aDurationField.get(), pLine->m_aEditButton.get(),
1563 0 : pLine->m_aYesNoButton.get(), pLine->m_aRemoveButton.get(), NULL };
1564 0 : vcl::Window** pCurrent = pWindows;
1565 0 : while ( *pCurrent )
1566 : {
1567 0 : Point aPos = (*pCurrent)->GetPosPixel();
1568 0 : aPos.Y() -= nDelta;
1569 0 : (*pCurrent)->SetPosPixel( aPos );
1570 0 : pCurrent++;
1571 : }
1572 : }
1573 : }
1574 :
1575 0 : m_aRemovedHdl.Call(0);
1576 0 : return 0;
1577 : }
1578 :
1579 0 : IMPL_LINK( CustomPropertiesWindow, EditLoseFocusHdl, CustomPropertiesEdit*, pEdit )
1580 : {
1581 0 : if ( pEdit )
1582 : {
1583 0 : CustomPropertyLine* pLine = pEdit->GetLine();
1584 0 : if ( !pLine->m_bTypeLostFocus )
1585 : {
1586 0 : m_pCurrentLine = pLine;
1587 0 : m_aEditLoseFocusIdle.Start();
1588 : }
1589 : else
1590 0 : pLine->m_bTypeLostFocus = false;
1591 : }
1592 0 : return 0;
1593 : }
1594 :
1595 0 : IMPL_LINK( CustomPropertiesWindow, BoxLoseFocusHdl, CustomPropertiesTypeBox*, pBox )
1596 : {
1597 0 : if ( pBox )
1598 : {
1599 0 : m_pCurrentLine = pBox->GetLine();
1600 0 : m_aBoxLoseFocusIdle.Start();
1601 : }
1602 :
1603 0 : return 0;
1604 : }
1605 :
1606 0 : IMPL_LINK_NOARG_TYPED(CustomPropertiesWindow, EditTimeoutHdl, Idle *, void)
1607 : {
1608 0 : ValidateLine( m_pCurrentLine, false );
1609 0 : }
1610 :
1611 0 : IMPL_LINK_NOARG_TYPED(CustomPropertiesWindow, BoxTimeoutHdl, Idle *, void)
1612 : {
1613 0 : ValidateLine( m_pCurrentLine, true );
1614 0 : }
1615 :
1616 0 : bool CustomPropertiesWindow::IsLineValid( CustomPropertyLine* pLine ) const
1617 : {
1618 0 : bool bIsValid = true;
1619 0 : pLine->m_bTypeLostFocus = false;
1620 : long nType = reinterpret_cast<long>(
1621 0 : pLine->m_aTypeBox->GetSelectEntryData() );
1622 0 : OUString sValue = pLine->m_aValueEdit->GetText();
1623 0 : if ( sValue.isEmpty() )
1624 0 : return true;
1625 :
1626 0 : sal_uInt32 nIndex = 0xFFFFFFFF;
1627 0 : if ( CUSTOM_TYPE_NUMBER == nType )
1628 : nIndex = const_cast< SvNumberFormatter& >(
1629 0 : m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
1630 0 : else if ( CUSTOM_TYPE_DATE == nType )
1631 : nIndex = const_cast< SvNumberFormatter& >(
1632 0 : m_aNumberFormatter).GetFormatIndex( NF_DATE_SYS_DDMMYYYY );
1633 :
1634 0 : if ( nIndex != 0xFFFFFFFF )
1635 : {
1636 0 : sal_uInt32 nTemp = nIndex;
1637 0 : double fDummy = 0.0;
1638 : bIsValid = const_cast< SvNumberFormatter& >(
1639 0 : m_aNumberFormatter ).IsNumberFormat( sValue, nIndex, fDummy );
1640 0 : if ( bIsValid && nTemp != nIndex )
1641 : // sValue is a number but the format doesn't match the index
1642 0 : bIsValid = false;
1643 : }
1644 :
1645 0 : return bIsValid;
1646 : }
1647 :
1648 0 : void CustomPropertiesWindow::ValidateLine( CustomPropertyLine* pLine, bool bIsFromTypeBox )
1649 : {
1650 0 : if ( !IsLineValid( pLine ) )
1651 : {
1652 0 : if ( bIsFromTypeBox ) // LoseFocus of TypeBox
1653 0 : pLine->m_bTypeLostFocus = true;
1654 0 : vcl::Window* pParent = GetParent()->GetParent();
1655 0 : if (ScopedVclPtrInstance<MessageDialog>::Create(pParent, SfxResId(STR_SFX_QUERY_WRONG_TYPE), VCL_MESSAGE_QUESTION, VCL_BUTTONS_OK_CANCEL)->Execute() == RET_OK)
1656 0 : pLine->m_aTypeBox->SelectEntryPos( m_aTypeBox->GetEntryPos( reinterpret_cast<void*>(CUSTOM_TYPE_TEXT) ) );
1657 : else
1658 0 : pLine->m_aValueEdit->GrabFocus();
1659 : }
1660 0 : }
1661 :
1662 0 : bool CustomPropertiesWindow::InitControls( HeaderBar* pHeaderBar, const ScrollBar* pScrollBar )
1663 : {
1664 0 : bool bChanged = false;
1665 :
1666 : DBG_ASSERT( pHeaderBar, "CustomPropertiesWindow::InitControls(): invalid headerbar" );
1667 : DBG_ASSERT( pScrollBar, "CustomPropertiesWindow::InitControls(): invalid scrollbar" );
1668 :
1669 0 : const long nOffset = 4;
1670 0 : const long nScrollBarWidth = pScrollBar->GetSizePixel().Width();
1671 0 : const long nButtonWidth = m_aRemoveButton->GetSizePixel().Width() + nScrollBarWidth + nOffset;
1672 0 : long nTypeWidth = m_aTypeBox->CalcMinimumSize().Width() + ( 2 * nOffset );
1673 0 : long nFullWidth = pHeaderBar->GetSizePixel().Width();
1674 0 : long nItemWidth = ( nFullWidth - nTypeWidth - nButtonWidth ) / 2;
1675 0 : pHeaderBar->SetItemSize( HI_NAME, nItemWidth );
1676 0 : pHeaderBar->SetItemSize( HI_TYPE, nTypeWidth );
1677 0 : pHeaderBar->SetItemSize( HI_VALUE, nItemWidth );
1678 0 : pHeaderBar->SetItemSize( HI_ACTION, nButtonWidth );
1679 :
1680 0 : vcl::Window* pWindows[] = { m_aNameBox.get(), m_aTypeBox.get(), m_aValueEdit.get(), m_aRemoveButton.get(), NULL };
1681 0 : vcl::Window** pCurrent = pWindows;
1682 0 : sal_uInt16 nPos = 0;
1683 0 : while ( *pCurrent )
1684 : {
1685 0 : Rectangle aRect = pHeaderBar->GetItemRect( pHeaderBar->GetItemId( nPos++ ) );
1686 0 : Size aOrigSize = (*pCurrent)->GetSizePixel();
1687 0 : Point aOrigPos = (*pCurrent)->GetPosPixel();
1688 0 : Size aSize(aOrigSize);
1689 0 : Point aPos(aOrigPos);
1690 0 : long nWidth = aRect.GetWidth() - nOffset;
1691 0 : if ( *pCurrent == m_aRemoveButton.get() )
1692 0 : nWidth -= pScrollBar->GetSizePixel().Width();
1693 0 : aSize.Width() = nWidth;
1694 0 : aPos.X() = aRect.getX() + ( nOffset / 2 );
1695 :
1696 0 : if (aOrigSize != aSize || aOrigPos != aPos)
1697 : {
1698 0 : (*pCurrent)->SetPosSizePixel(aPos, aSize);
1699 0 : bChanged = true;
1700 : }
1701 :
1702 0 : if ( *pCurrent == m_aValueEdit.get() )
1703 : {
1704 0 : Point aDurationPos( aPos );
1705 0 : m_aDurationField->SetPosPixel( aDurationPos );
1706 0 : Size aDurationSize(aSize);
1707 0 : aDurationSize.Width() -= (m_aEditButton->GetSizePixel().Width() + 3 );
1708 0 : m_aDurationField->SetSizePixel(aDurationSize);
1709 0 : aDurationPos.X() = aPos.X() - m_aEditButton->GetSizePixel().Width() + aSize.Width();
1710 0 : m_aEditButton->SetPosPixel(aDurationPos);
1711 :
1712 0 : m_aYesNoButton->SetPosSizePixel( aPos, aSize );
1713 :
1714 0 : aSize.Width() /= 2;
1715 0 : aSize.Width() -= 2;
1716 0 : m_aDateField->SetPosSizePixel( aPos, aSize );
1717 0 : aPos.X() += aSize.Width() + 4;
1718 0 : m_aTimeField->SetPosSizePixel( aPos, aSize );
1719 : }
1720 :
1721 0 : pCurrent++;
1722 : }
1723 0 : return bChanged;
1724 : }
1725 :
1726 0 : sal_uInt16 CustomPropertiesWindow::GetVisibleLineCount() const
1727 : {
1728 0 : sal_uInt16 nCount = 0;
1729 0 : std::vector< CustomPropertyLine* >::const_iterator pIter;
1730 0 : for ( pIter = m_aCustomPropertiesLines.begin();
1731 0 : pIter != m_aCustomPropertiesLines.end(); ++pIter )
1732 : {
1733 0 : CustomPropertyLine* pLine = *pIter;
1734 0 : if ( !pLine->m_bIsRemoved )
1735 0 : nCount++;
1736 : }
1737 0 : return nCount;
1738 : }
1739 :
1740 0 : void CustomPropertiesWindow::updateLineWidth()
1741 : {
1742 0 : vcl::Window* pWindows[] = { m_aNameBox.get(), m_aTypeBox.get(), m_aValueEdit.get(),
1743 0 : m_aDateField.get(), m_aTimeField.get(),
1744 0 : m_aDurationField.get(), m_aEditButton.get(),
1745 0 : m_aYesNoButton.get(), m_aRemoveButton.get(), NULL };
1746 :
1747 0 : for (std::vector< CustomPropertyLine* >::iterator aI =
1748 0 : m_aCustomPropertiesLines.begin(), aEnd = m_aCustomPropertiesLines.end();
1749 : aI != aEnd; ++aI)
1750 : {
1751 0 : CustomPropertyLine* pNewLine = *aI;
1752 :
1753 : vcl::Window* pNewWindows[] =
1754 0 : { pNewLine->m_aNameBox.get(), pNewLine->m_aTypeBox.get(), pNewLine->m_aValueEdit.get(),
1755 0 : pNewLine->m_aDateField.get(), pNewLine->m_aTimeField.get(),
1756 0 : pNewLine->m_aDurationField.get(), pNewLine->m_aEditButton.get(),
1757 0 : pNewLine->m_aYesNoButton.get(), pNewLine->m_aRemoveButton.get(), NULL };
1758 :
1759 0 : vcl::Window** pCurrent = pWindows;
1760 0 : vcl::Window** pNewCurrent = pNewWindows;
1761 0 : while ( *pCurrent )
1762 : {
1763 0 : Size aSize = (*pCurrent)->GetSizePixel();
1764 0 : Point aPos = (*pCurrent)->GetPosPixel();
1765 0 : aPos.Y() = (*pNewCurrent)->GetPosPixel().Y();
1766 0 : (*pNewCurrent)->SetPosSizePixel( aPos, aSize );
1767 0 : pCurrent++;
1768 0 : pNewCurrent++;
1769 : }
1770 :
1771 : // if we have type "Date", we use the full width, not only the half
1772 0 : if (pNewLine->m_bIsDate)
1773 0 : pNewLine->m_aDateField->SetSizePixel( pNewLine->m_aValueEdit->GetSizePixel() );
1774 : }
1775 0 : }
1776 :
1777 0 : void CustomPropertiesWindow::AddLine( const OUString& sName, Any& rAny )
1778 : {
1779 0 : CustomPropertyLine* pNewLine = new CustomPropertyLine( this );
1780 0 : pNewLine->m_aTypeBox->SetSelectHdl( LINK( this, CustomPropertiesWindow, TypeHdl ) );
1781 0 : pNewLine->m_aRemoveButton->SetClickHdl( LINK( this, CustomPropertiesWindow, RemoveHdl ) );
1782 0 : pNewLine->m_aValueEdit->SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, EditLoseFocusHdl ) );
1783 : //add lose focus handlers of date/time fields
1784 :
1785 0 : pNewLine->m_aTypeBox->SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, BoxLoseFocusHdl ) );
1786 :
1787 0 : pNewLine->m_aNameBox->add_mnemonic_label(m_pHeaderAccName);
1788 0 : pNewLine->m_aNameBox->SetAccessibleName(m_pHeaderAccName->GetText());
1789 0 : pNewLine->m_aTypeBox->add_mnemonic_label(m_pHeaderAccType);
1790 0 : pNewLine->m_aTypeBox->SetAccessibleName(m_pHeaderAccType->GetText());
1791 0 : pNewLine->m_aValueEdit->add_mnemonic_label(m_pHeaderAccValue);
1792 0 : pNewLine->m_aValueEdit->SetAccessibleName(m_pHeaderAccValue->GetText());
1793 :
1794 0 : sal_Int32 nPos = GetVisibleLineCount() * GetLineHeight();
1795 0 : m_aCustomPropertiesLines.push_back( pNewLine );
1796 0 : vcl::Window* pWindows[] = { m_aNameBox.get(), m_aTypeBox.get(), m_aValueEdit.get(),
1797 0 : m_aDateField.get(), m_aTimeField.get(),
1798 0 : m_aDurationField.get(), m_aEditButton.get(),
1799 0 : m_aYesNoButton.get(), m_aRemoveButton.get(), NULL };
1800 : vcl::Window* pNewWindows[] =
1801 0 : { pNewLine->m_aNameBox.get(), pNewLine->m_aTypeBox.get(), pNewLine->m_aValueEdit.get(),
1802 0 : pNewLine->m_aDateField.get(), pNewLine->m_aTimeField.get(),
1803 0 : pNewLine->m_aDurationField.get(), pNewLine->m_aEditButton.get(),
1804 0 : pNewLine->m_aYesNoButton.get(), pNewLine->m_aRemoveButton.get(), NULL };
1805 0 : vcl::Window** pCurrent = pWindows;
1806 0 : vcl::Window** pNewCurrent = pNewWindows;
1807 0 : while ( *pCurrent )
1808 : {
1809 0 : Size aSize = (*pCurrent)->GetSizePixel();
1810 0 : Point aPos = (*pCurrent)->GetPosPixel();
1811 0 : aPos.Y() += nPos;
1812 0 : aPos.Y() += m_nScrollPos;
1813 0 : (*pNewCurrent)->SetPosSizePixel( aPos, aSize );
1814 0 : (*pNewCurrent)->Show();
1815 0 : pCurrent++;
1816 0 : pNewCurrent++;
1817 : }
1818 :
1819 0 : double nTmpValue = 0;
1820 0 : bool bTmpValue = false;
1821 0 : OUString sTmpValue;
1822 0 : util::DateTime aTmpDateTime;
1823 0 : util::Date aTmpDate;
1824 0 : util::DateTimeWithTimezone aTmpDateTimeTZ;
1825 0 : util::DateWithTimezone aTmpDateTZ;
1826 0 : util::Duration aTmpDuration;
1827 0 : SvtSysLocale aSysLocale;
1828 0 : const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData();
1829 0 : pNewLine->m_aNameBox->SetText( sName );
1830 0 : sal_IntPtr nType = CUSTOM_TYPE_UNKNOWN;
1831 0 : OUString sValue;
1832 :
1833 0 : if ( rAny >>= nTmpValue )
1834 : {
1835 0 : sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM );
1836 0 : m_aNumberFormatter.GetInputLineString( nTmpValue, nIndex, sValue );
1837 0 : pNewLine->m_aValueEdit->SetText( sValue );
1838 0 : nType = CUSTOM_TYPE_NUMBER;
1839 : }
1840 0 : else if ( rAny >>= bTmpValue )
1841 : {
1842 0 : sValue = ( bTmpValue ? rLocaleWrapper.getTrueWord() : rLocaleWrapper.getFalseWord() );
1843 0 : nType = CUSTOM_TYPE_BOOLEAN;
1844 : }
1845 0 : else if ( rAny >>= sTmpValue )
1846 : {
1847 0 : pNewLine->m_aValueEdit->SetText( sTmpValue );
1848 0 : nType = CUSTOM_TYPE_TEXT;
1849 : }
1850 0 : else if ( rAny >>= aTmpDate )
1851 : {
1852 0 : pNewLine->m_aDateField->SetDate( Date( aTmpDate ) );
1853 0 : nType = CUSTOM_TYPE_DATE;
1854 : }
1855 0 : else if ( rAny >>= aTmpDateTime )
1856 : {
1857 0 : pNewLine->m_aDateField->SetDate( Date( aTmpDateTime ) );
1858 0 : pNewLine->m_aTimeField->SetTime( tools::Time( aTmpDateTime ) );
1859 0 : pNewLine->m_aTimeField->m_isUTC = aTmpDateTime.IsUTC;
1860 0 : nType = CUSTOM_TYPE_DATETIME;
1861 : }
1862 0 : else if ( rAny >>= aTmpDateTZ )
1863 : {
1864 0 : pNewLine->m_aDateField->SetDate( Date( aTmpDateTZ.DateInTZ.Day,
1865 0 : aTmpDateTZ.DateInTZ.Month, aTmpDateTZ.DateInTZ.Year ) );
1866 0 : pNewLine->m_aDateField->m_TZ = aTmpDateTZ.Timezone;
1867 0 : nType = CUSTOM_TYPE_DATE;
1868 : }
1869 0 : else if ( rAny >>= aTmpDateTimeTZ )
1870 : {
1871 0 : util::DateTime const& rDT(aTmpDateTimeTZ.DateTimeInTZ);
1872 0 : pNewLine->m_aDateField->SetDate( Date( rDT ) );
1873 0 : pNewLine->m_aTimeField->SetTime( tools::Time( rDT ) );
1874 0 : pNewLine->m_aTimeField->m_isUTC = rDT.IsUTC;
1875 0 : pNewLine->m_aDateField->m_TZ = aTmpDateTimeTZ.Timezone;
1876 0 : nType = CUSTOM_TYPE_DATETIME;
1877 : }
1878 0 : else if ( rAny >>= aTmpDuration )
1879 : {
1880 0 : nType = CUSTOM_TYPE_DURATION;
1881 0 : pNewLine->m_aDurationField->SetDuration( aTmpDuration );
1882 : }
1883 :
1884 0 : if ( nType != CUSTOM_TYPE_UNKNOWN )
1885 : {
1886 0 : if ( CUSTOM_TYPE_BOOLEAN == nType )
1887 : {
1888 0 : if ( bTmpValue )
1889 0 : pNewLine->m_aYesNoButton->CheckYes();
1890 : else
1891 0 : pNewLine->m_aYesNoButton->CheckNo();
1892 : }
1893 0 : pNewLine->m_aTypeBox->SelectEntryPos( m_aTypeBox->GetEntryPos( reinterpret_cast<void*>(nType) ) );
1894 : }
1895 :
1896 0 : TypeHdl( nullptr, pNewLine->m_aTypeBox.get() );
1897 0 : pNewLine->m_aNameBox->GrabFocus();
1898 0 : }
1899 :
1900 0 : bool CustomPropertiesWindow::AreAllLinesValid() const
1901 : {
1902 0 : bool bRet = true;
1903 0 : std::vector< CustomPropertyLine* >::const_iterator pIter;
1904 0 : for ( pIter = m_aCustomPropertiesLines.begin();
1905 0 : pIter != m_aCustomPropertiesLines.end(); ++pIter )
1906 : {
1907 0 : CustomPropertyLine* pLine = *pIter;
1908 0 : if ( !IsLineValid( pLine ) )
1909 : {
1910 0 : bRet = false;
1911 0 : break;
1912 : }
1913 : }
1914 :
1915 0 : return bRet;
1916 : }
1917 :
1918 0 : void CustomPropertiesWindow::ClearAllLines()
1919 : {
1920 0 : std::vector< CustomPropertyLine* >::iterator pIter;
1921 0 : for ( pIter = m_aCustomPropertiesLines.begin();
1922 0 : pIter != m_aCustomPropertiesLines.end(); ++pIter )
1923 : {
1924 0 : CustomPropertyLine* pLine = *pIter;
1925 0 : pLine->SetRemoved();
1926 0 : delete pLine;
1927 : }
1928 0 : m_aCustomPropertiesLines.clear();
1929 0 : m_nScrollPos = 0;
1930 0 : }
1931 :
1932 0 : void CustomPropertiesWindow::DoScroll( sal_Int32 nNewPos )
1933 : {
1934 0 : m_nScrollPos += nNewPos;
1935 0 : std::vector< CustomPropertyLine* >::iterator pIter;
1936 0 : for ( pIter = m_aCustomPropertiesLines.begin();
1937 0 : pIter != m_aCustomPropertiesLines.end(); ++pIter )
1938 : {
1939 0 : CustomPropertyLine* pLine = *pIter;
1940 0 : if ( pLine->m_bIsRemoved )
1941 0 : continue;
1942 :
1943 0 : vcl::Window* pWindows[] = { pLine->m_aNameBox.get(), pLine->m_aTypeBox.get(), pLine->m_aValueEdit.get(), pLine->m_aDateField.get(), pLine->m_aTimeField.get(),
1944 0 : pLine->m_aDurationField.get(), pLine->m_aEditButton.get(), pLine->m_aYesNoButton.get(), pLine->m_aRemoveButton.get(), NULL };
1945 0 : vcl::Window** pCurrent = pWindows;
1946 0 : while ( *pCurrent )
1947 : {
1948 0 : Point aPos = (*pCurrent)->GetPosPixel();
1949 0 : aPos.Y() += nNewPos;
1950 0 : (*pCurrent)->SetPosPixel( aPos );
1951 0 : pCurrent++;
1952 : }
1953 : }
1954 0 : }
1955 :
1956 0 : Sequence< beans::PropertyValue > CustomPropertiesWindow::GetCustomProperties() const
1957 : {
1958 0 : Sequence< beans::PropertyValue > aPropertiesSeq( m_aCustomPropertiesLines.size() );
1959 0 : sal_Int32 i = 0;
1960 0 : std::vector< CustomPropertyLine* >::const_iterator pIter;
1961 0 : for ( pIter = m_aCustomPropertiesLines.begin();
1962 0 : pIter != m_aCustomPropertiesLines.end(); ++pIter, ++i )
1963 : {
1964 0 : CustomPropertyLine* pLine = *pIter;
1965 0 : if ( pLine->m_bIsRemoved )
1966 0 : continue;
1967 :
1968 0 : OUString sPropertyName = pLine->m_aNameBox->GetText();
1969 0 : if ( !sPropertyName.isEmpty() )
1970 : {
1971 0 : aPropertiesSeq[i].Name = sPropertyName;
1972 : long nType = reinterpret_cast<long>(
1973 0 : pLine->m_aTypeBox->GetSelectEntryData() );
1974 0 : if ( CUSTOM_TYPE_NUMBER == nType )
1975 : {
1976 0 : double nValue = 0;
1977 : sal_uInt32 nIndex = const_cast< SvNumberFormatter& >(
1978 0 : m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
1979 : bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ).
1980 0 : IsNumberFormat( pLine->m_aValueEdit->GetText(), nIndex, nValue );
1981 0 : if ( bIsNum )
1982 0 : aPropertiesSeq[i].Value <<= makeAny( nValue );
1983 : }
1984 0 : else if ( CUSTOM_TYPE_BOOLEAN == nType )
1985 : {
1986 0 : bool bValue = pLine->m_aYesNoButton->IsYesChecked();
1987 0 : aPropertiesSeq[i].Value <<= makeAny( bValue );
1988 : }
1989 0 : else if ( CUSTOM_TYPE_DATETIME == nType )
1990 : {
1991 0 : Date aTmpDate = pLine->m_aDateField->GetDate();
1992 0 : tools::Time aTmpTime = pLine->m_aTimeField->GetTime();
1993 0 : util::DateTime const aDateTime(aTmpTime.GetNanoSec(),
1994 0 : aTmpTime.GetSec(), aTmpTime.GetMin(), aTmpTime.GetHour(),
1995 0 : aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear(),
1996 0 : pLine->m_aTimeField->m_isUTC);
1997 0 : if (pLine->m_aDateField->m_TZ.is_initialized())
1998 : {
1999 0 : aPropertiesSeq[i].Value <<= util::DateTimeWithTimezone(
2000 0 : aDateTime, pLine->m_aDateField->m_TZ.get());
2001 : }
2002 : else
2003 : {
2004 0 : aPropertiesSeq[i].Value <<= aDateTime;
2005 : }
2006 : }
2007 0 : else if ( CUSTOM_TYPE_DATE == nType )
2008 : {
2009 0 : Date aTmpDate = pLine->m_aDateField->GetDate();
2010 0 : util::Date const aDate(aTmpDate.GetDay(), aTmpDate.GetMonth(),
2011 0 : aTmpDate.GetYear());
2012 0 : if (pLine->m_aDateField->m_TZ.is_initialized())
2013 : {
2014 0 : aPropertiesSeq[i].Value <<= util::DateWithTimezone(
2015 0 : aDate, pLine->m_aDateField->m_TZ.get());
2016 : }
2017 : else
2018 : {
2019 0 : aPropertiesSeq[i].Value <<= aDate;
2020 : }
2021 : }
2022 0 : else if ( CUSTOM_TYPE_DURATION == nType )
2023 : {
2024 0 : aPropertiesSeq[i].Value <<= pLine->m_aDurationField->GetDuration();
2025 : }
2026 : else
2027 : {
2028 0 : OUString sValue( pLine->m_aValueEdit->GetText() );
2029 0 : aPropertiesSeq[i].Value <<= makeAny( sValue );
2030 : }
2031 : }
2032 0 : }
2033 :
2034 0 : return aPropertiesSeq;
2035 : }
2036 :
2037 0 : CustomPropertiesControl::CustomPropertiesControl(vcl::Window* pParent)
2038 : : Window(pParent, WB_HIDE | WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL | WB_BORDER)
2039 : , m_pVBox(NULL)
2040 : , m_pHeaderBar(NULL)
2041 : , m_pBody(NULL)
2042 : , m_pPropertiesWin(NULL)
2043 : , m_pVertScroll(NULL)
2044 0 : , m_nThumbPos(0)
2045 : {
2046 0 : }
2047 :
2048 0 : void CustomPropertiesControl::Init(VclBuilderContainer& rBuilder)
2049 : {
2050 0 : m_pVBox = VclPtr<VclVBox>::Create(this);
2051 0 : m_pHeaderBar = VclPtr<HeaderBar>::Create(m_pVBox, WB_BUTTONSTYLE | WB_BOTTOMBORDER);
2052 0 : m_pBody = VclPtr<VclHBox>::Create(m_pVBox);
2053 0 : FixedText* pName = rBuilder.get<FixedText>("name");
2054 0 : FixedText* pType = rBuilder.get<FixedText>("type");
2055 0 : FixedText* pValue = rBuilder.get<FixedText>("value");
2056 0 : OUString sName = pName->GetText();
2057 0 : OUString sType = pType->GetText();
2058 0 : OUString sValue = pValue->GetText();
2059 0 : m_pPropertiesWin = VclPtr<CustomPropertiesWindow>::Create(m_pBody, pName, pType, pValue);
2060 0 : m_pVertScroll = VclPtr<ScrollBar>::Create(m_pBody, WB_VERT);
2061 :
2062 0 : set_hexpand(true);
2063 0 : set_vexpand(true);
2064 0 : set_expand(true);
2065 0 : set_fill(true);
2066 :
2067 0 : m_pVBox->set_hexpand(true);
2068 0 : m_pVBox->set_vexpand(true);
2069 0 : m_pVBox->set_expand(true);
2070 0 : m_pVBox->set_fill(true);
2071 0 : m_pVBox->Show();
2072 :
2073 0 : m_pBody->set_hexpand(true);
2074 0 : m_pBody->set_vexpand(true);
2075 0 : m_pBody->set_expand(true);
2076 0 : m_pBody->set_fill(true);
2077 0 : m_pBody->Show();
2078 :
2079 0 : m_pPropertiesWin->set_hexpand(true);
2080 0 : m_pPropertiesWin->set_vexpand(true);
2081 0 : m_pPropertiesWin->set_expand(true);
2082 0 : m_pPropertiesWin->set_fill(true);
2083 0 : m_pPropertiesWin->Show();
2084 :
2085 0 : m_pPropertiesWin->SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
2086 0 : m_pVertScroll->EnableDrag();
2087 0 : m_pVertScroll->Show();
2088 :
2089 0 : m_pHeaderBar->set_height_request(GetTextHeight() + 6);
2090 :
2091 0 : const HeaderBarItemBits nHeadBits = HeaderBarItemBits::VCENTER | HeaderBarItemBits::FIXED | HeaderBarItemBits::FIXEDPOS | HeaderBarItemBits::LEFT;
2092 :
2093 0 : m_pHeaderBar->InsertItem( HI_NAME, sName, 0, nHeadBits );
2094 0 : m_pHeaderBar->InsertItem( HI_TYPE, sType, 0, nHeadBits );
2095 0 : m_pHeaderBar->InsertItem( HI_VALUE, sValue, 0, nHeadBits );
2096 0 : m_pHeaderBar->InsertItem( HI_ACTION, OUString(), 0, nHeadBits );
2097 0 : m_pHeaderBar->Show();
2098 :
2099 0 : m_pPropertiesWin->SetRemovedHdl( LINK( this, CustomPropertiesControl, RemovedHdl ) );
2100 :
2101 0 : m_pVertScroll->SetRangeMin( 0 );
2102 0 : m_pVertScroll->SetRangeMax( 0 );
2103 0 : m_pVertScroll->SetVisibleSize( 0xFFFF );
2104 :
2105 0 : Link<> aScrollLink = LINK( this, CustomPropertiesControl, ScrollHdl );
2106 0 : m_pVertScroll->SetScrollHdl( aScrollLink );
2107 0 : }
2108 :
2109 0 : void CustomPropertiesControl::Resize()
2110 : {
2111 0 : Window::Resize();
2112 :
2113 0 : if (!m_pVBox)
2114 0 : return;
2115 :
2116 0 : m_pVBox->SetSizePixel(GetSizePixel());
2117 :
2118 0 : bool bWidgetsResized = m_pPropertiesWin->InitControls( m_pHeaderBar, m_pVertScroll );
2119 0 : sal_Int32 nScrollOffset = m_pPropertiesWin->GetLineHeight();
2120 0 : sal_Int32 nVisibleEntries = m_pPropertiesWin->GetSizePixel().Height() / nScrollOffset;
2121 0 : m_pVertScroll->SetPageSize( nVisibleEntries - 1 );
2122 0 : m_pVertScroll->SetVisibleSize( nVisibleEntries );
2123 0 : if (bWidgetsResized)
2124 : {
2125 0 : m_pPropertiesWin->updateLineWidth();
2126 : }
2127 : }
2128 :
2129 0 : VCL_BUILDER_FACTORY(CustomPropertiesControl)
2130 :
2131 0 : CustomPropertiesControl::~CustomPropertiesControl()
2132 : {
2133 0 : disposeOnce();
2134 0 : }
2135 :
2136 0 : void CustomPropertiesControl::dispose()
2137 : {
2138 0 : m_pVertScroll.disposeAndClear();
2139 0 : m_pPropertiesWin.disposeAndClear();
2140 0 : m_pBody.disposeAndClear();
2141 0 : m_pHeaderBar.disposeAndClear();
2142 0 : m_pVBox.disposeAndClear();
2143 0 : vcl::Window::dispose();
2144 0 : }
2145 :
2146 0 : IMPL_LINK( CustomPropertiesControl, ScrollHdl, ScrollBar*, pScrollBar )
2147 : {
2148 0 : sal_Int32 nOffset = m_pPropertiesWin->GetLineHeight();
2149 0 : nOffset *= ( m_nThumbPos - pScrollBar->GetThumbPos() );
2150 0 : m_nThumbPos = pScrollBar->GetThumbPos();
2151 0 : m_pPropertiesWin->DoScroll( nOffset );
2152 0 : return 0;
2153 : }
2154 :
2155 0 : IMPL_LINK_NOARG(CustomPropertiesControl, RemovedHdl)
2156 : {
2157 0 : long nLineCount = m_pPropertiesWin->GetVisibleLineCount();
2158 0 : m_pVertScroll->SetRangeMax(nLineCount + 1);
2159 0 : if ( m_pPropertiesWin->GetOutputSizePixel().Height() < nLineCount * m_pPropertiesWin->GetLineHeight() )
2160 0 : m_pVertScroll->DoScrollAction ( SCROLL_LINEUP );
2161 0 : return 0;
2162 : }
2163 :
2164 0 : void CustomPropertiesControl::AddLine( const OUString& sName, Any& rAny, bool bInteractive )
2165 : {
2166 0 : m_pPropertiesWin->AddLine( sName, rAny );
2167 0 : long nLineCount = m_pPropertiesWin->GetVisibleLineCount();
2168 0 : m_pVertScroll->SetRangeMax(nLineCount + 1);
2169 0 : if ( bInteractive && m_pPropertiesWin->GetOutputSizePixel().Height() < nLineCount * m_pPropertiesWin->GetLineHeight() )
2170 0 : m_pVertScroll->DoScroll(nLineCount + 1);
2171 0 : }
2172 :
2173 : // class SfxCustomPropertiesPage -----------------------------------------
2174 0 : SfxCustomPropertiesPage::SfxCustomPropertiesPage( vcl::Window* pParent, const SfxItemSet& rItemSet )
2175 0 : : SfxTabPage(pParent, "CustomInfoPage", "sfx/ui/custominfopage.ui", &rItemSet)
2176 : {
2177 0 : get(m_pPropertiesCtrl, "properties");
2178 0 : m_pPropertiesCtrl->Init(*this);
2179 0 : get<PushButton>("add")->SetClickHdl(LINK(this, SfxCustomPropertiesPage, AddHdl));
2180 0 : }
2181 :
2182 0 : SfxCustomPropertiesPage::~SfxCustomPropertiesPage()
2183 : {
2184 0 : disposeOnce();
2185 0 : }
2186 :
2187 0 : void SfxCustomPropertiesPage::dispose()
2188 : {
2189 0 : m_pPropertiesCtrl.clear();
2190 0 : SfxTabPage::dispose();
2191 0 : }
2192 :
2193 0 : IMPL_LINK_NOARG(SfxCustomPropertiesPage, AddHdl)
2194 : {
2195 0 : Any aAny;
2196 0 : m_pPropertiesCtrl->AddLine( OUString(), aAny, true );
2197 0 : return 0;
2198 : }
2199 :
2200 0 : bool SfxCustomPropertiesPage::FillItemSet( SfxItemSet* rSet )
2201 : {
2202 0 : bool bModified = false;
2203 0 : const SfxPoolItem* pItem = NULL;
2204 0 : SfxDocumentInfoItem* pInfo = NULL;
2205 0 : bool bMustDelete = false;
2206 :
2207 0 : if ( GetTabDialog() && GetTabDialog()->GetExampleSet() )
2208 : {
2209 0 : if ( SfxItemState::SET !=
2210 0 : GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO, true, &pItem ) )
2211 0 : pInfo = const_cast<SfxDocumentInfoItem*>(&static_cast<const SfxDocumentInfoItem& >(rSet->Get( SID_DOCINFO )));
2212 : else
2213 : {
2214 0 : bMustDelete = true;
2215 0 : pInfo = new SfxDocumentInfoItem( *static_cast<const SfxDocumentInfoItem*>(pItem) );
2216 : }
2217 : }
2218 :
2219 0 : if ( pInfo )
2220 : {
2221 : // If it's a CMIS document, we can't save custom properties
2222 0 : if ( pInfo->isCmisDocument( ) )
2223 : {
2224 0 : if ( bMustDelete )
2225 0 : delete pInfo;
2226 0 : return false;
2227 : }
2228 :
2229 0 : pInfo->ClearCustomProperties();
2230 0 : Sequence< beans::PropertyValue > aPropertySeq = m_pPropertiesCtrl->GetCustomProperties();
2231 0 : sal_Int32 i = 0, nCount = aPropertySeq.getLength();
2232 0 : for ( ; i < nCount; ++i )
2233 : {
2234 0 : if ( !aPropertySeq[i].Name.isEmpty() )
2235 0 : pInfo->AddCustomProperty( aPropertySeq[i].Name, aPropertySeq[i].Value );
2236 0 : }
2237 : }
2238 :
2239 0 : bModified = true; //!!!
2240 :
2241 0 : if (pInfo)
2242 : {
2243 0 : if ( bModified )
2244 0 : rSet->Put( *pInfo );
2245 0 : if ( bMustDelete )
2246 0 : delete pInfo;
2247 : }
2248 0 : return bModified;
2249 : }
2250 :
2251 0 : void SfxCustomPropertiesPage::Reset( const SfxItemSet* rItemSet )
2252 : {
2253 0 : m_pPropertiesCtrl->ClearAllLines();
2254 0 : const SfxDocumentInfoItem& rInfoItem = static_cast<const SfxDocumentInfoItem &>(rItemSet->Get(SID_DOCINFO));
2255 0 : std::vector< CustomProperty* > aCustomProps = rInfoItem.GetCustomProperties();
2256 0 : for ( size_t i = 0; i < aCustomProps.size(); i++ )
2257 : {
2258 0 : m_pPropertiesCtrl->AddLine( aCustomProps[i]->m_sName, aCustomProps[i]->m_aValue, false );
2259 0 : }
2260 0 : }
2261 :
2262 0 : SfxTabPage::sfxpg SfxCustomPropertiesPage::DeactivatePage( SfxItemSet* /*pSet*/ )
2263 : {
2264 0 : sfxpg nRet = LEAVE_PAGE;
2265 0 : if ( !m_pPropertiesCtrl->AreAllLinesValid() )
2266 0 : nRet = KEEP_PAGE;
2267 0 : return nRet;
2268 : }
2269 :
2270 0 : VclPtr<SfxTabPage> SfxCustomPropertiesPage::Create( vcl::Window* pParent, const SfxItemSet* rItemSet )
2271 : {
2272 0 : return VclPtr<SfxCustomPropertiesPage>::Create( pParent, *rItemSet );
2273 : }
2274 :
2275 0 : CmisValue::CmisValue( vcl::Window* pParent, const OUString& aStr )
2276 : {
2277 0 : m_pUIBuilder = new VclBuilder( pParent, getUIRootDir(), "sfx/ui/cmisline.ui");
2278 0 : get( m_aValueEdit, "value");
2279 0 : m_aValueEdit->Show( true );
2280 0 : m_aValueEdit->SetText( aStr );
2281 0 : }
2282 :
2283 0 : CmisDateTime::CmisDateTime( vcl::Window* pParent, const util::DateTime& aDateTime )
2284 : {
2285 0 : m_pUIBuilder = new VclBuilder( pParent, getUIRootDir(), "sfx/ui/cmisline.ui");
2286 0 : get( m_aDateField, "date");
2287 0 : get( m_aTimeField, "time");
2288 0 : m_aDateField->Show( true );
2289 0 : m_aTimeField->Show( true );
2290 0 : m_aDateField->SetDate( Date( aDateTime ) );
2291 0 : m_aTimeField->SetTime( tools::Time( aDateTime ) );
2292 0 : }
2293 :
2294 0 : CmisYesNo::CmisYesNo( vcl::Window* pParent, bool bValue )
2295 : {
2296 0 : m_pUIBuilder = new VclBuilder( pParent, getUIRootDir(), "sfx/ui/cmisline.ui");
2297 0 : get( m_aYesButton, "yes");
2298 0 : get( m_aNoButton, "no");
2299 0 : m_aYesButton->Show( true );
2300 0 : m_aNoButton->Show( true );
2301 0 : if ( bValue )
2302 0 : m_aYesButton->Check( );
2303 : else
2304 0 : m_aNoButton->Check( );
2305 0 : }
2306 :
2307 : // struct CmisPropertyLine ---------------------------------------------
2308 0 : 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)
2314 0 : , m_nNumValue(1)
2315 : {
2316 0 : m_pUIBuilder = new VclBuilder( pParent, getUIRootDir(), "sfx/ui/cmisline.ui");
2317 0 : get( m_pFrame, "CmisFrame" );
2318 0 : get( m_aName, "name" );
2319 0 : get( m_aType, "type" );
2320 0 : m_pFrame->Enable();
2321 0 : }
2322 :
2323 0 : CmisPropertyLine::~CmisPropertyLine( )
2324 : {
2325 0 : std::vector< CmisValue* >::iterator pIter;
2326 0 : for ( pIter = m_aValues.begin();
2327 0 : pIter != m_aValues.end(); ++pIter )
2328 : {
2329 0 : CmisValue* pValue = *pIter;
2330 0 : delete pValue;
2331 : }
2332 0 : m_aValues.clear();
2333 :
2334 0 : std::vector< CmisYesNo* >::iterator pIterYesNo;
2335 0 : for ( pIterYesNo = m_aYesNos.begin();
2336 0 : pIterYesNo != m_aYesNos.end(); ++pIterYesNo )
2337 : {
2338 0 : CmisYesNo* pYesNo = *pIterYesNo;
2339 0 : delete pYesNo;
2340 : }
2341 0 : m_aYesNos.clear();
2342 :
2343 0 : std::vector< CmisDateTime* >::iterator pIterDateTime;
2344 0 : for ( pIterDateTime = m_aDateTimes.begin();
2345 0 : pIterDateTime != m_aDateTimes.end(); ++pIterDateTime )
2346 : {
2347 0 : CmisDateTime* pDateTime = *pIterDateTime;
2348 0 : delete pDateTime;
2349 : }
2350 0 : m_aDateTimes.clear();
2351 :
2352 0 : }
2353 :
2354 0 : long CmisPropertyLine::getItemHeight() const
2355 : {
2356 0 : return VclContainer::getLayoutRequisition(*m_pFrame).Height();
2357 : }
2358 :
2359 : // class CmisPropertiesWindow -----------------------------------------
2360 :
2361 0 : CmisPropertiesWindow::CmisPropertiesWindow(SfxTabPage* pParent):
2362 : m_aNumberFormatter( ::comphelper::getProcessComponentContext(),
2363 0 : Application::GetSettings().GetLanguageTag().getLanguageType() )
2364 :
2365 : {
2366 0 : pParent->get(m_pBox, "CmisWindow");
2367 0 : CmisPropertyLine aTemp( m_pBox );
2368 0 : m_nItemHeight = aTemp.getItemHeight();
2369 0 : }
2370 :
2371 0 : CmisPropertiesWindow::~CmisPropertiesWindow()
2372 : {
2373 0 : ClearAllLines();
2374 0 : }
2375 :
2376 0 : void CmisPropertiesWindow::ClearAllLines()
2377 : {
2378 0 : std::vector< CmisPropertyLine* >::iterator pIter;
2379 0 : for ( pIter = m_aCmisPropertiesLines.begin();
2380 0 : pIter != m_aCmisPropertiesLines.end(); ++pIter )
2381 : {
2382 0 : CmisPropertyLine* pLine = *pIter;
2383 0 : delete pLine;
2384 : }
2385 0 : m_aCmisPropertiesLines.clear();
2386 0 : }
2387 :
2388 0 : sal_uInt16 CmisPropertiesWindow::GetLineCount() const
2389 : {
2390 0 : sal_uInt16 nCount = 0;
2391 0 : std::vector< CmisPropertyLine* >::const_iterator pIter;
2392 0 : for ( pIter = m_aCmisPropertiesLines.begin();
2393 0 : pIter != m_aCmisPropertiesLines.end(); ++pIter )
2394 0 : nCount += ( (*pIter)->m_nNumValue + 1 );
2395 0 : return nCount;
2396 : }
2397 :
2398 0 : 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 )
2402 : {
2403 0 : CmisPropertyLine* pNewLine = new CmisPropertyLine( m_pBox );
2404 :
2405 0 : pNewLine->m_sId = sId;
2406 0 : pNewLine->m_sType = sType;
2407 0 : pNewLine->m_bUpdatable = bUpdatable;
2408 0 : pNewLine->m_bRequired = bRequired;
2409 0 : pNewLine->m_bMultiValued = bMultiValued;
2410 0 : pNewLine->m_bOpenChoice = bOpenChoice;
2411 :
2412 0 : if ( sType == CMIS_TYPE_INTEGER )
2413 : {
2414 0 : Sequence< sal_Int64 > seqValue;
2415 0 : rAny >>= seqValue;
2416 0 : sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM );
2417 0 : sal_Int32 m_nNumValue = seqValue.getLength( );
2418 0 : for ( sal_Int32 i = 0; i < m_nNumValue; ++i )
2419 : {
2420 0 : OUString sValue;
2421 0 : m_aNumberFormatter.GetInputLineString( seqValue[i], nIndex, sValue );
2422 0 : CmisValue* pValue = new CmisValue( m_pBox, sValue );
2423 0 : pValue->m_aValueEdit->SetReadOnly( !bUpdatable );
2424 0 : pNewLine->m_aValues.push_back( pValue );
2425 0 : }
2426 : }
2427 0 : else if ( sType == CMIS_TYPE_DECIMAL )
2428 : {
2429 0 : Sequence< double > seqValue;
2430 0 : rAny >>= seqValue;
2431 0 : sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM );
2432 0 : sal_Int32 m_nNumValue = seqValue.getLength( );
2433 0 : for ( sal_Int32 i = 0; i < m_nNumValue; ++i )
2434 : {
2435 0 : OUString sValue;
2436 0 : m_aNumberFormatter.GetInputLineString( seqValue[i], nIndex, sValue );
2437 0 : CmisValue* pValue = new CmisValue( m_pBox, sValue );
2438 0 : pValue->m_aValueEdit->SetReadOnly( !bUpdatable );
2439 0 : pNewLine->m_aValues.push_back( pValue );
2440 0 : }
2441 :
2442 : }
2443 0 : else if ( sType == CMIS_TYPE_BOOL )
2444 : {
2445 0 : Sequence<sal_Bool> seqValue;
2446 0 : rAny >>= seqValue;
2447 0 : sal_Int32 m_nNumValue = seqValue.getLength( );
2448 0 : for ( sal_Int32 i = 0; i < m_nNumValue; ++i )
2449 : {
2450 0 : CmisYesNo* pYesNo = new CmisYesNo( m_pBox, seqValue[i] );
2451 0 : pYesNo->m_aYesButton->Enable( bUpdatable );
2452 0 : pYesNo->m_aNoButton->Enable( bUpdatable );
2453 0 : pNewLine->m_aYesNos.push_back( pYesNo );
2454 0 : }
2455 : }
2456 0 : else if ( sType == CMIS_TYPE_STRING )
2457 : {
2458 0 : Sequence< OUString > seqValue;
2459 0 : rAny >>= seqValue;
2460 0 : sal_Int32 m_nNumValue = seqValue.getLength( );
2461 0 : for ( sal_Int32 i = 0; i < m_nNumValue; ++i )
2462 : {
2463 0 : CmisValue* pValue = new CmisValue( m_pBox, seqValue[i] );
2464 0 : pValue->m_aValueEdit->SetReadOnly( !bUpdatable );
2465 0 : pNewLine->m_aValues.push_back( pValue );
2466 0 : }
2467 : }
2468 0 : else if ( sType == CMIS_TYPE_DATETIME )
2469 : {
2470 0 : Sequence< util::DateTime > seqValue;
2471 0 : rAny >>= seqValue;
2472 0 : sal_Int32 m_nNumValue = seqValue.getLength( );
2473 0 : for ( sal_Int32 i = 0; i < m_nNumValue; ++i )
2474 : {
2475 0 : CmisDateTime* pDateTime = new CmisDateTime( m_pBox, seqValue[i]);
2476 0 : pDateTime->m_aDateField->SetReadOnly( !bUpdatable );
2477 0 : pDateTime->m_aTimeField->SetReadOnly( !bUpdatable );
2478 0 : pNewLine->m_aDateTimes.push_back( pDateTime );
2479 0 : }
2480 :
2481 : }
2482 0 : pNewLine->m_aName->SetText( sName );
2483 0 : pNewLine->m_aName->Show( true );
2484 0 : pNewLine->m_aType->SetText( sType );
2485 0 : pNewLine->m_aType->Show( true );
2486 :
2487 0 : m_aCmisPropertiesLines.push_back( pNewLine );
2488 0 : }
2489 :
2490 0 : void CmisPropertiesWindow::DoScroll( sal_Int32 nNewPos )
2491 : {
2492 0 : m_pBox->SetPosPixel(Point(0, nNewPos));
2493 0 : }
2494 :
2495 0 : Sequence< document::CmisProperty > CmisPropertiesWindow::GetCmisProperties() const
2496 : {
2497 0 : Sequence< document::CmisProperty > aPropertiesSeq( m_aCmisPropertiesLines.size() );
2498 0 : sal_Int32 i = 0;
2499 0 : std::vector< CmisPropertyLine* >::const_iterator pIter;
2500 0 : for ( pIter = m_aCmisPropertiesLines.begin();
2501 0 : pIter != m_aCmisPropertiesLines.end(); ++pIter, ++i )
2502 : {
2503 0 : CmisPropertyLine* pLine = *pIter;
2504 :
2505 0 : aPropertiesSeq[i].Id = pLine->m_sId;
2506 0 : aPropertiesSeq[i].Type = pLine->m_sType;
2507 0 : aPropertiesSeq[i].Updatable = pLine->m_bUpdatable;
2508 0 : aPropertiesSeq[i].Required = pLine->m_bRequired;
2509 0 : aPropertiesSeq[i].OpenChoice = pLine->m_bOpenChoice;
2510 0 : aPropertiesSeq[i].MultiValued = pLine->m_bMultiValued;
2511 :
2512 0 : OUString sPropertyName = pLine->m_aName->GetText();
2513 0 : if ( !sPropertyName.isEmpty() )
2514 : {
2515 0 : aPropertiesSeq[i].Name = sPropertyName;
2516 0 : OUString sType = pLine->m_aType->GetText( );
2517 0 : if ( CMIS_TYPE_DECIMAL == sType )
2518 : {
2519 : sal_uInt32 nIndex = const_cast< SvNumberFormatter& >(
2520 0 : m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
2521 0 : Sequence< double > seqValue( pLine->m_aValues.size( ) );
2522 0 : sal_Int32 k = 0;
2523 0 : for ( std::vector< CmisValue*>::const_iterator it = pLine->m_aValues.begin();
2524 0 : it != pLine->m_aValues.end(); ++it, ++k)
2525 : {
2526 0 : double dValue = 0.0;
2527 0 : OUString sValue( (*it)->m_aValueEdit->GetText() );
2528 : bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ).
2529 0 : IsNumberFormat( sValue, nIndex, dValue );
2530 0 : if ( bIsNum )
2531 0 : seqValue[k] = dValue;
2532 0 : }
2533 0 : aPropertiesSeq[i].Value <<= makeAny( seqValue );
2534 : }
2535 0 : else if ( CMIS_TYPE_INTEGER == sType )
2536 : {
2537 : sal_uInt32 nIndex = const_cast< SvNumberFormatter& >(
2538 0 : m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
2539 0 : Sequence< sal_Int64 > seqValue( pLine->m_aValues.size( ) );
2540 0 : sal_Int32 k = 0;
2541 0 : for ( std::vector< CmisValue*>::const_iterator it = pLine->m_aValues.begin();
2542 0 : it != pLine->m_aValues.end(); ++it, ++k)
2543 : {
2544 0 : double dValue = 0;
2545 0 : OUString sValue( (*it)->m_aValueEdit->GetText() );
2546 : bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ).
2547 0 : IsNumberFormat( sValue, nIndex, dValue );
2548 0 : if ( bIsNum )
2549 0 : seqValue[k] = (sal_Int64) dValue;
2550 0 : }
2551 0 : aPropertiesSeq[i].Value <<= makeAny( seqValue );
2552 : }
2553 0 : else if ( CMIS_TYPE_BOOL == sType )
2554 : {
2555 0 : Sequence<sal_Bool> seqValue( pLine->m_aYesNos.size( ) );
2556 0 : sal_Int32 k = 0;
2557 0 : for ( std::vector< CmisYesNo*>::const_iterator it = pLine->m_aYesNos.begin();
2558 0 : it != pLine->m_aYesNos.end(); ++it, ++k)
2559 : {
2560 0 : bool bValue = (*it)->m_aYesButton->IsChecked();
2561 0 : seqValue[k] = bValue;
2562 : }
2563 0 : aPropertiesSeq[i].Value <<= makeAny( seqValue );
2564 :
2565 : }
2566 0 : else if ( CMIS_TYPE_DATETIME == sType )
2567 : {
2568 0 : Sequence< util::DateTime > seqValue( pLine->m_aDateTimes.size( ) );
2569 0 : sal_Int32 k = 0;
2570 0 : for ( std::vector< CmisDateTime*>::const_iterator it = pLine->m_aDateTimes.begin();
2571 0 : it != pLine->m_aDateTimes.end(); ++it, ++k)
2572 : {
2573 0 : Date aTmpDate = (*it)->m_aDateField->GetDate();
2574 0 : tools::Time aTmpTime = (*it)->m_aTimeField->GetTime();
2575 0 : util::DateTime aDateTime( aTmpTime.GetNanoSec(), aTmpTime.GetSec(),
2576 0 : aTmpTime.GetMin(), aTmpTime.GetHour(),
2577 0 : aTmpDate.GetDay(), aTmpDate.GetMonth(),
2578 0 : aTmpDate.GetYear(), sal_True );
2579 0 : seqValue[k] = aDateTime;
2580 : }
2581 0 : aPropertiesSeq[i].Value <<= makeAny( seqValue );
2582 : }
2583 : else
2584 : {
2585 0 : Sequence< OUString > seqValue( pLine->m_aValues.size( ) );
2586 0 : sal_Int32 k = 0;
2587 0 : for ( std::vector< CmisValue*>::const_iterator it = pLine->m_aValues.begin();
2588 0 : it != pLine->m_aValues.end(); ++it, ++k)
2589 : {
2590 0 : OUString sValue( (*it)->m_aValueEdit->GetText() );
2591 0 : seqValue[k] = sValue;
2592 0 : }
2593 0 : aPropertiesSeq[i].Value <<= makeAny( seqValue );
2594 0 : }
2595 : }
2596 0 : }
2597 :
2598 0 : return aPropertiesSeq;
2599 : }
2600 :
2601 0 : CmisPropertiesControl::CmisPropertiesControl(SfxTabPage* pParent)
2602 : : m_pPropertiesWin( pParent )
2603 0 : , m_rScrolledWindow( *pParent->get<VclScrolledWindow>("CmisScroll"))
2604 0 : , m_rVertScroll( m_rScrolledWindow.getVertScrollBar())
2605 : {
2606 0 : m_rScrolledWindow.setUserManagedScrolling(true);
2607 0 : m_rVertScroll.EnableDrag();
2608 0 : m_rVertScroll.Show( m_rScrolledWindow.GetStyle() & WB_VSCROLL);
2609 0 : m_rVertScroll.SetRangeMin(0);
2610 0 : m_rVertScroll.SetVisibleSize( 0xFFFF );
2611 :
2612 0 : Link<> aScrollLink = LINK( this, CmisPropertiesControl, ScrollHdl );
2613 0 : m_rVertScroll.SetScrollHdl( aScrollLink );
2614 0 : }
2615 :
2616 0 : void CmisPropertiesControl::ClearAllLines()
2617 : {
2618 0 : m_pPropertiesWin.ClearAllLines();
2619 0 : }
2620 :
2621 0 : IMPL_LINK( CmisPropertiesControl, ScrollHdl, ScrollBar*, pScrollBar )
2622 : {
2623 0 : sal_Int32 nOffset = m_pPropertiesWin.GetItemHeight();
2624 0 : nOffset *= ( pScrollBar->GetThumbPos() );
2625 0 : m_pPropertiesWin.DoScroll( -nOffset );
2626 0 : return 0;
2627 : }
2628 :
2629 0 : void CmisPropertiesControl::checkAutoVScroll()
2630 : {
2631 0 : WinBits nBits = m_rScrolledWindow.GetStyle();
2632 0 : if (nBits & WB_VSCROLL)
2633 0 : return;
2634 0 : if (nBits & WB_AUTOVSCROLL)
2635 : {
2636 0 : bool bShow = m_rVertScroll.GetRangeMax() > m_rVertScroll.GetVisibleSize();
2637 0 : if (bShow != m_rVertScroll.IsVisible())
2638 0 : m_rVertScroll.Show(bShow);
2639 : }
2640 : }
2641 :
2642 0 : void CmisPropertiesControl::setScrollRange()
2643 : {
2644 0 : sal_Int32 nScrollOffset = m_pPropertiesWin.GetItemHeight();
2645 0 : sal_Int32 nVisibleItems = m_rScrolledWindow.getVisibleChildSize().Height() / nScrollOffset;
2646 0 : m_rVertScroll.SetPageSize( nVisibleItems - 1 );
2647 0 : m_rVertScroll.SetVisibleSize( nVisibleItems );
2648 0 : m_rVertScroll.Scroll();
2649 0 : checkAutoVScroll();
2650 0 : }
2651 :
2652 0 : 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
2656 : )
2657 : {
2658 0 : m_rVertScroll.SetRangeMax( m_pPropertiesWin.GetLineCount() + 1 );
2659 0 : m_rVertScroll.DoScroll( m_pPropertiesWin.GetLineCount() + 1 );
2660 : m_pPropertiesWin.AddLine( sId, sName, sType, bUpdatable, bRequired, bMultiValued,
2661 0 : bOpenChoice, aChoices, rAny );
2662 0 : checkAutoVScroll();
2663 0 : }
2664 :
2665 : // class SfxCmisPropertiesPage -----------------------------------------
2666 0 : SfxCmisPropertiesPage::SfxCmisPropertiesPage( vcl::Window* pParent, const SfxItemSet& rItemSet )
2667 : : SfxTabPage(pParent, "CmisInfoPage", "sfx/ui/cmisinfopage.ui", &rItemSet)
2668 0 : , m_pPropertiesCtrl( this )
2669 : {
2670 0 : }
2671 :
2672 0 : bool SfxCmisPropertiesPage::FillItemSet( SfxItemSet* rSet )
2673 : {
2674 0 : const SfxPoolItem* pItem = NULL;
2675 0 : SfxDocumentInfoItem* pInfo = NULL;
2676 0 : bool bMustDelete = false;
2677 :
2678 0 : if ( GetTabDialog() && GetTabDialog()->GetExampleSet() )
2679 : {
2680 0 : if ( SfxItemState::SET !=
2681 0 : GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO, true, &pItem ) )
2682 0 : pInfo = const_cast<SfxDocumentInfoItem*>(&static_cast<const SfxDocumentInfoItem& >(rSet->Get( SID_DOCINFO )));
2683 : else
2684 : {
2685 0 : bMustDelete = true;
2686 0 : pInfo = new SfxDocumentInfoItem( *static_cast<const SfxDocumentInfoItem*>(pItem) );
2687 : }
2688 : }
2689 :
2690 0 : sal_Int32 modifiedNum = 0;
2691 0 : if ( pInfo )
2692 : {
2693 0 : Sequence< document::CmisProperty > aOldProps = pInfo->GetCmisProperties( );
2694 0 : Sequence< document::CmisProperty > aNewProps = m_pPropertiesCtrl.GetCmisProperties();
2695 :
2696 0 : std::vector< document::CmisProperty > changedProps;
2697 0 : for ( sal_Int32 i = 0; i< aNewProps.getLength( ); ++i )
2698 : {
2699 0 : if ( aOldProps[i].Updatable && !aNewProps[i].Id.isEmpty( ) )
2700 : {
2701 0 : if ( aOldProps[i].Type == CMIS_TYPE_DATETIME )
2702 : {
2703 0 : Sequence< util::DateTime > oldValue;
2704 0 : aOldProps[i].Value >>= oldValue;
2705 : // We only edit hours and minutes
2706 : // don't compare NanoSeconds and Seconds
2707 0 : for ( sal_Int32 ii = 0; ii < oldValue.getLength( ); ++ii )
2708 : {
2709 0 : oldValue[ii].NanoSeconds = 0;
2710 0 : oldValue[ii].Seconds = 0;
2711 : }
2712 0 : Sequence< util::DateTime > newValue;
2713 0 : aNewProps[i].Value >>= newValue;
2714 0 : if ( oldValue != newValue )
2715 : {
2716 0 : modifiedNum++;
2717 0 : changedProps.push_back( aNewProps[i] );
2718 0 : }
2719 : }
2720 0 : else if ( aOldProps[i].Value != aNewProps[i].Value )
2721 : {
2722 0 : modifiedNum++;
2723 0 : changedProps.push_back( aNewProps[i] );
2724 : }
2725 : }
2726 : }
2727 0 : Sequence< document::CmisProperty> aModifiedProps( modifiedNum );
2728 0 : sal_Int32 nCount = 0;
2729 0 : for( std::vector< document::CmisProperty>::const_iterator pIter = changedProps.begin();
2730 0 : pIter != changedProps.end( ); ++pIter )
2731 0 : aModifiedProps[ nCount++ ] = *pIter;
2732 0 : pInfo->SetCmisProperties( aModifiedProps );
2733 0 : rSet->Put( *pInfo );
2734 0 : if ( bMustDelete )
2735 0 : delete pInfo;
2736 : }
2737 :
2738 0 : return modifiedNum;
2739 : }
2740 :
2741 0 : void SfxCmisPropertiesPage::Reset( const SfxItemSet* rItemSet )
2742 : {
2743 0 : m_pPropertiesCtrl.ClearAllLines();
2744 0 : const SfxDocumentInfoItem& rInfoItem = static_cast<const SfxDocumentInfoItem& >(rItemSet->Get(SID_DOCINFO));
2745 0 : uno::Sequence< document::CmisProperty > aCmisProps = rInfoItem.GetCmisProperties();
2746 0 : for ( sal_Int32 i = 0; i < aCmisProps.getLength(); i++ )
2747 : {
2748 0 : m_pPropertiesCtrl.AddLine( aCmisProps[i].Id,
2749 0 : aCmisProps[i].Name,
2750 0 : aCmisProps[i].Type,
2751 0 : aCmisProps[i].Updatable,
2752 0 : aCmisProps[i].Required,
2753 0 : aCmisProps[i].MultiValued,
2754 0 : aCmisProps[i].OpenChoice,
2755 0 : aCmisProps[i].Choices,
2756 0 : aCmisProps[i].Value );
2757 : }
2758 0 : m_pPropertiesCtrl.setScrollRange();
2759 0 : }
2760 :
2761 0 : SfxTabPage::sfxpg SfxCmisPropertiesPage::DeactivatePage( SfxItemSet* /*pSet*/ )
2762 : {
2763 0 : return LEAVE_PAGE;
2764 : }
2765 :
2766 0 : VclPtr<SfxTabPage> SfxCmisPropertiesPage::Create( vcl::Window* pParent, const SfxItemSet* rItemSet )
2767 : {
2768 0 : return VclPtr<SfxCmisPropertiesPage>::Create( pParent, *rItemSet );
2769 648 : }
2770 :
2771 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|