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