1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 #include <limits.h> 32 #include <stdlib.h> 33 #include <vcl/msgbox.hxx> 34 #include <unotools/viewoptions.hxx> 35 36 #define _SVSTDARR_USHORTS 37 #include <svl/svstdarr.hxx> 38 39 #include "appdata.hxx" 40 #include "sfxtypes.hxx" 41 #include <sfx2/minarray.hxx> 42 #include <sfx2/tabdlg.hxx> 43 #include <sfx2/viewfrm.hxx> 44 #include <sfx2/app.hxx> 45 #include "sfx2/sfxresid.hxx" 46 #include "sfx2/sfxhelp.hxx" 47 #include <sfx2/ctrlitem.hxx> 48 #include <sfx2/bindings.hxx> 49 #include <sfx2/sfxdlg.hxx> 50 #include <sfx2/itemconnect.hxx> 51 52 #include "dialog.hrc" 53 #include "helpid.hrc" 54 55 #if ENABLE_LAYOUT_SFX_TABDIALOG 56 #undef TabPage 57 #undef SfxTabPage 58 #define SfxTabPage ::SfxTabPage 59 #undef SfxTabDialog 60 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 61 62 using namespace ::com::sun::star::uno; 63 using namespace ::rtl; 64 65 #define USERITEM_NAME OUString::createFromAscii( "UserItem" ) 66 67 TYPEINIT1(LAYOUT_NS_SFX_TABDIALOG SfxTabDialogItem,SfxSetItem); 68 69 struct TabPageImpl 70 { 71 sal_Bool mbStandard; 72 sfx::ItemConnectionArray maItemConn; 73 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > mxFrame; 74 75 TabPageImpl() : mbStandard( sal_False ) {} 76 }; 77 78 NAMESPACE_LAYOUT_SFX_TABDIALOG 79 80 struct Data_Impl 81 { 82 sal_uInt16 nId; // Die ID 83 CreateTabPage fnCreatePage; // Pointer auf die Factory 84 GetTabPageRanges fnGetRanges;// Pointer auf die Ranges-Funktion 85 SfxTabPage* pTabPage; // die TabPage selber 86 sal_Bool bOnDemand; // Flag: ItemSet onDemand 87 sal_Bool bRefresh; // Flag: Seite mu\s neu initialisiert werden 88 89 // Konstruktor 90 Data_Impl( sal_uInt16 Id, CreateTabPage fnPage, 91 GetTabPageRanges fnRanges, sal_Bool bDemand ) : 92 93 nId ( Id ), 94 fnCreatePage( fnPage ), 95 fnGetRanges ( fnRanges ), 96 pTabPage ( 0 ), 97 bOnDemand ( bDemand ), 98 bRefresh ( sal_False ) 99 { 100 if ( !fnCreatePage ) 101 { 102 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); 103 if ( pFact ) 104 { 105 fnCreatePage = pFact->GetTabPageCreatorFunc( nId ); 106 fnGetRanges = pFact->GetTabPageRangesFunc( nId ); 107 } 108 } 109 } 110 }; 111 112 SfxTabDialogItem::SfxTabDialogItem( const SfxTabDialogItem& rAttr, SfxItemPool* pItemPool ) 113 : SfxSetItem( rAttr, pItemPool ) 114 { 115 } 116 117 SfxTabDialogItem::SfxTabDialogItem( sal_uInt16 nId, const SfxItemSet& rItemSet ) 118 : SfxSetItem( nId, rItemSet ) 119 { 120 } 121 122 SfxPoolItem* __EXPORT SfxTabDialogItem::Clone(SfxItemPool* pToPool) const 123 { 124 return new SfxTabDialogItem( *this, pToPool ); 125 } 126 127 SfxPoolItem* __EXPORT SfxTabDialogItem::Create(SvStream& /*rStream*/, sal_uInt16 /*nVersion*/) const 128 { 129 DBG_ERROR( "Use it only in UI!" ); 130 return NULL; 131 } 132 133 class SfxTabDialogController : public SfxControllerItem 134 { 135 SfxTabDialog* pDialog; 136 const SfxItemSet* pSet; 137 public: 138 SfxTabDialogController( sal_uInt16 nSlotId, SfxBindings& rBindings, SfxTabDialog* pDlg ) 139 : SfxControllerItem( nSlotId, rBindings ) 140 , pDialog( pDlg ) 141 , pSet( NULL ) 142 {} 143 144 ~SfxTabDialogController(); 145 146 DECL_LINK( Execute_Impl, void* ); 147 virtual void StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState ); 148 }; 149 150 SfxTabDialogController::~SfxTabDialogController() 151 { 152 delete pSet; 153 } 154 155 IMPL_LINK( SfxTabDialogController, Execute_Impl, void*, pVoid ) 156 { 157 (void)pVoid; //unused 158 if ( pDialog->OK_Impl() && pDialog->Ok() ) 159 { 160 const SfxPoolItem* aItems[2]; 161 SfxTabDialogItem aItem( GetId(), *pDialog->GetOutputItemSet() ); 162 aItems[0] = &aItem; 163 aItems[1] = NULL; 164 GetBindings().Execute( GetId(), aItems ); 165 } 166 167 return 0; 168 } 169 170 void SfxTabDialogController::StateChanged( sal_uInt16 /*nSID*/, SfxItemState /*eState*/, const SfxPoolItem* pState ) 171 { 172 const SfxSetItem* pSetItem = PTR_CAST( SfxSetItem, pState ); 173 if ( pSetItem ) 174 { 175 pSet = pDialog->pSet = pSetItem->GetItemSet().Clone(); 176 sal_Bool bDialogStarted = sal_False; 177 for ( sal_uInt16 n=0; n<pDialog->aTabCtrl.GetPageCount(); n++ ) 178 { 179 sal_uInt16 nPageId = pDialog->aTabCtrl.GetPageId( n ); 180 SfxTabPage* pTabPage = dynamic_cast<SfxTabPage*> (pDialog->aTabCtrl.GetTabPage( nPageId )); 181 if ( pTabPage ) 182 { 183 pTabPage->Reset( pSetItem->GetItemSet() ); 184 bDialogStarted = sal_True; 185 } 186 } 187 188 if ( bDialogStarted ) 189 pDialog->Show(); 190 } 191 else 192 pDialog->Hide(); 193 } 194 195 DECL_PTRARRAY(SfxTabDlgData_Impl, Data_Impl *, 4,4) 196 197 struct TabDlg_Impl 198 { 199 sal_Bool bModified : 1, 200 bModal : 1, 201 bInOK : 1, 202 bHideResetBtn : 1; 203 SfxTabDlgData_Impl* pData; 204 205 PushButton* pApplyButton; 206 SfxTabDialogController* pController; 207 208 TabDlg_Impl( sal_uInt8 nCnt ) : 209 210 bModified ( sal_False ), 211 bModal ( sal_True ), 212 bInOK ( sal_False ), 213 bHideResetBtn ( sal_False ), 214 pData ( new SfxTabDlgData_Impl( nCnt ) ), 215 pApplyButton ( NULL ), 216 pController ( NULL ) 217 {} 218 }; 219 220 Data_Impl* Find( SfxTabDlgData_Impl& rArr, sal_uInt16 nId, sal_uInt16* pPos = 0 ); 221 222 Data_Impl* Find( SfxTabDlgData_Impl& rArr, sal_uInt16 nId, sal_uInt16* pPos ) 223 { 224 const sal_uInt16 nCount = rArr.Count(); 225 226 for ( sal_uInt16 i = 0; i < nCount; ++i ) 227 { 228 Data_Impl* pObj = rArr[i]; 229 230 if ( pObj->nId == nId ) 231 { 232 if ( pPos ) 233 *pPos = i; 234 return pObj; 235 } 236 } 237 return 0; 238 } 239 240 #if !ENABLE_LAYOUT_SFX_TABDIALOG 241 242 void SfxTabPage::SetFrame(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame) 243 { 244 if (pImpl) 245 pImpl->mxFrame = xFrame; 246 } 247 248 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxTabPage::GetFrame() 249 { 250 if (pImpl) 251 return pImpl->mxFrame; 252 return ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >(); 253 } 254 255 SfxTabPage::SfxTabPage( Window *pParent, 256 const ResId &rResId, const SfxItemSet &rAttrSet ) : 257 258 /* [Beschreibung] 259 260 Konstruktor 261 */ 262 263 TabPage( pParent, rResId ), 264 265 pSet ( &rAttrSet ), 266 bHasExchangeSupport ( sal_False ), 267 pTabDlg ( NULL ), 268 pImpl ( new TabPageImpl ) 269 270 { 271 } 272 // ----------------------------------------------------------------------- 273 SfxTabPage:: SfxTabPage( Window *pParent, WinBits nStyle, const SfxItemSet &rAttrSet ) : 274 TabPage(pParent, nStyle), 275 pSet ( &rAttrSet ), 276 bHasExchangeSupport ( sal_False ), 277 pTabDlg ( NULL ), 278 pImpl ( new TabPageImpl ) 279 { 280 } 281 // ----------------------------------------------------------------------- 282 283 SfxTabPage::~SfxTabPage() 284 285 /* [Beschreibung] 286 287 Destruktor 288 */ 289 290 { 291 #if !ENABLE_LAYOUT 292 delete pImpl; 293 #endif /* ENABLE_LAYOUT */ 294 } 295 296 // ----------------------------------------------------------------------- 297 298 sal_Bool SfxTabPage::FillItemSet( SfxItemSet& rSet ) 299 { 300 return pImpl->maItemConn.DoFillItemSet( rSet, GetItemSet() ); 301 } 302 303 // ----------------------------------------------------------------------- 304 305 void SfxTabPage::Reset( const SfxItemSet& rSet ) 306 { 307 pImpl->maItemConn.DoApplyFlags( rSet ); 308 pImpl->maItemConn.DoReset( rSet ); 309 } 310 311 // ----------------------------------------------------------------------- 312 313 void SfxTabPage::ActivatePage( const SfxItemSet& ) 314 315 /* [Beschreibung] 316 317 Defaultimplementierung der virtuellen ActivatePage-Methode 318 Diese wird gerufen, wenn eine Seite des Dialogs den Datenaustausch 319 zwischen Pages unterst"utzt. 320 321 <SfxTabPage::DeactivatePage(SfxItemSet *)> 322 */ 323 324 { 325 } 326 327 // ----------------------------------------------------------------------- 328 329 int SfxTabPage::DeactivatePage( SfxItemSet* ) 330 331 /* [Beschreibung] 332 333 Defaultimplementierung der virtuellen DeactivatePage-Methode 334 Diese wird vor dem Verlassen einer Seite durch den Sfx gerufen; 335 die Anwendung kann "uber den Returnwert steuern, 336 ob die Seite verlassen werden soll. 337 Falls die Seite "uber bHasExchangeSupport 338 anzeigt, da\s sie einen Datenaustausch zwischen Seiten 339 unterst"utzt, wird ein Pointer auf das Austausch-Set als 340 Parameter "ubergeben. Dieser nimmt die Daten f"ur den Austausch 341 entgegen; das Set steht anschlie\send als Parameter in 342 <SfxTabPage::ActivatePage(const SfxItemSet &)> zur Verf"ugung. 343 344 [R"uckgabewert] 345 346 LEAVE_PAGE; Verlassen der Seite erlauben 347 */ 348 349 { 350 return LEAVE_PAGE; 351 } 352 353 // ----------------------------------------------------------------------- 354 355 void SfxTabPage::FillUserData() 356 357 /* [Beschreibung] 358 359 virtuelle Methode, wird von der Basisklasse im Destruktor gerufen 360 um spezielle Informationen der TabPage in der Ini-Datei zu speichern. 361 Beim "Uberladen muss ein String zusammengestellt werden, der mit 362 <SetUserData()> dann weggeschrieben wird. 363 */ 364 365 { 366 } 367 368 // ----------------------------------------------------------------------- 369 370 sal_Bool SfxTabPage::IsReadOnly() const 371 372 /* [Description] 373 374 */ 375 376 { 377 return sal_False; 378 } 379 380 // ----------------------------------------------------------------------- 381 382 const SfxPoolItem* SfxTabPage::GetItem( const SfxItemSet& rSet, sal_uInt16 nSlot, sal_Bool bDeep ) 383 384 /* [Beschreibung] 385 386 static Methode: hiermit wird der Code der TabPage-Implementierungen 387 vereinfacht. 388 389 */ 390 391 { 392 const SfxItemPool* pPool = rSet.GetPool(); 393 sal_uInt16 nWh = pPool->GetWhich( nSlot, bDeep ); 394 const SfxPoolItem* pItem = 0; 395 #ifdef DEBUG 396 SfxItemState eState; 397 eState = 398 #endif 399 rSet.GetItemState( nWh, sal_True, &pItem ); // -Wall required?? 400 401 if ( !pItem && nWh != nSlot ) 402 pItem = &pPool->GetDefaultItem( nWh ); 403 return pItem; 404 } 405 406 // ----------------------------------------------------------------------- 407 408 const SfxPoolItem* SfxTabPage::GetOldItem( const SfxItemSet& rSet, 409 sal_uInt16 nSlot, sal_Bool bDeep ) 410 411 /* [Beschreibung] 412 413 Diese Methode gibt f"ur Vergleiche den alten Wert eines 414 Attributs zur"uck. 415 */ 416 417 { 418 const SfxItemSet& rOldSet = GetItemSet(); 419 sal_uInt16 nWh = GetWhich( nSlot, bDeep ); 420 const SfxPoolItem* pItem = 0; 421 422 if ( pImpl->mbStandard && rOldSet.GetParent() ) 423 pItem = GetItem( *rOldSet.GetParent(), nSlot ); 424 else if ( rSet.GetParent() && 425 SFX_ITEM_DONTCARE == rSet.GetItemState( nWh ) ) 426 pItem = GetItem( *rSet.GetParent(), nSlot ); 427 else 428 pItem = GetItem( rOldSet, nSlot ); 429 return pItem; 430 } 431 432 // ----------------------------------------------------------------------- 433 434 const SfxPoolItem* SfxTabPage::GetExchangeItem( const SfxItemSet& rSet, 435 sal_uInt16 nSlot ) 436 437 /* [Beschreibung] 438 439 Diese Methode gibt f"ur Vergleiche den alten Wert eines 440 Attributs zur"uck. Dabei wird ber"ucksichtigt, ob der Dialog 441 gerade mit OK beendet wurde. 442 */ 443 444 { 445 if ( pTabDlg && !pTabDlg->IsInOK() && pTabDlg->GetExampleSet() ) 446 return GetItem( *pTabDlg->GetExampleSet(), nSlot ); 447 else 448 return GetOldItem( rSet, nSlot ); 449 } 450 451 // add CHINA001 begin 452 void SfxTabPage::PageCreated( SfxAllItemSet /*aSet*/ ) 453 { 454 DBG_ASSERT(0, "SfxTabPage::PageCreated should not be called"); 455 }//CHINA001 456 // add CHINA001 end 457 458 // ----------------------------------------------------------------------- 459 460 void SfxTabPage::AddItemConnection( sfx::ItemConnectionBase* pConnection ) 461 { 462 pImpl->maItemConn.AddConnection( pConnection ); 463 } 464 465 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 466 467 #if ENABLE_LAYOUT_SFX_TABDIALOG 468 #undef ResId 469 #define ResId(id, foo) #id 470 #undef TabDialog 471 #define TabDialog(parent, res_id) Dialog (parent, "tab-dialog.xml", "tab-dialog") 472 473 #define aOKBtn(this) aOKBtn (this, "BTN_OK") 474 #undef PushButton 475 #define PushButton(this) layout::PushButton (this, "BTN_USER") 476 #define aCancelBtn(this) aCancelBtn (this, "BTN_CANCEL") 477 #define aHelpBtn(this) aHelpBtn (this, "BTN_HELP") 478 #define aResetBtn(this) aResetBtn (this, "BTN_RESET") 479 #define aBaseFmtBtn(this) aBaseFmtBtn (this, "BTN_BASEFMT") 480 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 481 482 #define INI_LIST(ItemSetPtr) \ 483 aTabCtrl ( this, ResId(ID_TABCONTROL,*rResId.GetResMgr() ) ),\ 484 aOKBtn ( this ),\ 485 pUserBtn ( pUserButtonText? new PushButton(this): 0 ),\ 486 aCancelBtn ( this ),\ 487 aHelpBtn ( this ),\ 488 aResetBtn ( this ),\ 489 aBaseFmtBtn ( this ),\ 490 pSet ( ItemSetPtr ),\ 491 pOutSet ( 0 ),\ 492 pImpl ( new TabDlg_Impl( (sal_uInt8)aTabCtrl.GetPageCount() ) ), \ 493 pRanges ( 0 ), \ 494 nResId ( rResId.GetId() ), \ 495 nAppPageId ( USHRT_MAX ), \ 496 bItemsReset ( sal_False ),\ 497 bFmt ( bEditFmt ),\ 498 pExampleSet ( 0 ) 499 500 // ----------------------------------------------------------------------- 501 502 SfxTabDialog::SfxTabDialog 503 504 /* [Beschreibung] 505 506 Konstruktor 507 */ 508 509 ( 510 SfxViewFrame* pViewFrame, // Frame, zu dem der Dialog geh"ort 511 Window* pParent, // Parent-Fenster 512 const ResId& rResId, // ResourceId 513 const SfxItemSet* pItemSet, // Itemset mit den Daten; 514 // kann NULL sein, wenn Pages onDemand 515 sal_Bool bEditFmt, // Flag: es werden Vorlagen bearbeitet 516 // wenn ja -> zus"atzlicher Button f"ur Standard 517 const String* pUserButtonText // Text fuer BenutzerButton; 518 // wenn != 0, wird der UserButton erzeugt 519 ) : 520 TabDialog( pParent, rResId ), 521 pFrame( pViewFrame ), 522 INI_LIST(pItemSet) 523 { 524 Init_Impl( bFmt, pUserButtonText ); 525 } 526 527 // ----------------------------------------------------------------------- 528 529 SfxTabDialog::SfxTabDialog 530 531 /* [Beschreibung] 532 533 Konstruktor, tempor"ar ohne Frame 534 */ 535 536 ( 537 Window* pParent, // Parent-Fenster 538 const ResId& rResId, // ResourceId 539 const SfxItemSet* pItemSet, // Itemset mit den Daten; kann NULL sein, 540 // wenn Pages onDemand 541 sal_Bool bEditFmt, // Flag: es werden Vorlagen bearbeitet 542 // wenn ja -> zus"atzlicher Button f"ur Standard 543 const String* pUserButtonText // Text f"ur BenutzerButton; 544 // wenn != 0, wird der UserButton erzeugt 545 ) : 546 TabDialog( pParent, rResId ), 547 pFrame( 0 ), 548 INI_LIST(pItemSet) 549 { 550 Init_Impl( bFmt, pUserButtonText ); 551 DBG_WARNING( "bitte den Ctor mit ViewFrame verwenden" ); 552 } 553 554 SfxTabDialog::SfxTabDialog 555 556 /* [Beschreibung] 557 558 Konstruktor, tempor"ar ohne Frame 559 */ 560 561 ( 562 Window* pParent, // Parent-Fenster 563 const ResId& rResId, // ResourceId 564 sal_uInt16 nSetId, 565 SfxBindings& rBindings, 566 sal_Bool bEditFmt, // Flag: es werden Vorlagen bearbeitet 567 // wenn ja -> zus"atzlicher Button f"ur Standard 568 const String* pUserButtonText // Text f"ur BenutzerButton; 569 // wenn != 0, wird der UserButton erzeugt 570 ) : 571 TabDialog( pParent, rResId ), 572 pFrame( 0 ), 573 INI_LIST(NULL) 574 { 575 rBindings.ENTERREGISTRATIONS(); 576 pImpl->pController = new SfxTabDialogController( nSetId, rBindings, this ); 577 rBindings.LEAVEREGISTRATIONS(); 578 579 EnableApplyButton( sal_True ); 580 SetApplyHandler( LINK( pImpl->pController, SfxTabDialogController, Execute_Impl ) ); 581 582 rBindings.Invalidate( nSetId ); 583 rBindings.Update( nSetId ); 584 DBG_ASSERT( pSet, "No ItemSet!" ); 585 586 Init_Impl( bFmt, pUserButtonText ); 587 } 588 589 // ----------------------------------------------------------------------- 590 591 #if ENABLE_LAYOUT_SFX_TABDIALOG 592 #undef ResId 593 #undef TabDialog 594 #undef aOKBtn 595 #undef PushButton 596 #undef aCancelBtn 597 #undef aHelpBtn 598 #undef aResetBtn 599 #undef aBaseFmtBtn 600 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 601 602 SfxTabDialog::~SfxTabDialog() 603 { 604 // save settings (screen position and current page) 605 SvtViewOptions aDlgOpt( E_TABDIALOG, String::CreateFromInt32( nResId ) ); 606 #if !ENABLE_LAYOUT_SFX_TABDIALOG 607 aDlgOpt.SetWindowState( OUString::createFromAscii( GetWindowState( WINDOWSTATE_MASK_POS ).GetBuffer() ) ); 608 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 609 aDlgOpt.SetPageID( aTabCtrl.GetCurPageId() ); 610 611 const sal_uInt16 nCount = pImpl->pData->Count(); 612 for ( sal_uInt16 i = 0; i < nCount; ++i ) 613 { 614 Data_Impl* pDataObject = pImpl->pData->GetObject(i); 615 616 if ( pDataObject->pTabPage ) 617 { 618 // save settings of all pages (user data) 619 pDataObject->pTabPage->FillUserData(); 620 String aPageData( pDataObject->pTabPage->GetUserData() ); 621 if ( aPageData.Len() ) 622 { 623 // save settings of all pages (user data) 624 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) ); 625 aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aPageData ) ) ); 626 } 627 628 if ( pDataObject->bOnDemand ) 629 delete (SfxItemSet*)&pDataObject->pTabPage->GetItemSet(); 630 delete pDataObject->pTabPage; 631 } 632 delete pDataObject; 633 } 634 635 delete pImpl->pController; 636 delete pImpl->pApplyButton; 637 delete pImpl->pData; 638 delete pImpl; 639 delete pUserBtn; 640 delete pOutSet; 641 delete pExampleSet; 642 delete [] pRanges; 643 } 644 645 // ----------------------------------------------------------------------- 646 647 void SfxTabDialog::Init_Impl( sal_Bool bFmtFlag, const String* pUserButtonText ) 648 649 /* [Beschreibung] 650 651 interne Initialisierung des Dialogs 652 */ 653 654 { 655 aOKBtn.SetClickHdl( LINK( this, SfxTabDialog, OkHdl ) ); 656 aResetBtn.SetClickHdl( LINK( this, SfxTabDialog, ResetHdl ) ); 657 aResetBtn.SetText( String( SfxResId( STR_RESET ) ) ); 658 aTabCtrl.SetActivatePageHdl( 659 LINK( this, SfxTabDialog, ActivatePageHdl ) ); 660 aTabCtrl.SetDeactivatePageHdl( 661 LINK( this, SfxTabDialog, DeactivatePageHdl ) ); 662 aTabCtrl.Show(); 663 aOKBtn.Show(); 664 aCancelBtn.Show(); 665 aHelpBtn.Show(); 666 aResetBtn.Show(); 667 aResetBtn.SetHelpId( HID_TABDLG_RESET_BTN ); 668 669 if ( pUserBtn ) 670 { 671 pUserBtn->SetText( *pUserButtonText ); 672 pUserBtn->SetClickHdl( LINK( this, SfxTabDialog, UserHdl ) ); 673 pUserBtn->Show(); 674 } 675 676 /* TODO: Check what is up with bFmt/bFmtFlag. Comment below suggests a 677 different behavior than implemented!! */ 678 if ( bFmtFlag ) 679 { 680 String aStd( SfxResId( STR_STANDARD_SHORTCUT ) ); 681 aBaseFmtBtn.SetText( aStd ); 682 aBaseFmtBtn.SetClickHdl( LINK( this, SfxTabDialog, BaseFmtHdl ) ); 683 aBaseFmtBtn.SetHelpId( HID_TABDLG_STANDARD_BTN ); 684 685 // bFmt = tempor"ares Flag im Ctor() "ubergeben, 686 // wenn bFmt == 2, dann auch sal_True, 687 // zus"atzlich Ausblendung vom StandardButton, 688 // nach der Initialisierung wieder auf sal_True setzen 689 if ( bFmtFlag != 2 ) 690 aBaseFmtBtn.Show(); 691 else 692 bFmtFlag = sal_True; 693 } 694 695 if ( pSet ) 696 { 697 pExampleSet = new SfxItemSet( *pSet ); 698 pOutSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ); 699 } 700 701 aOKBtn.SetAccessibleRelationMemberOf( &aOKBtn ); 702 aCancelBtn.SetAccessibleRelationMemberOf( &aCancelBtn ); 703 aHelpBtn.SetAccessibleRelationMemberOf( &aHelpBtn ); 704 aResetBtn.SetAccessibleRelationMemberOf( &aResetBtn ); 705 } 706 707 // ----------------------------------------------------------------------- 708 709 void SfxTabDialog::RemoveResetButton() 710 { 711 aResetBtn.Hide(); 712 pImpl->bHideResetBtn = sal_True; 713 } 714 715 // ----------------------------------------------------------------------- 716 717 #if ENABLE_LAYOUT_SFX_TABDIALOG 718 #undef TabDialog 719 #define TabDialog Dialog 720 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 721 722 short SfxTabDialog::Execute() 723 { 724 if ( !aTabCtrl.GetPageCount() ) 725 return RET_CANCEL; 726 Start_Impl(); 727 return TabDialog::Execute(); 728 } 729 730 // ----------------------------------------------------------------------- 731 732 void SfxTabDialog::StartExecuteModal( const Link& rEndDialogHdl ) 733 { 734 #if !ENABLE_LAYOUT_SFX_TABDIALOG 735 if ( !aTabCtrl.GetPageCount() ) 736 return; 737 Start_Impl(); 738 TabDialog::StartExecuteModal( rEndDialogHdl ); 739 #else 740 rEndDialogHdl.IsSet(); 741 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 742 } 743 744 // ----------------------------------------------------------------------- 745 746 void SfxTabDialog::Start( sal_Bool bShow ) 747 { 748 aCancelBtn.SetClickHdl( LINK( this, SfxTabDialog, CancelHdl ) ); 749 pImpl->bModal = sal_False; 750 Start_Impl(); 751 752 if ( bShow ) 753 Show(); 754 } 755 756 // ----------------------------------------------------------------------- 757 758 void SfxTabDialog::SetApplyHandler(const Link& _rHdl) 759 { 760 DBG_ASSERT( pImpl->pApplyButton, "SfxTabDialog::GetApplyHandler: no apply button enabled!" ); 761 if ( pImpl->pApplyButton ) 762 pImpl->pApplyButton->SetClickHdl( _rHdl ); 763 } 764 765 // ----------------------------------------------------------------------- 766 767 Link SfxTabDialog::GetApplyHandler() const 768 { 769 DBG_ASSERT( pImpl->pApplyButton, "SfxTabDialog::GetApplyHandler: no button enabled!" ); 770 if ( !pImpl->pApplyButton ) 771 return Link(); 772 773 return pImpl->pApplyButton->GetClickHdl(); 774 } 775 776 // ----------------------------------------------------------------------- 777 778 void SfxTabDialog::EnableApplyButton(sal_Bool bEnable) 779 { 780 if ( IsApplyButtonEnabled() == bEnable ) 781 // nothing to do 782 return; 783 784 // create or remove the apply button 785 if ( bEnable ) 786 { 787 pImpl->pApplyButton = new PushButton( this ); 788 #if !ENABLE_LAYOUT_SFX_TABDIALOG 789 // in the z-order, the apply button should be behind the ok button, thus appearing at the right side of it 790 pImpl->pApplyButton->SetZOrder(&aOKBtn, WINDOW_ZORDER_BEHIND); 791 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 792 pImpl->pApplyButton->SetText( String( SfxResId( STR_APPLY ) ) ); 793 pImpl->pApplyButton->Show(); 794 795 pImpl->pApplyButton->SetHelpId( HID_TABDLG_APPLY_BTN ); 796 } 797 else 798 { 799 delete pImpl->pApplyButton; 800 pImpl->pApplyButton = NULL; 801 } 802 803 #if !ENABLE_LAYOUT_SFX_TABDIALOG 804 // adjust the layout 805 if (IsReallyShown()) 806 AdjustLayout(); 807 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 808 } 809 810 // ----------------------------------------------------------------------- 811 812 sal_Bool SfxTabDialog::IsApplyButtonEnabled() const 813 { 814 return ( NULL != pImpl->pApplyButton ); 815 } 816 817 // ----------------------------------------------------------------------- 818 819 const PushButton* SfxTabDialog::GetApplyButton() const 820 { 821 return pImpl->pApplyButton; 822 } 823 824 // ----------------------------------------------------------------------- 825 826 PushButton* SfxTabDialog::GetApplyButton() 827 { 828 return pImpl->pApplyButton; 829 } 830 831 // ----------------------------------------------------------------------- 832 833 void SfxTabDialog::Start_Impl() 834 { 835 DBG_ASSERT( pImpl->pData->Count() == aTabCtrl.GetPageCount(), "not all pages registered" ); 836 sal_uInt16 nActPage = aTabCtrl.GetPageId( 0 ); 837 838 // load old settings, when exists 839 SvtViewOptions aDlgOpt( E_TABDIALOG, String::CreateFromInt32( nResId ) ); 840 if ( aDlgOpt.Exists() ) 841 { 842 #if !ENABLE_LAYOUT_SFX_TABDIALOG 843 SetWindowState( ByteString( aDlgOpt.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US ) ); 844 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 845 846 // initiale TabPage aus Programm/Hilfe/Konfig 847 nActPage = (sal_uInt16)aDlgOpt.GetPageID(); 848 849 if ( USHRT_MAX != nAppPageId ) 850 nActPage = nAppPageId; 851 else 852 { 853 sal_uInt16 nAutoTabPageId = SFX_APP()->Get_Impl()->nAutoTabPageId; 854 if ( nAutoTabPageId ) 855 nActPage = nAutoTabPageId; 856 } 857 858 if ( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nActPage ) ) 859 nActPage = aTabCtrl.GetPageId( 0 ); 860 } 861 else if ( USHRT_MAX != nAppPageId && TAB_PAGE_NOTFOUND != aTabCtrl.GetPagePos( nAppPageId ) ) 862 nActPage = nAppPageId; 863 864 aTabCtrl.SetCurPageId( nActPage ); 865 ActivatePageHdl( &aTabCtrl ); 866 } 867 868 void SfxTabDialog::AddTabPage( sal_uInt16 nId, sal_Bool bItemsOnDemand ) 869 { 870 AddTabPage( nId, 0, 0, bItemsOnDemand ); 871 } 872 873 void SfxTabDialog::AddTabPage( sal_uInt16 nId, const String &rRiderText, sal_Bool bItemsOnDemand, sal_uInt16 nPos ) 874 { 875 AddTabPage( nId, rRiderText, 0, 0, bItemsOnDemand, nPos ); 876 } 877 878 #ifdef SV_HAS_RIDERBITMAPS 879 880 void SfxTabDialog::AddTabPage( sal_uInt16 nId, const Bitmap &rRiderBitmap, sal_Bool bItemsOnDemand, sal_uInt16 nPos ) 881 { 882 AddTabPage( nId, rRiderBitmap, 0, 0, bItemsOnDemand, nPos ); 883 } 884 885 #endif 886 887 // ----------------------------------------------------------------------- 888 889 void SfxTabDialog::AddTabPage 890 891 /* [Beschreibung] 892 893 Hinzuf"ugen einer Seite zu dem Dialog. 894 Mu\s korrespondieren zu einem entsprechende Eintrag im 895 TabControl in der Resource des Dialogs. 896 */ 897 898 ( 899 sal_uInt16 nId, // ID der Seite 900 CreateTabPage pCreateFunc, // Pointer auf die Factory-Methode 901 GetTabPageRanges pRangesFunc, // Pointer auf die Methode f"ur das 902 // Erfragen der Ranges onDemand 903 sal_Bool bItemsOnDemand // gibt an, ob das Set dieser Seite beim 904 // Erzeugen der Seite erfragt wird 905 ) 906 { 907 pImpl->pData->Append( 908 new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) ); 909 } 910 911 // ----------------------------------------------------------------------- 912 913 void SfxTabDialog::AddTabPage 914 915 /* [Beschreibung] 916 917 Hinzuf"ugen einer Seite zu dem Dialog. 918 Der Ridertext wird "ubergeben, die Seite hat keine Entsprechung im 919 TabControl in der Resource des Dialogs. 920 */ 921 922 ( 923 sal_uInt16 nId, 924 const String& rRiderText, 925 CreateTabPage pCreateFunc, 926 GetTabPageRanges pRangesFunc, 927 sal_Bool bItemsOnDemand, 928 sal_uInt16 nPos 929 ) 930 { 931 DBG_ASSERT( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nId ), 932 "Doppelte Page-Ids in der Tabpage" ); 933 aTabCtrl.InsertPage( nId, rRiderText, nPos ); 934 pImpl->pData->Append( 935 new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) ); 936 } 937 938 // ----------------------------------------------------------------------- 939 #ifdef SV_HAS_RIDERBITMAPS 940 941 void SfxTabDialog::AddTabPage 942 943 /* [Beschreibung] 944 945 Hinzuf"ugen einer Seite zu dem Dialog. 946 Die Riderbitmap wird "ubergeben, die Seite hat keine Entsprechung im 947 TabControl in der Resource des Dialogs. 948 */ 949 950 ( 951 sal_uInt16 nId, 952 const Bitmap &rRiderBitmap, 953 CreateTabPage pCreateFunc, 954 GetTabPageRanges pRangesFunc, 955 sal_Bool bItemsOnDemand, 956 sal_uInt16 nPos 957 ) 958 { 959 DBG_ASSERT( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nId ), 960 "Doppelte Page-Ids in der Tabpage" ); 961 aTabCtrl.InsertPage( nId, rRiderBitmap, nPos ); 962 pImpl->pData->Append( 963 new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) ); 964 } 965 #endif 966 967 // ----------------------------------------------------------------------- 968 969 void SfxTabDialog::RemoveTabPage( sal_uInt16 nId ) 970 971 /* [Beschreibung] 972 973 L"oschen der TabPage mit der ID nId 974 */ 975 976 { 977 sal_uInt16 nPos = 0; 978 aTabCtrl.RemovePage( nId ); 979 Data_Impl* pDataObject = Find( *pImpl->pData, nId, &nPos ); 980 981 if ( pDataObject ) 982 { 983 if ( pDataObject->pTabPage ) 984 { 985 pDataObject->pTabPage->FillUserData(); 986 String aPageData( pDataObject->pTabPage->GetUserData() ); 987 if ( aPageData.Len() ) 988 { 989 // save settings of this page (user data) 990 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) ); 991 aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aPageData ) ) ); 992 } 993 994 if ( pDataObject->bOnDemand ) 995 delete (SfxItemSet*)&pDataObject->pTabPage->GetItemSet(); 996 delete pDataObject->pTabPage; 997 } 998 999 delete pDataObject; 1000 pImpl->pData->Remove( nPos ); 1001 } 1002 else 1003 { 1004 DBG_WARNINGFILE( "TabPage-Id nicht bekannt" ); 1005 } 1006 } 1007 1008 // ----------------------------------------------------------------------- 1009 1010 void SfxTabDialog::PageCreated 1011 1012 /* [Beschreibung] 1013 1014 Defaultimplemetierung der virtuellen Methode. 1015 Diese wird unmittelbar nach dem Erzeugen einer Seite gerufen. 1016 Hier kann der Dialog direkt an der TabPage Methoden rufen. 1017 */ 1018 1019 ( 1020 sal_uInt16, // Id der erzeugten Seite 1021 SfxTabPage& // Referenz auf die erzeugte Seite 1022 ) 1023 { 1024 } 1025 1026 // ----------------------------------------------------------------------- 1027 1028 SfxItemSet* SfxTabDialog::GetInputSetImpl() 1029 1030 /* [Beschreibung] 1031 1032 Abgeleitete Klassen legen ggf. fuer den InputSet neuen Speicher an. 1033 Dieser mu\s im Destruktor auch wieder freigegeben werden. Dazu mu\s 1034 diese Methode gerufen werden. 1035 */ 1036 1037 { 1038 return (SfxItemSet*)pSet; 1039 } 1040 1041 // ----------------------------------------------------------------------- 1042 1043 SfxTabPage* SfxTabDialog::GetTabPage( sal_uInt16 nPageId ) const 1044 1045 /* [Beschreibung] 1046 1047 TabPage mit der "Ubergebenen Id zur"uckgeben. 1048 */ 1049 1050 { 1051 sal_uInt16 nPos = 0; 1052 Data_Impl* pDataObject = Find( *pImpl->pData, nPageId, &nPos ); 1053 1054 if ( pDataObject ) 1055 return pDataObject->pTabPage; 1056 return NULL; 1057 } 1058 1059 // ----------------------------------------------------------------------- 1060 1061 sal_Bool SfxTabDialog::IsInOK() const 1062 1063 /* [Beschreibung] 1064 1065 */ 1066 1067 { 1068 return pImpl->bInOK; 1069 } 1070 1071 // ----------------------------------------------------------------------- 1072 1073 short SfxTabDialog::Ok() 1074 1075 /* [Beschreibung] 1076 1077 Ok-Handler des Dialogs 1078 Das OutputSet wird erstellt und jede Seite wird mit 1079 dem bzw. ihrem speziellen OutputSet durch Aufruf der Methode 1080 <SfxTabPage::FillItemSet(SfxItemSet &)> dazu aufgefordert, 1081 die vom Benuzter eingestellten Daten in das Set zu tun. 1082 1083 [R"uckgabewert] 1084 1085 RET_OK: wenn mindestens eine Seite sal_True als Returnwert von 1086 FillItemSet geliefert hat, sonst RET_CANCEL. 1087 */ 1088 1089 { 1090 pImpl->bInOK = sal_True; 1091 1092 if ( !pOutSet ) 1093 { 1094 if ( !pExampleSet && pSet ) 1095 pOutSet = pSet->Clone( sal_False ); // ohne Items 1096 else if ( pExampleSet ) 1097 pOutSet = new SfxItemSet( *pExampleSet ); 1098 } 1099 sal_Bool bModified = sal_False; 1100 1101 const sal_uInt16 nCount = pImpl->pData->Count(); 1102 1103 for ( sal_uInt16 i = 0; i < nCount; ++i ) 1104 { 1105 Data_Impl* pDataObject = pImpl->pData->GetObject(i); 1106 SfxTabPage* pTabPage = pDataObject->pTabPage; 1107 1108 if ( pTabPage ) 1109 { 1110 if ( pDataObject->bOnDemand ) 1111 { 1112 SfxItemSet& rSet = (SfxItemSet&)pTabPage->GetItemSet(); 1113 rSet.ClearItem(); 1114 bModified |= pTabPage->FillItemSet( rSet ); 1115 } 1116 else if ( pSet && !pTabPage->HasExchangeSupport() ) 1117 { 1118 SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() ); 1119 1120 if ( pTabPage->FillItemSet( aTmp ) ) 1121 { 1122 bModified |= sal_True; 1123 pExampleSet->Put( aTmp ); 1124 pOutSet->Put( aTmp ); 1125 } 1126 } 1127 } 1128 } 1129 1130 if ( pImpl->bModified || ( pOutSet && pOutSet->Count() > 0 ) ) 1131 bModified |= sal_True; 1132 1133 if ( bFmt == 2 ) 1134 bModified |= sal_True; 1135 return bModified ? RET_OK : RET_CANCEL; 1136 } 1137 1138 // ----------------------------------------------------------------------- 1139 1140 IMPL_LINK( SfxTabDialog, CancelHdl, Button*, pButton ) 1141 { 1142 (void)pButton; //unused 1143 Close(); 1144 return 0; 1145 } 1146 1147 // ----------------------------------------------------------------------- 1148 1149 SfxItemSet* SfxTabDialog::CreateInputItemSet( sal_uInt16 ) 1150 1151 /* [Beschreibung] 1152 1153 Defaultimplemetierung der virtuellen Methode. 1154 Diese wird gerufen, wenn Pages ihre Sets onDenamd anlegen 1155 */ 1156 1157 { 1158 DBG_WARNINGFILE( "CreateInputItemSet nicht implementiert" ); 1159 return new SfxAllItemSet( SFX_APP()->GetPool() ); 1160 } 1161 1162 // ----------------------------------------------------------------------- 1163 1164 const SfxItemSet* SfxTabDialog::GetRefreshedSet() 1165 1166 /* [Beschreibung] 1167 1168 Defaultimplemetierung der virtuellen Methode. 1169 Diese wird gerufen, wenn <SfxTabPage::DeactivatePage(SfxItemSet *)> 1170 <SfxTabPage::REFRESH_SET> liefert. 1171 */ 1172 1173 { 1174 DBG_ERRORFILE( "GetRefreshedSet nicht implementiert" ); 1175 return 0; 1176 } 1177 1178 // ----------------------------------------------------------------------- 1179 1180 IMPL_LINK( SfxTabDialog, OkHdl, Button *, EMPTYARG ) 1181 1182 /* [Beschreibung] 1183 1184 Handler des Ok-Buttons 1185 Dieser ruft f"ur die aktuelle Seite 1186 <SfxTabPage::DeactivatePage(SfxItemSet *)>. 1187 Liefert diese <SfxTabPage::LEAVE_PAGE>, wird <SfxTabDialog::Ok()> gerufen 1188 und so der Dialog beendet. 1189 */ 1190 1191 { 1192 pImpl->bInOK = sal_True; 1193 1194 if ( OK_Impl() ) 1195 { 1196 if ( pImpl->bModal ) 1197 EndDialog( Ok() ); 1198 else 1199 { 1200 Ok(); 1201 Close(); 1202 } 1203 } 1204 return 0; 1205 } 1206 1207 // ----------------------------------------------------------------------- 1208 1209 bool SfxTabDialog::PrepareLeaveCurrentPage() 1210 { 1211 sal_uInt16 const nId = aTabCtrl.GetCurPageId(); 1212 SfxTabPage* pPage = dynamic_cast<SfxTabPage*> (aTabCtrl.GetTabPage( nId )); 1213 bool bEnd = !pPage; 1214 1215 if ( pPage ) 1216 { 1217 int nRet = SfxTabPage::LEAVE_PAGE; 1218 if ( pSet ) 1219 { 1220 SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() ); 1221 1222 if ( pPage->HasExchangeSupport() ) 1223 nRet = pPage->DeactivatePage( &aTmp ); 1224 else 1225 nRet = pPage->DeactivatePage( NULL ); 1226 1227 if ( ( SfxTabPage::LEAVE_PAGE & nRet ) == SfxTabPage::LEAVE_PAGE 1228 && aTmp.Count() ) 1229 { 1230 pExampleSet->Put( aTmp ); 1231 pOutSet->Put( aTmp ); 1232 } 1233 } 1234 else 1235 nRet = pPage->DeactivatePage( NULL ); 1236 bEnd = nRet; 1237 } 1238 1239 return bEnd; 1240 } 1241 1242 1243 // ----------------------------------------------------------------------- 1244 1245 IMPL_LINK( SfxTabDialog, UserHdl, Button *, EMPTYARG ) 1246 1247 /* [Beschreibung] 1248 1249 Handler des User-Buttons 1250 Dieser ruft f"ur die aktuelle Seite 1251 <SfxTabPage::DeactivatePage(SfxItemSet *)>. 1252 Liefert diese <SfxTabPage::LEAVE_PAGE>, wird <SfxTabDialog::Ok()> gerufen. 1253 Mit dem Return-Wert von <SfxTabDialog::Ok()> wird dann der Dialog beendet. 1254 */ 1255 1256 { 1257 if ( PrepareLeaveCurrentPage () ) 1258 { 1259 short nRet = Ok(); 1260 1261 if ( RET_OK == nRet ) 1262 nRet = RET_USER; 1263 else 1264 nRet = RET_USER_CANCEL; 1265 EndDialog( nRet ); 1266 } 1267 return 0; 1268 } 1269 1270 // ----------------------------------------------------------------------- 1271 1272 IMPL_LINK( SfxTabDialog, ResetHdl, Button *, EMPTYARG ) 1273 1274 /* [Beschreibung] 1275 1276 Handler hinter dem Zur"ucksetzen-Button. 1277 Die aktuelle Page wird mit ihren initialen Daten 1278 neu initialisiert; alle Einstellungen, die der Benutzer 1279 auf dieser Seite get"atigt hat, werden aufgehoben. 1280 */ 1281 1282 { 1283 const sal_uInt16 nId = aTabCtrl.GetCurPageId(); 1284 Data_Impl* pDataObject = Find( *pImpl->pData, nId ); 1285 DBG_ASSERT( pDataObject, "Id nicht bekannt" ); 1286 1287 if ( pDataObject->bOnDemand ) 1288 { 1289 // CSet auf AIS hat hier Probleme, daher getrennt 1290 const SfxItemSet* pItemSet = &pDataObject->pTabPage->GetItemSet(); 1291 pDataObject->pTabPage->Reset( *(SfxItemSet*)pItemSet ); 1292 } 1293 else 1294 pDataObject->pTabPage->Reset( *pSet ); 1295 return 0; 1296 } 1297 1298 // ----------------------------------------------------------------------- 1299 1300 IMPL_LINK( SfxTabDialog, BaseFmtHdl, Button *, EMPTYARG ) 1301 1302 /* [Beschreibung] 1303 1304 Handler hinter dem Standard-Button. 1305 Dieser Button steht beim Bearbeiten von StyleSheets zur Verf"ugung. 1306 Alle in dem bearbeiteten StyleSheet eingestellten Attribute 1307 werden gel"oscht. 1308 */ 1309 1310 { 1311 const sal_uInt16 nId = aTabCtrl.GetCurPageId(); 1312 Data_Impl* pDataObject = Find( *pImpl->pData, nId ); 1313 DBG_ASSERT( pDataObject, "Id nicht bekannt" ); 1314 bFmt = 2; 1315 1316 if ( pDataObject->fnGetRanges ) 1317 { 1318 if ( !pExampleSet ) 1319 pExampleSet = new SfxItemSet( *pSet ); 1320 1321 const SfxItemPool* pPool = pSet->GetPool(); 1322 const sal_uInt16* pTmpRanges = (pDataObject->fnGetRanges)(); 1323 SfxItemSet aTmpSet( *pExampleSet ); 1324 1325 while ( *pTmpRanges ) 1326 { 1327 const sal_uInt16* pU = pTmpRanges + 1; 1328 1329 if ( *pTmpRanges == *pU ) 1330 { 1331 // Range mit zwei gleichen Werten -> nur ein Item setzen 1332 sal_uInt16 nWh = pPool->GetWhich( *pTmpRanges ); 1333 pExampleSet->ClearItem( nWh ); 1334 aTmpSet.ClearItem( nWh ); 1335 // am OutSet mit InvalidateItem, 1336 // damit die "Anderung wirksam wird 1337 pOutSet->InvalidateItem( nWh ); 1338 } 1339 else 1340 { 1341 // richtiger Range mit mehreren Werten 1342 sal_uInt16 nTmp = *pTmpRanges, nTmpEnd = *pU; 1343 DBG_ASSERT( nTmp <= nTmpEnd, "Range ist falsch sortiert" ); 1344 1345 if ( nTmp > nTmpEnd ) 1346 { 1347 // wenn wirklich falsch sortiert, dann neu setzen 1348 sal_uInt16 nTmp1 = nTmp; 1349 nTmp = nTmpEnd; 1350 nTmpEnd = nTmp1; 1351 } 1352 1353 while ( nTmp <= nTmpEnd ) 1354 { 1355 // "uber den Range iterieren, und die Items setzen 1356 sal_uInt16 nWh = pPool->GetWhich( nTmp ); 1357 pExampleSet->ClearItem( nWh ); 1358 aTmpSet.ClearItem( nWh ); 1359 // am OutSet mit InvalidateItem, 1360 // damit die "Anderung wirksam wird 1361 pOutSet->InvalidateItem( nWh ); 1362 nTmp++; 1363 } 1364 } 1365 // zum n"achsten Paar gehen 1366 pTmpRanges += 2; 1367 } 1368 // alle Items neu gesetzt -> dann an der aktuellen Page Reset() rufen 1369 DBG_ASSERT( pDataObject->pTabPage, "die Page ist weg" ); 1370 pDataObject->pTabPage->Reset( aTmpSet ); 1371 pDataObject->pTabPage->pImpl->mbStandard = sal_True; 1372 } 1373 return 1; 1374 } 1375 1376 // ----------------------------------------------------------------------- 1377 1378 #if ENABLE_LAYOUT_SFX_TABDIALOG 1379 #define tabControlWindow pTabCtrl->GetWindow () 1380 #else /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 1381 #define tabControlWindow pTabCtrl 1382 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 1383 1384 IMPL_LINK( SfxTabDialog, ActivatePageHdl, TabControl *, pTabCtrl ) 1385 1386 /* [Beschreibung] 1387 1388 Handler, der vor dem Umschalten auf eine andere Seite 1389 durch Starview gerufen wird. 1390 Existiert die Seite noch nicht, so wird sie erzeugt und 1391 die virtuelle Methode <SfxTabDialog::PageCreated( sal_uInt16, SfxTabPage &)> 1392 gerufen. Existiert die Seite bereits, so wird ggf. 1393 <SfxTabPage::Reset(const SfxItemSet &)> oder 1394 <SfxTabPage::ActivatePage(const SfxItemSet &)> gerufen. 1395 */ 1396 1397 { 1398 sal_uInt16 const nId = pTabCtrl->GetCurPageId(); 1399 1400 DBG_ASSERT( pImpl->pData->Count(), "keine Pages angemeldet" ); 1401 SFX_APP(); 1402 1403 // Tab Page schon da? 1404 SfxTabPage* pTabPage = dynamic_cast<SfxTabPage*> (pTabCtrl->GetTabPage( nId )); 1405 Data_Impl* pDataObject = Find( *pImpl->pData, nId ); 1406 DBG_ASSERT( pDataObject, "Id nicht bekannt" ); 1407 1408 // ggf. TabPage erzeugen: 1409 if ( !pTabPage ) 1410 { 1411 #if ENABLE_LAYOUT_SFX_TABDIALOG 1412 if (dynamic_cast<layout SfxTabPage*> (pTabPage)) 1413 layout::TabPage::global_parent = pTabCtrl->GetWindow (); 1414 #endif 1415 const SfxItemSet* pTmpSet = 0; 1416 1417 if ( pSet ) 1418 { 1419 if ( bItemsReset && pSet->GetParent() ) 1420 pTmpSet = pSet->GetParent(); 1421 else 1422 pTmpSet = pSet; 1423 } 1424 1425 if ( pTmpSet && !pDataObject->bOnDemand ) 1426 pTabPage = (pDataObject->fnCreatePage)( tabControlWindow, *pTmpSet ); 1427 else 1428 pTabPage = (pDataObject->fnCreatePage) 1429 ( tabControlWindow, *CreateInputItemSet( nId ) ); 1430 DBG_ASSERT( NULL == pDataObject->pTabPage, "create TabPage more than once" ); 1431 pDataObject->pTabPage = pTabPage; 1432 1433 #if !ENABLE_LAYOUT_SFX_TABDIALOG 1434 pDataObject->pTabPage->SetTabDialog( this ); 1435 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 1436 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) ); 1437 String sUserData; 1438 Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME ); 1439 OUString aTemp; 1440 if ( aUserItem >>= aTemp ) 1441 sUserData = String( aTemp ); 1442 pTabPage->SetUserData( sUserData ); 1443 Size aSiz = pTabPage->GetSizePixel(); 1444 1445 #if ENABLE_LAYOUT 1446 Size optimalSize = pTabPage->GetOptimalSize (WINDOWSIZE_MINIMUM); 1447 #if ENABLE_LAYOUT_SFX_TABDIALOG 1448 if (dynamic_cast<layout SfxTabPage*> (pTabPage)) 1449 { 1450 if (optimalSize.Height () && optimalSize.Width ()) 1451 { 1452 optimalSize.Width () = optimalSize.Width (); 1453 optimalSize.Height () = optimalSize.Height () + 40; 1454 } 1455 } 1456 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 1457 if (optimalSize.Height () > 0 && optimalSize.Width () > 0 ) 1458 aSiz = optimalSize; 1459 #endif /* ENABLE_LAYOUT */ 1460 1461 Size aCtrlSiz = pTabCtrl->GetTabPageSizePixel(); 1462 // Gr"o/se am TabControl nur dann setzen, wenn < als TabPage 1463 if ( aCtrlSiz.Width() < aSiz.Width() || 1464 aCtrlSiz.Height() < aSiz.Height() ) 1465 { 1466 pTabCtrl->SetTabPageSizePixel( aSiz ); 1467 } 1468 1469 PageCreated( nId, *pTabPage ); 1470 1471 if ( pDataObject->bOnDemand ) 1472 pTabPage->Reset( (SfxItemSet &)pTabPage->GetItemSet() ); 1473 else 1474 pTabPage->Reset( *pSet ); 1475 1476 pTabCtrl->SetTabPage( nId, pTabPage ); 1477 } 1478 else if ( pDataObject->bRefresh ) 1479 pTabPage->Reset( *pSet ); 1480 pDataObject->bRefresh = sal_False; 1481 1482 #if ENABLE_LAYOUT_SFX_TABDIALOG 1483 pTabCtrl->GetPagePos (nId); 1484 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 1485 1486 if ( pExampleSet ) 1487 pTabPage->ActivatePage( *pExampleSet ); 1488 sal_Bool bReadOnly = pTabPage->IsReadOnly(); 1489 ( bReadOnly || pImpl->bHideResetBtn ) ? aResetBtn.Hide() : aResetBtn.Show(); 1490 return 0; 1491 } 1492 1493 // ----------------------------------------------------------------------- 1494 1495 IMPL_LINK( SfxTabDialog, DeactivatePageHdl, TabControl *, pTabCtrl ) 1496 1497 /* [Beschreibung] 1498 1499 Handler, der vor dem Verlassen einer Seite durch Starview gerufen wird. 1500 1501 [Querverweise] 1502 1503 <SfxTabPage::DeactivatePage(SfxItemSet *)> 1504 */ 1505 1506 { 1507 sal_uInt16 nId = pTabCtrl->GetCurPageId(); 1508 SFX_APP(); 1509 SfxTabPage *pPage = dynamic_cast<SfxTabPage*> (pTabCtrl->GetTabPage( nId )); 1510 DBG_ASSERT( pPage, "keine aktive Page" ); 1511 #ifdef DBG_UTIL 1512 Data_Impl* pDataObject = Find( *pImpl->pData, pTabCtrl->GetCurPageId() ); 1513 DBG_ASSERT( pDataObject, "keine Datenstruktur zur aktuellen Seite" ); 1514 if ( pPage->HasExchangeSupport() && pDataObject->bOnDemand ) 1515 { 1516 DBG_WARNING( "Datenaustausch bei ItemsOnDemand ist nicht gewuenscht!" ); 1517 } 1518 #endif 1519 1520 int nRet = SfxTabPage::LEAVE_PAGE; 1521 1522 if ( !pExampleSet && pPage->HasExchangeSupport() && pSet ) 1523 pExampleSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ); 1524 1525 if ( pSet ) 1526 { 1527 SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() ); 1528 1529 if ( pPage->HasExchangeSupport() ) 1530 nRet = pPage->DeactivatePage( &aTmp ); 1531 else 1532 nRet = pPage->DeactivatePage( NULL ); 1533 //! else 1534 //! pPage->FillItemSet( aTmp ); 1535 1536 if ( ( SfxTabPage::LEAVE_PAGE & nRet ) == SfxTabPage::LEAVE_PAGE && 1537 aTmp.Count() ) 1538 { 1539 pExampleSet->Put( aTmp ); 1540 pOutSet->Put( aTmp ); 1541 } 1542 } 1543 else 1544 { 1545 if ( pPage->HasExchangeSupport() ) //!!! 1546 { 1547 if ( !pExampleSet ) 1548 { 1549 SfxItemPool* pPool = pPage->GetItemSet().GetPool(); 1550 pExampleSet = 1551 new SfxItemSet( *pPool, GetInputRanges( *pPool ) ); 1552 } 1553 nRet = pPage->DeactivatePage( pExampleSet ); 1554 } 1555 else 1556 nRet = pPage->DeactivatePage( NULL ); 1557 } 1558 1559 if ( nRet & SfxTabPage::REFRESH_SET ) 1560 { 1561 pSet = GetRefreshedSet(); 1562 DBG_ASSERT( pSet, "GetRefreshedSet() liefert NULL" ); 1563 // alle Pages als neu zu initialsieren flaggen 1564 const sal_uInt16 nCount = pImpl->pData->Count(); 1565 1566 for ( sal_uInt16 i = 0; i < nCount; ++i ) 1567 { 1568 Data_Impl* pObj = (*pImpl->pData)[i]; 1569 1570 if ( pObj->pTabPage != pPage ) // eigene Page nicht mehr refreshen 1571 pObj->bRefresh = sal_True; 1572 else 1573 pObj->bRefresh = sal_False; 1574 } 1575 } 1576 if ( nRet & SfxTabPage::LEAVE_PAGE ) 1577 return sal_True; 1578 else 1579 return sal_False; 1580 } 1581 1582 // ----------------------------------------------------------------------- 1583 1584 const SfxItemSet* SfxTabDialog::GetOutputItemSet 1585 1586 /* [Beschreibung] 1587 1588 Liefert die Pages, die ihre Sets onDemand liefern, das OutputItemSet. 1589 1590 [Querverweise] 1591 1592 <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, sal_Bool)> 1593 <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)> 1594 <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)> 1595 */ 1596 1597 ( 1598 sal_uInt16 nId // die Id, unter der die Seite bei AddTabPage() 1599 // hinzugef"ugt wurde. 1600 ) const 1601 { 1602 Data_Impl* pDataObject = Find( *pImpl->pData, nId ); 1603 DBG_ASSERT( pDataObject, "TabPage nicht gefunden" ); 1604 1605 if ( pDataObject ) 1606 { 1607 if ( !pDataObject->pTabPage ) 1608 return NULL; 1609 1610 if ( pDataObject->bOnDemand ) 1611 return &pDataObject->pTabPage->GetItemSet(); 1612 // else 1613 return pOutSet; 1614 } 1615 return NULL; 1616 } 1617 1618 // ----------------------------------------------------------------------- 1619 1620 int SfxTabDialog::FillOutputItemSet() 1621 { 1622 int nRet = SfxTabPage::LEAVE_PAGE; 1623 if ( OK_Impl() ) 1624 Ok(); 1625 else 1626 nRet = SfxTabPage::KEEP_PAGE; 1627 return nRet; 1628 } 1629 1630 // ----------------------------------------------------------------------- 1631 1632 #ifdef WNT 1633 int __cdecl TabDlgCmpUS_Impl( const void* p1, const void* p2 ) 1634 #else 1635 #if defined(OS2) && defined(ICC) 1636 int _Optlink TabDlgCmpUS_Impl( const void* p1, const void* p2 ) 1637 #else 1638 extern "C" int TabDlgCmpUS_Impl( const void* p1, const void* p2 ) 1639 #endif 1640 #endif 1641 1642 /* [Beschreibung] 1643 1644 Vergleichsfunktion f"ur qsort 1645 */ 1646 1647 { 1648 return *(sal_uInt16*)p1 - *(sal_uInt16*)p2; 1649 } 1650 1651 // ----------------------------------------------------------------------- 1652 1653 void SfxTabDialog::ShowPage( sal_uInt16 nId ) 1654 1655 /* [Beschreibung] 1656 1657 Es wird die TabPage mit der "ubergebenen Id aktiviert. 1658 */ 1659 1660 { 1661 aTabCtrl.SetCurPageId( nId ); 1662 ActivatePageHdl( &aTabCtrl ); 1663 } 1664 1665 // ----------------------------------------------------------------------- 1666 1667 const sal_uInt16* SfxTabDialog::GetInputRanges( const SfxItemPool& rPool ) 1668 1669 /* [Beschreibung] 1670 1671 Bildet das Set "uber die Ranges aller Seiten des Dialogs. 1672 Die Pages m"ussen die statische Methode f"ur das Erfragen ihrer 1673 Ranges bei AddTabPage angegeben haben, liefern also ihre Sets onDemand. 1674 1675 [Querverweise] 1676 1677 <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, sal_Bool)> 1678 <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)> 1679 <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)> 1680 1681 [R"uckgabewert] 1682 1683 Pointer auf nullterminiertes Array von USHORTs 1684 Dieses Array geh"ort dem Dialog und wird beim 1685 Zerst"oren des Dialogs gel"oscht. 1686 */ 1687 1688 { 1689 if ( pSet ) 1690 { 1691 DBG_ERRORFILE( "Set bereits vorhanden!" ); 1692 return pSet->GetRanges(); 1693 } 1694 1695 if ( pRanges ) 1696 return pRanges; 1697 SvUShorts aUS( 16, 16 ); 1698 sal_uInt16 nCount = pImpl->pData->Count(); 1699 1700 sal_uInt16 i; 1701 for ( i = 0; i < nCount; ++i ) 1702 { 1703 Data_Impl* pDataObject = pImpl->pData->GetObject(i); 1704 1705 if ( pDataObject->fnGetRanges ) 1706 { 1707 const sal_uInt16* pTmpRanges = (pDataObject->fnGetRanges)(); 1708 const sal_uInt16* pIter = pTmpRanges; 1709 1710 sal_uInt16 nLen; 1711 for( nLen = 0; *pIter; ++nLen, ++pIter ) 1712 ; 1713 aUS.Insert( pTmpRanges, nLen, aUS.Count() ); 1714 } 1715 } 1716 1717 //! Doppelte Ids entfernen? 1718 #ifndef TF_POOLABLE 1719 if ( rPool.HasMap() ) 1720 #endif 1721 { 1722 nCount = aUS.Count(); 1723 1724 for ( i = 0; i < nCount; ++i ) 1725 aUS[i] = rPool.GetWhich( aUS[i] ); 1726 } 1727 1728 // sortieren 1729 if ( aUS.Count() > 1 ) 1730 qsort( (void*)aUS.GetData(), 1731 aUS.Count(), sizeof(sal_uInt16), TabDlgCmpUS_Impl ); 1732 1733 // Ranges erzeugen 1734 //!! Auskommentiert, da fehlerhaft 1735 /* 1736 pRanges = new sal_uInt16[aUS.Count() * 2 + 1]; 1737 int j = 0; 1738 i = 0; 1739 1740 while ( i < aUS.Count() ) 1741 { 1742 pRanges[j++] = aUS[i]; 1743 // aufeinanderfolgende Zahlen 1744 for( ; i < aUS.Count()-1; ++i ) 1745 if ( aUS[i] + 1 != aUS[i+1] ) 1746 break; 1747 pRanges[j++] = aUS[i++]; 1748 } 1749 pRanges[j] = 0; // terminierende NULL 1750 */ 1751 1752 pRanges = new sal_uInt16[aUS.Count() + 1]; 1753 memcpy(pRanges, aUS.GetData(), sizeof(sal_uInt16) * aUS.Count()); 1754 pRanges[aUS.Count()] = 0; 1755 return pRanges; 1756 } 1757 1758 // ----------------------------------------------------------------------- 1759 1760 void SfxTabDialog::SetInputSet( const SfxItemSet* pInSet ) 1761 1762 /* [Beschreibung] 1763 1764 Mit dieser Methode kann nachtr"aglich der Input-Set initial oder 1765 neu gesetzt werden. 1766 */ 1767 1768 { 1769 bool bSet = ( pSet != NULL ); 1770 1771 pSet = pInSet; 1772 1773 if ( !bSet && !pExampleSet && !pOutSet ) 1774 { 1775 pExampleSet = new SfxItemSet( *pSet ); 1776 pOutSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ); 1777 } 1778 } 1779 1780 long SfxTabDialog::Notify( NotifyEvent& rNEvt ) 1781 { 1782 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 1783 { 1784 SfxViewFrame* pViewFrame = GetViewFrame() ? GetViewFrame() : SfxViewFrame::Current(); 1785 if ( pViewFrame ) 1786 { 1787 Window* pWindow = rNEvt.GetWindow(); 1788 rtl::OString sHelpId; 1789 while ( !sHelpId.getLength() && pWindow ) 1790 { 1791 sHelpId = pWindow->GetHelpId(); 1792 pWindow = pWindow->GetParent(); 1793 } 1794 1795 if ( sHelpId.getLength() ) 1796 SfxHelp::OpenHelpAgent( &pViewFrame->GetFrame(), sHelpId ); 1797 } 1798 } 1799 1800 return TabDialog::Notify( rNEvt ); 1801 } 1802 1803 END_NAMESPACE_LAYOUT_SFX_TABDIALOG 1804