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