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 const long nPosY( pLine->m_aDateField.GetPosPixel().Y() ); 1851 pLine->m_aDateField.SetPosPixel( ::Point( m_nDatePosX, nPosY ) ); 1852 pLine->m_aTimeField.SetPosPixel( ::Point( m_nTimePosX, nPosY ) ); 1853 } 1854 1855 return 0; 1856 } 1857 1858 IMPL_LINK( CustomPropertiesWindow, RemoveHdl, CustomPropertiesRemoveButton*, pButton ) 1859 { 1860 CustomPropertyLine* pLine = pButton->GetLine(); 1861 std::vector< CustomPropertyLine* >::iterator pFound = 1862 std::find( m_aCustomPropertiesLines.begin(), m_aCustomPropertiesLines.end(), pLine ); 1863 if ( pFound != m_aCustomPropertiesLines.end() ) 1864 { 1865 pLine = *pFound; 1866 pLine->SetRemoved(); 1867 std::vector< CustomPropertyLine* >::iterator pIter = pFound + 1; 1868 const long nDelta = GetLineHeight(); 1869 for ( ; pIter != m_aCustomPropertiesLines.end(); ++pIter ) 1870 { 1871 pLine = *pIter; 1872 if ( pLine->m_bIsRemoved ) 1873 continue; 1874 1875 Window* pWindows[] = { &pLine->m_aNameBox, 1876 &pLine->m_aTypeBox, 1877 &pLine->m_aValueEdit, 1878 &pLine->m_aDateField, 1879 &pLine->m_aTimeField, 1880 &pLine->m_aDurationField, 1881 &pLine->m_aEditButton, 1882 &pLine->m_aYesNoButton, 1883 &pLine->m_aRemoveButton, NULL }; 1884 Window** pCurrent = pWindows; 1885 while ( *pCurrent ) 1886 { 1887 Point aPos = (*pCurrent)->GetPosPixel(); 1888 aPos.Y() -= nDelta; 1889 (*pCurrent)->SetPosPixel( aPos ); 1890 pCurrent++; 1891 } 1892 } 1893 } 1894 1895 m_aRemovedHdl.Call(0); 1896 return 0; 1897 } 1898 1899 IMPL_LINK( CustomPropertiesWindow, EditLoseFocusHdl, CustomPropertiesEdit*, pEdit ) 1900 { 1901 if ( pEdit ) 1902 { 1903 CustomPropertyLine* pLine = pEdit->GetLine(); 1904 if ( !pLine->m_bTypeLostFocus ) 1905 { 1906 m_pCurrentLine = pLine; 1907 m_aEditLoseFocusTimer.Start(); 1908 } 1909 else 1910 pLine->m_bTypeLostFocus = false; 1911 } 1912 return 0; 1913 } 1914 1915 IMPL_LINK( CustomPropertiesWindow, BoxLoseFocusHdl, CustomPropertiesTypeBox*, pBox ) 1916 { 1917 if ( pBox ) 1918 { 1919 m_pCurrentLine = pBox->GetLine(); 1920 m_aBoxLoseFocusTimer.Start(); 1921 } 1922 1923 return 0; 1924 } 1925 1926 IMPL_LINK( CustomPropertiesWindow, EditTimeoutHdl, Timer*, EMPTYARG ) 1927 { 1928 ValidateLine( m_pCurrentLine, false ); 1929 return 0; 1930 } 1931 1932 IMPL_LINK( CustomPropertiesWindow, BoxTimeoutHdl, Timer*, EMPTYARG ) 1933 { 1934 ValidateLine( m_pCurrentLine, true ); 1935 return 0; 1936 } 1937 1938 bool CustomPropertiesWindow::IsLineValid( CustomPropertyLine* pLine ) const 1939 { 1940 bool bIsValid = true; 1941 pLine->m_bTypeLostFocus = false; 1942 sal_Int64 nType = sal_Int64( 1943 (long)pLine->m_aTypeBox.GetEntryData( pLine->m_aTypeBox.GetSelectEntryPos() ) ); 1944 String sValue = pLine->m_aValueEdit.GetText(); 1945 if ( sValue.Len() == 0 ) 1946 return true; 1947 1948 double fDummy = 0.0; 1949 sal_uInt32 nIndex = 0xFFFFFFFF; 1950 if ( CUSTOM_TYPE_NUMBER == nType ) 1951 nIndex = const_cast< SvNumberFormatter& >( 1952 m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM ); 1953 else if ( CUSTOM_TYPE_DATE == nType ) 1954 nIndex = const_cast< SvNumberFormatter& >( 1955 m_aNumberFormatter).GetFormatIndex( NF_DATE_SYS_DDMMYYYY ); 1956 1957 if ( nIndex != 0xFFFFFFFF ) 1958 { 1959 sal_uInt32 nTemp = nIndex; 1960 bIsValid = const_cast< SvNumberFormatter& >( 1961 m_aNumberFormatter ).IsNumberFormat( sValue, nIndex, fDummy ) != sal_False; 1962 if ( bIsValid && nTemp != nIndex ) 1963 // sValue is a number but the format doesn't match the index 1964 bIsValid = false; 1965 } 1966 1967 return bIsValid; 1968 } 1969 1970 void CustomPropertiesWindow::ValidateLine( CustomPropertyLine* pLine, bool bIsFromTypeBox ) 1971 { 1972 if ( !IsLineValid( pLine ) ) 1973 { 1974 if ( bIsFromTypeBox ) // LoseFocus of TypeBox 1975 pLine->m_bTypeLostFocus = true; 1976 Window* pParent = GetParent()->GetParent(); 1977 if ( QueryBox( pParent, SfxResId( SFX_QB_WRONG_TYPE ) ).Execute() == RET_OK ) 1978 pLine->m_aTypeBox.SelectEntryPos( m_aTypeBox.GetEntryPos( (void*)CUSTOM_TYPE_TEXT ) ); 1979 else 1980 pLine->m_aValueEdit.GrabFocus(); 1981 } 1982 } 1983 1984 void CustomPropertiesWindow::InitControls( HeaderBar* pHeaderBar, const ScrollBar* pScrollBar ) 1985 { 1986 DBG_ASSERT( pHeaderBar, "CustomPropertiesWindow::InitControls(): invalid headerbar" ); 1987 DBG_ASSERT( pScrollBar, "CustomPropertiesWindow::InitControls(): invalid scrollbar" ); 1988 1989 m_aNameBox.Hide(); 1990 m_aTypeBox.Hide(); 1991 m_aValueEdit.Hide(); 1992 m_aDateField.Hide(); 1993 m_aTimeField.Hide(); 1994 m_aDurationField.Hide(); 1995 m_aEditButton.Hide(); 1996 m_aYesNoButton.Hide(); 1997 m_aRemoveButton.Hide(); 1998 1999 const long nOffset = 4; 2000 const long nScrollBarWidth = pScrollBar->GetSizePixel().Width(); 2001 const long nButtonWidth = m_aRemoveButton.GetSizePixel().Width() + nScrollBarWidth + nOffset; 2002 long nTypeWidth = m_aTypeBox.CalcMinimumSize().Width() + ( 2 * nOffset ); 2003 long nFullWidth = pHeaderBar->GetSizePixel().Width(); 2004 long nItemWidth = ( nFullWidth - nTypeWidth - nButtonWidth ) / 2; 2005 pHeaderBar->SetItemSize( HI_NAME, nItemWidth ); 2006 pHeaderBar->SetItemSize( HI_TYPE, nTypeWidth ); 2007 pHeaderBar->SetItemSize( HI_VALUE, nItemWidth ); 2008 pHeaderBar->SetItemSize( HI_ACTION, nButtonWidth ); 2009 2010 Window* pWindows[] = { &m_aNameBox, &m_aTypeBox, &m_aValueEdit, &m_aRemoveButton, NULL }; 2011 Window** pCurrent = pWindows; 2012 sal_uInt16 nPos = 0; 2013 while ( *pCurrent ) 2014 { 2015 Rectangle aRect = pHeaderBar->GetItemRect( pHeaderBar->GetItemId( nPos++ ) ); 2016 Size aSize = (*pCurrent)->GetSizePixel(); 2017 Point aPos = (*pCurrent)->GetPosPixel(); 2018 long nWidth = aRect.getWidth() - nOffset; 2019 if ( *pCurrent == &m_aRemoveButton ) 2020 nWidth -= pScrollBar->GetSizePixel().Width(); 2021 aSize.Width() = nWidth; 2022 aPos.X() = aRect.getX() + ( nOffset / 2 ); 2023 (*pCurrent)->SetPosSizePixel( aPos, aSize ); 2024 2025 if ( *pCurrent == &m_aValueEdit ) 2026 { 2027 Point aDurationPos( aPos ); 2028 m_aDurationField.SetPosPixel( aDurationPos ); 2029 Size aDurationSize(aSize); 2030 aDurationSize.Width() -= (m_aEditButton.GetSizePixel().Width() + 3 ); 2031 m_aDurationField.SetSizePixel(aDurationSize); 2032 aDurationPos.X() = aPos.X() - m_aEditButton.GetSizePixel().Width() + aSize.Width(); 2033 m_aEditButton.SetPosPixel(aDurationPos); 2034 aSize = m_aYesNoButton.GetSizePixel(); 2035 aPos = m_aYesNoButton.GetPosPixel(); 2036 aSize.Width() = nWidth; 2037 aPos.X() = aRect.getX() + ( nOffset / 2 ); 2038 m_aYesNoButton.SetPosSizePixel( aPos, aSize ); 2039 aSize.Width() /= 2; 2040 aSize.Width() -= 2; 2041 m_aDateField.SetPosSizePixel( aPos, aSize ); 2042 aPos.X() += aSize.Width() + 4; 2043 m_aTimeField.SetPosSizePixel( aPos, aSize ); 2044 } 2045 2046 pCurrent++; 2047 } 2048 2049 m_nLineHeight = 2050 ( m_aRemoveButton.GetPosPixel().Y() * 2 ) + m_aRemoveButton.GetSizePixel().Height(); 2051 2052 m_nDatePosX = m_aDateField.GetPosPixel().X(); 2053 m_nTimePosX = m_aTimeField.GetPosPixel().X(); 2054 } 2055 2056 sal_uInt16 CustomPropertiesWindow::GetVisibleLineCount() const 2057 { 2058 sal_uInt16 nCount = 0; 2059 std::vector< CustomPropertyLine* >::const_iterator pIter; 2060 for ( pIter = m_aCustomPropertiesLines.begin(); 2061 pIter != m_aCustomPropertiesLines.end(); ++pIter ) 2062 { 2063 CustomPropertyLine* pLine = *pIter; 2064 if ( !pLine->m_bIsRemoved ) 2065 nCount++; 2066 } 2067 return nCount; 2068 } 2069 2070 void CustomPropertiesWindow::AddLine( const ::rtl::OUString& sName, Any& rAny ) 2071 { 2072 CustomPropertyLine* pNewLine = new CustomPropertyLine( this ); 2073 pNewLine->m_aTypeBox.SetSelectHdl( LINK( this, CustomPropertiesWindow, TypeHdl ) ); 2074 pNewLine->m_aRemoveButton.SetClickHdl( LINK( this, CustomPropertiesWindow, RemoveHdl ) ); 2075 pNewLine->m_aValueEdit.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, EditLoseFocusHdl ) ); 2076 //add lose focus handlers of date/time fields 2077 2078 pNewLine->m_aTypeBox.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, BoxLoseFocusHdl ) ); 2079 2080 pNewLine->m_aNameBox.SetAccessibleName(m_aNameBox.GetAccessibleName()); 2081 pNewLine->m_aTypeBox.SetAccessibleName(m_aTypeBox.GetAccessibleName()); 2082 pNewLine->m_aValueEdit.SetAccessibleName(m_aValueEdit.GetAccessibleName()); 2083 2084 long nPos = GetVisibleLineCount() * GetLineHeight(); 2085 m_aCustomPropertiesLines.push_back( pNewLine ); 2086 Window* pWindows[] = { &m_aNameBox, &m_aTypeBox, &m_aValueEdit, 2087 &m_aDateField, &m_aTimeField, 2088 &m_aDurationField, &m_aEditButton, 2089 &m_aYesNoButton, &m_aRemoveButton, NULL }; 2090 Window* pNewWindows[] = 2091 { &pNewLine->m_aNameBox, &pNewLine->m_aTypeBox, &pNewLine->m_aValueEdit, 2092 &pNewLine->m_aDateField, &pNewLine->m_aTimeField, 2093 &pNewLine->m_aDurationField, &pNewLine->m_aEditButton, 2094 &pNewLine->m_aYesNoButton, &pNewLine->m_aRemoveButton, NULL }; 2095 Window** pCurrent = pWindows; 2096 Window** pNewCurrent = pNewWindows; 2097 while ( *pCurrent ) 2098 { 2099 Size aSize = (*pCurrent)->GetSizePixel(); 2100 Point aPos = (*pCurrent)->GetPosPixel(); 2101 aPos.Y() += nPos; 2102 aPos.Y() += m_nScrollPos; 2103 (*pNewCurrent)->SetPosSizePixel( aPos, aSize ); 2104 (*pNewCurrent)->Show(); 2105 pCurrent++; 2106 pNewCurrent++; 2107 } 2108 2109 double nTmpValue = 0; 2110 bool bTmpValue = false; 2111 ::rtl::OUString sTmpValue; 2112 util::DateTime aTmpDateTime; 2113 util::Date aTmpDate; 2114 util::Duration aTmpDuration; 2115 SvtSysLocale aSysLocale; 2116 const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData(); 2117 pNewLine->m_aNameBox.SetText( sName ); 2118 sal_Int32 nType = CUSTOM_TYPE_UNKNOWN; 2119 String sValue; 2120 2121 if ( rAny >>= nTmpValue ) 2122 { 2123 sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM ); 2124 m_aNumberFormatter.GetInputLineString( nTmpValue, nIndex, sValue ); 2125 pNewLine->m_aValueEdit.SetText( sValue ); 2126 nType = CUSTOM_TYPE_NUMBER; 2127 } 2128 else if ( rAny >>= bTmpValue ) 2129 { 2130 sValue = ( bTmpValue ? rLocaleWrapper.getTrueWord() : rLocaleWrapper.getFalseWord() ); 2131 nType = CUSTOM_TYPE_BOOLEAN; 2132 } 2133 else if ( rAny >>= sTmpValue ) 2134 { 2135 pNewLine->m_aValueEdit.SetText( sTmpValue ); 2136 nType = CUSTOM_TYPE_TEXT; 2137 } 2138 else if ( rAny >>= aTmpDate ) 2139 { 2140 nType = CUSTOM_TYPE_DATE; 2141 pNewLine->m_aDateField.SetDate( Date( aTmpDate.Day, aTmpDate.Month, aTmpDate.Year ) ); 2142 2143 } 2144 else if ( rAny >>= aTmpDuration ) 2145 { 2146 nType = CUSTOM_TYPE_DURATION; 2147 pNewLine->m_aDurationField.SetDuration( aTmpDuration ); 2148 } 2149 else if ( rAny >>= aTmpDateTime ) 2150 { 2151 pNewLine->m_aDateField.SetDate( Date( aTmpDateTime.Day, aTmpDateTime.Month, aTmpDateTime.Year ) ); 2152 pNewLine->m_aTimeField.SetTime( Time( aTmpDateTime.Hours, aTmpDateTime.Minutes, aTmpDateTime.Seconds, aTmpDateTime.HundredthSeconds ) ); 2153 2154 nType = CUSTOM_TYPE_DATETIME; 2155 } 2156 2157 if ( nType != CUSTOM_TYPE_UNKNOWN ) 2158 { 2159 if ( CUSTOM_TYPE_BOOLEAN == nType ) 2160 { 2161 if ( bTmpValue ) 2162 pNewLine->m_aYesNoButton.CheckYes(); 2163 else 2164 pNewLine->m_aYesNoButton.CheckNo(); 2165 } 2166 pNewLine->m_aTypeBox.SelectEntryPos( m_aTypeBox.GetEntryPos( (void*)nType ) ); 2167 } 2168 2169 TypeHdl( &pNewLine->m_aTypeBox ); 2170 pNewLine->m_aNameBox.GrabFocus(); 2171 } 2172 2173 bool CustomPropertiesWindow::AreAllLinesValid() const 2174 { 2175 bool bRet = true; 2176 std::vector< CustomPropertyLine* >::const_iterator pIter; 2177 for ( pIter = m_aCustomPropertiesLines.begin(); 2178 pIter != m_aCustomPropertiesLines.end(); ++pIter ) 2179 { 2180 CustomPropertyLine* pLine = *pIter; 2181 if ( !IsLineValid( pLine ) ) 2182 { 2183 bRet = false; 2184 break; 2185 } 2186 } 2187 2188 return bRet; 2189 } 2190 2191 void CustomPropertiesWindow::ClearAllLines() 2192 { 2193 std::vector< CustomPropertyLine* >::iterator pIter; 2194 for ( pIter = m_aCustomPropertiesLines.begin(); 2195 pIter != m_aCustomPropertiesLines.end(); ++pIter ) 2196 { 2197 CustomPropertyLine* pLine = *pIter; 2198 pLine->SetRemoved(); 2199 delete pLine; 2200 } 2201 m_aCustomPropertiesLines.clear(); 2202 m_nScrollPos = 0; 2203 } 2204 2205 void CustomPropertiesWindow::DoScroll( sal_Int32 nNewPos ) 2206 { 2207 m_nScrollPos += nNewPos; 2208 std::vector< CustomPropertyLine* >::iterator pIter; 2209 for ( pIter = m_aCustomPropertiesLines.begin(); 2210 pIter != m_aCustomPropertiesLines.end(); ++pIter ) 2211 { 2212 CustomPropertyLine* pLine = *pIter; 2213 if ( pLine->m_bIsRemoved ) 2214 continue; 2215 2216 Window* pWindows[] = { &pLine->m_aNameBox, 2217 &pLine->m_aTypeBox, 2218 &pLine->m_aValueEdit, 2219 &pLine->m_aDurationField, 2220 &pLine->m_aEditButton, 2221 &pLine->m_aDateField, 2222 &pLine->m_aTimeField, 2223 &pLine->m_aYesNoButton, 2224 &pLine->m_aRemoveButton, NULL }; 2225 Window** pCurrent = pWindows; 2226 while ( *pCurrent ) 2227 { 2228 Point aPos = (*pCurrent)->GetPosPixel(); 2229 aPos.Y() += nNewPos; 2230 (*pCurrent)->SetPosPixel( aPos ); 2231 pCurrent++; 2232 } 2233 } 2234 } 2235 2236 bool CustomPropertiesWindow::DoesCustomPropertyExist( const String& rName ) const 2237 { 2238 bool bRet = false; 2239 std::vector< CustomPropertyLine* >::const_iterator pIter; 2240 for ( pIter = m_aCustomPropertiesLines.begin(); 2241 pIter != m_aCustomPropertiesLines.end(); ++pIter ) 2242 { 2243 CustomPropertyLine* pLine = *pIter; 2244 if ( !pLine->m_bIsRemoved && pLine->m_aNameBox.GetText() == rName ) 2245 { 2246 bRet = true; 2247 break; 2248 } 2249 } 2250 2251 return bRet; 2252 } 2253 2254 Sequence< beans::PropertyValue > CustomPropertiesWindow::GetCustomProperties() const 2255 { 2256 Sequence< beans::PropertyValue > aPropertiesSeq( m_aCustomPropertiesLines.size() ); 2257 sal_Int32 i = 0; 2258 std::vector< CustomPropertyLine* >::const_iterator pIter; 2259 for ( pIter = m_aCustomPropertiesLines.begin(); 2260 pIter != m_aCustomPropertiesLines.end(); ++pIter, ++i ) 2261 { 2262 CustomPropertyLine* pLine = *pIter; 2263 if ( pLine->m_bIsRemoved ) 2264 continue; 2265 2266 String sPropertyName = pLine->m_aNameBox.GetText(); 2267 if ( sPropertyName.Len() > 0 ) 2268 { 2269 aPropertiesSeq[i].Name = sPropertyName; 2270 sal_Int64 nType = sal_Int64( 2271 (long)pLine->m_aTypeBox.GetEntryData( pLine->m_aTypeBox.GetSelectEntryPos() ) ); 2272 if ( CUSTOM_TYPE_NUMBER == nType ) 2273 { 2274 double nValue = 0; 2275 sal_uInt32 nIndex = const_cast< SvNumberFormatter& >( 2276 m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM ); 2277 sal_Bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ). 2278 IsNumberFormat( pLine->m_aValueEdit.GetText(), nIndex, nValue ); 2279 if ( bIsNum ) 2280 aPropertiesSeq[i].Value <<= makeAny( nValue ); 2281 } 2282 else if ( CUSTOM_TYPE_BOOLEAN == nType ) 2283 { 2284 bool bValue = pLine->m_aYesNoButton.IsYesChecked(); 2285 aPropertiesSeq[i].Value <<= makeAny( bValue ); 2286 } 2287 else if ( CUSTOM_TYPE_DATETIME == nType ) 2288 { 2289 Date aTmpDate = pLine->m_aDateField.GetDate(); 2290 Time aTmpTime = pLine->m_aTimeField.GetTime(); 2291 util::DateTime aDateTime(aTmpTime.Get100Sec(), aTmpTime.GetSec(), aTmpTime.GetMin(), aTmpTime.GetHour(), 2292 aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear() ); 2293 aPropertiesSeq[i].Value <<= aDateTime; 2294 } 2295 else if ( CUSTOM_TYPE_DURATION == nType ) 2296 { 2297 aPropertiesSeq[i].Value <<= pLine->m_aDurationField.GetDuration(); 2298 } 2299 else if ( CUSTOM_TYPE_DATE == nType ) 2300 { 2301 Date aTmpDate = pLine->m_aDateField.GetDate(); 2302 util::Date aDate(aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear()); 2303 aPropertiesSeq[i].Value <<= aDate; 2304 2305 } 2306 else 2307 { 2308 ::rtl::OUString sValue( pLine->m_aValueEdit.GetText() ); 2309 aPropertiesSeq[i].Value <<= makeAny( sValue ); 2310 } 2311 } 2312 } 2313 2314 return aPropertiesSeq; 2315 } 2316 2317 // class CustomPropertiesControl ----------------------------------------- 2318 2319 CustomPropertiesControl::CustomPropertiesControl( Window* pParent, const ResId& rResId ) : 2320 2321 Control( pParent, rResId ), 2322 2323 m_aHeaderBar ( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER ), 2324 m_aPropertiesWin( this, ResId( WIN_PROPERTIES, *rResId.GetResMgr() ) ), 2325 m_aVertScroll ( this, ResId( SB_VERTICAL, *rResId.GetResMgr() ) ), 2326 2327 m_bIsInitialized( false ), 2328 m_nThumbPos ( 0 ) 2329 2330 { 2331 m_aPropertiesWin.SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) ); 2332 m_aVertScroll.EnableDrag(); 2333 m_aVertScroll.Show(); 2334 long nWidth = GetOutputSizePixel().Width(); 2335 m_aHeaderBar.SetPosSizePixel( Point(), Size( nWidth, m_aVertScroll.GetPosPixel().Y() ) ); 2336 const HeaderBarItemBits nHeadBits = HIB_VCENTER | HIB_FIXED | HIB_FIXEDPOS | HIB_LEFT; 2337 nWidth = nWidth / 4; 2338 ResMgr* pResMgr = rResId.GetResMgr(); 2339 m_aHeaderBar.InsertItem( HI_NAME, String( ResId( STR_HEADER_NAME, *pResMgr ) ), nWidth, nHeadBits ); 2340 m_aHeaderBar.InsertItem( HI_TYPE, String( ResId( STR_HEADER_TYPE, *pResMgr ) ), nWidth, nHeadBits ); 2341 m_aHeaderBar.InsertItem( HI_VALUE, String( ResId( STR_HEADER_VALUE, *pResMgr ) ), nWidth, nHeadBits ); 2342 m_aHeaderBar.InsertItem( HI_ACTION, String( ResId( STR_HEADER_ACTION, *pResMgr ) ), nWidth, nHeadBits ); 2343 m_aHeaderBar.Show(); 2344 2345 FreeResource(); 2346 2347 XubString sTEST = m_aHeaderBar.GetItemText( HI_NAME ); 2348 2349 m_aPropertiesWin.InitControls( &m_aHeaderBar, &m_aVertScroll ); 2350 m_aPropertiesWin.SetRemovedHdl( LINK( this, CustomPropertiesControl, RemovedHdl ) ); 2351 2352 m_aVertScroll.SetRangeMin( 0 ); 2353 sal_Int32 nScrollOffset = m_aPropertiesWin.GetLineHeight(); 2354 sal_Int32 nVisibleEntries = m_aPropertiesWin.GetSizePixel().Height() / nScrollOffset; 2355 m_aVertScroll.SetRangeMax( nVisibleEntries ); 2356 m_aVertScroll.SetPageSize( nVisibleEntries - 1 ); 2357 m_aVertScroll.SetVisibleSize( nVisibleEntries ); 2358 2359 Point aPos = m_aHeaderBar.GetPosPixel(); 2360 Size aSize = m_aHeaderBar.GetSizePixel(); 2361 aPos = m_aVertScroll.GetPosPixel(); 2362 aSize = m_aVertScroll.GetSizePixel(); 2363 2364 Link aScrollLink = LINK( this, CustomPropertiesControl, ScrollHdl ); 2365 m_aVertScroll.SetScrollHdl( aScrollLink ); 2366 // m_aVertScroll.SetEndScrollHdl( aScrollLink ); 2367 } 2368 2369 CustomPropertiesControl::~CustomPropertiesControl() 2370 { 2371 } 2372 2373 void CustomPropertiesControl::Initialize() 2374 { 2375 } 2376 2377 IMPL_LINK( CustomPropertiesControl, ScrollHdl, ScrollBar*, pScrollBar ) 2378 { 2379 sal_Int32 nOffset = m_aPropertiesWin.GetLineHeight(); 2380 nOffset *= ( m_nThumbPos - pScrollBar->GetThumbPos() ); 2381 m_nThumbPos = pScrollBar->GetThumbPos(); 2382 m_aPropertiesWin.DoScroll( nOffset ); 2383 return 0; 2384 } 2385 2386 IMPL_LINK( CustomPropertiesControl, RemovedHdl, void*, EMPTYARG ) 2387 { 2388 m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 ); 2389 if ( m_aPropertiesWin.GetOutputSizePixel().Height() < m_aPropertiesWin.GetVisibleLineCount() * m_aPropertiesWin.GetLineHeight() ) 2390 m_aVertScroll.DoScrollAction ( SCROLL_LINEUP ); 2391 return 0; 2392 } 2393 2394 void CustomPropertiesControl::AddLine( const ::rtl::OUString& sName, Any& rAny, bool bInteractive ) 2395 { 2396 m_aPropertiesWin.AddLine( sName, rAny ); 2397 m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 ); 2398 if ( bInteractive && m_aPropertiesWin.GetOutputSizePixel().Height() < m_aPropertiesWin.GetVisibleLineCount() * m_aPropertiesWin.GetLineHeight() ) 2399 m_aVertScroll.DoScroll( m_aPropertiesWin.GetVisibleLineCount() + 1 ); 2400 } 2401 2402 // class SfxCustomPropertiesPage ----------------------------------------- 2403 2404 SfxCustomPropertiesPage::SfxCustomPropertiesPage( Window* pParent, const SfxItemSet& rItemSet ) : 2405 2406 SfxTabPage( pParent, SfxResId( TP_CUSTOMPROPERTIES ), rItemSet ), 2407 m_aPropertiesCtrl ( this, SfxResId( CTRL_PROPERTIES ) ), 2408 m_aAddBtn ( this, SfxResId( BTN_ADD ) ), 2409 m_aPropertiesFT ( this, SfxResId( FT_PROPERTIES ) ) 2410 2411 { 2412 FreeResource(); 2413 2414 m_aAddBtn.SetClickHdl( LINK( this, SfxCustomPropertiesPage, AddHdl ) ); 2415 } 2416 2417 IMPL_LINK( SfxCustomPropertiesPage, AddHdl, PushButton*, EMPTYARG ) 2418 { 2419 Any aAny; 2420 m_aPropertiesCtrl.AddLine( ::rtl::OUString(), aAny, true ); 2421 return 0; 2422 } 2423 2424 sal_Bool SfxCustomPropertiesPage::FillItemSet( SfxItemSet& rSet ) 2425 { 2426 sal_Bool bModified = sal_False; 2427 const SfxPoolItem* pItem = NULL; 2428 SfxDocumentInfoItem* pInfo = NULL; 2429 bool bMustDelete = false; 2430 2431 if ( GetTabDialog() && GetTabDialog()->GetExampleSet() ) 2432 { 2433 if( SFX_ITEM_SET != 2434 GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO, sal_True, &pItem ) ) 2435 pInfo = &( SfxDocumentInfoItem& )rSet.Get( SID_DOCINFO ); 2436 else 2437 { 2438 bMustDelete = true; 2439 pInfo = new SfxDocumentInfoItem( *( const SfxDocumentInfoItem* ) pItem ); 2440 } 2441 } 2442 2443 if ( pInfo ) 2444 { 2445 pInfo->ClearCustomProperties(); 2446 Sequence< beans::PropertyValue > aPropertySeq = m_aPropertiesCtrl.GetCustomProperties(); 2447 sal_Int32 i = 0, nCount = aPropertySeq.getLength(); 2448 for ( ; i < nCount; ++i ) 2449 { 2450 if ( aPropertySeq[i].Name.getLength() > 0 ) 2451 pInfo->AddCustomProperty( aPropertySeq[i].Name, aPropertySeq[i].Value ); 2452 } 2453 } 2454 2455 bModified = sal_True; //!!! 2456 if ( bModified ) 2457 rSet.Put( *pInfo ); 2458 if ( bMustDelete ) 2459 delete pInfo; 2460 return bModified; 2461 } 2462 2463 void SfxCustomPropertiesPage::Reset( const SfxItemSet& rItemSet ) 2464 { 2465 m_aPropertiesCtrl.ClearAllLines(); 2466 const SfxDocumentInfoItem* pInfoItem = &(const SfxDocumentInfoItem &)rItemSet.Get(SID_DOCINFO); 2467 std::vector< CustomProperty* > aCustomProps = pInfoItem->GetCustomProperties(); 2468 for ( sal_uInt32 i = 0; i < aCustomProps.size(); i++ ) 2469 { 2470 m_aPropertiesCtrl.AddLine( aCustomProps[i]->m_sName, aCustomProps[i]->m_aValue, false ); 2471 } 2472 } 2473 2474 int SfxCustomPropertiesPage::DeactivatePage( SfxItemSet* /*pSet*/ ) 2475 { 2476 int nRet = LEAVE_PAGE; 2477 if ( !m_aPropertiesCtrl.AreAllLinesValid() ) 2478 nRet = KEEP_PAGE; 2479 return nRet; 2480 } 2481 2482 SfxTabPage* SfxCustomPropertiesPage::Create( Window* pParent, const SfxItemSet& rItemSet ) 2483 { 2484 return new SfxCustomPropertiesPage( pParent, rItemSet ); 2485 } 2486 2487