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