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