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