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