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