1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 // include --------------------------------------------------------------- 32 33 #include <stdlib.h> 34 #include <vcl/fixed.hxx> 35 #include <vcl/help.hxx> 36 #include <vcl/msgbox.hxx> 37 #include <svl/eitem.hxx> 38 #include <unotools/viewoptions.hxx> 39 #include <svtools/fixedhyper.hxx> 40 #include <svtools/controldims.hrc> 41 42 #include <sfx2/basedlgs.hxx> 43 #include <sfx2/viewfrm.hxx> 44 #include <sfx2/tabdlg.hxx> 45 #include <sfx2/app.hxx> 46 #include <sfx2/bindings.hxx> 47 #include <sfx2/dispatch.hxx> 48 #include <sfx2/childwin.hxx> 49 #include <sfx2/viewsh.hxx> 50 #include "sfx2/sfxhelp.hxx" 51 #include "workwin.hxx" 52 #include "sfx2/sfxresid.hxx" 53 #include "dialog.hrc" 54 55 using namespace ::com::sun::star::uno; 56 using namespace ::rtl; 57 58 #define USERITEM_NAME OUString::createFromAscii( "UserItem" ) 59 60 class SfxModelessDialog_Impl : public SfxListener 61 { 62 public: 63 ByteString aWinState; 64 SfxChildWindow* pMgr; 65 sal_Bool bConstructed; 66 void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); 67 68 Timer aMoveTimer; 69 }; 70 71 void SfxModelessDialog_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint ) 72 { 73 if ( rHint.IsA(TYPE(SfxSimpleHint)) ) 74 { 75 switch( ( (SfxSimpleHint&) rHint ).GetId() ) 76 { 77 case SFX_HINT_DYING: 78 pMgr->Destroy(); 79 break; 80 } 81 } 82 } 83 84 class SfxFloatingWindow_Impl : public SfxListener 85 { 86 public: 87 ByteString aWinState; 88 SfxChildWindow* pMgr; 89 sal_Bool bConstructed; 90 Timer aMoveTimer; 91 92 void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); 93 }; 94 95 void SfxFloatingWindow_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint ) 96 { 97 if ( rHint.IsA(TYPE(SfxSimpleHint)) ) 98 { 99 switch( ( (SfxSimpleHint&) rHint ).GetId() ) 100 { 101 case SFX_HINT_DYING: 102 pMgr->Destroy(); 103 break; 104 } 105 } 106 } 107 108 // class SfxModalDefParentHelper ----------------------------------------- 109 110 SfxModalDefParentHelper::SfxModalDefParentHelper( Window *pWindow) 111 { 112 pOld = Application::GetDefDialogParent(); 113 Application::SetDefDialogParent( pWindow ); 114 } 115 116 // ----------------------------------------------------------------------- 117 118 SfxModalDefParentHelper::~SfxModalDefParentHelper() 119 { 120 Application::SetDefDialogParent( pOld ); 121 } 122 123 // ----------------------------------------------------------------------- 124 125 void SfxModalDialog::SetDialogData_Impl() 126 { 127 // save settings (position and user data) 128 SvtViewOptions aDlgOpt( E_DIALOG, String::CreateFromInt32( nUniqId ) ); 129 aDlgOpt.SetWindowState( 130 OUString::createFromAscii( GetWindowState( WINDOWSTATE_MASK_POS ).GetBuffer() ) ); 131 if ( aExtraData.Len() ) 132 aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aExtraData ) ) ); 133 } 134 135 // ----------------------------------------------------------------------- 136 137 void SfxModalDialog::GetDialogData_Impl() 138 139 /* [Beschreibung] 140 141 Hilfsfunktion; liest die Dialogposition aus der Ini-Datei 142 und setzt diese am "ubergebenen Window. 143 */ 144 145 { 146 SvtViewOptions aDlgOpt( E_DIALOG, String::CreateFromInt32( nUniqId ) ); 147 if ( aDlgOpt.Exists() ) 148 { 149 // load settings 150 SetWindowState( ByteString( aDlgOpt.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US ) ); 151 Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME ); 152 OUString aTemp; 153 if ( aUserItem >>= aTemp ) 154 aExtraData = String( aTemp ); 155 } 156 } 157 158 // ----------------------------------------------------------------------- 159 160 void SfxModalDialog::init() 161 { 162 GetDialogData_Impl(); 163 } 164 165 // ----------------------------------------------------------------------- 166 167 SfxModalDialog::SfxModalDialog(Window* pParent, const ResId &rResId ) 168 169 /* [Beschreibung] 170 171 Konstruktor der allgemeinen Basisklasse f"ur modale Dialoge; 172 ResId wird als ID im ini-file verwendet. 173 Die dort gespeicherte Position wird gesetzt. 174 */ 175 176 : ModalDialog(pParent, rResId), 177 nUniqId(rResId.GetId()), 178 pInputSet(0), 179 pOutputSet(0) 180 { 181 init(); 182 } 183 184 // ----------------------------------------------------------------------- 185 186 SfxModalDialog::SfxModalDialog(Window* pParent, 187 sal_uInt32 nUniqueId, 188 WinBits nWinStyle) : 189 /* [Beschreibung] 190 191 Konstruktor der allgemeinen Basisklasse f"ur modale Dialoge; 192 ID f"ur das ini-file wird explizit "ubergeben. 193 Die dort gespeicherte Position wird gesetzt. 194 */ 195 196 ModalDialog(pParent, nWinStyle), 197 nUniqId(nUniqueId), 198 pInputSet(0), 199 pOutputSet(0) 200 { 201 init(); 202 } 203 204 // ----------------------------------------------------------------------- 205 206 SfxModalDialog::~SfxModalDialog() 207 208 /* [Beschreibung] 209 210 Dtor; schreibt Dialogposition in das ini-file 211 */ 212 213 { 214 SetDialogData_Impl(); 215 delete pOutputSet; 216 } 217 218 void SfxModalDialog::CreateOutputItemSet( SfxItemPool& rPool ) 219 { 220 DBG_ASSERT( !pOutputSet, "Double creation of OutputSet!" ); 221 if (!pOutputSet) 222 pOutputSet = new SfxAllItemSet( rPool ); 223 } 224 225 // ----------------------------------------------------------------------- 226 227 void SfxModalDialog::CreateOutputItemSet( const SfxItemSet& rSet ) 228 { 229 DBG_ASSERT( !pOutputSet, "Double creation of OutputSet!" ); 230 if (!pOutputSet) 231 { 232 pOutputSet = new SfxItemSet( rSet ); 233 pOutputSet->ClearItem(); 234 } 235 } 236 237 //------------------------------------------------------------------------- 238 void SfxModelessDialog::StateChanged( StateChangedType nStateChange ) 239 { 240 if ( nStateChange == STATE_CHANGE_INITSHOW ) 241 { 242 if ( pImp->aWinState.Len() ) 243 { 244 SetWindowState( pImp->aWinState ); 245 } 246 else 247 { 248 Point aPos = GetPosPixel(); 249 if ( !aPos.X() ) 250 { 251 aSize = GetSizePixel(); 252 253 Size aParentSize = GetParent()->GetOutputSizePixel(); 254 Size aDlgSize = GetSizePixel(); 255 aPos.X() += ( aParentSize.Width() - aDlgSize.Width() ) / 2; 256 aPos.Y() += ( aParentSize.Height() - aDlgSize.Height() ) / 2; 257 258 Point aPoint; 259 Rectangle aRect = GetDesktopRectPixel(); 260 aPoint.X() = aRect.Right() - aDlgSize.Width(); 261 aPoint.Y() = aRect.Bottom() - aDlgSize.Height(); 262 263 aPoint = OutputToScreenPixel( aPoint ); 264 265 if ( aPos.X() > aPoint.X() ) 266 aPos.X() = aPoint.X() ; 267 if ( aPos.Y() > aPoint.Y() ) 268 aPos.Y() = aPoint.Y(); 269 270 if ( aPos.X() < 0 ) aPos.X() = 0; 271 if ( aPos.Y() < 0 ) aPos.Y() = 0; 272 273 SetPosPixel( aPos ); 274 } 275 } 276 277 pImp->bConstructed = sal_True; 278 } 279 280 ModelessDialog::StateChanged( nStateChange ); 281 } 282 283 void SfxModelessDialog::Initialize(SfxChildWinInfo *pInfo) 284 285 /* [Beschreibung] 286 287 Initialisierung der Klasse SfxModelessDialog "uber ein SfxChildWinInfo. 288 Die Initialisierung erfolgt erst in einem 2.Schritt 289 nach dem ctor und sollte vom ctor der abgeleiteten Klasse 290 oder von dem des SfxChildWindows aufgerufen werden. 291 */ 292 293 { 294 pImp->aWinState = pInfo->aWinState; 295 } 296 297 void SfxModelessDialog::Resize() 298 299 /* [Beschreibung] 300 301 Diese virtuelle Methode der Klasse FloatingWindow merkt sich ggf. eine 302 ver"anderte Gr"o\se. 303 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 304 auch SfxFloatingWindow::Resize() gerufen werden. 305 */ 306 307 { 308 ModelessDialog::Resize(); 309 if ( pImp->bConstructed && pImp->pMgr ) 310 { 311 // start timer for saving window status information 312 pImp->aMoveTimer.Start(); 313 } 314 } 315 316 void SfxModelessDialog::Move() 317 { 318 ModelessDialog::Move(); 319 if ( pImp->bConstructed && pImp->pMgr && IsReallyVisible() ) 320 { 321 // start timer for saving window status information 322 pImp->aMoveTimer.Start(); 323 } 324 } 325 326 /* 327 Implements a timer event that is triggered by a move or resize of the window 328 This will save config information to Views.xcu with a small delay 329 */ 330 IMPL_LINK( SfxModelessDialog, TimerHdl, Timer*, EMPTYARG) 331 { 332 pImp->aMoveTimer.Stop(); 333 if ( pImp->bConstructed && pImp->pMgr ) 334 { 335 if ( !IsRollUp() ) 336 aSize = GetSizePixel(); 337 sal_uIntPtr nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE; 338 if ( GetStyle() & WB_SIZEABLE ) 339 nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT ); 340 pImp->aWinState = GetWindowState( nMask ); 341 GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SFX_CHILDWIN_DOCKINGWINDOW, SFX_ALIGNDOCKINGWINDOW, pImp->pMgr->GetType() ); 342 } 343 return 0; 344 } 345 346 // ----------------------------------------------------------------------- 347 348 SfxModelessDialog::SfxModelessDialog( SfxBindings *pBindinx, 349 SfxChildWindow *pCW, 350 Window* pParent, WinBits nWinBits ) : 351 ModelessDialog (pParent, nWinBits), 352 pBindings(pBindinx), 353 pImp( new SfxModelessDialog_Impl ) 354 { 355 pImp->pMgr = pCW; 356 pImp->bConstructed = sal_False; 357 SetUniqueId( GetHelpId() ); 358 SetHelpId(""); 359 if ( pBindinx ) 360 pImp->StartListening( *pBindinx ); 361 pImp->aMoveTimer.SetTimeout(50); 362 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxModelessDialog,TimerHdl)); 363 } 364 365 // ----------------------------------------------------------------------- 366 367 SfxModelessDialog::SfxModelessDialog( SfxBindings *pBindinx, 368 SfxChildWindow *pCW, Window *pParent, 369 const ResId& rResId ) : 370 ModelessDialog(pParent, rResId), 371 pBindings(pBindinx), 372 pImp( new SfxModelessDialog_Impl ) 373 { 374 pImp->pMgr = pCW; 375 pImp->bConstructed = sal_False; 376 SetUniqueId( GetHelpId() ); 377 SetHelpId(""); 378 if ( pBindinx ) 379 pImp->StartListening( *pBindinx ); 380 pImp->aMoveTimer.SetTimeout(50); 381 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxModelessDialog,TimerHdl)); 382 } 383 384 // ----------------------------------------------------------------------- 385 386 long SfxModelessDialog::Notify( NotifyEvent& rEvt ) 387 388 /* [Beschreibung] 389 390 Wenn ein ModelessDialog aktiviert wird, wird sein ViewFrame aktiviert. 391 Notwendig ist das bei PlugInFrames. 392 */ 393 394 { 395 if ( rEvt.GetType() == EVENT_GETFOCUS ) 396 { 397 pBindings->SetActiveFrame( pImp->pMgr->GetFrame() ); 398 pImp->pMgr->Activate_Impl(); 399 Window* pWindow = rEvt.GetWindow(); 400 rtl::OString sHelpId; 401 while ( !sHelpId.getLength() && pWindow ) 402 { 403 sHelpId = pWindow->GetHelpId(); 404 pWindow = pWindow->GetParent(); 405 } 406 407 if ( sHelpId.getLength() ) 408 SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId ); 409 } 410 else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() ) 411 { 412 pBindings->SetActiveFrame( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > () ); 413 pImp->pMgr->Deactivate_Impl(); 414 } 415 else if( rEvt.GetType() == EVENT_KEYINPUT ) 416 { 417 // KeyInput zuerst f"ur Dialogfunktionen zulassen ( TAB etc. ) 418 if ( !ModelessDialog::Notify( rEvt ) && SfxViewShell::Current() ) 419 // dann auch global g"ultige Acceleratoren verwenden 420 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() ); 421 return sal_True; 422 } 423 424 return ModelessDialog::Notify( rEvt ); 425 } 426 427 // ----------------------------------------------------------------------- 428 429 SfxModelessDialog::~SfxModelessDialog() 430 431 /* [Beschreibung] 432 433 Dtor 434 */ 435 436 { 437 if ( pImp->pMgr->GetFrame().is() && pImp->pMgr->GetFrame() == pBindings->GetActiveFrame() ) 438 pBindings->SetActiveFrame( NULL ); 439 delete pImp; 440 } 441 442 //------------------------------------------------------------------------- 443 444 sal_Bool SfxModelessDialog::Close() 445 446 /* [Beschreibung] 447 448 Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des 449 ChildWindow-Slots zerst"ort wird. 450 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 451 danach SfxModelessDialogWindow::Close() gerufen werden, wenn nicht das 452 Close() mit "return sal_False" abgebrochen wird. 453 454 */ 455 456 { 457 // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert 458 // werden kann 459 SfxBoolItem aValue( pImp->pMgr->GetType(), sal_False); 460 pBindings->GetDispatcher_Impl()->Execute( 461 pImp->pMgr->GetType(), 462 SFX_CALLMODE_RECORD|SFX_CALLMODE_SYNCHRON, &aValue, 0L ); 463 return sal_True; 464 } 465 466 //------------------------------------------------------------------------- 467 468 void SfxModelessDialog::FillInfo(SfxChildWinInfo& rInfo) const 469 470 /* [Beschreibung] 471 472 F"ullt ein SfxChildWinInfo mit f"ur SfxModelessDialof spezifischen Daten, 473 damit sie in die INI-Datei geschrieben werden koennen. 474 Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in 475 der ChildWindow-Klasse erh"alt. 476 ModelessDialogs haben keine spezifischen Informationen, so dass die 477 Basisimplementierung nichts tut und daher nicht gerufen werden mu\s. 478 */ 479 480 { 481 rInfo.aSize = aSize; 482 if ( IsRollUp() ) 483 rInfo.nFlags |= SFX_CHILDWIN_ZOOMIN; 484 } 485 486 // ----------------------------------------------------------------------- 487 488 long SfxFloatingWindow::Notify( NotifyEvent& rEvt ) 489 490 /* [Beschreibung] 491 492 Wenn ein ModelessDialog aktiviert wird, wird sein ViewFrame aktiviert. 493 Notwendig ist das bei PlugInFrames. 494 */ 495 496 { 497 if ( rEvt.GetType() == EVENT_GETFOCUS ) 498 { 499 pBindings->SetActiveFrame( pImp->pMgr->GetFrame() ); 500 pImp->pMgr->Activate_Impl(); 501 Window* pWindow = rEvt.GetWindow(); 502 rtl::OString sHelpId; 503 while ( !sHelpId.getLength() && pWindow ) 504 { 505 sHelpId = pWindow->GetHelpId(); 506 pWindow = pWindow->GetParent(); 507 } 508 509 if ( sHelpId.getLength() ) 510 SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId ); 511 } 512 else if ( rEvt.GetType() == EVENT_LOSEFOCUS ) 513 { 514 if ( !HasChildPathFocus() ) 515 { 516 pBindings->SetActiveFrame( NULL ); 517 pImp->pMgr->Deactivate_Impl(); 518 } 519 } 520 else if( rEvt.GetType() == EVENT_KEYINPUT ) 521 { 522 // KeyInput zuerst f"ur Dialogfunktionen zulassen 523 if ( !FloatingWindow::Notify( rEvt ) && SfxViewShell::Current() ) 524 // dann auch global g"ultige Acceleratoren verwenden 525 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() ); 526 return sal_True; 527 } 528 529 return FloatingWindow::Notify( rEvt ); 530 } 531 532 // ----------------------------------------------------------------------- 533 534 SfxFloatingWindow::SfxFloatingWindow( SfxBindings *pBindinx, 535 SfxChildWindow *pCW, 536 Window* pParent, WinBits nWinBits) : 537 FloatingWindow (pParent, nWinBits), 538 pBindings(pBindinx), 539 pImp( new SfxFloatingWindow_Impl ) 540 { 541 pImp->pMgr = pCW; 542 pImp->bConstructed = sal_False; 543 SetUniqueId( GetHelpId() ); 544 SetHelpId(""); 545 if ( pBindinx ) 546 pImp->StartListening( *pBindinx ); 547 pImp->aMoveTimer.SetTimeout(50); 548 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxFloatingWindow,TimerHdl)); 549 } 550 551 // ----------------------------------------------------------------------- 552 553 SfxFloatingWindow::SfxFloatingWindow( SfxBindings *pBindinx, 554 SfxChildWindow *pCW, 555 Window* pParent, 556 const ResId& rResId) : 557 FloatingWindow(pParent, rResId), 558 pBindings(pBindinx), 559 pImp( new SfxFloatingWindow_Impl ) 560 { 561 pImp->pMgr = pCW; 562 pImp->bConstructed = sal_False; 563 SetUniqueId( GetHelpId() ); 564 SetHelpId(""); 565 if ( pBindinx ) 566 pImp->StartListening( *pBindinx ); 567 pImp->aMoveTimer.SetTimeout(50); 568 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxFloatingWindow,TimerHdl)); 569 } 570 571 //------------------------------------------------------------------------- 572 573 sal_Bool SfxFloatingWindow::Close() 574 575 /* [Beschreibung] 576 577 Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des 578 ChildWindow-Slots zerst"ort wird. 579 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 580 danach SfxFloatingWindow::Close() gerufen werden, wenn nicht das Close() 581 mit "return sal_False" abgebrochen wird. 582 583 */ 584 585 { 586 // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert 587 // werden kann 588 SfxBoolItem aValue( pImp->pMgr->GetType(), sal_False); 589 pBindings->GetDispatcher_Impl()->Execute( 590 pImp->pMgr->GetType(), 591 SFX_CALLMODE_RECORD|SFX_CALLMODE_SYNCHRON, &aValue, 0L ); 592 return sal_True; 593 } 594 595 // ----------------------------------------------------------------------- 596 597 SfxFloatingWindow::~SfxFloatingWindow() 598 599 /* [Beschreibung] 600 601 Dtor 602 */ 603 604 { 605 if ( pImp->pMgr->GetFrame() == pBindings->GetActiveFrame() ) 606 pBindings->SetActiveFrame( NULL ); 607 delete pImp; 608 } 609 610 //------------------------------------------------------------------------- 611 612 void SfxFloatingWindow::Resize() 613 614 /* [Beschreibung] 615 616 Diese virtuelle Methode der Klasse FloatingWindow merkt sich ggf. eine 617 ver"anderte Gr"o\se. 618 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 619 auch SfxFloatingWindow::Resize() gerufen werden. 620 */ 621 622 { 623 FloatingWindow::Resize(); 624 if ( pImp->bConstructed && pImp->pMgr ) 625 { 626 // start timer for saving window status information 627 pImp->aMoveTimer.Start(); 628 } 629 } 630 631 void SfxFloatingWindow::Move() 632 { 633 FloatingWindow::Move(); 634 if ( pImp->bConstructed && pImp->pMgr ) 635 { 636 // start timer for saving window status information 637 pImp->aMoveTimer.Start(); 638 } 639 } 640 641 /* 642 Implements a timer event that is triggered by a move or resize of the window 643 This will save config information to Views.xcu with a small delay 644 */ 645 IMPL_LINK( SfxFloatingWindow, TimerHdl, Timer*, EMPTYARG) 646 { 647 pImp->aMoveTimer.Stop(); 648 if ( pImp->bConstructed && pImp->pMgr ) 649 { 650 if ( !IsRollUp() ) 651 aSize = GetSizePixel(); 652 sal_uIntPtr nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE; 653 if ( GetStyle() & WB_SIZEABLE ) 654 nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT ); 655 pImp->aWinState = GetWindowState( nMask ); 656 GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SFX_CHILDWIN_DOCKINGWINDOW, SFX_ALIGNDOCKINGWINDOW, pImp->pMgr->GetType() ); 657 } 658 return 0; 659 } 660 661 //------------------------------------------------------------------------- 662 void SfxFloatingWindow::StateChanged( StateChangedType nStateChange ) 663 { 664 if ( nStateChange == STATE_CHANGE_INITSHOW ) 665 { 666 // FloatingWindows are not centered by default 667 if ( pImp->aWinState.Len() ) 668 SetWindowState( pImp->aWinState ); 669 pImp->bConstructed = sal_True; 670 } 671 672 FloatingWindow::StateChanged( nStateChange ); 673 } 674 675 676 void SfxFloatingWindow::Initialize(SfxChildWinInfo *pInfo) 677 678 /* [Beschreibung] 679 680 Initialisierung der Klasse SfxFloatingWindow "uber ein SfxChildWinInfo. 681 Die Initialisierung erfolgt erst in einem 2.Schritt 682 nach dem ctor und sollte vom ctor der abgeleiteten Klasse 683 oder von dem des SfxChildWindows aufgerufen werden. 684 */ 685 { 686 pImp->aWinState = pInfo->aWinState; 687 } 688 689 //------------------------------------------------------------------------- 690 691 void SfxFloatingWindow::FillInfo(SfxChildWinInfo& rInfo) const 692 693 /* [Beschreibung] 694 695 F"ullt ein SfxChildWinInfo mit f"ur SfxFloatingWindow spezifischen Daten, 696 damit sie in die INI-Datei geschrieben werden koennen. 697 Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in 698 der ChildWindow-Klasse erh"alt. 699 Eingetragen werden hier gemerkte Gr"o\se und das ZoomIn-Flag. 700 Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung 701 gerufen werden. 702 */ 703 704 { 705 rInfo.aSize = aSize; 706 if ( IsRollUp() ) 707 rInfo.nFlags |= SFX_CHILDWIN_ZOOMIN; 708 } 709 710 // SfxSingleTabDialog ---------------------------------------------------- 711 712 IMPL_LINK( SfxSingleTabDialog, OKHdl_Impl, Button *, EMPTYARG ) 713 714 /* [Beschreibung] 715 716 Ok_Handler; f"ur die gesetzte Page wird FillItemSet() gerufen. 717 */ 718 719 { 720 if ( !GetInputItemSet() ) 721 { 722 // TabPage without ItemSet 723 EndDialog( RET_OK ); 724 return 1; 725 } 726 727 if ( !GetOutputItemSet() ) 728 { 729 CreateOutputItemSet( *GetInputItemSet() ); 730 } 731 sal_Bool bModified = sal_False; 732 733 if ( pImpl->m_pSfxPage->HasExchangeSupport() ) 734 { 735 int nRet = pImpl->m_pSfxPage->DeactivatePage( GetOutputSetImpl() ); 736 if ( nRet != SfxTabPage::LEAVE_PAGE ) 737 return 0; 738 else 739 bModified = ( GetOutputItemSet()->Count() > 0 ); 740 } 741 else 742 bModified = pImpl->m_pSfxPage->FillItemSet( *GetOutputSetImpl() ); 743 744 if ( bModified ) 745 { 746 // auch noch schnell User-Daten im IniManager abspeichern 747 pImpl->m_pSfxPage->FillUserData(); 748 String sData( pImpl->m_pSfxPage->GetUserData() ); 749 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( GetUniqId() ) ); 750 aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( sData ) ) ); 751 EndDialog( RET_OK ); 752 } 753 else 754 EndDialog( RET_CANCEL ); 755 return 0; 756 } 757 758 // ----------------------------------------------------------------------- 759 760 SfxSingleTabDialog::SfxSingleTabDialog 761 ( 762 Window *pParent, 763 const SfxItemSet& rSet, 764 sal_uInt16 nUniqueId 765 ) : 766 767 /* [Beschreibung] 768 769 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge; 770 ID f"ur das ini-file wird "ubergeben. 771 */ 772 773 SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ), 774 775 pOKBtn ( 0 ), 776 pCancelBtn ( 0 ), 777 pHelpBtn ( 0 ), 778 pImpl ( new SingleTabDlgImpl ) 779 { 780 DBG_WARNING( "please use the ctor with ViewFrame" ); 781 SetInputSet( &rSet ); 782 } 783 784 // ----------------------------------------------------------------------- 785 786 SfxSingleTabDialog::SfxSingleTabDialog 787 ( 788 Window* pParent, 789 sal_uInt16 nUniqueId, 790 const SfxItemSet* pInSet 791 ) 792 793 /* [Beschreibung] 794 795 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge; 796 ID f"ur das ini-file wird "ubergeben. 797 Sollte nicht mehr benutzt werden. 798 */ 799 800 : SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ), 801 802 pOKBtn ( 0 ), 803 pCancelBtn ( 0 ), 804 pHelpBtn ( 0 ), 805 pImpl ( new SingleTabDlgImpl ) 806 { 807 DBG_WARNING( "bitte den Ctor mit ViewFrame verwenden" ); 808 SetInputSet( pInSet ); 809 } 810 811 // ----------------------------------------------------------------------- 812 813 SfxSingleTabDialog::SfxSingleTabDialog 814 ( 815 Window* pParent, 816 sal_uInt16 nUniqueId, 817 const String& rInfoURL 818 ) 819 820 /* [Beschreibung] 821 822 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge; 823 ID f"ur das ini-file wird "ubergeben. 824 */ 825 826 : SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ), 827 828 pOKBtn ( NULL ), 829 pCancelBtn ( NULL ), 830 pHelpBtn ( NULL ), 831 pImpl ( new SingleTabDlgImpl ) 832 { 833 pImpl->m_sInfoURL = rInfoURL; 834 } 835 836 // ----------------------------------------------------------------------- 837 838 SfxSingleTabDialog::~SfxSingleTabDialog() 839 { 840 delete pOKBtn; 841 delete pCancelBtn; 842 delete pHelpBtn; 843 delete pImpl->m_pTabPage; 844 delete pImpl->m_pSfxPage; 845 delete pImpl->m_pLine; 846 delete pImpl->m_pInfoImage; 847 delete pImpl; 848 } 849 850 // ----------------------------------------------------------------------- 851 852 void SfxSingleTabDialog::SetPage( TabPage* pNewPage ) 853 { 854 if ( !pImpl->m_pLine ) 855 pImpl->m_pLine = new FixedLine( this ); 856 857 if ( !pOKBtn ) 858 { 859 pOKBtn = new OKButton( this, WB_DEFBUTTON ); 860 pOKBtn->SetClickHdl( LINK( this, SfxSingleTabDialog, OKHdl_Impl ) ); 861 } 862 863 if ( pImpl->m_sInfoURL.Len() > 0 && !pImpl->m_pInfoImage ) 864 { 865 pImpl->m_pInfoImage = new ::svt::FixedHyperlinkImage( this ); 866 Image aInfoImage = Image( SfxResId( IMG_INFO ) ); 867 Size aImageSize = aInfoImage.GetSizePixel(); 868 aImageSize.Width() += 4; 869 aImageSize.Height() += 4; 870 pImpl->m_pInfoImage->SetSizePixel( aImageSize ); 871 pImpl->m_pInfoImage->SetImage( aInfoImage ); 872 pImpl->m_pInfoImage->SetURL( pImpl->m_sInfoURL ); 873 pImpl->m_pInfoImage->SetClickHdl( pImpl->m_aInfoLink ); 874 } 875 876 if ( pImpl->m_pTabPage ) 877 delete pImpl->m_pTabPage; 878 if ( pImpl->m_pSfxPage ) 879 delete pImpl->m_pSfxPage; 880 pImpl->m_pTabPage = pNewPage; 881 882 if ( pImpl->m_pTabPage ) 883 { 884 // Gr"ossen und Positionen anpassen 885 pImpl->m_pTabPage->SetPosPixel( Point() ); 886 Size aOutSz( pImpl->m_pTabPage->GetSizePixel() ); 887 Size aOffSz = LogicToPixel( Size( RSC_SP_CTRL_X, RSC_SP_CTRL_Y ), MAP_APPFONT ); 888 Size aFLSz = LogicToPixel( Size( aOutSz.Width(), RSC_CD_FIXEDLINE_HEIGHT ) ); 889 Size aBtnSz = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ), MAP_APPFONT ); 890 891 Point aPnt( 0, aOutSz.Height() ); 892 pImpl->m_pLine->SetPosSizePixel( aPnt, aFLSz ); 893 aPnt.X() = aOutSz.Width() - aOffSz.Width() - aBtnSz.Width(); 894 aPnt.Y() += aFLSz.Height() + ( aOffSz.Height() / 2 ); 895 pOKBtn->SetPosSizePixel( aPnt, aBtnSz ); 896 897 if ( pImpl->m_pInfoImage ) 898 { 899 aPnt.X() = aOffSz.Width(); 900 long nDelta = ( pImpl->m_pInfoImage->GetSizePixel().Height() - aBtnSz.Height() ) / 2; 901 aPnt.Y() -= nDelta; 902 pImpl->m_pInfoImage->SetPosPixel( aPnt ); 903 pImpl->m_pInfoImage->Show(); 904 } 905 906 aOutSz.Height() += aFLSz.Height() + ( aOffSz.Height() / 2 ) + aBtnSz.Height() + aOffSz.Height(); 907 SetOutputSizePixel( aOutSz ); 908 909 pImpl->m_pLine->Show(); 910 pOKBtn->Show(); 911 pImpl->m_pTabPage->Show(); 912 913 // Text der TabPage in den Dialog setzen 914 SetText( pImpl->m_pTabPage->GetText() ); 915 916 // Dialog bekommt HelpId der TabPage 917 SetHelpId( pImpl->m_pTabPage->GetHelpId() ); 918 SetUniqueId( pImpl->m_pTabPage->GetUniqueId() ); 919 } 920 } 921 922 // ----------------------------------------------------------------------- 923 924 void SfxSingleTabDialog::SetTabPage( SfxTabPage* pTabPage, 925 GetTabPageRanges pRangesFunc ) 926 /* [Beschreibung] 927 928 Setzen einer (neuen) TabPage; eine bereits vorhandene Page 929 wird gel"oscht. 930 Die "ubergebene Page wird durch Aufruf von Reset() mit dem 931 initial "ubergebenen Itemset initialisiert. 932 */ 933 934 { 935 if ( !pOKBtn ) 936 { 937 pOKBtn = new OKButton( this, WB_DEFBUTTON ); 938 pOKBtn->SetClickHdl( LINK( this, SfxSingleTabDialog, OKHdl_Impl ) ); 939 } 940 if ( !pCancelBtn ) 941 pCancelBtn = new CancelButton( this ); 942 if ( !pHelpBtn ) 943 pHelpBtn = new HelpButton( this ); 944 945 if ( pImpl->m_pTabPage ) 946 delete pImpl->m_pTabPage; 947 if ( pImpl->m_pSfxPage ) 948 delete pImpl->m_pSfxPage; 949 pImpl->m_pSfxPage = pTabPage; 950 fnGetRanges = pRangesFunc; 951 952 if ( pImpl->m_pSfxPage ) 953 { 954 // erstmal die User-Daten besorgen, dann erst Reset() 955 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( GetUniqId() ) ); 956 String sUserData; 957 Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME ); 958 OUString aTemp; 959 if ( aUserItem >>= aTemp ) 960 sUserData = String( aTemp ); 961 pImpl->m_pSfxPage->SetUserData( sUserData ); 962 pImpl->m_pSfxPage->Reset( *GetInputItemSet() ); 963 pImpl->m_pSfxPage->Show(); 964 965 // Gr"ossen und Positionen anpassen 966 pImpl->m_pSfxPage->SetPosPixel( Point() ); 967 Size aOutSz( pImpl->m_pSfxPage->GetSizePixel() ); 968 Size aBtnSiz = LogicToPixel( Size( 50, 14 ), MAP_APPFONT ); 969 Point aPnt( aOutSz.Width(), LogicToPixel( Point( 0, 6 ), MAP_APPFONT ).Y() ); 970 aOutSz.Width() += aBtnSiz.Width() + LogicToPixel( Size( 6, 0 ), MAP_APPFONT ).Width(); 971 SetOutputSizePixel( aOutSz ); 972 pOKBtn->SetPosSizePixel( aPnt, aBtnSiz ); 973 pOKBtn->Show(); 974 aPnt.Y() = LogicToPixel( Point( 0, 23 ), MAP_APPFONT ).Y(); 975 pCancelBtn->SetPosSizePixel( aPnt, aBtnSiz ); 976 pCancelBtn->Show(); 977 aPnt.Y() = LogicToPixel( Point( 0, 43 ), MAP_APPFONT ).Y(); 978 pHelpBtn->SetPosSizePixel( aPnt, aBtnSiz ); 979 980 if ( Help::IsContextHelpEnabled() ) 981 pHelpBtn->Show(); 982 983 // Text der TabPage in den Dialog setzen 984 SetText( pImpl->m_pSfxPage->GetText() ); 985 986 // Dialog bekommt HelpId der TabPage 987 SetHelpId( pImpl->m_pSfxPage->GetHelpId() ); 988 SetUniqueId( pImpl->m_pSfxPage->GetUniqueId() ); 989 } 990 } 991 992 // ----------------------------------------------------------------------- 993 994 void SfxSingleTabDialog::SetInfoLink( const Link& rLink ) 995 { 996 pImpl->m_aInfoLink = rLink; 997 } 998 999 //-------------------------------------------------------------------- 1000 // Vergleichsfunktion fuer qsort 1001 1002 #ifdef WNT 1003 int __cdecl BaseDlgsCmpUS_Impl( const void* p1, const void* p2 ) 1004 #else 1005 #if defined(OS2) && defined(ICC) 1006 int _Optlink BaseDlgsCmpUS_Impl( const void* p1, const void* p2 ) 1007 #else 1008 extern "C" int BaseDlgsCmpUS_Impl( const void* p1, const void* p2 ) 1009 #endif 1010 #endif 1011 { 1012 return *(sal_uInt16*)p1 - *(sal_uInt16*)p2; 1013 } 1014 1015 // ----------------------------------------------------------------------- 1016 1017 /* 1018 Bildet das Set "uber die Ranges der Page. Die Page muss die statische 1019 Methode f"ur das Erfragen ihrer Ranges bei SetTabPage angegeben haben, 1020 liefert also ihr Set onDemand. 1021 */ 1022 const sal_uInt16* SfxSingleTabDialog::GetInputRanges( const SfxItemPool& rPool ) 1023 { 1024 if ( GetInputItemSet() ) 1025 { 1026 DBG_ERROR( "Set bereits vorhanden!" ); 1027 return GetInputItemSet()->GetRanges(); 1028 } 1029 1030 if ( pRanges ) 1031 return pRanges; 1032 SvUShorts aUS(16, 16); 1033 1034 if ( fnGetRanges) 1035 { 1036 const sal_uInt16 *pTmpRanges = (fnGetRanges)(); 1037 const sal_uInt16 *pIter = pTmpRanges; 1038 sal_uInt16 nLen; 1039 for ( nLen = 0; *pIter; ++nLen, ++pIter ) 1040 ; 1041 aUS.Insert( pTmpRanges, nLen, aUS.Count() ); 1042 } 1043 1044 //! Doppelte Ids entfernen? 1045 sal_uInt16 nCount = aUS.Count(); 1046 1047 for ( sal_uInt16 i = 0; i < nCount; ++i ) 1048 aUS[i] = rPool.GetWhich( aUS[i]) ; 1049 1050 // sortieren 1051 if ( aUS.Count() > 1 ) 1052 qsort( (void*)aUS.GetData(), aUS.Count(), sizeof(sal_uInt16), BaseDlgsCmpUS_Impl ); 1053 1054 pRanges = new sal_uInt16[aUS.Count() + 1]; 1055 memcpy( pRanges, aUS.GetData(), sizeof(sal_uInt16) * aUS.Count() ); 1056 pRanges[aUS.Count()] = 0; 1057 return pRanges; 1058 } 1059 1060