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 752 // ----------------------------------------------------------------------- 753 754 void SfxTabDialog::SetApplyHandler(const Link& _rHdl) 755 { 756 DBG_ASSERT( pImpl->pApplyButton, "SfxTabDialog::GetApplyHandler: no apply button enabled!" ); 757 if ( pImpl->pApplyButton ) 758 pImpl->pApplyButton->SetClickHdl( _rHdl ); 759 } 760 761 // ----------------------------------------------------------------------- 762 763 Link SfxTabDialog::GetApplyHandler() const 764 { 765 DBG_ASSERT( pImpl->pApplyButton, "SfxTabDialog::GetApplyHandler: no button enabled!" ); 766 if ( !pImpl->pApplyButton ) 767 return Link(); 768 769 return pImpl->pApplyButton->GetClickHdl(); 770 } 771 772 // ----------------------------------------------------------------------- 773 774 void SfxTabDialog::EnableApplyButton(sal_Bool bEnable) 775 { 776 if ( IsApplyButtonEnabled() == bEnable ) 777 // nothing to do 778 return; 779 780 // create or remove the apply button 781 if ( bEnable ) 782 { 783 pImpl->pApplyButton = new PushButton( this ); 784 #if !ENABLE_LAYOUT_SFX_TABDIALOG 785 // in the z-order, the apply button should be behind the ok button, thus appearing at the right side of it 786 pImpl->pApplyButton->SetZOrder(&aOKBtn, WINDOW_ZORDER_BEHIND); 787 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 788 pImpl->pApplyButton->SetText( String( SfxResId( STR_APPLY ) ) ); 789 pImpl->pApplyButton->Show(); 790 791 pImpl->pApplyButton->SetHelpId( HID_TABDLG_APPLY_BTN ); 792 } 793 else 794 { 795 delete pImpl->pApplyButton; 796 pImpl->pApplyButton = NULL; 797 } 798 799 #if !ENABLE_LAYOUT_SFX_TABDIALOG 800 // adjust the layout 801 if (IsReallyShown()) 802 AdjustLayout(); 803 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 804 } 805 806 // ----------------------------------------------------------------------- 807 808 sal_Bool SfxTabDialog::IsApplyButtonEnabled() const 809 { 810 return ( NULL != pImpl->pApplyButton ); 811 } 812 813 // ----------------------------------------------------------------------- 814 815 const PushButton* SfxTabDialog::GetApplyButton() const 816 { 817 return pImpl->pApplyButton; 818 } 819 820 // ----------------------------------------------------------------------- 821 822 PushButton* SfxTabDialog::GetApplyButton() 823 { 824 return pImpl->pApplyButton; 825 } 826 827 // ----------------------------------------------------------------------- 828 829 void SfxTabDialog::Start_Impl() 830 { 831 DBG_ASSERT( pImpl->pData->Count() == aTabCtrl.GetPageCount(), "not all pages registered" ); 832 sal_uInt16 nActPage = aTabCtrl.GetPageId( 0 ); 833 834 // load old settings, when exists 835 SvtViewOptions aDlgOpt( E_TABDIALOG, String::CreateFromInt32( nResId ) ); 836 if ( aDlgOpt.Exists() ) 837 { 838 #if !ENABLE_LAYOUT_SFX_TABDIALOG 839 SetWindowState( ByteString( aDlgOpt.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US ) ); 840 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 841 842 // initiale TabPage aus Programm/Hilfe/Konfig 843 nActPage = (sal_uInt16)aDlgOpt.GetPageID(); 844 845 if ( USHRT_MAX != nAppPageId ) 846 nActPage = nAppPageId; 847 else 848 { 849 sal_uInt16 nAutoTabPageId = SFX_APP()->Get_Impl()->nAutoTabPageId; 850 if ( nAutoTabPageId ) 851 nActPage = nAutoTabPageId; 852 } 853 854 if ( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nActPage ) ) 855 nActPage = aTabCtrl.GetPageId( 0 ); 856 } 857 else if ( USHRT_MAX != nAppPageId && TAB_PAGE_NOTFOUND != aTabCtrl.GetPagePos( nAppPageId ) ) 858 nActPage = nAppPageId; 859 860 aTabCtrl.SetCurPageId( nActPage ); 861 ActivatePageHdl( &aTabCtrl ); 862 } 863 864 void SfxTabDialog::AddTabPage( sal_uInt16 nId, sal_Bool bItemsOnDemand ) 865 { 866 AddTabPage( nId, 0, 0, bItemsOnDemand ); 867 } 868 869 void SfxTabDialog::AddTabPage( sal_uInt16 nId, const String &rRiderText, sal_Bool bItemsOnDemand, sal_uInt16 nPos ) 870 { 871 AddTabPage( nId, rRiderText, 0, 0, bItemsOnDemand, nPos ); 872 } 873 874 #ifdef SV_HAS_RIDERBITMAPS 875 876 void SfxTabDialog::AddTabPage( sal_uInt16 nId, const Bitmap &rRiderBitmap, sal_Bool bItemsOnDemand, sal_uInt16 nPos ) 877 { 878 AddTabPage( nId, rRiderBitmap, 0, 0, bItemsOnDemand, nPos ); 879 } 880 881 #endif 882 883 // ----------------------------------------------------------------------- 884 885 void SfxTabDialog::AddTabPage 886 887 /* [Beschreibung] 888 889 Hinzuf"ugen einer Seite zu dem Dialog. 890 Mu\s korrespondieren zu einem entsprechende Eintrag im 891 TabControl in der Resource des Dialogs. 892 */ 893 894 ( 895 sal_uInt16 nId, // ID der Seite 896 CreateTabPage pCreateFunc, // Pointer auf die Factory-Methode 897 GetTabPageRanges pRangesFunc, // Pointer auf die Methode f"ur das 898 // Erfragen der Ranges onDemand 899 sal_Bool bItemsOnDemand // gibt an, ob das Set dieser Seite beim 900 // Erzeugen der Seite erfragt wird 901 ) 902 { 903 pImpl->pData->Append( 904 new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) ); 905 } 906 907 // ----------------------------------------------------------------------- 908 909 void SfxTabDialog::AddTabPage 910 911 /* [Beschreibung] 912 913 Hinzuf"ugen einer Seite zu dem Dialog. 914 Der Ridertext wird "ubergeben, die Seite hat keine Entsprechung im 915 TabControl in der Resource des Dialogs. 916 */ 917 918 ( 919 sal_uInt16 nId, 920 const String& rRiderText, 921 CreateTabPage pCreateFunc, 922 GetTabPageRanges pRangesFunc, 923 sal_Bool bItemsOnDemand, 924 sal_uInt16 nPos 925 ) 926 { 927 DBG_ASSERT( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nId ), 928 "Doppelte Page-Ids in der Tabpage" ); 929 aTabCtrl.InsertPage( nId, rRiderText, nPos ); 930 pImpl->pData->Append( 931 new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) ); 932 } 933 934 // ----------------------------------------------------------------------- 935 #ifdef SV_HAS_RIDERBITMAPS 936 937 void SfxTabDialog::AddTabPage 938 939 /* [Beschreibung] 940 941 Hinzuf"ugen einer Seite zu dem Dialog. 942 Die Riderbitmap wird "ubergeben, die Seite hat keine Entsprechung im 943 TabControl in der Resource des Dialogs. 944 */ 945 946 ( 947 sal_uInt16 nId, 948 const Bitmap &rRiderBitmap, 949 CreateTabPage pCreateFunc, 950 GetTabPageRanges pRangesFunc, 951 sal_Bool bItemsOnDemand, 952 sal_uInt16 nPos 953 ) 954 { 955 DBG_ASSERT( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nId ), 956 "Doppelte Page-Ids in der Tabpage" ); 957 aTabCtrl.InsertPage( nId, rRiderBitmap, nPos ); 958 pImpl->pData->Append( 959 new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) ); 960 } 961 #endif 962 963 // ----------------------------------------------------------------------- 964 965 void SfxTabDialog::RemoveTabPage( sal_uInt16 nId ) 966 967 /* [Beschreibung] 968 969 L"oschen der TabPage mit der ID nId 970 */ 971 972 { 973 sal_uInt16 nPos = 0; 974 aTabCtrl.RemovePage( nId ); 975 Data_Impl* pDataObject = Find( *pImpl->pData, nId, &nPos ); 976 977 if ( pDataObject ) 978 { 979 if ( pDataObject->pTabPage ) 980 { 981 pDataObject->pTabPage->FillUserData(); 982 String aPageData( pDataObject->pTabPage->GetUserData() ); 983 if ( aPageData.Len() ) 984 { 985 // save settings of this page (user data) 986 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) ); 987 aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aPageData ) ) ); 988 } 989 990 if ( pDataObject->bOnDemand ) 991 delete (SfxItemSet*)&pDataObject->pTabPage->GetItemSet(); 992 delete pDataObject->pTabPage; 993 } 994 995 delete pDataObject; 996 pImpl->pData->Remove( nPos ); 997 } 998 else 999 { 1000 DBG_WARNINGFILE( "TabPage-Id nicht bekannt" ); 1001 } 1002 } 1003 1004 // ----------------------------------------------------------------------- 1005 1006 void SfxTabDialog::PageCreated 1007 1008 /* [Beschreibung] 1009 1010 Defaultimplemetierung der virtuellen Methode. 1011 Diese wird unmittelbar nach dem Erzeugen einer Seite gerufen. 1012 Hier kann der Dialog direkt an der TabPage Methoden rufen. 1013 */ 1014 1015 ( 1016 sal_uInt16, // Id der erzeugten Seite 1017 SfxTabPage& // Referenz auf die erzeugte Seite 1018 ) 1019 { 1020 } 1021 1022 // ----------------------------------------------------------------------- 1023 1024 SfxItemSet* SfxTabDialog::GetInputSetImpl() 1025 1026 /* [Beschreibung] 1027 1028 Abgeleitete Klassen legen ggf. fuer den InputSet neuen Speicher an. 1029 Dieser mu\s im Destruktor auch wieder freigegeben werden. Dazu mu\s 1030 diese Methode gerufen werden. 1031 */ 1032 1033 { 1034 return (SfxItemSet*)pSet; 1035 } 1036 1037 // ----------------------------------------------------------------------- 1038 1039 SfxTabPage* SfxTabDialog::GetTabPage( sal_uInt16 nPageId ) const 1040 1041 /* [Beschreibung] 1042 1043 TabPage mit der "Ubergebenen Id zur"uckgeben. 1044 */ 1045 1046 { 1047 sal_uInt16 nPos = 0; 1048 Data_Impl* pDataObject = Find( *pImpl->pData, nPageId, &nPos ); 1049 1050 if ( pDataObject ) 1051 return pDataObject->pTabPage; 1052 return NULL; 1053 } 1054 1055 // ----------------------------------------------------------------------- 1056 1057 sal_Bool SfxTabDialog::IsInOK() const 1058 1059 /* [Beschreibung] 1060 1061 */ 1062 1063 { 1064 return pImpl->bInOK; 1065 } 1066 1067 // ----------------------------------------------------------------------- 1068 1069 short SfxTabDialog::Ok() 1070 1071 /* [Beschreibung] 1072 1073 Ok-Handler des Dialogs 1074 Das OutputSet wird erstellt und jede Seite wird mit 1075 dem bzw. ihrem speziellen OutputSet durch Aufruf der Methode 1076 <SfxTabPage::FillItemSet(SfxItemSet &)> dazu aufgefordert, 1077 die vom Benuzter eingestellten Daten in das Set zu tun. 1078 1079 [R"uckgabewert] 1080 1081 RET_OK: wenn mindestens eine Seite sal_True als Returnwert von 1082 FillItemSet geliefert hat, sonst RET_CANCEL. 1083 */ 1084 1085 { 1086 pImpl->bInOK = sal_True; 1087 1088 if ( !pOutSet ) 1089 { 1090 if ( !pExampleSet && pSet ) 1091 pOutSet = pSet->Clone( sal_False ); // ohne Items 1092 else if ( pExampleSet ) 1093 pOutSet = new SfxItemSet( *pExampleSet ); 1094 } 1095 sal_Bool bModified = sal_False; 1096 1097 const sal_uInt16 nCount = pImpl->pData->Count(); 1098 1099 for ( sal_uInt16 i = 0; i < nCount; ++i ) 1100 { 1101 Data_Impl* pDataObject = pImpl->pData->GetObject(i); 1102 SfxTabPage* pTabPage = pDataObject->pTabPage; 1103 1104 if ( pTabPage ) 1105 { 1106 if ( pDataObject->bOnDemand ) 1107 { 1108 SfxItemSet& rSet = (SfxItemSet&)pTabPage->GetItemSet(); 1109 rSet.ClearItem(); 1110 bModified |= pTabPage->FillItemSet( rSet ); 1111 } 1112 else if ( pSet && !pTabPage->HasExchangeSupport() ) 1113 { 1114 SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() ); 1115 1116 if ( pTabPage->FillItemSet( aTmp ) ) 1117 { 1118 bModified |= sal_True; 1119 pExampleSet->Put( aTmp ); 1120 pOutSet->Put( aTmp ); 1121 } 1122 } 1123 } 1124 } 1125 1126 if ( pImpl->bModified || ( pOutSet && pOutSet->Count() > 0 ) ) 1127 bModified |= sal_True; 1128 1129 if ( bFmt == 2 ) 1130 bModified |= sal_True; 1131 return bModified ? RET_OK : RET_CANCEL; 1132 } 1133 1134 // ----------------------------------------------------------------------- 1135 1136 IMPL_LINK( SfxTabDialog, CancelHdl, Button*, pButton ) 1137 { 1138 (void)pButton; //unused 1139 Close(); 1140 return 0; 1141 } 1142 1143 // ----------------------------------------------------------------------- 1144 1145 SfxItemSet* SfxTabDialog::CreateInputItemSet( sal_uInt16 ) 1146 1147 /* [Beschreibung] 1148 1149 Defaultimplemetierung der virtuellen Methode. 1150 Diese wird gerufen, wenn Pages ihre Sets onDenamd anlegen 1151 */ 1152 1153 { 1154 DBG_WARNINGFILE( "CreateInputItemSet nicht implementiert" ); 1155 return new SfxAllItemSet( SFX_APP()->GetPool() ); 1156 } 1157 1158 // ----------------------------------------------------------------------- 1159 1160 const SfxItemSet* SfxTabDialog::GetRefreshedSet() 1161 1162 /* [Beschreibung] 1163 1164 Defaultimplemetierung der virtuellen Methode. 1165 Diese wird gerufen, wenn <SfxTabPage::DeactivatePage(SfxItemSet *)> 1166 <SfxTabPage::REFRESH_SET> liefert. 1167 */ 1168 1169 { 1170 DBG_ERRORFILE( "GetRefreshedSet nicht implementiert" ); 1171 return 0; 1172 } 1173 1174 // ----------------------------------------------------------------------- 1175 1176 IMPL_LINK( SfxTabDialog, OkHdl, Button *, EMPTYARG ) 1177 1178 /* [Beschreibung] 1179 1180 Handler des Ok-Buttons 1181 Dieser ruft f"ur die aktuelle Seite 1182 <SfxTabPage::DeactivatePage(SfxItemSet *)>. 1183 Liefert diese <SfxTabPage::LEAVE_PAGE>, wird <SfxTabDialog::Ok()> gerufen 1184 und so der Dialog beendet. 1185 */ 1186 1187 { 1188 pImpl->bInOK = sal_True; 1189 1190 if ( OK_Impl() ) 1191 { 1192 if ( pImpl->bModal ) 1193 EndDialog( Ok() ); 1194 else 1195 { 1196 Ok(); 1197 Close(); 1198 } 1199 } 1200 return 0; 1201 } 1202 1203 // ----------------------------------------------------------------------- 1204 1205 bool SfxTabDialog::PrepareLeaveCurrentPage() 1206 { 1207 sal_uInt16 const nId = aTabCtrl.GetCurPageId(); 1208 SfxTabPage* pPage = dynamic_cast<SfxTabPage*> (aTabCtrl.GetTabPage( nId )); 1209 bool bEnd = !pPage; 1210 1211 if ( pPage ) 1212 { 1213 int nRet = SfxTabPage::LEAVE_PAGE; 1214 if ( pSet ) 1215 { 1216 SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() ); 1217 1218 if ( pPage->HasExchangeSupport() ) 1219 nRet = pPage->DeactivatePage( &aTmp ); 1220 else 1221 nRet = pPage->DeactivatePage( NULL ); 1222 1223 if ( ( SfxTabPage::LEAVE_PAGE & nRet ) == SfxTabPage::LEAVE_PAGE 1224 && aTmp.Count() ) 1225 { 1226 pExampleSet->Put( aTmp ); 1227 pOutSet->Put( aTmp ); 1228 } 1229 } 1230 else 1231 nRet = pPage->DeactivatePage( NULL ); 1232 bEnd = nRet; 1233 } 1234 1235 return bEnd; 1236 } 1237 1238 1239 // ----------------------------------------------------------------------- 1240 1241 IMPL_LINK( SfxTabDialog, UserHdl, Button *, EMPTYARG ) 1242 1243 /* [Beschreibung] 1244 1245 Handler des User-Buttons 1246 Dieser ruft f"ur die aktuelle Seite 1247 <SfxTabPage::DeactivatePage(SfxItemSet *)>. 1248 Liefert diese <SfxTabPage::LEAVE_PAGE>, wird <SfxTabDialog::Ok()> gerufen. 1249 Mit dem Return-Wert von <SfxTabDialog::Ok()> wird dann der Dialog beendet. 1250 */ 1251 1252 { 1253 if ( PrepareLeaveCurrentPage () ) 1254 { 1255 short nRet = Ok(); 1256 1257 if ( RET_OK == nRet ) 1258 nRet = RET_USER; 1259 else 1260 nRet = RET_USER_CANCEL; 1261 EndDialog( nRet ); 1262 } 1263 return 0; 1264 } 1265 1266 // ----------------------------------------------------------------------- 1267 1268 IMPL_LINK( SfxTabDialog, ResetHdl, Button *, EMPTYARG ) 1269 1270 /* [Beschreibung] 1271 1272 Handler hinter dem Zur"ucksetzen-Button. 1273 Die aktuelle Page wird mit ihren initialen Daten 1274 neu initialisiert; alle Einstellungen, die der Benutzer 1275 auf dieser Seite get"atigt hat, werden aufgehoben. 1276 */ 1277 1278 { 1279 const sal_uInt16 nId = aTabCtrl.GetCurPageId(); 1280 Data_Impl* pDataObject = Find( *pImpl->pData, nId ); 1281 DBG_ASSERT( pDataObject, "Id nicht bekannt" ); 1282 1283 if ( pDataObject->bOnDemand ) 1284 { 1285 // CSet auf AIS hat hier Probleme, daher getrennt 1286 const SfxItemSet* pItemSet = &pDataObject->pTabPage->GetItemSet(); 1287 pDataObject->pTabPage->Reset( *(SfxItemSet*)pItemSet ); 1288 } 1289 else 1290 pDataObject->pTabPage->Reset( *pSet ); 1291 return 0; 1292 } 1293 1294 // ----------------------------------------------------------------------- 1295 1296 IMPL_LINK( SfxTabDialog, BaseFmtHdl, Button *, EMPTYARG ) 1297 1298 /* [Beschreibung] 1299 1300 Handler hinter dem Standard-Button. 1301 Dieser Button steht beim Bearbeiten von StyleSheets zur Verf"ugung. 1302 Alle in dem bearbeiteten StyleSheet eingestellten Attribute 1303 werden gel"oscht. 1304 */ 1305 1306 { 1307 const sal_uInt16 nId = aTabCtrl.GetCurPageId(); 1308 Data_Impl* pDataObject = Find( *pImpl->pData, nId ); 1309 DBG_ASSERT( pDataObject, "Id nicht bekannt" ); 1310 bFmt = 2; 1311 1312 if ( pDataObject->fnGetRanges ) 1313 { 1314 if ( !pExampleSet ) 1315 pExampleSet = new SfxItemSet( *pSet ); 1316 1317 const SfxItemPool* pPool = pSet->GetPool(); 1318 const sal_uInt16* pTmpRanges = (pDataObject->fnGetRanges)(); 1319 SfxItemSet aTmpSet( *pExampleSet ); 1320 1321 while ( *pTmpRanges ) 1322 { 1323 const sal_uInt16* pU = pTmpRanges + 1; 1324 1325 if ( *pTmpRanges == *pU ) 1326 { 1327 // Range mit zwei gleichen Werten -> nur ein Item setzen 1328 sal_uInt16 nWh = pPool->GetWhich( *pTmpRanges ); 1329 pExampleSet->ClearItem( nWh ); 1330 aTmpSet.ClearItem( nWh ); 1331 // am OutSet mit InvalidateItem, 1332 // damit die "Anderung wirksam wird 1333 pOutSet->InvalidateItem( nWh ); 1334 } 1335 else 1336 { 1337 // richtiger Range mit mehreren Werten 1338 sal_uInt16 nTmp = *pTmpRanges, nTmpEnd = *pU; 1339 DBG_ASSERT( nTmp <= nTmpEnd, "Range ist falsch sortiert" ); 1340 1341 if ( nTmp > nTmpEnd ) 1342 { 1343 // wenn wirklich falsch sortiert, dann neu setzen 1344 sal_uInt16 nTmp1 = nTmp; 1345 nTmp = nTmpEnd; 1346 nTmpEnd = nTmp1; 1347 } 1348 1349 while ( nTmp <= nTmpEnd ) 1350 { 1351 // "uber den Range iterieren, und die Items setzen 1352 sal_uInt16 nWh = pPool->GetWhich( nTmp ); 1353 pExampleSet->ClearItem( nWh ); 1354 aTmpSet.ClearItem( nWh ); 1355 // am OutSet mit InvalidateItem, 1356 // damit die "Anderung wirksam wird 1357 pOutSet->InvalidateItem( nWh ); 1358 nTmp++; 1359 } 1360 } 1361 // zum n"achsten Paar gehen 1362 pTmpRanges += 2; 1363 } 1364 // alle Items neu gesetzt -> dann an der aktuellen Page Reset() rufen 1365 DBG_ASSERT( pDataObject->pTabPage, "die Page ist weg" ); 1366 pDataObject->pTabPage->Reset( aTmpSet ); 1367 pDataObject->pTabPage->pImpl->mbStandard = sal_True; 1368 } 1369 return 1; 1370 } 1371 1372 // ----------------------------------------------------------------------- 1373 1374 #if ENABLE_LAYOUT_SFX_TABDIALOG 1375 #define tabControlWindow pTabCtrl->GetWindow () 1376 #else /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 1377 #define tabControlWindow pTabCtrl 1378 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */ 1379 1380 IMPL_LINK( SfxTabDialog, ActivatePageHdl, TabControl *, pTabCtrl ) 1381 1382 /* [Beschreibung] 1383 1384 Handler, der vor dem Umschalten auf eine andere Seite 1385 durch Starview gerufen wird. 1386 Existiert die Seite noch nicht, so wird sie erzeugt und 1387 die virtuelle Methode <SfxTabDialog::PageCreated( sal_uInt16, SfxTabPage &)> 1388 gerufen. Existiert die Seite bereits, so wird ggf. 1389 <SfxTabPage::Reset(const SfxItemSet &)> oder 1390 <SfxTabPage::ActivatePage(const SfxItemSet &)> gerufen. 1391 */ 1392 1393 { 1394 sal_uInt16 const nId = pTabCtrl->GetCurPageId(); 1395 1396 DBG_ASSERT( pImpl->pData->Count(), "keine Pages angemeldet" ); 1397 SFX_APP(); 1398 1399 // Tab Page schon da? 1400 SfxTabPage* pTabPage = dynamic_cast<SfxTabPage*> (pTabCtrl->GetTabPage( nId )); 1401 Data_Impl* pDataObject = Find( *pImpl->pData, nId ); 1402 DBG_ASSERT( pDataObject, "Id nicht bekannt" ); 1403 1404 // ggf. TabPage erzeugen: 1405 if ( !pTabPage ) 1406 { 1407 #if ENABLE_LAYOUT_SFX_TABDIALOG 1408 if (dynamic_cast<layout SfxTabPage*> (pTabPage)) 1409 layout::TabPage::global_parent = pTabCtrl->GetWindow (); 1410 #endif 1411 const SfxItemSet* pTmpSet = 0; 1412 1413 if ( pSet ) 1414 { 1415 if ( bItemsReset && pSet->GetParent() ) 1416 pTmpSet = pSet->GetParent(); 1417 else 1418 pTmpSet = pSet; 1419 } 1420 1421 if ( pTmpSet && !pDataObject->bOnDemand ) 1422 pTabPage = (pDataObject->fnCreatePage)( tabControlWindow, *pTmpSet ); 1423 else 1424 pTabPage = (pDataObject->fnCreatePage) 1425 ( tabControlWindow, *CreateInputItemSet( nId ) ); 1426 DBG_ASSERT( NULL == pDataObject->pTabPage, "create TabPage more than once" ); 1427 pDataObject->pTabPage = pTabPage; 1428 1429 #if !ENABLE_LAYOUT_SFX_TABDIALOG 1430 pDataObject->pTabPage->SetTabDialog( this ); 1431 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 1432 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) ); 1433 String sUserData; 1434 Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME ); 1435 OUString aTemp; 1436 if ( aUserItem >>= aTemp ) 1437 sUserData = String( aTemp ); 1438 pTabPage->SetUserData( sUserData ); 1439 Size aSiz = pTabPage->GetSizePixel(); 1440 1441 #if ENABLE_LAYOUT 1442 Size optimalSize = pTabPage->GetOptimalSize (WINDOWSIZE_MINIMUM); 1443 #if ENABLE_LAYOUT_SFX_TABDIALOG 1444 if (dynamic_cast<layout SfxTabPage*> (pTabPage)) 1445 { 1446 if (optimalSize.Height () && optimalSize.Width ()) 1447 { 1448 optimalSize.Width () = optimalSize.Width (); 1449 optimalSize.Height () = optimalSize.Height () + 40; 1450 } 1451 } 1452 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 1453 if (optimalSize.Height () > 0 && optimalSize.Width () > 0 ) 1454 aSiz = optimalSize; 1455 #endif /* ENABLE_LAYOUT */ 1456 1457 Size aCtrlSiz = pTabCtrl->GetTabPageSizePixel(); 1458 // Gr"o/se am TabControl nur dann setzen, wenn < als TabPage 1459 if ( aCtrlSiz.Width() < aSiz.Width() || 1460 aCtrlSiz.Height() < aSiz.Height() ) 1461 { 1462 pTabCtrl->SetTabPageSizePixel( aSiz ); 1463 } 1464 1465 PageCreated( nId, *pTabPage ); 1466 1467 if ( pDataObject->bOnDemand ) 1468 pTabPage->Reset( (SfxItemSet &)pTabPage->GetItemSet() ); 1469 else 1470 pTabPage->Reset( *pSet ); 1471 1472 pTabCtrl->SetTabPage( nId, pTabPage ); 1473 } 1474 else if ( pDataObject->bRefresh ) 1475 pTabPage->Reset( *pSet ); 1476 pDataObject->bRefresh = sal_False; 1477 1478 #if ENABLE_LAYOUT_SFX_TABDIALOG 1479 pTabCtrl->GetPagePos (nId); 1480 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */ 1481 1482 if ( pExampleSet ) 1483 pTabPage->ActivatePage( *pExampleSet ); 1484 sal_Bool bReadOnly = pTabPage->IsReadOnly(); 1485 ( bReadOnly || pImpl->bHideResetBtn ) ? aResetBtn.Hide() : aResetBtn.Show(); 1486 return 0; 1487 } 1488 1489 // ----------------------------------------------------------------------- 1490 1491 IMPL_LINK( SfxTabDialog, DeactivatePageHdl, TabControl *, pTabCtrl ) 1492 1493 /* [Beschreibung] 1494 1495 Handler, der vor dem Verlassen einer Seite durch Starview gerufen wird. 1496 1497 [Querverweise] 1498 1499 <SfxTabPage::DeactivatePage(SfxItemSet *)> 1500 */ 1501 1502 { 1503 sal_uInt16 nId = pTabCtrl->GetCurPageId(); 1504 SFX_APP(); 1505 SfxTabPage *pPage = dynamic_cast<SfxTabPage*> (pTabCtrl->GetTabPage( nId )); 1506 DBG_ASSERT( pPage, "keine aktive Page" ); 1507 #ifdef DBG_UTIL 1508 Data_Impl* pDataObject = Find( *pImpl->pData, pTabCtrl->GetCurPageId() ); 1509 DBG_ASSERT( pDataObject, "keine Datenstruktur zur aktuellen Seite" ); 1510 if ( pPage->HasExchangeSupport() && pDataObject->bOnDemand ) 1511 { 1512 DBG_WARNING( "Datenaustausch bei ItemsOnDemand ist nicht gewuenscht!" ); 1513 } 1514 #endif 1515 1516 int nRet = SfxTabPage::LEAVE_PAGE; 1517 1518 if ( !pExampleSet && pPage->HasExchangeSupport() && pSet ) 1519 pExampleSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ); 1520 1521 if ( pSet ) 1522 { 1523 SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() ); 1524 1525 if ( pPage->HasExchangeSupport() ) 1526 nRet = pPage->DeactivatePage( &aTmp ); 1527 else 1528 nRet = pPage->DeactivatePage( NULL ); 1529 //! else 1530 //! pPage->FillItemSet( aTmp ); 1531 1532 if ( ( SfxTabPage::LEAVE_PAGE & nRet ) == SfxTabPage::LEAVE_PAGE && 1533 aTmp.Count() ) 1534 { 1535 pExampleSet->Put( aTmp ); 1536 pOutSet->Put( aTmp ); 1537 } 1538 } 1539 else 1540 { 1541 if ( pPage->HasExchangeSupport() ) //!!! 1542 { 1543 if ( !pExampleSet ) 1544 { 1545 SfxItemPool* pPool = pPage->GetItemSet().GetPool(); 1546 pExampleSet = 1547 new SfxItemSet( *pPool, GetInputRanges( *pPool ) ); 1548 } 1549 nRet = pPage->DeactivatePage( pExampleSet ); 1550 } 1551 else 1552 nRet = pPage->DeactivatePage( NULL ); 1553 } 1554 1555 if ( nRet & SfxTabPage::REFRESH_SET ) 1556 { 1557 pSet = GetRefreshedSet(); 1558 DBG_ASSERT( pSet, "GetRefreshedSet() liefert NULL" ); 1559 // alle Pages als neu zu initialsieren flaggen 1560 const sal_uInt16 nCount = pImpl->pData->Count(); 1561 1562 for ( sal_uInt16 i = 0; i < nCount; ++i ) 1563 { 1564 Data_Impl* pObj = (*pImpl->pData)[i]; 1565 1566 if ( pObj->pTabPage != pPage ) // eigene Page nicht mehr refreshen 1567 pObj->bRefresh = sal_True; 1568 else 1569 pObj->bRefresh = sal_False; 1570 } 1571 } 1572 if ( nRet & SfxTabPage::LEAVE_PAGE ) 1573 return sal_True; 1574 else 1575 return sal_False; 1576 } 1577 1578 // ----------------------------------------------------------------------- 1579 1580 const SfxItemSet* SfxTabDialog::GetOutputItemSet 1581 1582 /* [Beschreibung] 1583 1584 Liefert die Pages, die ihre Sets onDemand liefern, das OutputItemSet. 1585 1586 [Querverweise] 1587 1588 <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, sal_Bool)> 1589 <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)> 1590 <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)> 1591 */ 1592 1593 ( 1594 sal_uInt16 nId // die Id, unter der die Seite bei AddTabPage() 1595 // hinzugef"ugt wurde. 1596 ) const 1597 { 1598 Data_Impl* pDataObject = Find( *pImpl->pData, nId ); 1599 DBG_ASSERT( pDataObject, "TabPage nicht gefunden" ); 1600 1601 if ( pDataObject ) 1602 { 1603 if ( !pDataObject->pTabPage ) 1604 return NULL; 1605 1606 if ( pDataObject->bOnDemand ) 1607 return &pDataObject->pTabPage->GetItemSet(); 1608 // else 1609 return pOutSet; 1610 } 1611 return NULL; 1612 } 1613 1614 // ----------------------------------------------------------------------- 1615 1616 int SfxTabDialog::FillOutputItemSet() 1617 { 1618 int nRet = SfxTabPage::LEAVE_PAGE; 1619 if ( OK_Impl() ) 1620 Ok(); 1621 else 1622 nRet = SfxTabPage::KEEP_PAGE; 1623 return nRet; 1624 } 1625 1626 // ----------------------------------------------------------------------- 1627 1628 #ifdef WNT 1629 int __cdecl TabDlgCmpUS_Impl( const void* p1, const void* p2 ) 1630 #else 1631 #if defined(OS2) && defined(ICC) 1632 int _Optlink TabDlgCmpUS_Impl( const void* p1, const void* p2 ) 1633 #else 1634 extern "C" int TabDlgCmpUS_Impl( const void* p1, const void* p2 ) 1635 #endif 1636 #endif 1637 1638 /* [Beschreibung] 1639 1640 Vergleichsfunktion f"ur qsort 1641 */ 1642 1643 { 1644 return *(sal_uInt16*)p1 - *(sal_uInt16*)p2; 1645 } 1646 1647 // ----------------------------------------------------------------------- 1648 1649 void SfxTabDialog::ShowPage( sal_uInt16 nId ) 1650 1651 /* [Beschreibung] 1652 1653 Es wird die TabPage mit der "ubergebenen Id aktiviert. 1654 */ 1655 1656 { 1657 aTabCtrl.SetCurPageId( nId ); 1658 ActivatePageHdl( &aTabCtrl ); 1659 } 1660 1661 // ----------------------------------------------------------------------- 1662 1663 const sal_uInt16* SfxTabDialog::GetInputRanges( const SfxItemPool& rPool ) 1664 1665 /* [Beschreibung] 1666 1667 Bildet das Set "uber die Ranges aller Seiten des Dialogs. 1668 Die Pages m"ussen die statische Methode f"ur das Erfragen ihrer 1669 Ranges bei AddTabPage angegeben haben, liefern also ihre Sets onDemand. 1670 1671 [Querverweise] 1672 1673 <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, sal_Bool)> 1674 <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)> 1675 <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)> 1676 1677 [R"uckgabewert] 1678 1679 Pointer auf nullterminiertes Array von USHORTs 1680 Dieses Array geh"ort dem Dialog und wird beim 1681 Zerst"oren des Dialogs gel"oscht. 1682 */ 1683 1684 { 1685 if ( pSet ) 1686 { 1687 DBG_ERRORFILE( "Set bereits vorhanden!" ); 1688 return pSet->GetRanges(); 1689 } 1690 1691 if ( pRanges ) 1692 return pRanges; 1693 SvUShorts aUS( 16, 16 ); 1694 sal_uInt16 nCount = pImpl->pData->Count(); 1695 1696 sal_uInt16 i; 1697 for ( i = 0; i < nCount; ++i ) 1698 { 1699 Data_Impl* pDataObject = pImpl->pData->GetObject(i); 1700 1701 if ( pDataObject->fnGetRanges ) 1702 { 1703 const sal_uInt16* pTmpRanges = (pDataObject->fnGetRanges)(); 1704 const sal_uInt16* pIter = pTmpRanges; 1705 1706 sal_uInt16 nLen; 1707 for( nLen = 0; *pIter; ++nLen, ++pIter ) 1708 ; 1709 aUS.Insert( pTmpRanges, nLen, aUS.Count() ); 1710 } 1711 } 1712 1713 //! Doppelte Ids entfernen? 1714 #ifndef TF_POOLABLE 1715 if ( rPool.HasMap() ) 1716 #endif 1717 { 1718 nCount = aUS.Count(); 1719 1720 for ( i = 0; i < nCount; ++i ) 1721 aUS[i] = rPool.GetWhich( aUS[i] ); 1722 } 1723 1724 // sortieren 1725 if ( aUS.Count() > 1 ) 1726 qsort( (void*)aUS.GetData(), 1727 aUS.Count(), sizeof(sal_uInt16), TabDlgCmpUS_Impl ); 1728 1729 // Ranges erzeugen 1730 //!! Auskommentiert, da fehlerhaft 1731 /* 1732 pRanges = new sal_uInt16[aUS.Count() * 2 + 1]; 1733 int j = 0; 1734 i = 0; 1735 1736 while ( i < aUS.Count() ) 1737 { 1738 pRanges[j++] = aUS[i]; 1739 // aufeinanderfolgende Zahlen 1740 for( ; i < aUS.Count()-1; ++i ) 1741 if ( aUS[i] + 1 != aUS[i+1] ) 1742 break; 1743 pRanges[j++] = aUS[i++]; 1744 } 1745 pRanges[j] = 0; // terminierende NULL 1746 */ 1747 1748 pRanges = new sal_uInt16[aUS.Count() + 1]; 1749 memcpy(pRanges, aUS.GetData(), sizeof(sal_uInt16) * aUS.Count()); 1750 pRanges[aUS.Count()] = 0; 1751 return pRanges; 1752 } 1753 1754 // ----------------------------------------------------------------------- 1755 1756 void SfxTabDialog::SetInputSet( const SfxItemSet* pInSet ) 1757 1758 /* [Beschreibung] 1759 1760 Mit dieser Methode kann nachtr"aglich der Input-Set initial oder 1761 neu gesetzt werden. 1762 */ 1763 1764 { 1765 bool bSet = ( pSet != NULL ); 1766 1767 pSet = pInSet; 1768 1769 if ( !bSet && !pExampleSet && !pOutSet ) 1770 { 1771 pExampleSet = new SfxItemSet( *pSet ); 1772 pOutSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ); 1773 } 1774 } 1775 1776 long SfxTabDialog::Notify( NotifyEvent& rNEvt ) 1777 { 1778 if ( rNEvt.GetType() == EVENT_GETFOCUS ) 1779 { 1780 SfxViewFrame* pViewFrame = GetViewFrame() ? GetViewFrame() : SfxViewFrame::Current(); 1781 if ( pViewFrame ) 1782 { 1783 Window* pWindow = rNEvt.GetWindow(); 1784 rtl::OString sHelpId; 1785 while ( !sHelpId.getLength() && pWindow ) 1786 { 1787 sHelpId = pWindow->GetHelpId(); 1788 pWindow = pWindow->GetParent(); 1789 } 1790 1791 if ( sHelpId.getLength() ) 1792 SfxHelp::OpenHelpAgent( &pViewFrame->GetFrame(), sHelpId ); 1793 } 1794 } 1795 1796 return TabDialog::Notify( rNEvt ); 1797 } 1798 1799 END_NAMESPACE_LAYOUT_SFX_TABDIALOG 1800