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