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