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_vcl.hxx" 30 #include <tools/debug.hxx> 31 32 #include <vcl/svapp.hxx> 33 #include <vcl/menu.hxx> 34 #include <vcl/sound.hxx> 35 #include <vcl/svapp.hxx> 36 #include <vcl/event.hxx> 37 #include <vcl/syswin.hxx> 38 #include <vcl/taskpanelist.hxx> 39 #include <vcl/unowrap.hxx> 40 41 #include <salframe.hxx> 42 #include <svdata.hxx> 43 #include <brdwin.hxx> 44 #include <window.h> 45 46 using namespace ::com::sun::star::uno; 47 using namespace ::com::sun::star::lang; 48 49 // ======================================================================= 50 class SystemWindow::ImplData 51 { 52 public: 53 ImplData(); 54 ~ImplData(); 55 56 TaskPaneList* mpTaskPaneList; 57 Size maMaxOutSize; 58 rtl::OUString maRepresentedURL; 59 }; 60 61 SystemWindow::ImplData::ImplData() 62 { 63 mpTaskPaneList = NULL; 64 maMaxOutSize = Size( SHRT_MAX, SHRT_MAX ); 65 } 66 67 SystemWindow::ImplData::~ImplData() 68 { 69 if( mpTaskPaneList ) 70 delete mpTaskPaneList; 71 } 72 73 // ======================================================================= 74 75 SystemWindow::SystemWindow( WindowType nType ) : 76 Window( nType ) 77 { 78 mpImplData = new ImplData; 79 mpWindowImpl->mbSysWin = sal_True; 80 mpWindowImpl->mnActivateMode = ACTIVATE_MODE_GRABFOCUS; 81 82 mpMenuBar = NULL; 83 mbPined = sal_False; 84 mbRollUp = sal_False; 85 mbRollFunc = sal_False; 86 mbDockBtn = sal_False; 87 mbHideBtn = sal_False; 88 mbSysChild = sal_False; 89 mnMenuBarMode = MENUBAR_MODE_NORMAL; 90 mnIcon = 0; 91 } 92 93 SystemWindow::~SystemWindow() 94 { 95 delete mpImplData; 96 mpImplData = NULL; 97 } 98 99 // ----------------------------------------------------------------------- 100 101 long SystemWindow::Notify( NotifyEvent& rNEvt ) 102 { 103 // capture KeyEvents for menu handling 104 if ( rNEvt.GetType() == EVENT_KEYINPUT ) 105 { 106 MenuBar* pMBar = mpMenuBar; 107 if ( !pMBar && ( GetType() == WINDOW_FLOATINGWINDOW ) ) 108 { 109 Window* pWin = ImplGetFrameWindow()->ImplGetWindow(); 110 if( pWin && pWin->IsSystemWindow() ) 111 pMBar = ((SystemWindow*)pWin)->GetMenuBar(); 112 } 113 if ( pMBar && pMBar->ImplHandleKeyEvent( *rNEvt.GetKeyEvent(), sal_False ) ) 114 return sal_True; 115 } 116 117 return Window::Notify( rNEvt ); 118 } 119 120 // ----------------------------------------------------------------------- 121 122 long SystemWindow::PreNotify( NotifyEvent& rNEvt ) 123 { 124 // capture KeyEvents for taskpane cycling 125 if ( rNEvt.GetType() == EVENT_KEYINPUT ) 126 { 127 if( rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_F6 && 128 rNEvt.GetKeyEvent()->GetKeyCode().IsMod1() && 129 !rNEvt.GetKeyEvent()->GetKeyCode().IsShift() ) 130 { 131 // Ctrl-F6 goes directly to the document 132 GrabFocusToDocument(); 133 return sal_True; 134 } 135 else 136 { 137 TaskPaneList *pTList = mpImplData->mpTaskPaneList; 138 if( !pTList && ( GetType() == WINDOW_FLOATINGWINDOW ) ) 139 { 140 Window* pWin = ImplGetFrameWindow()->ImplGetWindow(); 141 if( pWin && pWin->IsSystemWindow() ) 142 pTList = ((SystemWindow*)pWin)->mpImplData->mpTaskPaneList; 143 } 144 if( !pTList ) 145 { 146 // search topmost system window which is the one to handle dialog/toolbar cycling 147 SystemWindow *pSysWin = this; 148 Window *pWin = this; 149 while( pWin ) 150 { 151 pWin = pWin->GetParent(); 152 if( pWin && pWin->IsSystemWindow() ) 153 pSysWin = (SystemWindow*) pWin; 154 } 155 pTList = pSysWin->mpImplData->mpTaskPaneList; 156 } 157 if( pTList && pTList->HandleKeyEvent( *rNEvt.GetKeyEvent() ) ) 158 return sal_True; 159 } 160 } 161 return Window::PreNotify( rNEvt ); 162 } 163 164 // ----------------------------------------------------------------------- 165 166 TaskPaneList* SystemWindow::GetTaskPaneList() 167 { 168 if( mpImplData->mpTaskPaneList ) 169 return mpImplData->mpTaskPaneList ; 170 else 171 { 172 mpImplData->mpTaskPaneList = new TaskPaneList(); 173 MenuBar* pMBar = mpMenuBar; 174 if ( !pMBar && ( GetType() == WINDOW_FLOATINGWINDOW ) ) 175 { 176 Window* pWin = ImplGetFrameWindow()->ImplGetWindow(); 177 if ( pWin && pWin->IsSystemWindow() ) 178 pMBar = ((SystemWindow*)pWin)->GetMenuBar(); 179 } 180 if( pMBar ) 181 mpImplData->mpTaskPaneList->AddWindow( pMBar->ImplGetWindow() ); 182 return mpImplData->mpTaskPaneList; 183 } 184 } 185 186 // ----------------------------------------------------------------------- 187 188 sal_Bool SystemWindow::Close() 189 { 190 ImplDelData aDelData; 191 ImplAddDel( &aDelData ); 192 ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE ); 193 if ( aDelData.IsDelete() ) 194 return sal_False; 195 ImplRemoveDel( &aDelData ); 196 197 if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() ) 198 return sal_False; 199 200 // Is Window not closeable, ignore close 201 Window* pBorderWin = ImplGetBorderWindow(); 202 WinBits nStyle; 203 if ( pBorderWin ) 204 nStyle = pBorderWin->GetStyle(); 205 else 206 nStyle = GetStyle(); 207 if ( !(nStyle & WB_CLOSEABLE) ) 208 { 209 Sound::Beep( SOUND_DISABLE, this ); 210 return sal_False; 211 } 212 213 Hide(); 214 215 return sal_True; 216 } 217 218 // ----------------------------------------------------------------------- 219 220 void SystemWindow::TitleButtonClick( sal_uInt16 ) 221 { 222 } 223 224 // ----------------------------------------------------------------------- 225 226 void SystemWindow::Pin() 227 { 228 } 229 230 // ----------------------------------------------------------------------- 231 232 void SystemWindow::Roll() 233 { 234 } 235 236 // ----------------------------------------------------------------------- 237 238 void SystemWindow::Resizing( Size& ) 239 { 240 } 241 242 // ----------------------------------------------------------------------- 243 244 void SystemWindow::SetZLevel( sal_uInt8 nLevel ) 245 { 246 Window* pWindow = this; 247 while ( pWindow->mpWindowImpl->mpBorderWindow ) 248 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 249 if ( pWindow->mpWindowImpl->mbOverlapWin && !pWindow->mpWindowImpl->mbFrame ) 250 { 251 sal_uInt8 nOldLevel = pWindow->mpWindowImpl->mpOverlapData->mnTopLevel; 252 pWindow->mpWindowImpl->mpOverlapData->mnTopLevel = nLevel; 253 // Wenn der neue Level groesser als der alte ist, schieben 254 // wir das Fenster nach hinten 255 if ( !IsReallyVisible() && (nLevel > nOldLevel) && pWindow->mpWindowImpl->mpNext ) 256 { 257 // Fenster aus der Liste entfernen 258 if ( pWindow->mpWindowImpl->mpPrev ) 259 pWindow->mpWindowImpl->mpPrev->mpWindowImpl->mpNext = pWindow->mpWindowImpl->mpNext; 260 else 261 pWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = pWindow->mpWindowImpl->mpNext; 262 pWindow->mpWindowImpl->mpNext->mpWindowImpl->mpPrev = pWindow->mpWindowImpl->mpPrev; 263 pWindow->mpWindowImpl->mpNext = NULL; 264 // und Fenster wieder in die Liste am Ende eintragen 265 pWindow->mpWindowImpl->mpPrev = pWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap; 266 pWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = pWindow; 267 pWindow->mpWindowImpl->mpPrev->mpWindowImpl->mpNext = pWindow; 268 } 269 } 270 } 271 272 // ----------------------------------------------------------------------- 273 274 void SystemWindow::SetRepresentedURL( const rtl::OUString& i_rURL ) 275 { 276 bool bChanged = (i_rURL != mpImplData->maRepresentedURL); 277 mpImplData->maRepresentedURL = i_rURL; 278 if ( !mbSysChild && bChanged ) 279 { 280 const Window* pWindow = this; 281 while ( pWindow->mpWindowImpl->mpBorderWindow ) 282 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 283 284 if ( pWindow->mpWindowImpl->mbFrame ) 285 pWindow->mpWindowImpl->mpFrame->SetRepresentedURL( i_rURL ); 286 } 287 } 288 // ----------------------------------------------------------------------- 289 290 const rtl::OUString& SystemWindow::GetRepresentedURL() const 291 { 292 return mpImplData->maRepresentedURL; 293 } 294 295 // ----------------------------------------------------------------------- 296 297 void SystemWindow::SetIcon( sal_uInt16 nIcon ) 298 { 299 if ( mnIcon == nIcon ) 300 return; 301 302 mnIcon = nIcon; 303 304 if ( !mbSysChild ) 305 { 306 const Window* pWindow = this; 307 while ( pWindow->mpWindowImpl->mpBorderWindow ) 308 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 309 310 if ( pWindow->mpWindowImpl->mbFrame ) 311 pWindow->mpWindowImpl->mpFrame->SetIcon( nIcon ); 312 } 313 } 314 315 // ----------------------------------------------------------------------- 316 317 sal_uInt8 SystemWindow::GetZLevel() const 318 { 319 const Window* pWindow = this; 320 while ( pWindow->mpWindowImpl->mpBorderWindow ) 321 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 322 if ( pWindow->mpWindowImpl->mpOverlapData ) 323 return pWindow->mpWindowImpl->mpOverlapData->mnTopLevel; 324 else 325 return sal_False; 326 } 327 328 // ----------------------------------------------------------------------- 329 330 void SystemWindow::EnableSaveBackground( sal_Bool bSave ) 331 { 332 if( ImplGetSVData()->maWinData.mbNoSaveBackground ) 333 bSave = false; 334 335 Window* pWindow = this; 336 while ( pWindow->mpWindowImpl->mpBorderWindow ) 337 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 338 if ( pWindow->mpWindowImpl->mbOverlapWin && !pWindow->mpWindowImpl->mbFrame ) 339 { 340 pWindow->mpWindowImpl->mpOverlapData->mbSaveBack = bSave; 341 if ( !bSave ) 342 pWindow->ImplDeleteOverlapBackground(); 343 } 344 } 345 346 // ----------------------------------------------------------------------- 347 348 sal_Bool SystemWindow::IsSaveBackgroundEnabled() const 349 { 350 const Window* pWindow = this; 351 while ( pWindow->mpWindowImpl->mpBorderWindow ) 352 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 353 if ( pWindow->mpWindowImpl->mpOverlapData ) 354 return pWindow->mpWindowImpl->mpOverlapData->mbSaveBack; 355 else 356 return sal_False; 357 } 358 359 // ----------------------------------------------------------------------- 360 361 void SystemWindow::ShowTitleButton( sal_uInt16 nButton, sal_Bool bVisible ) 362 { 363 if ( nButton == TITLE_BUTTON_DOCKING ) 364 { 365 if ( mbDockBtn != bVisible ) 366 { 367 mbDockBtn = bVisible; 368 if ( mpWindowImpl->mpBorderWindow ) 369 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetDockButton( bVisible ); 370 } 371 } 372 else if ( nButton == TITLE_BUTTON_HIDE ) 373 { 374 if ( mbHideBtn != bVisible ) 375 { 376 mbHideBtn = bVisible; 377 if ( mpWindowImpl->mpBorderWindow ) 378 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetHideButton( bVisible ); 379 } 380 } 381 else if ( nButton == TITLE_BUTTON_MENU ) 382 { 383 if ( mpWindowImpl->mpBorderWindow ) 384 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuButton( bVisible ); 385 } 386 else 387 return; 388 } 389 390 // ----------------------------------------------------------------------- 391 392 sal_Bool SystemWindow::IsTitleButtonVisible( sal_uInt16 nButton ) const 393 { 394 if ( nButton == TITLE_BUTTON_DOCKING ) 395 return mbDockBtn; 396 else /* if ( nButton == TITLE_BUTTON_HIDE ) */ 397 return mbHideBtn; 398 } 399 400 // ----------------------------------------------------------------------- 401 402 void SystemWindow::SetPin( sal_Bool bPin ) 403 { 404 if ( bPin != mbPined ) 405 { 406 mbPined = bPin; 407 if ( mpWindowImpl->mpBorderWindow ) 408 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetPin( bPin ); 409 } 410 } 411 412 // ----------------------------------------------------------------------- 413 414 void SystemWindow::RollUp() 415 { 416 if ( !mbRollUp ) 417 { 418 maOrgSize = GetOutputSizePixel(); 419 mbRollFunc = sal_True; 420 Size aSize = maRollUpOutSize; 421 if ( !aSize.Width() ) 422 aSize.Width() = GetOutputSizePixel().Width(); 423 mbRollUp = sal_True; 424 if ( mpWindowImpl->mpBorderWindow ) 425 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetRollUp( sal_True, aSize ); 426 else 427 SetOutputSizePixel( aSize ); 428 mbRollFunc = sal_False; 429 } 430 } 431 432 // ----------------------------------------------------------------------- 433 434 void SystemWindow::RollDown() 435 { 436 if ( mbRollUp ) 437 { 438 mbRollUp = sal_False; 439 if ( mpWindowImpl->mpBorderWindow ) 440 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetRollUp( sal_False, maOrgSize ); 441 else 442 SetOutputSizePixel( maOrgSize ); 443 } 444 } 445 446 // ----------------------------------------------------------------------- 447 448 void SystemWindow::SetMinOutputSizePixel( const Size& rSize ) 449 { 450 maMinOutSize = rSize; 451 if ( mpWindowImpl->mpBorderWindow ) 452 { 453 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMinOutputSize( rSize.Width(), rSize.Height() ); 454 if ( mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame ) 455 mpWindowImpl->mpBorderWindow->mpWindowImpl->mpFrame->SetMinClientSize( rSize.Width(), rSize.Height() ); 456 } 457 else if ( mpWindowImpl->mbFrame ) 458 mpWindowImpl->mpFrame->SetMinClientSize( rSize.Width(), rSize.Height() ); 459 } 460 461 // ----------------------------------------------------------------------- 462 463 void SystemWindow::SetMaxOutputSizePixel( const Size& rSize ) 464 { 465 Size aSize( rSize ); 466 if( aSize.Width() > SHRT_MAX || aSize.Width() <= 0 ) 467 aSize.Width() = SHRT_MAX; 468 if( aSize.Height() > SHRT_MAX || aSize.Height() <= 0 ) 469 aSize.Height() = SHRT_MAX; 470 471 mpImplData->maMaxOutSize = aSize; 472 if ( mpWindowImpl->mpBorderWindow ) 473 { 474 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMaxOutputSize( aSize.Width(), aSize.Height() ); 475 if ( mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame ) 476 mpWindowImpl->mpBorderWindow->mpWindowImpl->mpFrame->SetMaxClientSize( aSize.Width(), aSize.Height() ); 477 } 478 else if ( mpWindowImpl->mbFrame ) 479 mpWindowImpl->mpFrame->SetMaxClientSize( aSize.Width(), aSize.Height() ); 480 } 481 482 const Size& SystemWindow::GetMaxOutputSizePixel() const 483 { 484 return mpImplData->maMaxOutSize; 485 } 486 // ----------------------------------------------------------------------- 487 488 Size SystemWindow::GetResizeOutputSizePixel() const 489 { 490 Size aSize = GetOutputSizePixel(); 491 if ( aSize.Width() < maMinOutSize.Width() ) 492 aSize.Width() = maMinOutSize.Width(); 493 if ( aSize.Height() < maMinOutSize.Height() ) 494 aSize.Height() = maMinOutSize.Height(); 495 return aSize; 496 } 497 498 // ----------------------------------------------------------------------- 499 500 static void ImplWindowStateFromStr( WindowStateData& rData, const ByteString& rStr ) 501 { 502 sal_uLong nValidMask = 0; 503 xub_StrLen nIndex = 0; 504 ByteString aTokenStr; 505 506 aTokenStr = rStr.GetToken( 0, ',', nIndex ); 507 if ( aTokenStr.Len() ) 508 { 509 rData.SetX( aTokenStr.ToInt32() ); 510 if( rData.GetX() > -16384 && rData.GetX() < 16384 ) 511 nValidMask |= WINDOWSTATE_MASK_X; 512 else 513 rData.SetX( 0 ); 514 } 515 else 516 rData.SetX( 0 ); 517 aTokenStr = rStr.GetToken( 0, ',', nIndex ); 518 if ( aTokenStr.Len() ) 519 { 520 rData.SetY( aTokenStr.ToInt32() ); 521 if( rData.GetY() > -16384 && rData.GetY() < 16384 ) 522 nValidMask |= WINDOWSTATE_MASK_Y; 523 else 524 rData.SetY( 0 ); 525 } 526 else 527 rData.SetY( 0 ); 528 aTokenStr = rStr.GetToken( 0, ',', nIndex ); 529 if ( aTokenStr.Len() ) 530 { 531 rData.SetWidth( aTokenStr.ToInt32() ); 532 if( rData.GetWidth() > 0 && rData.GetWidth() < 16384 ) 533 nValidMask |= WINDOWSTATE_MASK_WIDTH; 534 else 535 rData.SetWidth( 0 ); 536 } 537 else 538 rData.SetWidth( 0 ); 539 aTokenStr = rStr.GetToken( 0, ';', nIndex ); 540 if ( aTokenStr.Len() ) 541 { 542 rData.SetHeight( aTokenStr.ToInt32() ); 543 if( rData.GetHeight() > 0 && rData.GetHeight() < 16384 ) 544 nValidMask |= WINDOWSTATE_MASK_HEIGHT; 545 else 546 rData.SetHeight( 0 ); 547 } 548 else 549 rData.SetHeight( 0 ); 550 aTokenStr = rStr.GetToken( 0, ';', nIndex ); 551 if ( aTokenStr.Len() ) 552 { 553 // #94144# allow Minimize again, should be masked out when read from configuration 554 // 91625 - ignore Minimize 555 sal_uLong nState = (sal_uLong)aTokenStr.ToInt32(); 556 //nState &= ~(WINDOWSTATE_STATE_MINIMIZED); 557 rData.SetState( nState ); 558 nValidMask |= WINDOWSTATE_MASK_STATE; 559 } 560 else 561 rData.SetState( 0 ); 562 563 // read maximized pos/size 564 aTokenStr = rStr.GetToken( 0, ',', nIndex ); 565 if ( aTokenStr.Len() ) 566 { 567 rData.SetMaximizedX( aTokenStr.ToInt32() ); 568 if( rData.GetMaximizedX() > -16384 && rData.GetMaximizedX() < 16384 ) 569 nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_X; 570 else 571 rData.SetMaximizedX( 0 ); 572 } 573 else 574 rData.SetMaximizedX( 0 ); 575 aTokenStr = rStr.GetToken( 0, ',', nIndex ); 576 if ( aTokenStr.Len() ) 577 { 578 rData.SetMaximizedY( aTokenStr.ToInt32() ); 579 if( rData.GetMaximizedY() > -16384 && rData.GetMaximizedY() < 16384 ) 580 nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_Y; 581 else 582 rData.SetMaximizedY( 0 ); 583 } 584 else 585 rData.SetMaximizedY( 0 ); 586 aTokenStr = rStr.GetToken( 0, ',', nIndex ); 587 if ( aTokenStr.Len() ) 588 { 589 rData.SetMaximizedWidth( aTokenStr.ToInt32() ); 590 if( rData.GetMaximizedWidth() > 0 && rData.GetMaximizedWidth() < 16384 ) 591 nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_WIDTH; 592 else 593 rData.SetMaximizedWidth( 0 ); 594 } 595 else 596 rData.SetMaximizedWidth( 0 ); 597 aTokenStr = rStr.GetToken( 0, ';', nIndex ); 598 if ( aTokenStr.Len() ) 599 { 600 rData.SetMaximizedHeight( aTokenStr.ToInt32() ); 601 if( rData.GetMaximizedHeight() > 0 && rData.GetMaximizedHeight() < 16384 ) 602 nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_HEIGHT; 603 else 604 rData.SetMaximizedHeight( 0 ); 605 } 606 else 607 rData.SetMaximizedHeight( 0 ); 608 609 // mark valid fields 610 rData.SetMask( nValidMask ); 611 } 612 613 // ----------------------------------------------------------------------- 614 615 static void ImplWindowStateToStr( const WindowStateData& rData, ByteString& rStr ) 616 { 617 sal_uLong nValidMask = rData.GetMask(); 618 if ( !nValidMask ) 619 return; 620 621 if ( nValidMask & WINDOWSTATE_MASK_X ) 622 rStr.Append( ByteString::CreateFromInt32( rData.GetX() ) ); 623 rStr.Append( ',' ); 624 if ( nValidMask & WINDOWSTATE_MASK_Y ) 625 rStr.Append( ByteString::CreateFromInt32( rData.GetY() ) ); 626 rStr.Append( ',' ); 627 if ( nValidMask & WINDOWSTATE_MASK_WIDTH ) 628 rStr.Append( ByteString::CreateFromInt32( rData.GetWidth() ) ); 629 rStr.Append( ',' ); 630 if ( nValidMask & WINDOWSTATE_MASK_HEIGHT ) 631 rStr.Append( ByteString::CreateFromInt32( rData.GetHeight() ) ); 632 rStr.Append( ';' ); 633 if ( nValidMask & WINDOWSTATE_MASK_STATE ) 634 { 635 // #94144# allow Minimize again, should be masked out when read from configuration 636 // 91625 - ignore Minimize 637 sal_uLong nState = rData.GetState(); 638 //nState &= ~(WINDOWSTATE_STATE_MINIMIZED); 639 rStr.Append( ByteString::CreateFromInt32( (long)nState ) ); 640 } 641 rStr.Append( ';' ); 642 if ( nValidMask & WINDOWSTATE_MASK_MAXIMIZED_X ) 643 rStr.Append( ByteString::CreateFromInt32( rData.GetMaximizedX() ) ); 644 rStr.Append( ',' ); 645 if ( nValidMask & WINDOWSTATE_MASK_MAXIMIZED_Y ) 646 rStr.Append( ByteString::CreateFromInt32( rData.GetMaximizedY() ) ); 647 rStr.Append( ',' ); 648 if ( nValidMask & WINDOWSTATE_MASK_MAXIMIZED_WIDTH ) 649 rStr.Append( ByteString::CreateFromInt32( rData.GetMaximizedWidth() ) ); 650 rStr.Append( ',' ); 651 if ( nValidMask & WINDOWSTATE_MASK_MAXIMIZED_HEIGHT ) 652 rStr.Append( ByteString::CreateFromInt32( rData.GetMaximizedHeight() ) ); 653 rStr.Append( ';' ); 654 } 655 656 // ----------------------------------------------------------------------- 657 658 void SystemWindow::ImplMoveToScreen( long& io_rX, long& io_rY, long i_nWidth, long i_nHeight, Window* i_pConfigureWin ) 659 { 660 Rectangle aScreenRect; 661 if( Application::IsMultiDisplay() ) 662 { 663 aScreenRect = Application::GetScreenPosSizePixel( GetScreenNumber() ); 664 } 665 else 666 { 667 aScreenRect = Application::GetScreenPosSizePixel( 0 ); 668 for( unsigned int i = 1; i < Application::GetScreenCount(); i++ ) 669 aScreenRect.Union( Application::GetScreenPosSizePixel( i ) ); 670 } 671 // unfortunately most of the time width and height are not really known 672 if( i_nWidth < 1 ) 673 i_nWidth = 50; 674 if( i_nHeight < 1 ) 675 i_nHeight = 50; 676 677 // check left border 678 bool bMove = false; 679 if( io_rX + i_nWidth < aScreenRect.Left() ) 680 { 681 bMove = true; 682 io_rX = aScreenRect.Left(); 683 } 684 // check right border 685 if( io_rX > aScreenRect.Right() - i_nWidth ) 686 { 687 bMove = true; 688 io_rX = aScreenRect.Right() - i_nWidth; 689 } 690 // check top border 691 if( io_rY + i_nHeight < aScreenRect.Top() ) 692 { 693 bMove = true; 694 io_rY = aScreenRect.Top(); 695 } 696 // check bottom border 697 if( io_rY > aScreenRect.Bottom() - i_nHeight ) 698 { 699 bMove = true; 700 io_rY = aScreenRect.Bottom() - i_nHeight; 701 } 702 Window* pParent = i_pConfigureWin->GetParent(); 703 if( bMove && pParent ) 704 { 705 // calculate absolute screen pos here, since that is what is contained in WindowState 706 Point aParentAbsPos( pParent->OutputToAbsoluteScreenPixel( Point(0,0) ) ); 707 Size aParentSizePixel( pParent->GetOutputSizePixel() ); 708 Point aPos( (aParentSizePixel.Width() - i_nWidth) / 2, 709 (aParentSizePixel.Height() - i_nHeight) / 2 ); 710 io_rX = aParentAbsPos.X() + aPos.X(); 711 io_rY = aParentAbsPos.Y() + aPos.Y(); 712 } 713 } 714 715 void SystemWindow::SetWindowStateData( const WindowStateData& rData ) 716 { 717 sal_uLong nValidMask = rData.GetMask(); 718 if ( !nValidMask ) 719 return; 720 721 if ( mbSysChild ) 722 return; 723 724 Window* pWindow = this; 725 while ( pWindow->mpWindowImpl->mpBorderWindow ) 726 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 727 728 if ( pWindow->mpWindowImpl->mbFrame ) 729 { 730 sal_uLong nState = rData.GetState(); 731 SalFrameState aState; 732 aState.mnMask = rData.GetMask(); 733 aState.mnX = rData.GetX(); 734 aState.mnY = rData.GetY(); 735 aState.mnWidth = rData.GetWidth(); 736 aState.mnHeight = rData.GetHeight(); 737 738 if( rData.GetMask() & (WINDOWSTATE_MASK_WIDTH|WINDOWSTATE_MASK_HEIGHT) ) 739 { 740 // #i43799# adjust window state sizes if a minimial output size was set 741 // otherwise the frame and the client might get different sizes 742 if( maMinOutSize.Width() > aState.mnWidth ) 743 aState.mnWidth = maMinOutSize.Width(); 744 if( maMinOutSize.Height() > aState.mnHeight ) 745 aState.mnHeight = maMinOutSize.Height(); 746 } 747 748 aState.mnMaximizedX = rData.GetMaximizedX(); 749 aState.mnMaximizedY = rData.GetMaximizedY(); 750 aState.mnMaximizedWidth = rData.GetMaximizedWidth(); 751 aState.mnMaximizedHeight = rData.GetMaximizedHeight(); 752 // #94144# allow Minimize again, should be masked out when read from configuration 753 // 91625 - ignore Minimize 754 //nState &= ~(WINDOWSTATE_STATE_MINIMIZED); 755 aState.mnState = nState & SAL_FRAMESTATE_SYSTEMMASK; 756 757 // normalize window positions onto screen 758 ImplMoveToScreen( aState.mnX, aState.mnY, aState.mnWidth, aState.mnHeight, pWindow ); 759 ImplMoveToScreen( aState.mnMaximizedX, aState.mnMaximizedY, aState.mnMaximizedWidth, aState.mnMaximizedHeight, pWindow ); 760 761 // #96568# avoid having multiple frames at the same screen location 762 // do the check only if not maximized 763 if( !((rData.GetMask() & WINDOWSTATE_MASK_STATE) && (nState & WINDOWSTATE_STATE_MAXIMIZED)) ) 764 if( rData.GetMask() & (WINDOWSTATE_MASK_POS|WINDOWSTATE_MASK_WIDTH|WINDOWSTATE_MASK_HEIGHT) ) 765 { 766 Rectangle aDesktop = GetDesktopRectPixel(); 767 ImplSVData *pSVData = ImplGetSVData(); 768 Window *pWin = pSVData->maWinData.mpFirstFrame; 769 sal_Bool bWrapped = sal_False; 770 while( pWin ) 771 { 772 if( !pWin->ImplIsRealParentPath( this ) && ( pWin != this ) && 773 pWin->ImplGetWindow()->IsTopWindow() && pWin->mpWindowImpl->mbReallyVisible ) 774 { 775 SalFrameGeometry g = pWin->mpWindowImpl->mpFrame->GetGeometry(); 776 if( abs(g.nX-aState.mnX) < 2 && abs(g.nY-aState.mnY) < 5 ) 777 { 778 long displacement = g.nTopDecoration ? g.nTopDecoration : 20; 779 if( (unsigned long) (aState.mnX + displacement + aState.mnWidth + g.nRightDecoration) > (unsigned long) aDesktop.nRight || 780 (unsigned long) (aState.mnY + displacement + aState.mnHeight + g.nBottomDecoration) > (unsigned long) aDesktop.nBottom ) 781 { 782 // displacing would leave screen 783 aState.mnX = g.nLeftDecoration ? g.nLeftDecoration : 10; // should result in (0,0) 784 aState.mnY = displacement; 785 if( bWrapped || 786 (unsigned long) (aState.mnX + displacement + aState.mnWidth + g.nRightDecoration) > (unsigned long) aDesktop.nRight || 787 (unsigned long) (aState.mnY + displacement + aState.mnHeight + g.nBottomDecoration) > (unsigned long) aDesktop.nBottom ) 788 break; // further displacement not possible -> break 789 // avoid endless testing 790 bWrapped = sal_True; 791 } 792 else 793 { 794 // displace 795 aState.mnX += displacement; 796 aState.mnY += displacement; 797 } 798 pWin = pSVData->maWinData.mpFirstFrame; // check new pos again 799 } 800 } 801 pWin = pWin->mpWindowImpl->mpFrameData->mpNextFrame; 802 } 803 } 804 805 mpWindowImpl->mpFrame->SetWindowState( &aState ); 806 807 // do a synchronous resize for layout reasons 808 // but use rData only when the window is not to be maximized (#i38089#) 809 // otherwise we have no useful size information 810 if( (rData.GetMask() & WINDOWSTATE_MASK_STATE) && (nState & WINDOWSTATE_STATE_MAXIMIZED) ) 811 { 812 // query maximized size from frame 813 SalFrameGeometry aGeometry = mpWindowImpl->mpFrame->GetGeometry(); 814 815 // but use it only if it is different from the restore size (rData) 816 // as currently only on windows the exact size of a maximized window 817 // can be computed without actually showing the window 818 if( aGeometry.nWidth != rData.GetWidth() || aGeometry.nHeight != rData.GetHeight() ) 819 ImplHandleResize( pWindow, aGeometry.nWidth, aGeometry.nHeight ); 820 } 821 else 822 if( rData.GetMask() & (WINDOWSTATE_MASK_WIDTH|WINDOWSTATE_MASK_HEIGHT) ) 823 ImplHandleResize( pWindow, aState.mnWidth, aState.mnHeight ); // #i43799# use aState and not rData, see above 824 } 825 else 826 { 827 sal_uInt16 nPosSize = 0; 828 if ( nValidMask & WINDOWSTATE_MASK_X ) 829 nPosSize |= WINDOW_POSSIZE_X; 830 if ( nValidMask & WINDOWSTATE_MASK_Y ) 831 nPosSize |= WINDOW_POSSIZE_Y; 832 if ( nValidMask & WINDOWSTATE_MASK_WIDTH ) 833 nPosSize |= WINDOW_POSSIZE_WIDTH; 834 if ( nValidMask & WINDOWSTATE_MASK_HEIGHT ) 835 nPosSize |= WINDOW_POSSIZE_HEIGHT; 836 837 if( IsRollUp() ) 838 RollDown(); 839 840 long nX = rData.GetX(); 841 long nY = rData.GetY(); 842 long nWidth = rData.GetWidth(); 843 long nHeight = rData.GetHeight(); 844 const SalFrameGeometry& rGeom = pWindow->mpWindowImpl->mpFrame->GetGeometry(); 845 if( nX < 0 ) 846 nX = 0; 847 if( nX + nWidth > (long) rGeom.nWidth ) 848 nX = rGeom.nWidth - nWidth; 849 if( nY < 0 ) 850 nY = 0; 851 if( nY + nHeight > (long) rGeom.nHeight ) 852 nY = rGeom.nHeight - nHeight; 853 SetPosSizePixel( nX, nY, nWidth, nHeight, nPosSize ); 854 maOrgSize = Size( nWidth, nHeight ); 855 856 // 91625 - ignore Minimize 857 if ( nValidMask & WINDOWSTATE_MASK_STATE ) 858 { 859 sal_uLong nState = rData.GetState(); 860 if ( nState & WINDOWSTATE_STATE_ROLLUP ) 861 RollUp(); 862 else 863 RollDown(); 864 } 865 } 866 } 867 868 // ----------------------------------------------------------------------- 869 870 void SystemWindow::GetWindowStateData( WindowStateData& rData ) const 871 { 872 sal_uLong nValidMask = rData.GetMask(); 873 if ( !nValidMask ) 874 return; 875 876 if ( mbSysChild ) 877 return; 878 879 const Window* pWindow = this; 880 while ( pWindow->mpWindowImpl->mpBorderWindow ) 881 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 882 883 if ( pWindow->mpWindowImpl->mbFrame ) 884 { 885 SalFrameState aState; 886 aState.mnMask = 0xFFFFFFFF; 887 if ( mpWindowImpl->mpFrame->GetWindowState( &aState ) ) 888 { 889 if ( nValidMask & WINDOWSTATE_MASK_X ) 890 rData.SetX( aState.mnX ); 891 if ( nValidMask & WINDOWSTATE_MASK_Y ) 892 rData.SetY( aState.mnY ); 893 if ( nValidMask & WINDOWSTATE_MASK_WIDTH ) 894 rData.SetWidth( aState.mnWidth ); 895 if ( nValidMask & WINDOWSTATE_MASK_HEIGHT ) 896 rData.SetHeight( aState.mnHeight ); 897 if ( aState.mnMask & SAL_FRAMESTATE_MASK_MAXIMIZED_X ) 898 { 899 rData.SetMaximizedX( aState.mnMaximizedX ); 900 nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_X; 901 } 902 if ( aState.mnMask & SAL_FRAMESTATE_MASK_MAXIMIZED_Y ) 903 { 904 rData.SetMaximizedY( aState.mnMaximizedY ); 905 nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_Y; 906 } 907 if ( aState.mnMask & SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH ) 908 { 909 rData.SetMaximizedWidth( aState.mnMaximizedWidth ); 910 nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_WIDTH; 911 } 912 if ( aState.mnMask & SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT ) 913 { 914 rData.SetMaximizedHeight( aState.mnMaximizedHeight ); 915 nValidMask |= WINDOWSTATE_MASK_MAXIMIZED_HEIGHT; 916 } 917 if ( nValidMask & WINDOWSTATE_MASK_STATE ) 918 { 919 // #94144# allow Minimize again, should be masked out when read from configuration 920 // 91625 - ignore Minimize 921 if ( !(nValidMask&WINDOWSTATE_MASK_MINIMIZED) ) 922 aState.mnState &= ~(WINDOWSTATE_STATE_MINIMIZED); 923 rData.SetState( aState.mnState ); 924 } 925 rData.SetMask( nValidMask ); 926 } 927 else 928 rData.SetMask( 0 ); 929 } 930 else 931 { 932 Point aPos = GetPosPixel(); 933 Size aSize = GetSizePixel(); 934 sal_uLong nState = 0; 935 936 if ( IsRollUp() ) 937 { 938 aSize.Height() += maOrgSize.Height(); 939 nState |= WINDOWSTATE_STATE_ROLLUP; 940 } 941 942 if ( nValidMask & WINDOWSTATE_MASK_X ) 943 rData.SetX( aPos.X() ); 944 if ( nValidMask & WINDOWSTATE_MASK_Y ) 945 rData.SetY( aPos.Y() ); 946 if ( nValidMask & WINDOWSTATE_MASK_WIDTH ) 947 rData.SetWidth( aSize.Width() ); 948 if ( nValidMask & WINDOWSTATE_MASK_HEIGHT ) 949 rData.SetHeight( aSize.Height() ); 950 if ( nValidMask & WINDOWSTATE_MASK_STATE ) 951 rData.SetState( nState ); 952 } 953 } 954 955 // ----------------------------------------------------------------------- 956 957 void SystemWindow::SetWindowState( const ByteString& rStr ) 958 { 959 if ( !rStr.Len() ) 960 return; 961 962 WindowStateData aData; 963 ImplWindowStateFromStr( aData, rStr ); 964 SetWindowStateData( aData ); 965 } 966 967 // ----------------------------------------------------------------------- 968 969 ByteString SystemWindow::GetWindowState( sal_uLong nMask ) const 970 { 971 WindowStateData aData; 972 aData.SetMask( nMask ); 973 GetWindowStateData( aData ); 974 975 ByteString aStr; 976 ImplWindowStateToStr( aData, aStr ); 977 return aStr; 978 } 979 980 // ----------------------------------------------------------------------- 981 982 void SystemWindow::SetMenuBar( MenuBar* pMenuBar ) 983 { 984 if ( mpMenuBar != pMenuBar ) 985 { 986 MenuBar* pOldMenuBar = mpMenuBar; 987 Window* pOldWindow = NULL; 988 Window* pNewWindow=NULL; 989 mpMenuBar = pMenuBar; 990 991 if ( mpWindowImpl->mpBorderWindow && (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) ) 992 { 993 if ( pOldMenuBar ) 994 pOldWindow = pOldMenuBar->ImplGetWindow(); 995 else 996 pOldWindow = NULL; 997 if ( pOldWindow ) 998 { 999 ImplCallEventListeners( VCLEVENT_WINDOW_MENUBARREMOVED, (void*) pOldMenuBar ); 1000 pOldWindow->SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >() ); 1001 } 1002 if ( pMenuBar ) 1003 { 1004 DBG_ASSERT( !pMenuBar->pWindow, "SystemWindow::SetMenuBar() - MenuBars can only set in one SystemWindow at time" ); 1005 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuBarWindow( pNewWindow = MenuBar::ImplCreate( mpWindowImpl->mpBorderWindow, pOldWindow, pMenuBar ) ); 1006 ImplCallEventListeners( VCLEVENT_WINDOW_MENUBARADDED, (void*) pMenuBar ); 1007 } 1008 else 1009 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuBarWindow( NULL ); 1010 ImplToBottomChild(); 1011 if ( pOldMenuBar ) 1012 { 1013 sal_Bool bDelete = (pMenuBar == 0) ? sal_True : sal_False; 1014 if( bDelete && pOldWindow ) 1015 { 1016 if( mpImplData->mpTaskPaneList ) 1017 mpImplData->mpTaskPaneList->RemoveWindow( pOldWindow ); 1018 } 1019 MenuBar::ImplDestroy( pOldMenuBar, bDelete ); 1020 if( bDelete ) 1021 pOldWindow = NULL; // will be deleted in MenuBar::ImplDestroy, 1022 } 1023 1024 } 1025 else 1026 { 1027 if( pMenuBar ) 1028 pNewWindow = pMenuBar->ImplGetWindow(); 1029 if( pOldMenuBar ) 1030 pOldWindow = pOldMenuBar->ImplGetWindow(); 1031 } 1032 1033 // update taskpane list to make menubar accessible 1034 if( mpImplData->mpTaskPaneList ) 1035 { 1036 if( pOldWindow ) 1037 mpImplData->mpTaskPaneList->RemoveWindow( pOldWindow ); 1038 if( pNewWindow ) 1039 mpImplData->mpTaskPaneList->AddWindow( pNewWindow ); 1040 } 1041 } 1042 } 1043 1044 // ----------------------------------------------------------------------- 1045 1046 void SystemWindow::SetMenuBarMode( sal_uInt16 nMode ) 1047 { 1048 if ( mnMenuBarMode != nMode ) 1049 { 1050 mnMenuBarMode = nMode; 1051 if ( mpWindowImpl->mpBorderWindow && (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) ) 1052 { 1053 if ( nMode == MENUBAR_MODE_HIDE ) 1054 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuBarMode( sal_True ); 1055 else 1056 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetMenuBarMode( sal_False ); 1057 } 1058 } 1059 } 1060 1061 // ----------------------------------------------------------------------- 1062 1063 sal_Bool SystemWindow::ImplIsInTaskPaneList( Window* pWin ) 1064 { 1065 if( mpImplData && mpImplData->mpTaskPaneList ) 1066 return mpImplData->mpTaskPaneList->IsInList( pWin ); 1067 return sal_False; 1068 } 1069 1070 // ----------------------------------------------------------------------- 1071 1072 unsigned int SystemWindow::GetScreenNumber() const 1073 { 1074 return mpWindowImpl->mpFrame->maGeometry.nScreenNumber; 1075 } 1076 1077 // ----------------------------------------------------------------------- 1078 1079 void SystemWindow::SetScreenNumber( unsigned int nScreen) 1080 { 1081 mpWindowImpl->mpFrame->SetScreenNumber( nScreen ); 1082 } 1083