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 27 #include "tools/time.hxx" 28 #include "tools/debug.hxx" 29 #include "tools/rc.h" 30 31 #include "unotools/fontcfg.hxx" 32 #include "unotools/confignode.hxx" 33 34 #include "vcl/unohelp.hxx" 35 #include "vcl/salgtype.hxx" 36 #include "vcl/event.hxx" 37 #include "vcl/help.hxx" 38 #include "vcl/cursor.hxx" 39 #include "vcl/svapp.hxx" 40 #include "vcl/window.hxx" 41 #include "vcl/syswin.hxx" 42 #include "vcl/syschild.hxx" 43 #include "vcl/dockwin.hxx" 44 #include "vcl/menu.hxx" 45 #include "vcl/wrkwin.hxx" 46 #include "vcl/wall.hxx" 47 #include "vcl/gradient.hxx" 48 #include "vcl/salctype.hxx" 49 #include "vcl/button.hxx" 50 #include "vcl/taskpanelist.hxx" 51 #include "vcl/dialog.hxx" 52 #include "vcl/unowrap.hxx" 53 #include "vcl/gdimtf.hxx" 54 #include "vcl/pdfextoutdevdata.hxx" 55 #include "vcl/lazydelete.hxx" 56 57 // declare system types in sysdata.hxx 58 #include "svsys.h" 59 #include "vcl/sysdata.hxx" 60 61 #include "salframe.hxx" 62 #include "salobj.hxx" 63 #include "salinst.hxx" 64 #include "salgdi.hxx" 65 #include "svdata.hxx" 66 #include "dbggui.hxx" 67 #include "outfont.hxx" 68 #include "window.h" 69 #include "toolbox.h" 70 #include "outdev.h" 71 #include "brdwin.hxx" 72 #include "helpwin.hxx" 73 #include "sallayout.hxx" 74 #include "dndlcon.hxx" 75 #include "dndevdis.hxx" 76 77 #include "com/sun/star/awt/XWindowPeer.hpp" 78 #include "com/sun/star/rendering/XCanvas.hpp" 79 #include "com/sun/star/rendering/XSpriteCanvas.hpp" 80 #include "com/sun/star/awt/XWindow.hpp" 81 #include "comphelper/processfactory.hxx" 82 #include "com/sun/star/datatransfer/dnd/XDragSource.hpp" 83 #include "com/sun/star/datatransfer/dnd/XDropTarget.hpp" 84 #include "com/sun/star/datatransfer/clipboard/XClipboard.hpp" 85 #include "com/sun/star/awt/XTopWindow.hpp" 86 #include "com/sun/star/awt/XDisplayConnection.hpp" 87 #include "com/sun/star/lang/XInitialization.hpp" 88 #include "com/sun/star/lang/XComponent.hpp" 89 #include "com/sun/star/lang/XServiceName.hpp" 90 #include "com/sun/star/accessibility/XAccessible.hpp" 91 #include "com/sun/star/accessibility/AccessibleRole.hpp" 92 93 #include <set> 94 #include <typeinfo> 95 96 using namespace rtl; 97 using namespace ::com::sun::star::uno; 98 using namespace ::com::sun::star::lang; 99 using namespace ::com::sun::star::datatransfer::clipboard; 100 using namespace ::com::sun::star::datatransfer::dnd; 101 using namespace ::com::sun::star; 102 using namespace com::sun; 103 104 using ::com::sun::star::awt::XTopWindow; 105 106 // ======================================================================= 107 108 DBG_NAME( Window ) 109 110 // ======================================================================= 111 112 #define IMPL_PAINT_PAINT ((sal_uInt16)0x0001) 113 #define IMPL_PAINT_PAINTALL ((sal_uInt16)0x0002) 114 #define IMPL_PAINT_PAINTALLCHILDS ((sal_uInt16)0x0004) 115 #define IMPL_PAINT_PAINTCHILDS ((sal_uInt16)0x0008) 116 #define IMPL_PAINT_ERASE ((sal_uInt16)0x0010) 117 #define IMPL_PAINT_CHECKRTL ((sal_uInt16)0x0020) 118 119 // ----------------------------------------------------------------------- 120 121 typedef Window* PWINDOW; 122 123 // ----------------------------------------------------------------------- 124 125 struct ImplCalcToTopData 126 { 127 ImplCalcToTopData* mpNext; 128 Window* mpWindow; 129 Region* mpInvalidateRegion; 130 }; 131 132 ImplAccessibleInfos::ImplAccessibleInfos() 133 { 134 nAccessibleRole = 0xFFFF; 135 pAccessibleName = NULL; 136 pAccessibleDescription = NULL; 137 pLabeledByWindow = NULL; 138 pLabelForWindow = NULL; 139 pMemberOfWindow = NULL; 140 } 141 142 ImplAccessibleInfos::~ImplAccessibleInfos() 143 { 144 delete pAccessibleName; 145 delete pAccessibleDescription; 146 } 147 148 // ----------------------------------------------------------------------- 149 150 WindowImpl::WindowImpl( WindowType nType ) 151 { 152 maZoom = Fraction( 1, 1 ); 153 maWinRegion = Region(true); 154 maWinClipRegion = Region(true); 155 mpWinData = NULL; // Extra Window Data, that we dont need for all windows 156 mpOverlapData = NULL; // Overlap Data 157 mpFrameData = NULL; // Frame Data 158 mpFrame = NULL; // Pointer to frame window 159 mpSysObj = NULL; 160 mpFrameWindow = NULL; // window to top level parent (same as frame window) 161 mpOverlapWindow = NULL; // first overlap parent 162 mpBorderWindow = NULL; // Border-Window 163 mpClientWindow = NULL; // Client-Window of a FrameWindow 164 mpParent = NULL; // parent (inkl. BorderWindow) 165 mpRealParent = NULL; // real parent (exkl. BorderWindow) 166 mpFirstChild = NULL; // first child window 167 mpLastChild = NULL; // last child window 168 mpFirstOverlap = NULL; // first overlap window (only set in overlap windows) 169 mpLastOverlap = NULL; // last overlap window (only set in overlap windows) 170 mpPrev = NULL; // prev window 171 mpNext = NULL; // next window 172 mpNextOverlap = NULL; // next overlap window of frame 173 mpLastFocusWindow = NULL; // window for focus restore 174 mpDlgCtrlDownWindow = NULL; // window for dialog control 175 mpFirstDel = NULL; // Dtor notification list 176 mpUserData = NULL; // user data 177 mpExtImpl = NULL; // extended implementation data 178 mpCursor = NULL; // cursor 179 mpControlFont = NULL; // font propertie 180 mpVCLXWindow = NULL; 181 mpAccessibleInfos = NULL; 182 maControlForeground = Color( COL_TRANSPARENT ); // foreground color not set 183 maControlBackground = Color( COL_TRANSPARENT ); // background color not set 184 mnLeftBorder = 0; // left border 185 mnTopBorder = 0; // top border 186 mnRightBorder = 0; // right border 187 mnBottomBorder = 0; // bottom border 188 mnX = 0; // X-Position to Parent 189 mnY = 0; // Y-Position to Parent 190 mnAbsScreenX = 0; // absolute X-position on screen, used for RTL window positioning 191 mpChildClipRegion = NULL; // Child-Clip-Region when ClipChildren 192 mpPaintRegion = NULL; // Paint-ClipRegion 193 mnStyle = 0; // style (init in ImplInitWindow) 194 mnPrevStyle = 0; // prevstyle (set in SetStyle) 195 mnExtendedStyle = 0; // extended style (init in ImplInitWindow) 196 mnPrevExtendedStyle = 0; // prevstyle (set in SetExtendedStyle) 197 mnType = nType; // window type 198 mnGetFocusFlags = 0; // Flags fuer GetFocus()-Aufruf 199 mnWaitCount = 0; // Wait-Count (>1 == Warte-MousePointer) 200 mnPaintFlags = 0; // Flags for ImplCallPaint 201 mnParentClipMode = 0; // Flags for Parent-ClipChildren-Mode 202 mnActivateMode = 0; // Wird bei System/Overlap-Windows umgesetzt 203 mnDlgCtrlFlags = 0; // DialogControl-Flags 204 mnLockCount = 0; // LockCount 205 meAlwaysInputMode = AlwaysInputNone; // neither AlwaysEnableInput nor AlwaysDisableInput called 206 mbFrame = sal_False; // sal_True: Window is a frame window 207 mbBorderWin = sal_False; // sal_True: Window is a border window 208 mbOverlapWin = sal_False; // sal_True: Window is a overlap window 209 mbSysWin = sal_False; // sal_True: SystemWindow is the base class 210 mbDialog = sal_False; // sal_True: Dialog is the base class 211 mbDockWin = sal_False; // sal_True: DockingWindow is the base class 212 mbFloatWin = sal_False; // sal_True: FloatingWindow is the base class 213 mbPushButton = sal_False; // sal_True: PushButton is the base class 214 mbToolBox = sal_False; // sal_True: ToolBox is the base class 215 mbMenuFloatingWindow= sal_False; // sal_True: MenuFloatingWindow is the base class 216 mbToolbarFloatingWindow= sal_False; // sal_True: ImplPopupFloatWin is the base class, used for subtoolbars 217 mbSplitter = sal_False; // sal_True: Splitter is the base class 218 mbVisible = sal_False; // sal_True: Show( sal_True ) called 219 mbOverlapVisible = sal_False; // sal_True: Hide called for visible window from ImplHideAllOverlapWindow() 220 mbDisabled = sal_False; // sal_True: Enable( sal_False ) called 221 mbInputDisabled = sal_False; // sal_True: EnableInput( sal_False ) called 222 mbDropDisabled = sal_False; // sal_True: Drop is enabled 223 mbNoUpdate = sal_False; // sal_True: SetUpdateMode( sal_False ) called 224 mbNoParentUpdate = sal_False; // sal_True: SetParentUpdateMode( sal_False ) called 225 mbActive = sal_False; // sal_True: Window Active 226 mbParentActive = sal_False; // sal_True: OverlapActive from Parent 227 mbReallyVisible = sal_False; // sal_True: this and all parents to an overlaped window are visible 228 mbReallyShown = sal_False; // sal_True: this and all parents to an overlaped window are shown 229 mbInInitShow = sal_False; // sal_True: we are in InitShow 230 mbChildNotify = sal_False; // sal_True: ChildNotify 231 mbChildPtrOverwrite = sal_False; // sal_True: PointerStyle overwrites Child-Pointer 232 mbNoPtrVisible = sal_False; // sal_True: ShowPointer( sal_False ) called 233 mbMouseMove = sal_False; // sal_True: BaseMouseMove called 234 mbPaintFrame = sal_False; // sal_True: Paint is visible, but not painted 235 mbInPaint = sal_False; // sal_True: Inside PaintHdl 236 mbMouseButtonDown = sal_False; // sal_True: BaseMouseButtonDown called 237 mbMouseButtonUp = sal_False; // sal_True: BaseMouseButtonUp called 238 mbKeyInput = sal_False; // sal_True: BaseKeyInput called 239 mbKeyUp = sal_False; // sal_True: BaseKeyUp called 240 mbCommand = sal_False; // sal_True: BaseCommand called 241 mbDefPos = sal_True; // sal_True: Position is not Set 242 mbDefSize = sal_True; // sal_True: Size is not Set 243 mbCallMove = sal_True; // sal_True: Move must be called by Show 244 mbCallResize = sal_True; // sal_True: Resize must be called by Show 245 mbWaitSystemResize = sal_True; // sal_True: Wait for System-Resize 246 mbInitWinClipRegion = sal_True; // sal_True: Calc Window Clip Region 247 mbInitChildRegion = sal_False; // sal_True: InitChildClipRegion 248 mbWinRegion = sal_False; // sal_True: Window Region 249 mbClipChildren = sal_False; // sal_True: request that child-windows get clipped 250 mbClipSiblings = sal_False; // sal_True: request that sibling child-windows get clipped 251 mbChildTransparent = sal_False; // sal_True: allow child-windows to enable transparency (incl. Parent-CLIPCHILDREN) 252 mbPaintTransparent = sal_False; // sal_True: Paints muessen auf Parent ausgeloest werden 253 mbMouseTransparent = sal_False; // sal_True: Window is transparent for Mouse 254 mbDlgCtrlStart = sal_False; // sal_True: Ab hier eigenes Dialog-Control 255 mbFocusVisible = sal_False; // sal_True: Focus Visible 256 mbUseNativeFocus = sal_False; 257 mbNativeFocusVisible= sal_False; // sal_True: native Focus Visible 258 mbInShowFocus = sal_False; // prevent recursion 259 mbInHideFocus = sal_False; // prevent recursion 260 mbTrackVisible = sal_False; // sal_True: Tracking Visible 261 mbControlForeground = sal_False; // sal_True: Foreground-Property set 262 mbControlBackground = sal_False; // sal_True: Background-Property set 263 mbAlwaysOnTop = sal_False; // sal_True: window is always on top 264 mbCompoundControl = sal_False; // sal_True: Zusammengesetztes Control => Listener... 265 mbCompoundControlHasFocus = sal_False; // sal_True: Zusammengesetztes Control hat irgendwo den Focus 266 mbPaintDisabled = sal_False; // sal_True: to disable paint events 267 mbAllResize = sal_False; // sal_True: to enable sending of ResizeEvents with both height=0 and width=0 268 mbInDtor = sal_False; // sal_True: is set when the window is being destructed 269 mbExtTextInput = sal_False; // sal_True: ExtTextInput-Mode is active 270 mbInFocusHdl = sal_False; // sal_True: is set when inside a GetFocus-Handler context 271 mbCreatedWithToolkit = sal_False; 272 mbSuppressAccessibilityEvents = sal_False; // sal_True: do not send any accessibility events 273 mbDrawSelectionBackground = sal_False; // sal_True: draws transparent window background to indicate (toolbox) selection 274 mbIsInTaskPaneList = sal_False; // sal_True: window was added to the taskpanelist in the topmost system window 275 mnNativeBackground = 0; // initialize later, depends on type 276 mbCallHandlersDuringInputDisabled = sal_False; // sal_True: call event handlers even if input is disabled 277 mbDisableAccessibleLabelForRelation = sal_False; // sal_True: do not set LabelFor relation on accessible objects 278 mbDisableAccessibleLabeledByRelation = sal_False; // sal_True: do not set LabeledBy relation on accessible objects 279 mbHelpTextDynamic = sal_False; // sal_True: append help id in HELP_DEBUG case 280 mbFakeFocusSet = sal_False; // sal_True: pretend as if the window 281 // has focus. 282 mbIsThemingEnabled = sal_True; 283 } 284 285 WindowImpl::~WindowImpl() 286 { 287 delete mpChildClipRegion; 288 delete mpAccessibleInfos; 289 delete mpControlFont; 290 } 291 292 293 // ----------------------------------------------------------------------- 294 295 // helper method to allow inline constructor even for pWindow!=NULL case 296 void ImplDelData::AttachToWindow( const Window* pWindow ) 297 { 298 if( pWindow ) 299 const_cast<Window*>(pWindow)->ImplAddDel( this ); 300 } 301 302 // ----------------------------------------------------------------------- 303 304 // define dtor for ImplDelData 305 ImplDelData::~ImplDelData() 306 { 307 // #112873# auto remove of ImplDelData 308 // due to this code actively calling ImplRemoveDel() is not mandatory anymore 309 if( !mbDel && mpWindow ) 310 { 311 // the window still exists but we were not removed 312 const_cast<Window*>(mpWindow)->ImplRemoveDel( this ); 313 mpWindow = NULL; 314 } 315 } 316 317 // ----------------------------------------------------------------------- 318 319 #ifdef DBG_UTIL 320 const char* ImplDbgCheckWindow( const void* pObj ) 321 { 322 DBG_TESTSOLARMUTEX(); 323 324 const Window* pWindow = (Window*)pObj; 325 326 if ( (pWindow->GetType() < WINDOW_FIRST) || (pWindow->GetType() > WINDOW_LAST) ) 327 return "Window data overwrite"; 328 329 // Fenster-Verkettung ueberpruefen 330 Window* pChild = pWindow->mpWindowImpl->mpFirstChild; 331 while ( pChild ) 332 { 333 if ( pChild->mpWindowImpl->mpParent != pWindow ) 334 return "Child-Window-Parent wrong"; 335 pChild = pChild->mpWindowImpl->mpNext; 336 } 337 338 return NULL; 339 } 340 #endif 341 342 // ======================================================================= 343 344 void Window::ImplInitAppFontData( Window* pWindow ) 345 { 346 ImplSVData* pSVData = ImplGetSVData(); 347 long nTextHeight = pWindow->GetTextHeight(); 348 long nTextWidth = pWindow->GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "aemnnxEM" ) ) ); 349 long nSymHeight = nTextHeight*4; 350 // Falls Font zu schmal ist, machen wir die Basis breiter, 351 // damit die Dialoge symetrisch aussehen und nicht zu schmal 352 // werden. Wenn der Dialog die gleiche breite hat, geben wir 353 // noch etwas Spielraum dazu, da etwas mehr Platz besser ist. 354 if ( nSymHeight > nTextWidth ) 355 nTextWidth = nSymHeight; 356 else if ( nSymHeight+5 > nTextWidth ) 357 nTextWidth = nSymHeight+5; 358 pSVData->maGDIData.mnAppFontX = nTextWidth * 10 / 8; 359 pSVData->maGDIData.mnAppFontY = nTextHeight * 10; 360 361 // FIXME: this is currently only on aqua, check with other 362 // platforms 363 if( pSVData->maNWFData.mbNoFocusRects ) 364 { 365 // try to find out wether there is a large correction 366 // of control sizes, if yes, make app font scalings larger 367 // so dialog positioning is not completely off 368 ImplControlValue aControlValue; 369 Rectangle aCtrlRegion( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) ); 370 Rectangle aBoundingRgn( aCtrlRegion ); 371 Rectangle aContentRgn( aCtrlRegion ); 372 if( pWindow->GetNativeControlRegion( CTRL_EDITBOX, PART_ENTIRE_CONTROL, aCtrlRegion, 373 CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), 374 aBoundingRgn, aContentRgn ) ) 375 { 376 // comment: the magical +6 is for the extra border in bordered 377 // (which is the standard) edit fields 378 if( aContentRgn.GetHeight() - nTextHeight > (nTextHeight+4)/4 ) 379 pSVData->maGDIData.mnAppFontY = (aContentRgn.GetHeight()-4) * 10; 380 } 381 } 382 383 384 pSVData->maGDIData.mnRealAppFontX = pSVData->maGDIData.mnAppFontX; 385 if ( pSVData->maAppData.mnDialogScaleX ) 386 pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*pSVData->maAppData.mnDialogScaleX)/100; 387 } 388 389 // ----------------------------------------------------------------------- 390 391 bool Window::ImplCheckUIFont( const Font& rFont ) 392 { 393 if( ImplGetSVData()->maGDIData.mbNativeFontConfig ) 394 return true; 395 396 // create a text string using the localized text of important buttons 397 String aTestText; 398 static const StandardButtonType aTestButtons[] = 399 { 400 BUTTON_OK, BUTTON_CANCEL, BUTTON_CLOSE, BUTTON_ABORT, 401 BUTTON_YES, BUTTON_NO, BUTTON_MORE, BUTTON_IGNORE, 402 BUTTON_RETRY, BUTTON_HELP 403 }; 404 405 const int nTestButtonCount = sizeof(aTestButtons)/sizeof(*aTestButtons); 406 for( int n = 0; n < nTestButtonCount; ++n ) 407 { 408 String aButtonStr = Button::GetStandardText( aTestButtons[n] ); 409 // #i115432# ignore mnemonic+accelerator part of each string 410 // TODO: use a string filtering method when it becomes available 411 const int nLen = aButtonStr.Len(); 412 bool bInside = false; 413 for( int i = 0; i < nLen; ++i ) { 414 const sal_Unicode c = aButtonStr.GetChar( i ); 415 if( (c == '(')) 416 bInside = true; 417 if( (c == ')')) 418 bInside = false; 419 if( (c == '~') 420 || (c == '(') || (c == ')') 421 || ((c >= 'A') && (c <= 'Z') && bInside) ) 422 aButtonStr.SetChar( i, ' ' ); 423 } 424 // append sanitized button text to test string 425 aTestText.Append( aButtonStr ); 426 } 427 428 const int nFirstChar = HasGlyphs( rFont, aTestText ); 429 const bool bUIFontOk = (nFirstChar >= aTestText.Len()); 430 return bUIFontOk; 431 } 432 433 // ----------------------------------------------------------------------- 434 435 void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, sal_Bool bCallHdl ) 436 { 437 // reset high contrast to false, so the system can either update it 438 // or AutoDetectSystemHC can kick in (see below) 439 StyleSettings aTmpSt( rSettings.GetStyleSettings() ); 440 aTmpSt.SetHighContrastMode( sal_False ); 441 rSettings.SetStyleSettings( aTmpSt ); 442 ImplGetFrame()->UpdateSettings( rSettings ); 443 // reset default border width for layouters 444 ImplGetSVData()->maAppData.mnDefaultLayoutBorder = -1; 445 446 // Verify availability of the configured UI font, otherwise choose "Andale Sans UI" 447 String aUserInterfaceFont; 448 bool bUseSystemFont = rSettings.GetStyleSettings().GetUseSystemUIFonts(); 449 450 // check whether system UI font can display a typical UI text 451 if( bUseSystemFont ) 452 bUseSystemFont = ImplCheckUIFont( rSettings.GetStyleSettings().GetAppFont() ); 453 454 if ( !bUseSystemFont ) 455 { 456 ImplInitFontList(); 457 String aConfigFont = utl::DefaultFontConfiguration::get()->getUserInterfaceFont( rSettings.GetUILocale() ); 458 xub_StrLen nIndex = 0; 459 while( nIndex != STRING_NOTFOUND ) 460 { 461 String aName( aConfigFont.GetToken( 0, ';', nIndex ) ); 462 if ( aName.Len() && mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aName ) ) 463 { 464 aUserInterfaceFont = aConfigFont; 465 break; 466 } 467 } 468 469 if ( ! aUserInterfaceFont.Len() ) 470 { 471 String aFallbackFont (RTL_CONSTASCII_USTRINGPARAM( "Andale Sans UI" )); 472 if ( mpWindowImpl->mpFrameData->mpFontList->FindFontFamily( aFallbackFont ) ) 473 aUserInterfaceFont = aFallbackFont; 474 } 475 } 476 477 if ( !bUseSystemFont && aUserInterfaceFont.Len() ) 478 { 479 StyleSettings aStyleSettings = rSettings.GetStyleSettings(); 480 Font aFont = aStyleSettings.GetAppFont(); 481 aFont.SetName( aUserInterfaceFont ); 482 aStyleSettings.SetAppFont( aFont ); 483 aFont = aStyleSettings.GetHelpFont(); 484 aFont.SetName( aUserInterfaceFont ); 485 aStyleSettings.SetHelpFont( aFont ); 486 aFont = aStyleSettings.GetTitleFont(); 487 aFont.SetName( aUserInterfaceFont ); 488 aStyleSettings.SetTitleFont( aFont ); 489 aFont = aStyleSettings.GetFloatTitleFont(); 490 aFont.SetName( aUserInterfaceFont ); 491 aStyleSettings.SetFloatTitleFont( aFont ); 492 aFont = aStyleSettings.GetMenuFont(); 493 aFont.SetName( aUserInterfaceFont ); 494 aStyleSettings.SetMenuFont( aFont ); 495 aFont = aStyleSettings.GetToolFont(); 496 aFont.SetName( aUserInterfaceFont ); 497 aStyleSettings.SetToolFont( aFont ); 498 aFont = aStyleSettings.GetLabelFont(); 499 aFont.SetName( aUserInterfaceFont ); 500 aStyleSettings.SetLabelFont( aFont ); 501 aFont = aStyleSettings.GetInfoFont(); 502 aFont.SetName( aUserInterfaceFont ); 503 aStyleSettings.SetInfoFont( aFont ); 504 aFont = aStyleSettings.GetRadioCheckFont(); 505 aFont.SetName( aUserInterfaceFont ); 506 aStyleSettings.SetRadioCheckFont( aFont ); 507 aFont = aStyleSettings.GetPushButtonFont(); 508 aFont.SetName( aUserInterfaceFont ); 509 aStyleSettings.SetPushButtonFont( aFont ); 510 aFont = aStyleSettings.GetFieldFont(); 511 aFont.SetName( aUserInterfaceFont ); 512 aStyleSettings.SetFieldFont( aFont ); 513 aFont = aStyleSettings.GetIconFont(); 514 aFont.SetName( aUserInterfaceFont ); 515 aStyleSettings.SetIconFont( aFont ); 516 aFont = aStyleSettings.GetGroupFont(); 517 aFont.SetName( aUserInterfaceFont ); 518 aStyleSettings.SetGroupFont( aFont ); 519 rSettings.SetStyleSettings( aStyleSettings ); 520 } 521 522 StyleSettings aStyleSettings = rSettings.GetStyleSettings(); 523 // #97047: Force all fonts except Menu and Help to a fixed height 524 // to avoid UI scaling due to large fonts 525 // - but allow bigger fonts on bigger screens (i16682, i21238) 526 // dialogs were designed to fit 800x600 with an 8pt font, so scale accordingly 527 int maxFontheight = 9; // #107886#: 9 is default for some asian systems, so always allow if requested 528 if( GetDesktopRectPixel().getHeight() > 600 ) 529 maxFontheight = (int) ((( 8.0 * (double) GetDesktopRectPixel().getHeight()) / 600.0) + 1.5); 530 531 Font aFont = aStyleSettings.GetMenuFont(); 532 int defFontheight = aFont.GetHeight(); 533 if( defFontheight > maxFontheight ) 534 defFontheight = maxFontheight; 535 536 // if the UI is korean, chinese or another locale 537 // where the system font size is kown to be often too small to 538 // generate readable fonts enforce a minimum font size of 9 points 539 bool bBrokenLangFontHeight = false; 540 static const LanguageType eBrokenSystemFontSizeLanguages[] = 541 { LANGUAGE_KOREAN, LANGUAGE_KOREAN_JOHAB, 542 LANGUAGE_CHINESE_HONGKONG, LANGUAGE_CHINESE_MACAU, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_SINGAPORE, LANGUAGE_CHINESE_TRADITIONAL 543 }; 544 static std::set< LanguageType > aBrokenSystemFontSizeLanguagesSet( 545 eBrokenSystemFontSizeLanguages, 546 eBrokenSystemFontSizeLanguages + 547 (sizeof(eBrokenSystemFontSizeLanguages)/sizeof(eBrokenSystemFontSizeLanguages[0])) 548 ); 549 LanguageType aLang = Application::GetSettings().GetUILanguage(); 550 if( aBrokenSystemFontSizeLanguagesSet.find( aLang ) != aBrokenSystemFontSizeLanguagesSet.end() ) 551 { 552 defFontheight = Max(9, defFontheight); 553 bBrokenLangFontHeight = true; 554 } 555 556 // i22098, toolfont will be scaled differently to avoid bloated rulers and status bars for big fonts 557 int toolfontheight = defFontheight; 558 if( toolfontheight > 9 ) 559 toolfontheight = (defFontheight+8) / 2; 560 561 aFont = aStyleSettings.GetAppFont(); 562 aFont.SetHeight( defFontheight ); 563 aStyleSettings.SetAppFont( aFont ); 564 aFont = aStyleSettings.GetTitleFont(); 565 aFont.SetHeight( defFontheight ); 566 aStyleSettings.SetTitleFont( aFont ); 567 aFont = aStyleSettings.GetFloatTitleFont(); 568 aFont.SetHeight( defFontheight ); 569 aStyleSettings.SetFloatTitleFont( aFont ); 570 // keep menu and help font size from system unless in broken locale size 571 if( bBrokenLangFontHeight ) 572 { 573 aFont = aStyleSettings.GetMenuFont(); 574 if( aFont.GetHeight() < defFontheight ) 575 { 576 aFont.SetHeight( defFontheight ); 577 aStyleSettings.SetMenuFont( aFont ); 578 } 579 aFont = aStyleSettings.GetHelpFont(); 580 if( aFont.GetHeight() < defFontheight ) 581 { 582 aFont.SetHeight( defFontheight ); 583 aStyleSettings.SetHelpFont( aFont ); 584 } 585 } 586 587 // use different height for toolfont 588 aFont = aStyleSettings.GetToolFont(); 589 aFont.SetHeight( toolfontheight ); 590 aStyleSettings.SetToolFont( aFont ); 591 592 aFont = aStyleSettings.GetLabelFont(); 593 aFont.SetHeight( defFontheight ); 594 aStyleSettings.SetLabelFont( aFont ); 595 aFont = aStyleSettings.GetInfoFont(); 596 aFont.SetHeight( defFontheight ); 597 aStyleSettings.SetInfoFont( aFont ); 598 aFont = aStyleSettings.GetRadioCheckFont(); 599 aFont.SetHeight( defFontheight ); 600 aStyleSettings.SetRadioCheckFont( aFont ); 601 aFont = aStyleSettings.GetPushButtonFont(); 602 aFont.SetHeight( defFontheight ); 603 aStyleSettings.SetPushButtonFont( aFont ); 604 aFont = aStyleSettings.GetFieldFont(); 605 aFont.SetHeight( defFontheight ); 606 aStyleSettings.SetFieldFont( aFont ); 607 aFont = aStyleSettings.GetIconFont(); 608 aFont.SetHeight( defFontheight ); 609 aStyleSettings.SetIconFont( aFont ); 610 aFont = aStyleSettings.GetGroupFont(); 611 aFont.SetHeight( defFontheight ); 612 aStyleSettings.SetGroupFont( aFont ); 613 614 // set workspace gradient to black in dark themes 615 if( aStyleSettings.GetWindowColor().IsDark() ) 616 aStyleSettings.SetWorkspaceGradient( Wallpaper( Color( COL_BLACK ) ) ); 617 else 618 { 619 Gradient aGrad( GRADIENT_LINEAR, DEFAULT_WORKSPACE_GRADIENT_START_COLOR, DEFAULT_WORKSPACE_GRADIENT_END_COLOR ); 620 aStyleSettings.SetWorkspaceGradient( Wallpaper( aGrad ) ); 621 } 622 623 rSettings.SetStyleSettings( aStyleSettings ); 624 625 626 // auto detect HC mode; if the system already set it to "yes" 627 // (see above) then accept that 628 if( !rSettings.GetStyleSettings().GetHighContrastMode() ) 629 { 630 sal_Bool bTmp = sal_False, bAutoHCMode = sal_True; 631 utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory( 632 vcl::unohelper::GetMultiServiceFactory(), 633 OUString::createFromAscii( "org.openoffice.Office.Common/Accessibility" ) ); // note: case sensisitive ! 634 if ( aNode.isValid() ) 635 { 636 ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString::createFromAscii( "AutoDetectSystemHC" ) ); 637 if( aValue >>= bTmp ) 638 bAutoHCMode = bTmp; 639 } 640 if( bAutoHCMode ) 641 { 642 if( rSettings.GetStyleSettings().GetFaceColor().IsDark() 643 || rSettings.GetStyleSettings().GetWindowColor().IsDark() ) 644 { 645 aStyleSettings = rSettings.GetStyleSettings(); 646 aStyleSettings.SetHighContrastMode( sal_True ); 647 rSettings.SetStyleSettings( aStyleSettings ); 648 } 649 } 650 } 651 652 static const char* pEnvHC = getenv( "SAL_FORCE_HC" ); 653 if( pEnvHC && *pEnvHC ) 654 { 655 aStyleSettings.SetHighContrastMode( sal_True ); 656 rSettings.SetStyleSettings( aStyleSettings ); 657 } 658 659 #ifdef DBG_UTIL 660 // Evt. AppFont auf Fett schalten, damit man feststellen kann, 661 // ob fuer die Texte auf anderen Systemen genuegend Platz 662 // vorhanden ist 663 if ( DbgIsBoldAppFont() ) 664 { 665 aStyleSettings = rSettings.GetStyleSettings(); 666 aFont = aStyleSettings.GetAppFont(); 667 aFont.SetWeight( WEIGHT_BOLD ); 668 aStyleSettings.SetAppFont( aFont ); 669 aFont = aStyleSettings.GetGroupFont(); 670 aFont.SetWeight( WEIGHT_BOLD ); 671 aStyleSettings.SetGroupFont( aFont ); 672 aFont = aStyleSettings.GetLabelFont(); 673 aFont.SetWeight( WEIGHT_BOLD ); 674 aStyleSettings.SetLabelFont( aFont ); 675 aFont = aStyleSettings.GetRadioCheckFont(); 676 aFont.SetWeight( WEIGHT_BOLD ); 677 aStyleSettings.SetRadioCheckFont( aFont ); 678 aFont = aStyleSettings.GetPushButtonFont(); 679 aFont.SetWeight( WEIGHT_BOLD ); 680 aStyleSettings.SetPushButtonFont( aFont ); 681 aFont = aStyleSettings.GetFieldFont(); 682 aFont.SetWeight( WEIGHT_BOLD ); 683 aStyleSettings.SetFieldFont( aFont ); 684 aFont = aStyleSettings.GetIconFont(); 685 aFont.SetWeight( WEIGHT_BOLD ); 686 aStyleSettings.SetIconFont( aFont ); 687 rSettings.SetStyleSettings( aStyleSettings ); 688 } 689 #endif 690 691 if ( bCallHdl ) 692 GetpApp()->SystemSettingsChanging( rSettings, this ); 693 } 694 695 // ----------------------------------------------------------------------- 696 697 MouseEvent ImplTranslateMouseEvent( const MouseEvent& rE, Window* pSource, Window* pDest ) 698 { 699 Point aPos = pSource->OutputToScreenPixel( rE.GetPosPixel() ); 700 aPos = pDest->ScreenToOutputPixel( aPos ); 701 return MouseEvent( aPos, rE.GetClicks(), rE.GetMode(), rE.GetButtons(), rE.GetModifier() ); 702 } 703 704 // ----------------------------------------------------------------------- 705 706 CommandEvent ImplTranslateCommandEvent( const CommandEvent& rCEvt, Window* pSource, Window* pDest ) 707 { 708 if ( !rCEvt.IsMouseEvent() ) 709 return rCEvt; 710 711 Point aPos = pSource->OutputToScreenPixel( rCEvt.GetMousePosPixel() ); 712 aPos = pDest->ScreenToOutputPixel( aPos ); 713 return CommandEvent( aPos, rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() ); 714 } 715 716 // ======================================================================= 717 718 void Window::ImplInitWindowData( WindowType nType ) 719 { 720 mpWindowImpl = new WindowImpl( nType ); 721 722 meOutDevType = OUTDEV_WINDOW; 723 724 mbEnableRTL = Application::GetSettings().GetLayoutRTL(); // sal_True: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active 725 } 726 727 // ----------------------------------------------------------------------- 728 729 void Window::ImplInit( Window* pParent, WinBits nStyle, const ::com::sun::star::uno::Any& /*aSystemWorkWindowToken*/ ) 730 { 731 ImplInit( pParent, nStyle, NULL ); 732 } 733 734 // ----------------------------------------------------------------------- 735 736 void Window::ImplInit( Window* pParent, WinBits nStyle, SystemParentData* pSystemParentData ) 737 { 738 DBG_ASSERT( mpWindowImpl->mbFrame || pParent, "Window::Window(): pParent == NULL" ); 739 740 ImplSVData* pSVData = ImplGetSVData(); 741 Window* pRealParent = pParent; 742 743 // 3D-Look vererben 744 if ( !mpWindowImpl->mbOverlapWin && pParent && (pParent->GetStyle() & WB_3DLOOK) ) 745 nStyle |= WB_3DLOOK; 746 747 // create border window if necessary 748 if ( !mpWindowImpl->mbFrame && !mpWindowImpl->mbBorderWin && !mpWindowImpl->mpBorderWindow 749 && (nStyle & (WB_BORDER | WB_SYSTEMCHILDWINDOW) ) ) 750 { 751 sal_uInt16 nBorderTypeStyle = 0; 752 if( (nStyle & WB_SYSTEMCHILDWINDOW) ) 753 { 754 // handle WB_SYSTEMCHILDWINDOW 755 // these should be analogous to a top level frame; meaning they 756 // should have a border window with style BORDERWINDOW_STYLE_FRAME 757 // which controls their size 758 nBorderTypeStyle |= BORDERWINDOW_STYLE_FRAME; 759 nStyle |= WB_BORDER; 760 } 761 ImplBorderWindow* pBorderWin = 762 mpWindowImpl->mbIsThemingEnabled 763 ? CreateBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle ) 764 : new ImplBorderWindow( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle ); 765 ((Window*)pBorderWin)->mpWindowImpl->mpClientWindow = this; 766 pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder ); 767 mpWindowImpl->mpBorderWindow = pBorderWin; 768 pParent = mpWindowImpl->mpBorderWindow; 769 } 770 else if( !mpWindowImpl->mbFrame && ! pParent ) 771 { 772 mpWindowImpl->mbOverlapWin = sal_True; 773 mpWindowImpl->mbFrame = sal_True; 774 } 775 776 // insert window in list 777 ImplInsertWindow( pParent ); 778 mpWindowImpl->mnStyle = nStyle; 779 780 // Overlap-Window-Daten 781 if ( mpWindowImpl->mbOverlapWin ) 782 { 783 mpWindowImpl->mpOverlapData = new ImplOverlapData; 784 mpWindowImpl->mpOverlapData->mpSaveBackDev = NULL; 785 mpWindowImpl->mpOverlapData->mpSaveBackRgn = NULL; 786 mpWindowImpl->mpOverlapData->mpNextBackWin = NULL; 787 mpWindowImpl->mpOverlapData->mnSaveBackSize = 0; 788 mpWindowImpl->mpOverlapData->mbSaveBack = sal_False; 789 mpWindowImpl->mpOverlapData->mnTopLevel = 1; 790 } 791 792 if( pParent && ! mpWindowImpl->mbFrame ) 793 mbEnableRTL = pParent->mbEnableRTL; 794 795 // test for frame creation 796 if ( mpWindowImpl->mbFrame ) 797 { 798 // create frame 799 sal_uLong nFrameStyle = 0; 800 801 if ( nStyle & WB_MOVEABLE ) 802 nFrameStyle |= SAL_FRAME_STYLE_MOVEABLE; 803 if ( nStyle & WB_SIZEABLE ) 804 nFrameStyle |= SAL_FRAME_STYLE_SIZEABLE; 805 if ( nStyle & WB_CLOSEABLE ) 806 nFrameStyle |= SAL_FRAME_STYLE_CLOSEABLE; 807 if ( nStyle & WB_APP ) 808 nFrameStyle |= SAL_FRAME_STYLE_DEFAULT; 809 // check for undecorated floating window 810 if( // 1. floating windows that are not moveable/sizeable (only closeable allowed) 811 ( !(nFrameStyle & ~SAL_FRAME_STYLE_CLOSEABLE) && 812 ( mpWindowImpl->mbFloatWin || ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow) || (nStyle & WB_SYSTEMFLOATWIN) ) ) || 813 // 2. borderwindows of floaters with ownerdraw decoration 814 ( ((GetType() == WINDOW_BORDERWINDOW) && ((ImplBorderWindow*)this)->mbFloatWindow && (nStyle & WB_OWNERDRAWDECORATION) ) ) ) 815 { 816 nFrameStyle = SAL_FRAME_STYLE_FLOAT; 817 if( nStyle & WB_OWNERDRAWDECORATION ) 818 nFrameStyle |= (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_NOSHADOW); 819 if( nStyle & WB_NEEDSFOCUS ) 820 nFrameStyle |= SAL_FRAME_STYLE_FLOAT_FOCUSABLE; 821 } 822 else if( mpWindowImpl->mbFloatWin ) 823 nFrameStyle |= SAL_FRAME_STYLE_TOOLWINDOW; 824 825 if( nStyle & WB_INTROWIN ) 826 nFrameStyle |= SAL_FRAME_STYLE_INTRO; 827 if( nStyle & WB_TOOLTIPWIN ) 828 nFrameStyle |= SAL_FRAME_STYLE_TOOLTIP; 829 830 if( nStyle & WB_NOSHADOW ) 831 nFrameStyle |= SAL_FRAME_STYLE_NOSHADOW; 832 833 if( nStyle & WB_SYSTEMCHILDWINDOW ) 834 nFrameStyle |= SAL_FRAME_STYLE_SYSTEMCHILD; 835 836 switch (mpWindowImpl->mnType) 837 { 838 case WINDOW_DIALOG: 839 case WINDOW_TABDIALOG: 840 case WINDOW_MODALDIALOG: 841 case WINDOW_MODELESSDIALOG: 842 case WINDOW_MESSBOX: 843 case WINDOW_INFOBOX: 844 case WINDOW_WARNINGBOX: 845 case WINDOW_ERRORBOX: 846 case WINDOW_QUERYBOX: 847 nFrameStyle |= SAL_FRAME_STYLE_DIALOG; 848 default: 849 break; 850 } 851 852 SalFrame* pParentFrame = NULL; 853 if ( pParent ) 854 pParentFrame = pParent->mpWindowImpl->mpFrame; 855 SalFrame* pFrame; 856 if ( pSystemParentData ) 857 pFrame = pSVData->mpDefInst->CreateChildFrame( pSystemParentData, nFrameStyle | SAL_FRAME_STYLE_PLUG ); 858 else 859 pFrame = pSVData->mpDefInst->CreateFrame( pParentFrame, nFrameStyle ); 860 if ( !pFrame ) 861 { 862 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario) 863 throw ::com::sun::star::uno::RuntimeException( 864 OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create system window!" ) ), 865 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); 866 //GetpApp()->Exception( EXC_SYSOBJNOTCREATED ); 867 } 868 869 pFrame->SetCallback( this, ImplWindowFrameProc ); 870 871 // set window frame data 872 mpWindowImpl->mpFrameData = new ImplFrameData; 873 mpWindowImpl->mpFrame = pFrame; 874 mpWindowImpl->mpFrameWindow = this; 875 mpWindowImpl->mpOverlapWindow = this; 876 877 // set frame data 878 mpWindowImpl->mpFrameData->mpNextFrame = pSVData->maWinData.mpFirstFrame; 879 pSVData->maWinData.mpFirstFrame = this; 880 mpWindowImpl->mpFrameData->mpFirstOverlap = NULL; 881 mpWindowImpl->mpFrameData->mpFocusWin = NULL; 882 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL; 883 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL; 884 mpWindowImpl->mpFrameData->mpFirstBackWin = NULL; 885 mpWindowImpl->mpFrameData->mpFontList = pSVData->maGDIData.mpScreenFontList; 886 mpWindowImpl->mpFrameData->mpFontCache = pSVData->maGDIData.mpScreenFontCache; 887 mpWindowImpl->mpFrameData->mnAllSaveBackSize = 0; 888 mpWindowImpl->mpFrameData->mnFocusId = 0; 889 mpWindowImpl->mpFrameData->mnMouseMoveId = 0; 890 mpWindowImpl->mpFrameData->mnLastMouseX = -1; 891 mpWindowImpl->mpFrameData->mnLastMouseY = -1; 892 mpWindowImpl->mpFrameData->mnBeforeLastMouseX = -1; 893 mpWindowImpl->mpFrameData->mnBeforeLastMouseY = -1; 894 mpWindowImpl->mpFrameData->mnFirstMouseX = -1; 895 mpWindowImpl->mpFrameData->mnFirstMouseY = -1; 896 mpWindowImpl->mpFrameData->mnLastMouseWinX = -1; 897 mpWindowImpl->mpFrameData->mnLastMouseWinY = -1; 898 mpWindowImpl->mpFrameData->mnModalMode = 0; 899 mpWindowImpl->mpFrameData->mnMouseDownTime = 0; 900 mpWindowImpl->mpFrameData->mnClickCount = 0; 901 mpWindowImpl->mpFrameData->mnFirstMouseCode = 0; 902 mpWindowImpl->mpFrameData->mnMouseCode = 0; 903 mpWindowImpl->mpFrameData->mnMouseMode = 0; 904 mpWindowImpl->mpFrameData->meMapUnit = MAP_PIXEL; 905 mpWindowImpl->mpFrameData->mbHasFocus = sal_False; 906 mpWindowImpl->mpFrameData->mbInMouseMove = sal_False; 907 mpWindowImpl->mpFrameData->mbMouseIn = sal_False; 908 mpWindowImpl->mpFrameData->mbStartDragCalled = sal_False; 909 mpWindowImpl->mpFrameData->mbNeedSysWindow = sal_False; 910 mpWindowImpl->mpFrameData->mbMinimized = sal_False; 911 mpWindowImpl->mpFrameData->mbStartFocusState = sal_False; 912 mpWindowImpl->mpFrameData->mbInSysObjFocusHdl = sal_False; 913 mpWindowImpl->mpFrameData->mbInSysObjToTopHdl = sal_False; 914 mpWindowImpl->mpFrameData->mbSysObjFocus = sal_False; 915 mpWindowImpl->mpFrameData->maPaintTimer.SetTimeout( 30 ); 916 mpWindowImpl->mpFrameData->maPaintTimer.SetTimeoutHdl( LINK( this, Window, ImplHandlePaintHdl ) ); 917 mpWindowImpl->mpFrameData->maResizeTimer.SetTimeout( 50 ); 918 mpWindowImpl->mpFrameData->maResizeTimer.SetTimeoutHdl( LINK( this, Window, ImplHandleResizeTimerHdl ) ); 919 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = sal_False; 920 921 if ( pRealParent && IsTopWindow() ) 922 { 923 ImplWinData* pParentWinData = pRealParent->ImplGetWinData(); 924 pParentWinData->maTopWindowChildren.push_back( this ); 925 } 926 } 927 928 // init data 929 mpWindowImpl->mpRealParent = pRealParent; 930 931 // #99318: make sure fontcache and list is available before call to SetSettings 932 mpFontList = mpWindowImpl->mpFrameData->mpFontList; 933 mpFontCache = mpWindowImpl->mpFrameData->mpFontCache; 934 935 if ( mpWindowImpl->mbFrame ) 936 { 937 if ( pParent ) 938 { 939 mpWindowImpl->mpFrameData->mnDPIX = pParent->mpWindowImpl->mpFrameData->mnDPIX; 940 mpWindowImpl->mpFrameData->mnDPIY = pParent->mpWindowImpl->mpFrameData->mnDPIY; 941 } 942 else 943 { 944 if ( ImplGetGraphics() ) 945 { 946 mpGraphics->GetResolution( mpWindowImpl->mpFrameData->mnDPIX, mpWindowImpl->mpFrameData->mnDPIY ); 947 } 948 } 949 950 // add ownerdraw decorated frame windows to list in the top-most frame window 951 // so they can be hidden on lose focus 952 if( nStyle & WB_OWNERDRAWDECORATION ) 953 ImplGetOwnerDrawList().push_back( this ); 954 955 // delay settings initialization until first "real" frame 956 // this relies on the IntroWindow not needing any system settings 957 if ( !pSVData->maAppData.mbSettingsInit && 958 ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) 959 ) 960 { 961 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings 962 ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings ); 963 OutputDevice::SetSettings( *pSVData->maAppData.mpSettings ); 964 pSVData->maAppData.mbSettingsInit = sal_True; 965 } 966 967 // If we create a Window with default size, query this 968 // size directly, because we want resize all Controls to 969 // the correct size before we display the window 970 if ( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_APP) ) 971 mpWindowImpl->mpFrame->GetClientSize( mnOutWidth, mnOutHeight ); 972 } 973 else 974 { 975 if ( pParent ) 976 { 977 if ( !ImplIsOverlapWindow() ) 978 { 979 mpWindowImpl->mbDisabled = pParent->mpWindowImpl->mbDisabled; 980 mpWindowImpl->mbInputDisabled = pParent->mpWindowImpl->mbInputDisabled; 981 mpWindowImpl->meAlwaysInputMode = pParent->mpWindowImpl->meAlwaysInputMode; 982 } 983 984 OutputDevice::SetSettings( pParent->GetSettings() ); 985 } 986 987 } 988 989 const StyleSettings& rStyleSettings = maSettings.GetStyleSettings(); 990 sal_uInt16 nScreenZoom = rStyleSettings.GetScreenZoom(); 991 mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100; 992 mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100; 993 maFont = rStyleSettings.GetAppFont(); 994 ImplPointToLogic( maFont ); 995 996 if ( nStyle & WB_3DLOOK ) 997 { 998 SetTextColor( rStyleSettings.GetButtonTextColor() ); 999 SetBackground( Wallpaper( rStyleSettings.GetFaceColor() ) ); 1000 } 1001 else 1002 { 1003 SetTextColor( rStyleSettings.GetWindowTextColor() ); 1004 SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) ); 1005 } 1006 1007 ImplUpdatePos(); 1008 1009 // calculate app font res (except for the Intro Window or the default window) 1010 if ( mpWindowImpl->mbFrame && !pSVData->maGDIData.mnAppFontX && ! (nStyle & (WB_INTROWIN|WB_DEFAULTWIN)) ) 1011 ImplInitAppFontData( this ); 1012 1013 if ( GetAccessibleParentWindow() && GetParent() != Application::GetDefDialogParent() ) 1014 GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDCREATED, this ); 1015 } 1016 1017 // ----------------------------------------------------------------------- 1018 1019 void Window::ImplSetFrameParent( const Window* pParent ) 1020 { 1021 Window* pFrameWindow = ImplGetSVData()->maWinData.mpFirstFrame; 1022 while( pFrameWindow ) 1023 { 1024 // search all frames that are children of this window 1025 // and reparent them 1026 if( ImplIsRealParentPath( pFrameWindow ) ) 1027 { 1028 DBG_ASSERT( mpWindowImpl->mpFrame != pFrameWindow->mpWindowImpl->mpFrame, "SetFrameParent to own" ); 1029 DBG_ASSERT( mpWindowImpl->mpFrame, "no frame" ); 1030 SalFrame* pParentFrame = pParent ? pParent->mpWindowImpl->mpFrame : NULL; 1031 pFrameWindow->mpWindowImpl->mpFrame->SetParent( pParentFrame ); 1032 } 1033 pFrameWindow = pFrameWindow->mpWindowImpl->mpFrameData->mpNextFrame; 1034 } 1035 } 1036 1037 // ----------------------------------------------------------------------- 1038 1039 void Window::ImplInsertWindow( Window* pParent ) 1040 { 1041 mpWindowImpl->mpParent = pParent; 1042 mpWindowImpl->mpRealParent = pParent; 1043 1044 if ( pParent && !mpWindowImpl->mbFrame ) 1045 { 1046 // search frame window and set window frame data 1047 Window* pFrameParent = pParent->mpWindowImpl->mpFrameWindow; 1048 mpWindowImpl->mpFrameData = pFrameParent->mpWindowImpl->mpFrameData; 1049 mpWindowImpl->mpFrame = pFrameParent->mpWindowImpl->mpFrame; 1050 mpWindowImpl->mpFrameWindow = pFrameParent; 1051 mpWindowImpl->mbFrame = sal_False; 1052 1053 // search overlap window and insert window in list 1054 if ( ImplIsOverlapWindow() ) 1055 { 1056 Window* pFirstOverlapParent = pParent; 1057 while ( !pFirstOverlapParent->ImplIsOverlapWindow() ) 1058 pFirstOverlapParent = pFirstOverlapParent->ImplGetParent(); 1059 mpWindowImpl->mpOverlapWindow = pFirstOverlapParent; 1060 1061 mpWindowImpl->mpNextOverlap = mpWindowImpl->mpFrameData->mpFirstOverlap; 1062 mpWindowImpl->mpFrameData->mpFirstOverlap = this; 1063 1064 // Overlap-Windows sind per default die obersten 1065 mpWindowImpl->mpNext = pFirstOverlapParent->mpWindowImpl->mpFirstOverlap; 1066 pFirstOverlapParent->mpWindowImpl->mpFirstOverlap = this; 1067 if ( !pFirstOverlapParent->mpWindowImpl->mpLastOverlap ) 1068 pFirstOverlapParent->mpWindowImpl->mpLastOverlap = this; 1069 else 1070 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; 1071 } 1072 else 1073 { 1074 if ( pParent->ImplIsOverlapWindow() ) 1075 mpWindowImpl->mpOverlapWindow = pParent; 1076 else 1077 mpWindowImpl->mpOverlapWindow = pParent->mpWindowImpl->mpOverlapWindow; 1078 mpWindowImpl->mpPrev = pParent->mpWindowImpl->mpLastChild; 1079 pParent->mpWindowImpl->mpLastChild = this; 1080 if ( !pParent->mpWindowImpl->mpFirstChild ) 1081 pParent->mpWindowImpl->mpFirstChild = this; 1082 else 1083 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; 1084 } 1085 } 1086 } 1087 1088 // ----------------------------------------------------------------------- 1089 1090 void Window::ImplRemoveWindow( sal_Bool bRemoveFrameData ) 1091 { 1092 // Fenster aus den Listen austragen 1093 if ( !mpWindowImpl->mbFrame ) 1094 { 1095 if ( ImplIsOverlapWindow() ) 1096 { 1097 if ( mpWindowImpl->mpFrameData->mpFirstOverlap == this ) 1098 mpWindowImpl->mpFrameData->mpFirstOverlap = mpWindowImpl->mpNextOverlap; 1099 else 1100 { 1101 Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap; 1102 while ( pTempWin->mpWindowImpl->mpNextOverlap != this ) 1103 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap; 1104 pTempWin->mpWindowImpl->mpNextOverlap = mpWindowImpl->mpNextOverlap; 1105 } 1106 1107 if ( mpWindowImpl->mpPrev ) 1108 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; 1109 else 1110 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; 1111 if ( mpWindowImpl->mpNext ) 1112 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; 1113 else 1114 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; 1115 } 1116 else 1117 { 1118 if ( mpWindowImpl->mpPrev ) 1119 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; 1120 else 1121 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; 1122 if ( mpWindowImpl->mpNext ) 1123 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; 1124 else 1125 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; 1126 } 1127 1128 mpWindowImpl->mpPrev = NULL; 1129 mpWindowImpl->mpNext = NULL; 1130 } 1131 1132 if ( bRemoveFrameData ) 1133 { 1134 // Graphic freigeben 1135 ImplReleaseGraphics(); 1136 } 1137 } 1138 1139 // ----------------------------------------------------------------------- 1140 1141 void Window::ImplCallResize() 1142 { 1143 mpWindowImpl->mbCallResize = sal_False; 1144 1145 if( GetBackground().IsGradient() ) 1146 Invalidate(); 1147 1148 Resize(); 1149 1150 // #88419# Most classes don't call the base class in Resize() and Move(), 1151 // => Call ImpleResize/Move instead of Resize/Move directly... 1152 ImplCallEventListeners( VCLEVENT_WINDOW_RESIZE ); 1153 1154 ImplExtResize(); 1155 } 1156 1157 // ----------------------------------------------------------------------- 1158 1159 void Window::ImplCallMove() 1160 { 1161 mpWindowImpl->mbCallMove = sal_False; 1162 1163 if( mpWindowImpl->mbFrame ) 1164 { 1165 // update frame position 1166 SalFrame *pParentFrame = NULL; 1167 Window *pParent = ImplGetParent(); 1168 while( pParent ) 1169 { 1170 if( pParent->mpWindowImpl->mpFrame != mpWindowImpl->mpFrame ) 1171 { 1172 pParentFrame = pParent->mpWindowImpl->mpFrame; 1173 break; 1174 } 1175 pParent = pParent->GetParent(); 1176 } 1177 1178 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry(); 1179 mpWindowImpl->maPos = Point( g.nX, g.nY ); 1180 if( pParentFrame ) 1181 { 1182 g = pParentFrame->GetGeometry(); 1183 mpWindowImpl->maPos -= Point( g.nX, g.nY ); 1184 } 1185 // the client window and and all its subclients have the same position as the borderframe 1186 // this is important for floating toolbars where the borderwindow is a floating window 1187 // which has another borderwindow (ie the system floating window) 1188 Window *pClientWin = mpWindowImpl->mpClientWindow; 1189 while( pClientWin ) 1190 { 1191 pClientWin->mpWindowImpl->maPos = mpWindowImpl->maPos; 1192 pClientWin = pClientWin->mpWindowImpl->mpClientWindow; 1193 } 1194 } 1195 1196 Move(); 1197 1198 ImplCallEventListeners( VCLEVENT_WINDOW_MOVE ); 1199 } 1200 1201 // ----------------------------------------------------------------------- 1202 1203 static rtl::OString ImplAutoHelpID( ResMgr* pResMgr ) 1204 { 1205 rtl::OString aRet; 1206 1207 if( pResMgr && Application::IsAutoHelpIdEnabled() ) 1208 aRet = pResMgr->GetAutoHelpId(); 1209 1210 return aRet; 1211 } 1212 1213 // ----------------------------------------------------------------------- 1214 1215 WinBits Window::ImplInitRes( const ResId& rResId ) 1216 { 1217 GetRes( rResId ); 1218 1219 char* pRes = (char*)GetClassRes(); 1220 pRes += 8; 1221 sal_uInt32 nStyle = (sal_uInt32)GetLongRes( (void*)pRes ); 1222 rResId.SetWinBits( nStyle ); 1223 return nStyle; 1224 } 1225 1226 // ----------------------------------------------------------------------- 1227 1228 void Window::ImplLoadRes( const ResId& rResId ) 1229 { 1230 sal_uLong nObjMask = ReadLongRes(); 1231 1232 // we need to calculate auto helpids before the resource gets closed 1233 // if the resource only contains flags, it will be closed before we try to read a help id 1234 // so we always create an auto help id that might be overwritten later 1235 // HelpId 1236 rtl::OString aHelpId = ImplAutoHelpID( rResId.GetResMgr() ); 1237 1238 // ResourceStyle 1239 sal_uLong nRSStyle = ReadLongRes(); 1240 // WinBits 1241 ReadLongRes(); 1242 1243 if( nObjMask & WINDOW_HELPID ) 1244 aHelpId = ReadByteStringRes(); 1245 1246 SetHelpId( aHelpId ); 1247 1248 sal_Bool bPos = sal_False; 1249 sal_Bool bSize = sal_False; 1250 Point aPos; 1251 Size aSize; 1252 1253 if ( nObjMask & (WINDOW_XYMAPMODE | WINDOW_X | WINDOW_Y) ) 1254 { 1255 // Groessenangabe aus der Resource verwenden 1256 MapUnit ePosMap = MAP_PIXEL; 1257 1258 bPos = sal_True; 1259 1260 if ( nObjMask & WINDOW_XYMAPMODE ) 1261 ePosMap = (MapUnit)ReadLongRes(); 1262 if ( nObjMask & WINDOW_X ) 1263 aPos.X() = ImplLogicUnitToPixelX( ReadLongRes(), ePosMap ); 1264 if ( nObjMask & WINDOW_Y ) 1265 aPos.Y() = ImplLogicUnitToPixelY( ReadLongRes(), ePosMap ); 1266 } 1267 1268 if ( nObjMask & (WINDOW_WHMAPMODE | WINDOW_WIDTH | WINDOW_HEIGHT) ) 1269 { 1270 // Groessenangabe aus der Resource verwenden 1271 MapUnit eSizeMap = MAP_PIXEL; 1272 1273 bSize = sal_True; 1274 1275 if ( nObjMask & WINDOW_WHMAPMODE ) 1276 eSizeMap = (MapUnit)ReadLongRes(); 1277 if ( nObjMask & WINDOW_WIDTH ) 1278 aSize.Width() = ImplLogicUnitToPixelX( ReadLongRes(), eSizeMap ); 1279 if ( nObjMask & WINDOW_HEIGHT ) 1280 aSize.Height() = ImplLogicUnitToPixelY( ReadLongRes(), eSizeMap ); 1281 } 1282 1283 // Wegen Optimierung so schlimm aussehend 1284 if ( nRSStyle & RSWND_CLIENTSIZE ) 1285 { 1286 if ( bPos ) 1287 SetPosPixel( aPos ); 1288 if ( bSize ) 1289 SetOutputSizePixel( aSize ); 1290 } 1291 else if ( bPos && bSize ) 1292 SetPosSizePixel( aPos, aSize ); 1293 else if ( bPos ) 1294 SetPosPixel( aPos ); 1295 else if ( bSize ) 1296 SetSizePixel( aSize ); 1297 1298 if ( nRSStyle & RSWND_DISABLED ) 1299 Enable( sal_False ); 1300 1301 if ( nObjMask & WINDOW_TEXT ) 1302 SetText( ReadStringRes() ); 1303 if ( nObjMask & WINDOW_HELPTEXT ) 1304 { 1305 SetHelpText( ReadStringRes() ); 1306 mpWindowImpl->mbHelpTextDynamic = sal_True; 1307 } 1308 if ( nObjMask & WINDOW_QUICKTEXT ) 1309 SetQuickHelpText( ReadStringRes() ); 1310 if ( nObjMask & WINDOW_EXTRALONG ) 1311 SetData( (void*)ReadLongRes() ); 1312 if ( nObjMask & WINDOW_UNIQUEID ) 1313 SetUniqueId( ReadByteStringRes() ); 1314 1315 if ( nObjMask & WINDOW_BORDER_STYLE ) 1316 { 1317 sal_uInt16 nBorderStyle = (sal_uInt16)ReadLongRes(); 1318 SetBorderStyle( nBorderStyle ); 1319 } 1320 } 1321 1322 // ----------------------------------------------------------------------- 1323 1324 ImplWinData* Window::ImplGetWinData() const 1325 { 1326 if ( !mpWindowImpl->mpWinData ) 1327 { 1328 static const char* pNoNWF = getenv( "SAL_NO_NWF" ); 1329 1330 ((Window*)this)->mpWindowImpl->mpWinData = new ImplWinData; 1331 mpWindowImpl->mpWinData->mpExtOldText = NULL; 1332 mpWindowImpl->mpWinData->mpExtOldAttrAry = NULL; 1333 mpWindowImpl->mpWinData->mpCursorRect = 0; 1334 mpWindowImpl->mpWinData->mnCursorExtWidth = 0; 1335 mpWindowImpl->mpWinData->mpFocusRect = NULL; 1336 mpWindowImpl->mpWinData->mpTrackRect = NULL; 1337 mpWindowImpl->mpWinData->mnTrackFlags = 0; 1338 mpWindowImpl->mpWinData->mnIsTopWindow = (sal_uInt16) ~0; // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow()) 1339 mpWindowImpl->mpWinData->mbMouseOver = sal_False; 1340 mpWindowImpl->mpWinData->mbEnableNativeWidget = (pNoNWF && *pNoNWF) ? sal_False : sal_True; // sal_True: try to draw this control with native theme API 1341 } 1342 1343 return mpWindowImpl->mpWinData; 1344 } 1345 1346 // ----------------------------------------------------------------------- 1347 1348 SalGraphics* Window::ImplGetFrameGraphics() const 1349 { 1350 if ( mpWindowImpl->mpFrameWindow->mpGraphics ) 1351 mpWindowImpl->mpFrameWindow->mbInitClipRegion = sal_True; 1352 else 1353 mpWindowImpl->mpFrameWindow->ImplGetGraphics(); 1354 mpWindowImpl->mpFrameWindow->mpGraphics->ResetClipRegion(); 1355 return mpWindowImpl->mpFrameWindow->mpGraphics; 1356 } 1357 1358 // ----------------------------------------------------------------------- 1359 1360 Window* Window::ImplFindWindow( const Point& rFramePos ) 1361 { 1362 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 1363 1364 Window* pTempWindow; 1365 Window* pFindWindow; 1366 1367 // Zuerst alle ueberlappenden Fenster ueberpruefen 1368 pTempWindow = mpWindowImpl->mpFirstOverlap; 1369 while ( pTempWindow ) 1370 { 1371 pFindWindow = pTempWindow->ImplFindWindow( rFramePos ); 1372 if ( pFindWindow ) 1373 return pFindWindow; 1374 pTempWindow = pTempWindow->mpWindowImpl->mpNext; 1375 } 1376 1377 // dann testen wir unser Fenster 1378 if ( !mpWindowImpl->mbVisible ) 1379 return NULL; 1380 1381 sal_uInt16 nHitTest = ImplHitTest( rFramePos ); 1382 if ( nHitTest & WINDOW_HITTEST_INSIDE ) 1383 { 1384 // und danach gehen wir noch alle Child-Fenster durch 1385 pTempWindow = mpWindowImpl->mpFirstChild; 1386 while ( pTempWindow ) 1387 { 1388 pFindWindow = pTempWindow->ImplFindWindow( rFramePos ); 1389 if ( pFindWindow ) 1390 return pFindWindow; 1391 pTempWindow = pTempWindow->mpWindowImpl->mpNext; 1392 } 1393 1394 if ( nHitTest & WINDOW_HITTEST_TRANSPARENT ) 1395 return NULL; 1396 else 1397 return this; 1398 } 1399 1400 return NULL; 1401 } 1402 1403 // ----------------------------------------------------------------------- 1404 1405 sal_uInt16 Window::ImplHitTest( const Point& rFramePos ) 1406 { 1407 Point aFramePos( rFramePos ); 1408 if( ImplIsAntiparallel() ) 1409 { 1410 // - RTL - re-mirror frame pos at this window 1411 ImplReMirror( aFramePos ); 1412 } 1413 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 1414 if ( !aRect.IsInside( aFramePos ) ) 1415 return 0; 1416 if ( mpWindowImpl->mbWinRegion ) 1417 { 1418 Point aTempPos = aFramePos; 1419 aTempPos.X() -= mnOutOffX; 1420 aTempPos.Y() -= mnOutOffY; 1421 if ( !mpWindowImpl->maWinRegion.IsInside( aTempPos ) ) 1422 return 0; 1423 } 1424 1425 sal_uInt16 nHitTest = WINDOW_HITTEST_INSIDE; 1426 if ( mpWindowImpl->mbMouseTransparent ) 1427 nHitTest |= WINDOW_HITTEST_TRANSPARENT; 1428 return nHitTest; 1429 } 1430 1431 // ----------------------------------------------------------------------- 1432 1433 sal_Bool Window::ImplIsRealParentPath( const Window* pWindow ) const 1434 { 1435 pWindow = pWindow->GetParent(); 1436 while ( pWindow ) 1437 { 1438 if ( pWindow == this ) 1439 return sal_True; 1440 pWindow = pWindow->GetParent(); 1441 } 1442 1443 return sal_False; 1444 } 1445 1446 // ----------------------------------------------------------------------- 1447 1448 sal_Bool Window::ImplIsChild( const Window* pWindow, sal_Bool bSystemWindow ) const 1449 { 1450 do 1451 { 1452 if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() ) 1453 break; 1454 1455 pWindow = pWindow->ImplGetParent(); 1456 1457 if ( pWindow == this ) 1458 return sal_True; 1459 } 1460 while ( pWindow ); 1461 1462 return sal_False; 1463 } 1464 1465 // ----------------------------------------------------------------------- 1466 1467 sal_Bool Window::ImplIsWindowOrChild( const Window* pWindow, sal_Bool bSystemWindow ) const 1468 { 1469 if ( this == pWindow ) 1470 return sal_True; 1471 return ImplIsChild( pWindow, bSystemWindow ); 1472 } 1473 1474 // ----------------------------------------------------------------------- 1475 1476 Window* Window::ImplGetSameParent( const Window* pWindow ) const 1477 { 1478 if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow ) 1479 return NULL; 1480 else 1481 { 1482 if ( pWindow->ImplIsChild( this ) ) 1483 return (Window*)pWindow; 1484 else 1485 { 1486 Window* pTestWindow = (Window*)this; 1487 while ( (pTestWindow == pWindow) || pTestWindow->ImplIsChild( pWindow ) ) 1488 pTestWindow = pTestWindow->ImplGetParent(); 1489 return pTestWindow; 1490 } 1491 } 1492 } 1493 1494 // ----------------------------------------------------------------------- 1495 1496 int Window::ImplTestMousePointerSet() 1497 { 1498 // Wenn Mouse gecaptured ist, dann soll MousePointer umgeschaltet werden 1499 if ( IsMouseCaptured() ) 1500 return sal_True; 1501 1502 // Wenn sich Mouse ueber dem Fenster befindet, dann soll MousePointer 1503 // umgeschaltet werden 1504 Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() ); 1505 if ( aClientRect.IsInside( GetPointerPosPixel() ) ) 1506 return sal_True; 1507 1508 return sal_False; 1509 } 1510 1511 // ----------------------------------------------------------------------- 1512 1513 PointerStyle Window::ImplGetMousePointer() const 1514 { 1515 PointerStyle ePointerStyle; 1516 sal_Bool bWait = sal_False; 1517 1518 if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() ) 1519 ePointerStyle = GetPointer().GetStyle(); 1520 else 1521 ePointerStyle = POINTER_ARROW; 1522 1523 const Window* pWindow = this; 1524 do 1525 { 1526 // Wenn Pointer nicht sichtbar, dann wird suche abgebrochen, da 1527 // dieser Status nicht ueberschrieben werden darf 1528 if ( pWindow->mpWindowImpl->mbNoPtrVisible ) 1529 return POINTER_NULL; 1530 1531 if ( !bWait ) 1532 { 1533 if ( pWindow->mpWindowImpl->mnWaitCount ) 1534 { 1535 ePointerStyle = POINTER_WAIT; 1536 bWait = sal_True; 1537 } 1538 else 1539 { 1540 if ( pWindow->mpWindowImpl->mbChildPtrOverwrite ) 1541 ePointerStyle = pWindow->GetPointer().GetStyle(); 1542 } 1543 } 1544 1545 if ( pWindow->ImplIsOverlapWindow() ) 1546 break; 1547 1548 pWindow = pWindow->ImplGetParent(); 1549 } 1550 while ( pWindow ); 1551 1552 return ePointerStyle; 1553 } 1554 1555 // ----------------------------------------------------------------------- 1556 1557 void Window::ImplResetReallyVisible() 1558 { 1559 sal_Bool bBecameReallyInvisible = mpWindowImpl->mbReallyVisible; 1560 1561 mbDevOutput = sal_False; 1562 mpWindowImpl->mbReallyVisible = sal_False; 1563 mpWindowImpl->mbReallyShown = sal_False; 1564 1565 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge. 1566 // For this, the data member of the event must not be NULL. 1567 // Previously, we did this in Window::Show, but there some events got lost in certain situations. 1568 // #104887# - 2004-08-10 - fs@openoffice.org 1569 if( bBecameReallyInvisible && ImplIsAccessibleCandidate() ) 1570 ImplCallEventListeners( VCLEVENT_WINDOW_HIDE, this ); 1571 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_HIDE. Normally, we should 1572 // introduce another event which explicitly triggers the Accessibility implementations. 1573 1574 Window* pWindow = mpWindowImpl->mpFirstOverlap; 1575 while ( pWindow ) 1576 { 1577 if ( pWindow->mpWindowImpl->mbReallyVisible ) 1578 pWindow->ImplResetReallyVisible(); 1579 pWindow = pWindow->mpWindowImpl->mpNext; 1580 } 1581 1582 pWindow = mpWindowImpl->mpFirstChild; 1583 while ( pWindow ) 1584 { 1585 if ( pWindow->mpWindowImpl->mbReallyVisible ) 1586 pWindow->ImplResetReallyVisible(); 1587 pWindow = pWindow->mpWindowImpl->mpNext; 1588 } 1589 } 1590 1591 // ----------------------------------------------------------------------- 1592 1593 void Window::ImplSetReallyVisible() 1594 { 1595 // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between 1596 // ImplCallInitShow() and ImplSetReallyVisible() when called from Show() 1597 // mbReallyShown is a useful indicator 1598 if( !mpWindowImpl->mbReallyShown ) 1599 ImplCallInitShow(); 1600 1601 sal_Bool bBecameReallyVisible = !mpWindowImpl->mbReallyVisible; 1602 1603 mbDevOutput = sal_True; 1604 mpWindowImpl->mbReallyVisible = sal_True; 1605 mpWindowImpl->mbReallyShown = sal_True; 1606 1607 // the SHOW/HIDE events serve as indicators to send child creation/destroy events to the access bridge. 1608 // For this, the data member of the event must not be NULL. 1609 // Previously, we did this in Window::Show, but there some events got lost in certain situations. Now 1610 // we're doing it when the visibility really changes 1611 // #104887# - 2004-08-10 - fs@openoffice.org 1612 if( bBecameReallyVisible && ImplIsAccessibleCandidate() ) 1613 ImplCallEventListeners( VCLEVENT_WINDOW_SHOW, this ); 1614 // TODO. It's kind of a hack that we're re-using the VCLEVENT_WINDOW_SHOW. Normally, we should 1615 // introduce another event which explicitly triggers the Accessibility implementations. 1616 1617 Window* pWindow = mpWindowImpl->mpFirstOverlap; 1618 while ( pWindow ) 1619 { 1620 if ( pWindow->mpWindowImpl->mbVisible ) 1621 pWindow->ImplSetReallyVisible(); 1622 pWindow = pWindow->mpWindowImpl->mpNext; 1623 } 1624 1625 pWindow = mpWindowImpl->mpFirstChild; 1626 while ( pWindow ) 1627 { 1628 if ( pWindow->mpWindowImpl->mbVisible ) 1629 pWindow->ImplSetReallyVisible(); 1630 pWindow = pWindow->mpWindowImpl->mpNext; 1631 } 1632 } 1633 1634 // ----------------------------------------------------------------------- 1635 1636 void Window::ImplCallInitShow() 1637 { 1638 mpWindowImpl->mbReallyShown = sal_True; 1639 mpWindowImpl->mbInInitShow = sal_True; 1640 StateChanged( STATE_CHANGE_INITSHOW ); 1641 mpWindowImpl->mbInInitShow = sal_False; 1642 1643 Window* pWindow = mpWindowImpl->mpFirstOverlap; 1644 while ( pWindow ) 1645 { 1646 if ( pWindow->mpWindowImpl->mbVisible ) 1647 pWindow->ImplCallInitShow(); 1648 pWindow = pWindow->mpWindowImpl->mpNext; 1649 } 1650 1651 pWindow = mpWindowImpl->mpFirstChild; 1652 while ( pWindow ) 1653 { 1654 if ( pWindow->mpWindowImpl->mbVisible ) 1655 pWindow->ImplCallInitShow(); 1656 pWindow = pWindow->mpWindowImpl->mpNext; 1657 } 1658 } 1659 1660 // ----------------------------------------------------------------------- 1661 1662 void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompatiblity ok 1663 { 1664 DBG_ASSERT( !pDel->mpWindow, "Window::ImplAddDel(): cannot add ImplDelData twice !" ); 1665 if( !pDel->mpWindow ) 1666 { 1667 pDel->mpWindow = this; // #112873# store ref to this window, so pDel can remove itself 1668 pDel->mpNext = mpWindowImpl->mpFirstDel; 1669 mpWindowImpl->mpFirstDel = pDel; 1670 } 1671 } 1672 1673 // ----------------------------------------------------------------------- 1674 1675 void Window::ImplRemoveDel( ImplDelData* pDel ) // TODO: make "const" when incompatiblity ok 1676 { 1677 pDel->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore 1678 if ( mpWindowImpl->mpFirstDel == pDel ) 1679 mpWindowImpl->mpFirstDel = pDel->mpNext; 1680 else 1681 { 1682 ImplDelData* pData = mpWindowImpl->mpFirstDel; 1683 while ( pData->mpNext != pDel ) 1684 pData = pData->mpNext; 1685 pData->mpNext = pDel->mpNext; 1686 } 1687 } 1688 1689 // ----------------------------------------------------------------------- 1690 1691 void Window::ImplInitResolutionSettings() 1692 { 1693 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen 1694 if ( mpWindowImpl->mbFrame ) 1695 { 1696 const StyleSettings& rStyleSettings = maSettings.GetStyleSettings(); 1697 sal_uInt16 nScreenZoom = rStyleSettings.GetScreenZoom(); 1698 mnDPIX = (mpWindowImpl->mpFrameData->mnDPIX*nScreenZoom)/100; 1699 mnDPIY = (mpWindowImpl->mpFrameData->mnDPIY*nScreenZoom)/100; 1700 SetPointFont( rStyleSettings.GetAppFont() ); 1701 } 1702 else if ( mpWindowImpl->mpParent ) 1703 { 1704 mnDPIX = mpWindowImpl->mpParent->mnDPIX; 1705 mnDPIY = mpWindowImpl->mpParent->mnDPIY; 1706 } 1707 1708 // Vorberechnete Werte fuer logische Einheiten updaten und auch 1709 // die entsprechenden Tools dazu 1710 if ( IsMapMode() ) 1711 { 1712 MapMode aMapMode = GetMapMode(); 1713 SetMapMode(); 1714 SetMapMode( aMapMode ); 1715 } 1716 } 1717 1718 // ----------------------------------------------------------------------- 1719 1720 void Window::ImplPointToLogic( Font& rFont ) const 1721 { 1722 Size aSize = rFont.GetSize(); 1723 sal_uInt16 nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom(); 1724 1725 if ( aSize.Width() ) 1726 { 1727 aSize.Width() *= mpWindowImpl->mpFrameData->mnDPIX; 1728 aSize.Width() += 72/2; 1729 aSize.Width() /= 72; 1730 aSize.Width() *= nScreenFontZoom; 1731 aSize.Width() /= 100; 1732 } 1733 aSize.Height() *= mpWindowImpl->mpFrameData->mnDPIY; 1734 aSize.Height() += 72/2; 1735 aSize.Height() /= 72; 1736 aSize.Height() *= nScreenFontZoom; 1737 aSize.Height() /= 100; 1738 1739 if ( IsMapModeEnabled() ) 1740 aSize = PixelToLogic( aSize ); 1741 1742 rFont.SetSize( aSize ); 1743 } 1744 1745 // ----------------------------------------------------------------------- 1746 1747 void Window::ImplLogicToPoint( Font& rFont ) const 1748 { 1749 Size aSize = rFont.GetSize(); 1750 sal_uInt16 nScreenFontZoom = maSettings.GetStyleSettings().GetScreenFontZoom(); 1751 1752 if ( IsMapModeEnabled() ) 1753 aSize = LogicToPixel( aSize ); 1754 1755 if ( aSize.Width() ) 1756 { 1757 aSize.Width() *= 100; 1758 aSize.Width() /= nScreenFontZoom; 1759 aSize.Width() *= 72; 1760 aSize.Width() += mpWindowImpl->mpFrameData->mnDPIX/2; 1761 aSize.Width() /= mpWindowImpl->mpFrameData->mnDPIX; 1762 } 1763 aSize.Height() *= 100; 1764 aSize.Height() /= nScreenFontZoom; 1765 aSize.Height() *= 72; 1766 aSize.Height() += mpWindowImpl->mpFrameData->mnDPIY/2; 1767 aSize.Height() /= mpWindowImpl->mpFrameData->mnDPIY; 1768 1769 rFont.SetSize( aSize ); 1770 } 1771 1772 // ----------------------------------------------------------------------- 1773 1774 sal_Bool Window::ImplSysObjClip( const Region* pOldRegion ) 1775 { 1776 sal_Bool bUpdate = sal_True; 1777 1778 if ( mpWindowImpl->mpSysObj ) 1779 { 1780 sal_Bool bVisibleState = mpWindowImpl->mbReallyVisible; 1781 1782 if ( bVisibleState ) 1783 { 1784 Region* pWinChildClipRegion = ImplGetWinChildClipRegion(); 1785 1786 if ( !pWinChildClipRegion->IsEmpty() ) 1787 { 1788 if ( pOldRegion ) 1789 { 1790 Region aNewRegion = *pWinChildClipRegion; 1791 pWinChildClipRegion->Intersect( *pOldRegion ); 1792 bUpdate = aNewRegion == *pWinChildClipRegion; 1793 } 1794 1795 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 1796 ImplInvalidateAllOverlapBackgrounds(); 1797 1798 Region aRegion = *pWinChildClipRegion; 1799 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 1800 Region aWinRectRegion( aWinRect ); 1801 sal_uInt16 nClipFlags = mpWindowImpl->mpSysObj->GetClipRegionType(); 1802 1803 if ( aRegion == aWinRectRegion ) 1804 mpWindowImpl->mpSysObj->ResetClipRegion(); 1805 else 1806 { 1807 if ( nClipFlags & SAL_OBJECT_CLIP_EXCLUDERECTS ) 1808 { 1809 aWinRectRegion.Exclude( aRegion ); 1810 aRegion = aWinRectRegion; 1811 } 1812 if ( !(nClipFlags & SAL_OBJECT_CLIP_ABSOLUTE) ) 1813 aRegion.Move( -mnOutOffX, -mnOutOffY ); 1814 1815 // ClipRegion setzen/updaten 1816 RectangleVector aRectangles; 1817 aRegion.GetRegionRectangles(aRectangles); 1818 mpWindowImpl->mpSysObj->BeginSetClipRegion(aRectangles.size()); 1819 1820 for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++) 1821 { 1822 mpWindowImpl->mpSysObj->UnionClipRegion( 1823 aRectIter->Left(), 1824 aRectIter->Top(), 1825 aRectIter->GetWidth(), // orig nWidth was ((R - L) + 1), same as GetWidth does 1826 aRectIter->GetHeight()); // same for height 1827 } 1828 1829 mpWindowImpl->mpSysObj->EndSetClipRegion(); 1830 1831 //long nX; 1832 //long nY; 1833 //long nWidth; 1834 //long nHeight; 1835 //sal_uLong nRectCount; 1836 //ImplRegionInfo aInfo; 1837 //sal_Bool bRegionRect; 1838 // 1839 //nRectCount = aRegion.GetRectCount(); 1840 //mpWindowImpl->mpSysObj->BeginSetClipRegion( nRectCount ); 1841 //bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight ); 1842 //while ( bRegionRect ) 1843 //{ 1844 // mpWindowImpl->mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight ); 1845 // bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight ); 1846 //} 1847 //mpWindowImpl->mpSysObj->EndSetClipRegion(); 1848 } 1849 } 1850 else 1851 bVisibleState = sal_False; 1852 } 1853 1854 // Visible-Status updaten 1855 mpWindowImpl->mpSysObj->Show( bVisibleState ); 1856 } 1857 1858 return bUpdate; 1859 } 1860 1861 // ----------------------------------------------------------------------- 1862 1863 void Window::ImplUpdateSysObjChildsClip() 1864 { 1865 if ( mpWindowImpl->mpSysObj && mpWindowImpl->mbInitWinClipRegion ) 1866 ImplSysObjClip( NULL ); 1867 1868 Window* pWindow = mpWindowImpl->mpFirstChild; 1869 while ( pWindow ) 1870 { 1871 pWindow->ImplUpdateSysObjChildsClip(); 1872 pWindow = pWindow->mpWindowImpl->mpNext; 1873 } 1874 } 1875 1876 // ----------------------------------------------------------------------- 1877 1878 void Window::ImplUpdateSysObjOverlapsClip() 1879 { 1880 ImplUpdateSysObjChildsClip(); 1881 1882 Window* pWindow = mpWindowImpl->mpFirstOverlap; 1883 while ( pWindow ) 1884 { 1885 pWindow->ImplUpdateSysObjOverlapsClip(); 1886 pWindow = pWindow->mpWindowImpl->mpNext; 1887 } 1888 } 1889 1890 // ----------------------------------------------------------------------- 1891 1892 void Window::ImplUpdateSysObjClip() 1893 { 1894 if ( !ImplIsOverlapWindow() ) 1895 { 1896 ImplUpdateSysObjChildsClip(); 1897 1898 // Schwestern muessen ihre ClipRegion auch neu berechnen 1899 if ( mpWindowImpl->mbClipSiblings ) 1900 { 1901 Window* pWindow = mpWindowImpl->mpNext; 1902 while ( pWindow ) 1903 { 1904 pWindow->ImplUpdateSysObjChildsClip(); 1905 pWindow = pWindow->mpWindowImpl->mpNext; 1906 } 1907 } 1908 } 1909 else 1910 mpWindowImpl->mpFrameWindow->ImplUpdateSysObjOverlapsClip(); 1911 } 1912 1913 // ----------------------------------------------------------------------- 1914 1915 sal_Bool Window::ImplSetClipFlagChilds( sal_Bool bSysObjOnlySmaller ) 1916 { 1917 sal_Bool bUpdate = sal_True; 1918 if ( mpWindowImpl->mpSysObj ) 1919 { 1920 Region* pOldRegion = NULL; 1921 if ( bSysObjOnlySmaller && !mpWindowImpl->mbInitWinClipRegion ) 1922 pOldRegion = new Region( mpWindowImpl->maWinClipRegion ); 1923 1924 mbInitClipRegion = sal_True; 1925 mpWindowImpl->mbInitWinClipRegion = sal_True; 1926 1927 Window* pWindow = mpWindowImpl->mpFirstChild; 1928 while ( pWindow ) 1929 { 1930 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) ) 1931 bUpdate = sal_False; 1932 pWindow = pWindow->mpWindowImpl->mpNext; 1933 } 1934 1935 if ( !ImplSysObjClip( pOldRegion ) ) 1936 { 1937 mbInitClipRegion = sal_True; 1938 mpWindowImpl->mbInitWinClipRegion = sal_True; 1939 bUpdate = sal_False; 1940 } 1941 1942 if ( pOldRegion ) 1943 delete pOldRegion; 1944 } 1945 else 1946 { 1947 mbInitClipRegion = sal_True; 1948 mpWindowImpl->mbInitWinClipRegion = sal_True; 1949 1950 Window* pWindow = mpWindowImpl->mpFirstChild; 1951 while ( pWindow ) 1952 { 1953 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) ) 1954 bUpdate = sal_False; 1955 pWindow = pWindow->mpWindowImpl->mpNext; 1956 } 1957 } 1958 return bUpdate; 1959 } 1960 1961 // ----------------------------------------------------------------------- 1962 1963 sal_Bool Window::ImplSetClipFlagOverlapWindows( sal_Bool bSysObjOnlySmaller ) 1964 { 1965 sal_Bool bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller ); 1966 1967 Window* pWindow = mpWindowImpl->mpFirstOverlap; 1968 while ( pWindow ) 1969 { 1970 if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) ) 1971 bUpdate = sal_False; 1972 pWindow = pWindow->mpWindowImpl->mpNext; 1973 } 1974 1975 return bUpdate; 1976 } 1977 1978 // ----------------------------------------------------------------------- 1979 1980 sal_Bool Window::ImplSetClipFlag( sal_Bool bSysObjOnlySmaller ) 1981 { 1982 if ( !ImplIsOverlapWindow() ) 1983 { 1984 sal_Bool bUpdate = ImplSetClipFlagChilds( bSysObjOnlySmaller ); 1985 1986 Window* pParent = ImplGetParent(); 1987 if ( pParent && 1988 ((pParent->GetStyle() & WB_CLIPCHILDREN) || (mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP)) ) 1989 { 1990 pParent->mbInitClipRegion = sal_True; 1991 pParent->mpWindowImpl->mbInitChildRegion = sal_True; 1992 } 1993 1994 // Schwestern muessen ihre ClipRegion auch neu berechnen 1995 if ( mpWindowImpl->mbClipSiblings ) 1996 { 1997 Window* pWindow = mpWindowImpl->mpNext; 1998 while ( pWindow ) 1999 { 2000 if ( !pWindow->ImplSetClipFlagChilds( bSysObjOnlySmaller ) ) 2001 bUpdate = sal_False; 2002 pWindow = pWindow->mpWindowImpl->mpNext; 2003 } 2004 } 2005 2006 return bUpdate; 2007 } 2008 else 2009 return mpWindowImpl->mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ); 2010 } 2011 2012 // ----------------------------------------------------------------------- 2013 2014 void Window::ImplIntersectWindowClipRegion( Region& rRegion ) 2015 { 2016 if ( mpWindowImpl->mbInitWinClipRegion ) 2017 ImplInitWinClipRegion(); 2018 2019 rRegion.Intersect( mpWindowImpl->maWinClipRegion ); 2020 } 2021 2022 // ----------------------------------------------------------------------- 2023 2024 void Window::ImplIntersectWindowRegion( Region& rRegion ) 2025 { 2026 rRegion.Intersect( Rectangle( Point( mnOutOffX, mnOutOffY ), 2027 Size( mnOutWidth, mnOutHeight ) ) ); 2028 if ( mpWindowImpl->mbWinRegion ) 2029 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) ); 2030 } 2031 2032 // ----------------------------------------------------------------------- 2033 2034 void Window::ImplExcludeWindowRegion( Region& rRegion ) 2035 { 2036 if ( mpWindowImpl->mbWinRegion ) 2037 { 2038 Point aPoint( mnOutOffX, mnOutOffY ); 2039 Region aRegion( Rectangle( aPoint, 2040 Size( mnOutWidth, mnOutHeight ) ) ); 2041 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) ); 2042 rRegion.Exclude( aRegion ); 2043 } 2044 else 2045 { 2046 Point aPoint( mnOutOffX, mnOutOffY ); 2047 rRegion.Exclude( Rectangle( aPoint, 2048 Size( mnOutWidth, mnOutHeight ) ) ); 2049 } 2050 } 2051 2052 // ----------------------------------------------------------------------- 2053 2054 void Window::ImplExcludeOverlapWindows( Region& rRegion ) 2055 { 2056 Window* pWindow = mpWindowImpl->mpFirstOverlap; 2057 while ( pWindow ) 2058 { 2059 if ( pWindow->mpWindowImpl->mbReallyVisible ) 2060 { 2061 pWindow->ImplExcludeWindowRegion( rRegion ); 2062 pWindow->ImplExcludeOverlapWindows( rRegion ); 2063 } 2064 2065 pWindow = pWindow->mpWindowImpl->mpNext; 2066 } 2067 } 2068 2069 // ----------------------------------------------------------------------- 2070 2071 void Window::ImplExcludeOverlapWindows2( Region& rRegion ) 2072 { 2073 if ( mpWindowImpl->mbReallyVisible ) 2074 ImplExcludeWindowRegion( rRegion ); 2075 2076 ImplExcludeOverlapWindows( rRegion ); 2077 } 2078 2079 // ----------------------------------------------------------------------- 2080 2081 void Window::ImplClipBoundaries( Region& rRegion, sal_Bool bThis, sal_Bool bOverlaps ) 2082 { 2083 if ( bThis ) 2084 ImplIntersectWindowClipRegion( rRegion ); 2085 else if ( ImplIsOverlapWindow() ) 2086 { 2087 // Evt. noch am Frame clippen 2088 if ( !mpWindowImpl->mbFrame ) 2089 rRegion.Intersect( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) ); 2090 2091 if ( bOverlaps && !rRegion.IsEmpty() ) 2092 { 2093 // Clip Overlap Siblings 2094 Window* pStartOverlapWindow = this; 2095 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame ) 2096 { 2097 Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; 2098 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) ) 2099 { 2100 pOverlapWindow->ImplExcludeOverlapWindows2( rRegion ); 2101 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; 2102 } 2103 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow; 2104 } 2105 2106 // Clip Child Overlap Windows 2107 ImplExcludeOverlapWindows( rRegion ); 2108 } 2109 } 2110 else 2111 ImplGetParent()->ImplIntersectWindowClipRegion( rRegion ); 2112 } 2113 2114 // ----------------------------------------------------------------------- 2115 2116 sal_Bool Window::ImplClipChilds( Region& rRegion ) 2117 { 2118 sal_Bool bOtherClip = sal_False; 2119 Window* pWindow = mpWindowImpl->mpFirstChild; 2120 while ( pWindow ) 2121 { 2122 if ( pWindow->mpWindowImpl->mbReallyVisible ) 2123 { 2124 // ParentClipMode-Flags auswerten 2125 sal_uInt16 nClipMode = pWindow->GetParentClipMode(); 2126 if ( !(nClipMode & PARENTCLIPMODE_NOCLIP) && 2127 ((nClipMode & PARENTCLIPMODE_CLIP) || (GetStyle() & WB_CLIPCHILDREN)) ) 2128 pWindow->ImplExcludeWindowRegion( rRegion ); 2129 else 2130 bOtherClip = sal_True; 2131 } 2132 2133 pWindow = pWindow->mpWindowImpl->mpNext; 2134 } 2135 2136 return bOtherClip; 2137 } 2138 2139 // ----------------------------------------------------------------------- 2140 2141 void Window::ImplClipAllChilds( Region& rRegion ) 2142 { 2143 Window* pWindow = mpWindowImpl->mpFirstChild; 2144 while ( pWindow ) 2145 { 2146 if ( pWindow->mpWindowImpl->mbReallyVisible ) 2147 pWindow->ImplExcludeWindowRegion( rRegion ); 2148 pWindow = pWindow->mpWindowImpl->mpNext; 2149 } 2150 } 2151 2152 // ----------------------------------------------------------------------- 2153 2154 void Window::ImplClipSiblings( Region& rRegion ) 2155 { 2156 Window* pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild; 2157 while ( pWindow ) 2158 { 2159 if ( pWindow == this ) 2160 break; 2161 2162 if ( pWindow->mpWindowImpl->mbReallyVisible ) 2163 pWindow->ImplExcludeWindowRegion( rRegion ); 2164 2165 pWindow = pWindow->mpWindowImpl->mpNext; 2166 } 2167 } 2168 2169 // ----------------------------------------------------------------------- 2170 2171 void Window::ImplInitWinClipRegion() 2172 { 2173 // Build Window Region 2174 mpWindowImpl->maWinClipRegion = Rectangle( Point( mnOutOffX, mnOutOffY ), 2175 Size( mnOutWidth, mnOutHeight ) ); 2176 if ( mpWindowImpl->mbWinRegion ) 2177 mpWindowImpl->maWinClipRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) ); 2178 2179 // ClipSiblings 2180 if ( mpWindowImpl->mbClipSiblings && !ImplIsOverlapWindow() ) 2181 ImplClipSiblings( mpWindowImpl->maWinClipRegion ); 2182 2183 // Clip Parent Boundaries 2184 ImplClipBoundaries( mpWindowImpl->maWinClipRegion, sal_False, sal_True ); 2185 2186 // Clip Children 2187 if ( (GetStyle() & WB_CLIPCHILDREN) || mpWindowImpl->mbClipChildren ) 2188 mpWindowImpl->mbInitChildRegion = sal_True; 2189 2190 mpWindowImpl->mbInitWinClipRegion = sal_False; 2191 } 2192 2193 // ----------------------------------------------------------------------- 2194 2195 void Window::ImplInitWinChildClipRegion() 2196 { 2197 if ( !mpWindowImpl->mpFirstChild ) 2198 { 2199 if ( mpWindowImpl->mpChildClipRegion ) 2200 { 2201 delete mpWindowImpl->mpChildClipRegion; 2202 mpWindowImpl->mpChildClipRegion = NULL; 2203 } 2204 } 2205 else 2206 { 2207 if ( !mpWindowImpl->mpChildClipRegion ) 2208 mpWindowImpl->mpChildClipRegion = new Region( mpWindowImpl->maWinClipRegion ); 2209 else 2210 *mpWindowImpl->mpChildClipRegion = mpWindowImpl->maWinClipRegion; 2211 2212 ImplClipChilds( *mpWindowImpl->mpChildClipRegion ); 2213 } 2214 2215 mpWindowImpl->mbInitChildRegion = sal_False; 2216 } 2217 2218 // ----------------------------------------------------------------------- 2219 2220 Region* Window::ImplGetWinChildClipRegion() 2221 { 2222 if ( mpWindowImpl->mbInitWinClipRegion ) 2223 ImplInitWinClipRegion(); 2224 if ( mpWindowImpl->mbInitChildRegion ) 2225 ImplInitWinChildClipRegion(); 2226 if ( mpWindowImpl->mpChildClipRegion ) 2227 return mpWindowImpl->mpChildClipRegion; 2228 else 2229 return &mpWindowImpl->maWinClipRegion; 2230 } 2231 2232 // ----------------------------------------------------------------------- 2233 2234 void Window::ImplIntersectAndUnionOverlapWindows( const Region& rInterRegion, Region& rRegion ) 2235 { 2236 Window* pWindow = mpWindowImpl->mpFirstOverlap; 2237 while ( pWindow ) 2238 { 2239 if ( pWindow->mpWindowImpl->mbReallyVisible ) 2240 { 2241 Region aTempRegion( rInterRegion ); 2242 pWindow->ImplIntersectWindowRegion( aTempRegion ); 2243 rRegion.Union( aTempRegion ); 2244 pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion ); 2245 } 2246 2247 pWindow = pWindow->mpWindowImpl->mpNext; 2248 } 2249 } 2250 2251 // ----------------------------------------------------------------------- 2252 2253 void Window::ImplIntersectAndUnionOverlapWindows2( const Region& rInterRegion, Region& rRegion ) 2254 { 2255 if ( mpWindowImpl->mbReallyVisible ) 2256 { 2257 Region aTempRegion( rInterRegion ); 2258 ImplIntersectWindowRegion( aTempRegion ); 2259 rRegion.Union( aTempRegion ); 2260 } 2261 2262 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion ); 2263 } 2264 2265 // ----------------------------------------------------------------------- 2266 2267 void Window::ImplCalcOverlapRegionOverlaps( const Region& rInterRegion, Region& rRegion ) 2268 { 2269 // Clip Overlap Siblings 2270 Window* pStartOverlapWindow; 2271 if ( !ImplIsOverlapWindow() ) 2272 pStartOverlapWindow = mpWindowImpl->mpOverlapWindow; 2273 else 2274 pStartOverlapWindow = this; 2275 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame ) 2276 { 2277 Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; 2278 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) ) 2279 { 2280 pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion ); 2281 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; 2282 } 2283 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow; 2284 } 2285 2286 // Clip Child Overlap Windows 2287 if ( !ImplIsOverlapWindow() ) 2288 mpWindowImpl->mpOverlapWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion ); 2289 else 2290 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion ); 2291 } 2292 2293 // ----------------------------------------------------------------------- 2294 2295 void Window::ImplCalcOverlapRegion( const Rectangle& rSourceRect, Region& rRegion, 2296 sal_Bool bChilds, sal_Bool bParent, sal_Bool bSiblings ) 2297 { 2298 Region aRegion( rSourceRect ); 2299 if ( mpWindowImpl->mbWinRegion ) 2300 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) ); 2301 Region aTempRegion; 2302 Window* pWindow; 2303 2304 ImplCalcOverlapRegionOverlaps( aRegion, rRegion ); 2305 2306 // Parent-Boundaries 2307 if ( bParent ) 2308 { 2309 pWindow = this; 2310 if ( !ImplIsOverlapWindow() ) 2311 { 2312 pWindow = ImplGetParent(); 2313 do 2314 { 2315 aTempRegion = aRegion; 2316 pWindow->ImplExcludeWindowRegion( aTempRegion ); 2317 rRegion.Union( aTempRegion ); 2318 if ( pWindow->ImplIsOverlapWindow() ) 2319 break; 2320 pWindow = pWindow->ImplGetParent(); 2321 } 2322 while ( pWindow ); 2323 } 2324 if ( !pWindow->mpWindowImpl->mbFrame ) 2325 { 2326 aTempRegion = aRegion; 2327 aTempRegion.Exclude( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) ); 2328 rRegion.Union( aTempRegion ); 2329 } 2330 } 2331 2332 // Siblings 2333 if ( bSiblings && !ImplIsOverlapWindow() ) 2334 { 2335 pWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild; 2336 do 2337 { 2338 if ( pWindow->mpWindowImpl->mbReallyVisible && (pWindow != this) ) 2339 { 2340 aTempRegion = aRegion; 2341 pWindow->ImplIntersectWindowRegion( aTempRegion ); 2342 rRegion.Union( aTempRegion ); 2343 } 2344 pWindow = pWindow->mpWindowImpl->mpNext; 2345 } 2346 while ( pWindow ); 2347 } 2348 2349 // Childs 2350 if ( bChilds ) 2351 { 2352 pWindow = mpWindowImpl->mpFirstChild; 2353 while ( pWindow ) 2354 { 2355 if ( pWindow->mpWindowImpl->mbReallyVisible ) 2356 { 2357 aTempRegion = aRegion; 2358 pWindow->ImplIntersectWindowRegion( aTempRegion ); 2359 rRegion.Union( aTempRegion ); 2360 } 2361 pWindow = pWindow->mpWindowImpl->mpNext; 2362 } 2363 } 2364 } 2365 2366 // ----------------------------------------------------------------------- 2367 2368 void Window::ImplCallPaint( const Region* pRegion, sal_uInt16 nPaintFlags ) 2369 { 2370 Exception aException; 2371 bool bExceptionCaught(false); 2372 2373 // call PrePaint. PrePaint may add to the invalidate region as well as 2374 // other parameters used below. 2375 PrePaint(); 2376 2377 mpWindowImpl->mbPaintFrame = sal_False; 2378 2379 if ( nPaintFlags & IMPL_PAINT_PAINTALLCHILDS ) 2380 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDS | (nPaintFlags & IMPL_PAINT_PAINTALL); 2381 if ( nPaintFlags & IMPL_PAINT_PAINTCHILDS ) 2382 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS; 2383 if ( nPaintFlags & IMPL_PAINT_ERASE ) 2384 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE; 2385 if ( nPaintFlags & IMPL_PAINT_CHECKRTL ) 2386 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL; 2387 if ( !mpWindowImpl->mpFirstChild ) 2388 mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDS; 2389 2390 if ( mpWindowImpl->mbPaintDisabled ) 2391 { 2392 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL ) 2393 Invalidate( INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN ); 2394 else if ( pRegion ) 2395 Invalidate( *pRegion, INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN ); 2396 return; 2397 } 2398 2399 nPaintFlags = mpWindowImpl->mnPaintFlags & ~(IMPL_PAINT_PAINT); 2400 2401 Region* pChildRegion = NULL; 2402 Rectangle aSelectionRect; 2403 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT ) 2404 { 2405 Region* pWinChildClipRegion = ImplGetWinChildClipRegion(); 2406 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL ) 2407 mpWindowImpl->maInvalidateRegion = *pWinChildClipRegion; 2408 else 2409 { 2410 if ( pRegion ) 2411 mpWindowImpl->maInvalidateRegion.Union( *pRegion ); 2412 2413 if( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible ) 2414 /* #98602# need to repaint all children within the 2415 * tracking rectangle, so the following invert 2416 * operation takes places without traces of the previous 2417 * one. 2418 */ 2419 mpWindowImpl->maInvalidateRegion.Union( *mpWindowImpl->mpWinData->mpTrackRect ); 2420 2421 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS ) 2422 pChildRegion = new Region( mpWindowImpl->maInvalidateRegion ); 2423 mpWindowImpl->maInvalidateRegion.Intersect( *pWinChildClipRegion ); 2424 } 2425 mpWindowImpl->mnPaintFlags = 0; 2426 if ( !mpWindowImpl->maInvalidateRegion.IsEmpty() ) 2427 { 2428 bool bRestoreCursor = false; 2429 if ( mpWindowImpl->mpCursor ) 2430 bRestoreCursor = mpWindowImpl->mpCursor->ImplHide( false ); 2431 2432 mbInitClipRegion = sal_True; 2433 mpWindowImpl->mbInPaint = sal_True; 2434 2435 // Paint-Region zuruecksetzen 2436 Region aPaintRegion( mpWindowImpl->maInvalidateRegion ); 2437 Rectangle aPaintRect = aPaintRegion.GetBoundRect(); 2438 2439 // - RTL - re-mirror paint rect and region at this window 2440 if( ImplIsAntiparallel() ) 2441 { 2442 ImplReMirror( aPaintRect ); 2443 ImplReMirror( aPaintRegion ); 2444 } 2445 aPaintRect = ImplDevicePixelToLogic( aPaintRect); 2446 mpWindowImpl->mpPaintRegion = &aPaintRegion; 2447 mpWindowImpl->maInvalidateRegion.SetEmpty(); 2448 2449 if ( (nPaintFlags & IMPL_PAINT_ERASE) && IsBackground() ) 2450 { 2451 if ( IsClipRegion() ) 2452 { 2453 Region aOldRegion = GetClipRegion(); 2454 SetClipRegion(); 2455 Erase(); 2456 SetClipRegion( aOldRegion ); 2457 } 2458 else 2459 Erase(); 2460 } 2461 2462 // #98943# trigger drawing of toolbox selection after all childern are painted 2463 if( mpWindowImpl->mbDrawSelectionBackground ) 2464 aSelectionRect = aPaintRect; 2465 2466 // Paint can throw exceptions; to not have a situation where 2467 // mpWindowImpl->mbInPaint keeps to be on true (and other 2468 // settings, too) better catch here to avoid to go completely out of 2469 // this method without executing the after-paint stuff 2470 try 2471 { 2472 Paint( aPaintRect ); 2473 } 2474 catch(Exception& rException) 2475 { 2476 aException = rException; 2477 bExceptionCaught = true; 2478 } 2479 2480 if ( mpWindowImpl->mpWinData ) 2481 { 2482 if ( mpWindowImpl->mbFocusVisible ) 2483 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) ); 2484 } 2485 mpWindowImpl->mbInPaint = sal_False; 2486 mbInitClipRegion = sal_True; 2487 mpWindowImpl->mpPaintRegion = NULL; 2488 if ( mpWindowImpl->mpCursor ) 2489 mpWindowImpl->mpCursor->ImplShow( false, bRestoreCursor ); 2490 } 2491 } 2492 else 2493 mpWindowImpl->mnPaintFlags = 0; 2494 2495 if ( nPaintFlags & (IMPL_PAINT_PAINTALLCHILDS | IMPL_PAINT_PAINTCHILDS) ) 2496 { 2497 // die Childfenster ausgeben 2498 Window* pTempWindow = mpWindowImpl->mpFirstChild; 2499 while ( pTempWindow ) 2500 { 2501 if ( pTempWindow->mpWindowImpl->mbVisible ) 2502 pTempWindow->ImplCallPaint( pChildRegion, nPaintFlags ); 2503 pTempWindow = pTempWindow->mpWindowImpl->mpNext; 2504 } 2505 } 2506 2507 if ( mpWindowImpl->mpWinData && mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) ) 2508 /* #98602# need to invert the tracking rect AFTER 2509 * the children have painted 2510 */ 2511 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags ); 2512 2513 // #98943# draw toolbox selection 2514 if( !aSelectionRect.IsEmpty() ) 2515 DrawSelectionBackground( aSelectionRect, 3, sal_False, sal_True, sal_False ); 2516 2517 if ( pChildRegion ) 2518 delete pChildRegion; 2519 2520 if(bExceptionCaught) 2521 { 2522 throw(aException); 2523 } 2524 } 2525 2526 // ----------------------------------------------------------------------- 2527 2528 void Window::ImplCallOverlapPaint() 2529 { 2530 // Zuerst geben wir die ueberlappenden Fenster aus 2531 Window* pTempWindow = mpWindowImpl->mpFirstOverlap; 2532 while ( pTempWindow ) 2533 { 2534 if ( pTempWindow->mpWindowImpl->mbReallyVisible ) 2535 pTempWindow->ImplCallOverlapPaint(); 2536 pTempWindow = pTempWindow->mpWindowImpl->mpNext; 2537 } 2538 2539 // und dann erst uns selber 2540 if ( mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) ) 2541 { 2542 // - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL) 2543 // because we were called from the Sal layer 2544 ImplCallPaint( NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */); 2545 } 2546 } 2547 2548 // ----------------------------------------------------------------------- 2549 2550 void Window::ImplPostPaint() 2551 { 2552 if ( !mpWindowImpl->mpFrameData->maPaintTimer.IsActive() ) 2553 mpWindowImpl->mpFrameData->maPaintTimer.Start(); 2554 } 2555 2556 // ----------------------------------------------------------------------- 2557 2558 IMPL_LINK( Window, ImplHandlePaintHdl, void*, EMPTYARG ) 2559 { 2560 // save paint events until resizing is done 2561 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeTimer.IsActive() ) 2562 mpWindowImpl->mpFrameData->maPaintTimer.Start(); 2563 else if ( mpWindowImpl->mbReallyVisible ) 2564 ImplCallOverlapPaint(); 2565 return 0; 2566 } 2567 2568 // ----------------------------------------------------------------------- 2569 2570 IMPL_LINK( Window, ImplHandleResizeTimerHdl, void*, EMPTYARG ) 2571 { 2572 if( mpWindowImpl->mbReallyVisible ) 2573 { 2574 ImplCallResize(); 2575 if( mpWindowImpl->mpFrameData->maPaintTimer.IsActive() ) 2576 { 2577 mpWindowImpl->mpFrameData->maPaintTimer.Stop(); 2578 mpWindowImpl->mpFrameData->maPaintTimer.GetTimeoutHdl().Call( NULL ); 2579 } 2580 } 2581 2582 return 0; 2583 } 2584 2585 // ----------------------------------------------------------------------- 2586 2587 void Window::ImplInvalidateFrameRegion( const Region* pRegion, sal_uInt16 nFlags ) 2588 { 2589 // PAINTCHILDS bei allen Parent-Fenster bis zum ersten OverlapWindow 2590 // setzen 2591 if ( !ImplIsOverlapWindow() ) 2592 { 2593 Window* pTempWindow = this; 2594 sal_uInt16 nTranspPaint = IsPaintTransparent() ? IMPL_PAINT_PAINT : 0; 2595 do 2596 { 2597 pTempWindow = pTempWindow->ImplGetParent(); 2598 if ( pTempWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDS ) 2599 break; 2600 pTempWindow->mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDS | nTranspPaint; 2601 if( ! pTempWindow->IsPaintTransparent() ) 2602 nTranspPaint = 0; 2603 } 2604 while ( !pTempWindow->ImplIsOverlapWindow() ); 2605 } 2606 2607 // Paint-Flags setzen 2608 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT; 2609 if ( nFlags & INVALIDATE_CHILDREN ) 2610 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDS; 2611 if ( !(nFlags & INVALIDATE_NOERASE) ) 2612 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE; 2613 if ( !pRegion ) 2614 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALL; 2615 2616 // Wenn nicht alles neu ausgegeben werden muss, dann die Region 2617 // dazupacken 2618 if ( !(mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL) ) 2619 mpWindowImpl->maInvalidateRegion.Union( *pRegion ); 2620 2621 // Handle transparent windows correctly: invalidate must be done on the first opaque parent 2622 if( ((IsPaintTransparent() && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) ) 2623 && ImplGetParent() ) 2624 { 2625 Window *pParent = ImplGetParent(); 2626 while( pParent && pParent->IsPaintTransparent() ) 2627 pParent = pParent->ImplGetParent(); 2628 if( pParent ) 2629 { 2630 Region *pChildRegion; 2631 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL ) 2632 // invalidate the whole child window region in the parent 2633 pChildRegion = ImplGetWinChildClipRegion(); 2634 else 2635 // invalidate the same region in the parent that has to be repainted in the child 2636 pChildRegion = &mpWindowImpl->maInvalidateRegion; 2637 2638 nFlags |= INVALIDATE_CHILDREN; // paint should also be done on all children 2639 nFlags &= ~INVALIDATE_NOERASE; // parent should paint and erase to create proper background 2640 pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags ); 2641 } 2642 } 2643 ImplPostPaint(); 2644 } 2645 2646 // ----------------------------------------------------------------------- 2647 2648 void Window::ImplInvalidateOverlapFrameRegion( const Region& rRegion ) 2649 { 2650 Region aRegion = rRegion; 2651 2652 ImplClipBoundaries( aRegion, sal_True, sal_True ); 2653 if ( !aRegion.IsEmpty() ) 2654 ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN ); 2655 2656 // Dann invalidieren wir die ueberlappenden Fenster 2657 Window* pTempWindow = mpWindowImpl->mpFirstOverlap; 2658 while ( pTempWindow ) 2659 { 2660 if ( pTempWindow->IsVisible() ) 2661 pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion ); 2662 2663 pTempWindow = pTempWindow->mpWindowImpl->mpNext; 2664 } 2665 } 2666 2667 // ----------------------------------------------------------------------- 2668 2669 void Window::ImplInvalidateParentFrameRegion( Region& rRegion ) 2670 { 2671 if ( mpWindowImpl->mbOverlapWin ) 2672 mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion ); 2673 else 2674 { 2675 if( ImplGetParent() ) 2676 ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, INVALIDATE_CHILDREN ); 2677 } 2678 } 2679 2680 // ----------------------------------------------------------------------- 2681 2682 void Window::ImplInvalidate( const Region* pRegion, sal_uInt16 nFlags ) 2683 { 2684 2685 // Hintergrund-Sicherung zuruecksetzen 2686 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 2687 ImplInvalidateAllOverlapBackgrounds(); 2688 2689 // Feststellen, was neu ausgegeben werden muss 2690 sal_Bool bInvalidateAll = !pRegion; 2691 2692 // Transparent-Invalidate beruecksichtigen 2693 Window* pOpaqueWindow = this; 2694 if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) ) 2695 { 2696 Window* pTempWindow = pOpaqueWindow->ImplGetParent(); 2697 while ( pTempWindow ) 2698 { 2699 if ( !pTempWindow->IsPaintTransparent() ) 2700 { 2701 pOpaqueWindow = pTempWindow; 2702 nFlags |= INVALIDATE_CHILDREN; 2703 bInvalidateAll = sal_False; 2704 break; 2705 } 2706 2707 if ( pTempWindow->ImplIsOverlapWindow() ) 2708 break; 2709 2710 pTempWindow = pTempWindow->ImplGetParent(); 2711 } 2712 } 2713 2714 // Region zusammenbauen 2715 sal_uInt16 nOrgFlags = nFlags; 2716 if ( !(nFlags & (INVALIDATE_CHILDREN | INVALIDATE_NOCHILDREN)) ) 2717 { 2718 if ( GetStyle() & WB_CLIPCHILDREN ) 2719 nFlags |= INVALIDATE_NOCHILDREN; 2720 else 2721 nFlags |= INVALIDATE_CHILDREN; 2722 } 2723 if ( (nFlags & INVALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild ) 2724 bInvalidateAll = sal_False; 2725 if ( bInvalidateAll ) 2726 ImplInvalidateFrameRegion( NULL, nFlags ); 2727 else 2728 { 2729 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 2730 Region aRegion( aRect ); 2731 if ( pRegion ) 2732 { 2733 // --- RTL --- remirror region before intersecting it 2734 if ( ImplIsAntiparallel() ) 2735 { 2736 Region aRgn( *pRegion ); 2737 ImplReMirror( aRgn ); 2738 aRegion.Intersect( aRgn ); 2739 } 2740 else 2741 aRegion.Intersect( *pRegion ); 2742 } 2743 ImplClipBoundaries( aRegion, sal_True, sal_True ); 2744 if ( nFlags & INVALIDATE_NOCHILDREN ) 2745 { 2746 nFlags &= ~INVALIDATE_CHILDREN; 2747 if ( !(nFlags & INVALIDATE_NOCLIPCHILDREN) ) 2748 { 2749 if ( nOrgFlags & INVALIDATE_NOCHILDREN ) 2750 ImplClipAllChilds( aRegion ); 2751 else 2752 { 2753 if ( ImplClipChilds( aRegion ) ) 2754 nFlags |= INVALIDATE_CHILDREN; 2755 } 2756 } 2757 } 2758 if ( !aRegion.IsEmpty() ) 2759 ImplInvalidateFrameRegion( &aRegion, nFlags ); // transparency is handled here, pOpaqueWindow not required 2760 } 2761 2762 if ( nFlags & INVALIDATE_UPDATE ) 2763 pOpaqueWindow->Update(); // start painting at the opaque parent 2764 } 2765 2766 // ----------------------------------------------------------------------- 2767 2768 void Window::ImplMoveInvalidateRegion( const Rectangle& rRect, 2769 long nHorzScroll, long nVertScroll, 2770 sal_Bool bChilds ) 2771 { 2772 if ( (mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT ) 2773 { 2774 Region aTempRegion = mpWindowImpl->maInvalidateRegion; 2775 aTempRegion.Intersect( rRect ); 2776 aTempRegion.Move( nHorzScroll, nVertScroll ); 2777 mpWindowImpl->maInvalidateRegion.Union( aTempRegion ); 2778 } 2779 2780 if ( bChilds && (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDS) ) 2781 { 2782 Window* pWindow = mpWindowImpl->mpFirstChild; 2783 while ( pWindow ) 2784 { 2785 pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, sal_True ); 2786 pWindow = pWindow->mpWindowImpl->mpNext; 2787 } 2788 } 2789 } 2790 2791 // ----------------------------------------------------------------------- 2792 2793 void Window::ImplMoveAllInvalidateRegions( const Rectangle& rRect, 2794 long nHorzScroll, long nVertScroll, 2795 sal_Bool bChilds ) 2796 { 2797 // Paint-Region auch verschieben, wenn noch Paints anstehen 2798 ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChilds ); 2799 // Paint-Region muss bei uns verschoben gesetzt werden, die durch 2800 // die Parents gezeichnet werden 2801 if ( !ImplIsOverlapWindow() ) 2802 { 2803 Region aPaintAllRegion; 2804 Window* pPaintAllWindow = this; 2805 do 2806 { 2807 pPaintAllWindow = pPaintAllWindow->ImplGetParent(); 2808 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS ) 2809 { 2810 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL ) 2811 { 2812 aPaintAllRegion.SetEmpty(); 2813 break; 2814 } 2815 else 2816 aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion ); 2817 } 2818 } 2819 while ( !pPaintAllWindow->ImplIsOverlapWindow() ); 2820 if ( !aPaintAllRegion.IsEmpty() ) 2821 { 2822 aPaintAllRegion.Move( nHorzScroll, nVertScroll ); 2823 sal_uInt16 nPaintFlags = 0; 2824 if ( bChilds ) 2825 mpWindowImpl->mnPaintFlags |= INVALIDATE_CHILDREN; 2826 ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags ); 2827 } 2828 } 2829 } 2830 2831 // ----------------------------------------------------------------------- 2832 2833 void Window::ImplValidateFrameRegion( const Region* pRegion, sal_uInt16 nFlags ) 2834 { 2835 if ( !pRegion ) 2836 mpWindowImpl->maInvalidateRegion.SetEmpty(); 2837 else 2838 { 2839 // Wenn alle Childfenster neu ausgegeben werden muessen, 2840 // dann invalidieren wir diese vorher 2841 if ( (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS) && mpWindowImpl->mpFirstChild ) 2842 { 2843 Region aChildRegion = mpWindowImpl->maInvalidateRegion; 2844 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL ) 2845 { 2846 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 2847 aChildRegion = aRect; 2848 } 2849 Window* pChild = mpWindowImpl->mpFirstChild; 2850 while ( pChild ) 2851 { 2852 pChild->Invalidate( aChildRegion, INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); 2853 pChild = pChild->mpWindowImpl->mpNext; 2854 } 2855 } 2856 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL ) 2857 { 2858 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 2859 mpWindowImpl->maInvalidateRegion = aRect; 2860 } 2861 mpWindowImpl->maInvalidateRegion.Exclude( *pRegion ); 2862 } 2863 mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALL; 2864 2865 if ( nFlags & VALIDATE_CHILDREN ) 2866 { 2867 Window* pChild = mpWindowImpl->mpFirstChild; 2868 while ( pChild ) 2869 { 2870 pChild->ImplValidateFrameRegion( pRegion, nFlags ); 2871 pChild = pChild->mpWindowImpl->mpNext; 2872 } 2873 } 2874 } 2875 2876 // ----------------------------------------------------------------------- 2877 2878 void Window::ImplValidate( const Region* pRegion, sal_uInt16 nFlags ) 2879 { 2880 // Region zusammenbauen 2881 sal_Bool bValidateAll = !pRegion; 2882 sal_uInt16 nOrgFlags = nFlags; 2883 if ( !(nFlags & (VALIDATE_CHILDREN | VALIDATE_NOCHILDREN)) ) 2884 { 2885 if ( GetStyle() & WB_CLIPCHILDREN ) 2886 nFlags |= VALIDATE_NOCHILDREN; 2887 else 2888 nFlags |= VALIDATE_CHILDREN; 2889 } 2890 if ( (nFlags & VALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild ) 2891 bValidateAll = sal_False; 2892 if ( bValidateAll ) 2893 ImplValidateFrameRegion( NULL, nFlags ); 2894 else 2895 { 2896 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 2897 Region aRegion( aRect ); 2898 if ( pRegion ) 2899 aRegion.Intersect( *pRegion ); 2900 ImplClipBoundaries( aRegion, sal_True, sal_True ); 2901 if ( nFlags & VALIDATE_NOCHILDREN ) 2902 { 2903 nFlags &= ~VALIDATE_CHILDREN; 2904 if ( nOrgFlags & VALIDATE_NOCHILDREN ) 2905 ImplClipAllChilds( aRegion ); 2906 else 2907 { 2908 if ( ImplClipChilds( aRegion ) ) 2909 nFlags |= VALIDATE_CHILDREN; 2910 } 2911 } 2912 if ( !aRegion.IsEmpty() ) 2913 ImplValidateFrameRegion( &aRegion, nFlags ); 2914 } 2915 } 2916 2917 // ----------------------------------------------------------------------- 2918 2919 void Window::ImplScroll( const Rectangle& rRect, 2920 long nHorzScroll, long nVertScroll, sal_uInt16 nFlags ) 2921 { 2922 if ( !IsDeviceOutputNecessary() ) 2923 return; 2924 2925 nHorzScroll = ImplLogicWidthToDevicePixel( nHorzScroll ); 2926 nVertScroll = ImplLogicHeightToDevicePixel( nVertScroll ); 2927 2928 if ( !nHorzScroll && !nVertScroll ) 2929 return; 2930 2931 // Hintergrund-Sicherung zuruecksetzen 2932 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 2933 ImplInvalidateAllOverlapBackgrounds(); 2934 2935 if ( mpWindowImpl->mpCursor ) 2936 mpWindowImpl->mpCursor->ImplHide( false ); 2937 2938 sal_uInt16 nOrgFlags = nFlags; 2939 if ( !(nFlags & (SCROLL_CHILDREN | SCROLL_NOCHILDREN)) ) 2940 { 2941 if ( GetStyle() & WB_CLIPCHILDREN ) 2942 nFlags |= SCROLL_NOCHILDREN; 2943 else 2944 nFlags |= SCROLL_CHILDREN; 2945 } 2946 2947 Region aInvalidateRegion; 2948 sal_Bool bScrollChilds = (nFlags & SCROLL_CHILDREN) != 0; 2949 sal_Bool bErase = (nFlags & SCROLL_NOERASE) == 0; 2950 2951 if ( !mpWindowImpl->mpFirstChild ) 2952 bScrollChilds = sal_False; 2953 2954 // --- RTL --- check if this window requires special action 2955 sal_Bool bReMirror = ( ImplIsAntiparallel() ); 2956 2957 Rectangle aRectMirror( rRect ); 2958 if( bReMirror ) 2959 { 2960 // --- RTL --- make sure the invalidate region of this window is 2961 // computed in the same coordinate space as the one from the overlap windows 2962 ImplReMirror( aRectMirror ); 2963 } 2964 2965 // Paint-Bereiche anpassen 2966 ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChilds ); 2967 2968 if ( !(nFlags & SCROLL_NOINVALIDATE) ) 2969 { 2970 ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChilds, sal_True, sal_False ); 2971 2972 // --- RTL --- 2973 // if the scrolling on the device is performed in the opposite direction 2974 // then move the overlaps in that direction to compute the invalidate region 2975 // on the correct side, i.e., revert nHorzScroll 2976 2977 if ( !aInvalidateRegion.IsEmpty() ) 2978 { 2979 aInvalidateRegion.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll ); 2980 bErase = sal_True; 2981 } 2982 if ( !(nFlags & SCROLL_NOWINDOWINVALIDATE) ) 2983 { 2984 Rectangle aDestRect( aRectMirror ); 2985 aDestRect.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll ); 2986 Region aWinInvalidateRegion( aRectMirror ); 2987 aWinInvalidateRegion.Exclude( aDestRect ); 2988 2989 aInvalidateRegion.Union( aWinInvalidateRegion ); 2990 } 2991 } 2992 2993 Point aPoint( mnOutOffX, mnOutOffY ); 2994 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) ); 2995 if ( nFlags & SCROLL_CLIP ) 2996 aRegion.Intersect( rRect ); 2997 if ( mpWindowImpl->mbWinRegion ) 2998 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) ); 2999 3000 aRegion.Exclude( aInvalidateRegion ); 3001 3002 ImplClipBoundaries( aRegion, sal_False, sal_True ); 3003 if ( !bScrollChilds ) 3004 { 3005 if ( nOrgFlags & SCROLL_NOCHILDREN ) 3006 ImplClipAllChilds( aRegion ); 3007 else 3008 ImplClipChilds( aRegion ); 3009 } 3010 if ( mbClipRegion && (nFlags & SCROLL_USECLIPREGION) ) 3011 aRegion.Intersect( maRegion ); 3012 if ( !aRegion.IsEmpty() ) 3013 { 3014 if ( mpWindowImpl->mpWinData ) 3015 { 3016 if ( mpWindowImpl->mbFocusVisible ) 3017 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) ); 3018 if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) ) 3019 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags ); 3020 } 3021 3022 SalGraphics* pGraphics = ImplGetFrameGraphics(); 3023 if ( pGraphics ) 3024 { 3025 if( bReMirror ) 3026 { 3027 // --- RTL --- frame coordinates require re-mirroring 3028 ImplReMirror( aRegion ); 3029 } 3030 3031 ImplSelectClipRegion( aRegion, pGraphics ); 3032 pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll, 3033 rRect.Left(), rRect.Top(), 3034 rRect.GetWidth(), rRect.GetHeight(), 3035 SAL_COPYAREA_WINDOWINVALIDATE, this ); 3036 } 3037 3038 if ( mpWindowImpl->mpWinData ) 3039 { 3040 if ( mpWindowImpl->mbFocusVisible ) 3041 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) ); 3042 if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) ) 3043 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags ); 3044 } 3045 } 3046 3047 if ( !aInvalidateRegion.IsEmpty() ) 3048 { 3049 // --- RTL --- the invalidate region for this windows is already computed in frame coordinates 3050 // so it has to be re-mirrored before calling the Paint-handler 3051 mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL; 3052 3053 sal_uInt16 nPaintFlags = INVALIDATE_CHILDREN; 3054 if ( !bErase ) 3055 nPaintFlags |= INVALIDATE_NOERASE; 3056 if ( !bScrollChilds ) 3057 { 3058 if ( nOrgFlags & SCROLL_NOCHILDREN ) 3059 ImplClipAllChilds( aInvalidateRegion ); 3060 else 3061 ImplClipChilds( aInvalidateRegion ); 3062 } 3063 ImplInvalidateFrameRegion( &aInvalidateRegion, nPaintFlags ); 3064 } 3065 3066 if ( bScrollChilds ) 3067 { 3068 Window* pWindow = mpWindowImpl->mpFirstChild; 3069 while ( pWindow ) 3070 { 3071 Point aPos = pWindow->GetPosPixel(); 3072 aPos += Point( nHorzScroll, nVertScroll ); 3073 pWindow->SetPosPixel( aPos ); 3074 3075 pWindow = pWindow->mpWindowImpl->mpNext; 3076 } 3077 } 3078 3079 if ( nFlags & SCROLL_UPDATE ) 3080 Update(); 3081 3082 if ( mpWindowImpl->mpCursor ) 3083 mpWindowImpl->mpCursor->ImplShow( false ); 3084 } 3085 3086 // ----------------------------------------------------------------------- 3087 3088 void Window::ImplUpdateAll( sal_Bool bOverlapWindows ) 3089 { 3090 if ( !mpWindowImpl->mbReallyVisible ) 3091 return; 3092 3093 sal_Bool bFlush = sal_False; 3094 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame ) 3095 { 3096 Point aPoint( 0, 0 ); 3097 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) ); 3098 ImplInvalidateOverlapFrameRegion( aRegion ); 3099 if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) 3100 bFlush = sal_True; 3101 } 3102 3103 // Ein Update wirkt immer auf das OverlapWindow, damit bei spaeteren 3104 // Paints nicht zuviel gemalt wird, wenn dort ALLCHILDREN usw. gesetzt 3105 // ist 3106 Window* pWindow = ImplGetFirstOverlapWindow(); 3107 if ( bOverlapWindows ) 3108 pWindow->ImplCallOverlapPaint(); 3109 else 3110 { 3111 if ( pWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) ) 3112 pWindow->ImplCallPaint( NULL, pWindow->mpWindowImpl->mnPaintFlags ); 3113 } 3114 3115 if ( bFlush ) 3116 Flush(); 3117 } 3118 3119 // ----------------------------------------------------------------------- 3120 3121 void Window::ImplUpdateWindowPtr( Window* pWindow ) 3122 { 3123 if ( mpWindowImpl->mpFrameWindow != pWindow->mpWindowImpl->mpFrameWindow ) 3124 { 3125 // Graphic freigeben 3126 ImplReleaseGraphics(); 3127 } 3128 3129 mpWindowImpl->mpFrameData = pWindow->mpWindowImpl->mpFrameData; 3130 mpWindowImpl->mpFrame = pWindow->mpWindowImpl->mpFrame; 3131 mpWindowImpl->mpFrameWindow = pWindow->mpWindowImpl->mpFrameWindow; 3132 if ( pWindow->ImplIsOverlapWindow() ) 3133 mpWindowImpl->mpOverlapWindow = pWindow; 3134 else 3135 mpWindowImpl->mpOverlapWindow = pWindow->mpWindowImpl->mpOverlapWindow; 3136 3137 Window* pChild = mpWindowImpl->mpFirstChild; 3138 while ( pChild ) 3139 { 3140 pChild->ImplUpdateWindowPtr( pWindow ); 3141 pChild = pChild->mpWindowImpl->mpNext; 3142 } 3143 } 3144 3145 // ----------------------------------------------------------------------- 3146 3147 void Window::ImplUpdateWindowPtr() 3148 { 3149 Window* pChild = mpWindowImpl->mpFirstChild; 3150 while ( pChild ) 3151 { 3152 pChild->ImplUpdateWindowPtr( this ); 3153 pChild = pChild->mpWindowImpl->mpNext; 3154 } 3155 } 3156 3157 // ----------------------------------------------------------------------- 3158 3159 void Window::ImplUpdateOverlapWindowPtr( sal_Bool bNewFrame ) 3160 { 3161 sal_Bool bVisible = IsVisible(); 3162 Show( sal_False ); 3163 ImplRemoveWindow( bNewFrame ); 3164 Window* pRealParent = mpWindowImpl->mpRealParent; 3165 ImplInsertWindow( ImplGetParent() ); 3166 mpWindowImpl->mpRealParent = pRealParent; 3167 ImplUpdateWindowPtr(); 3168 if ( ImplUpdatePos() ) 3169 ImplUpdateSysObjPos(); 3170 3171 if ( bNewFrame ) 3172 { 3173 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; 3174 while ( pOverlapWindow ) 3175 { 3176 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; 3177 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame ); 3178 pOverlapWindow = pNextOverlapWindow; 3179 } 3180 } 3181 3182 if ( bVisible ) 3183 Show( sal_True ); 3184 } 3185 3186 // ----------------------------------------------------------------------- 3187 3188 sal_Bool Window::ImplUpdatePos() 3189 { 3190 sal_Bool bSysChild = sal_False; 3191 3192 if ( ImplIsOverlapWindow() ) 3193 { 3194 mnOutOffX = mpWindowImpl->mnX; 3195 mnOutOffY = mpWindowImpl->mnY; 3196 } 3197 else 3198 { 3199 Window* pParent = ImplGetParent(); 3200 3201 mnOutOffX = mpWindowImpl->mnX + pParent->mnOutOffX; 3202 mnOutOffY = mpWindowImpl->mnY + pParent->mnOutOffY; 3203 } 3204 3205 Window* pChild = mpWindowImpl->mpFirstChild; 3206 while ( pChild ) 3207 { 3208 if ( pChild->ImplUpdatePos() ) 3209 bSysChild = sal_True; 3210 pChild = pChild->mpWindowImpl->mpNext; 3211 } 3212 3213 if ( mpWindowImpl->mpSysObj ) 3214 bSysChild = sal_True; 3215 3216 return bSysChild; 3217 } 3218 3219 // ----------------------------------------------------------------------- 3220 3221 void Window::ImplUpdateSysObjPos() 3222 { 3223 if ( mpWindowImpl->mpSysObj ) 3224 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ); 3225 3226 Window* pChild = mpWindowImpl->mpFirstChild; 3227 while ( pChild ) 3228 { 3229 pChild->ImplUpdateSysObjPos(); 3230 pChild = pChild->mpWindowImpl->mpNext; 3231 } 3232 } 3233 // ----------------------------------------------------------------------- 3234 3235 void Window::ImplPosSizeWindow( long nX, long nY, 3236 long nWidth, long nHeight, sal_uInt16 nFlags ) 3237 { 3238 sal_Bool bNewPos = sal_False; 3239 sal_Bool bNewSize = sal_False; 3240 sal_Bool bNewWidth = sal_False; 3241 sal_Bool bCopyBits = sal_False; 3242 long nOldOutOffX = mnOutOffX; 3243 long nOldOutOffY = mnOutOffY; 3244 long nOldOutWidth = mnOutWidth; 3245 long nOldOutHeight = mnOutHeight; 3246 Region* pOverlapRegion = NULL; 3247 Region* pOldRegion = NULL; 3248 3249 if ( IsReallyVisible() ) 3250 { 3251 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 3252 ImplInvalidateAllOverlapBackgrounds(); 3253 3254 Rectangle aOldWinRect( Point( nOldOutOffX, nOldOutOffY ), 3255 Size( nOldOutWidth, nOldOutHeight ) ); 3256 pOldRegion = new Region( aOldWinRect ); 3257 if ( mpWindowImpl->mbWinRegion ) 3258 pOldRegion->Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) ); 3259 3260 if ( mnOutWidth && mnOutHeight && !mpWindowImpl->mbPaintTransparent && 3261 !mpWindowImpl->mbInitWinClipRegion && !mpWindowImpl->maWinClipRegion.IsEmpty() && 3262 !HasPaintEvent() ) 3263 bCopyBits = sal_True; 3264 } 3265 3266 sal_Bool bnXRecycled = sal_False; // avoid duplicate mirroring in RTL case 3267 if ( nFlags & WINDOW_POSSIZE_WIDTH ) 3268 { 3269 if(!( nFlags & WINDOW_POSSIZE_X )) 3270 { 3271 nX = mpWindowImpl->mnX; 3272 nFlags |= WINDOW_POSSIZE_X; 3273 bnXRecycled = sal_True; // we're using a mnX which was already mirrored in RTL case 3274 } 3275 3276 if ( nWidth < 0 ) 3277 nWidth = 0; 3278 if ( nWidth != mnOutWidth ) 3279 { 3280 mnOutWidth = nWidth; 3281 bNewSize = sal_True; 3282 bCopyBits = sal_False; 3283 bNewWidth = sal_True; 3284 } 3285 } 3286 if ( nFlags & WINDOW_POSSIZE_HEIGHT ) 3287 { 3288 if ( nHeight < 0 ) 3289 nHeight = 0; 3290 if ( nHeight != mnOutHeight ) 3291 { 3292 mnOutHeight = nHeight; 3293 bNewSize = sal_True; 3294 bCopyBits = sal_False; 3295 } 3296 } 3297 3298 if ( nFlags & WINDOW_POSSIZE_X ) 3299 { 3300 long nOrgX = nX; 3301 // --- RTL --- (compare the screen coordinates) 3302 Point aPtDev( Point( nX+mnOutOffX, 0 ) ); 3303 if( ImplHasMirroredGraphics() ) 3304 { 3305 mpGraphics->mirror( aPtDev.X(), this ); 3306 3307 // #106948# always mirror our pos if our parent is not mirroring, even 3308 // if we are also not mirroring 3309 // --- RTL --- check if parent is in different coordinates 3310 if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() ) 3311 { 3312 // --- RTL --- (re-mirror at parent window) 3313 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX; 3314 } 3315 /* #i99166# An LTR window in RTL UI that gets sized only would be 3316 expected to not moved its upper left point 3317 */ 3318 if( bnXRecycled ) 3319 { 3320 if( ImplIsAntiparallel() ) 3321 { 3322 aPtDev.X() = mpWindowImpl->mnAbsScreenX; 3323 nOrgX = mpWindowImpl->maPos.X(); 3324 } 3325 } 3326 } 3327 else if( !bnXRecycled && mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() ) 3328 { 3329 // mirrored window in LTR UI 3330 { 3331 // --- RTL --- (re-mirror at parent window) 3332 nX = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - nX; 3333 } 3334 } 3335 3336 // check maPos as well, as it could have been changed for client windows (ImplCallMove()) 3337 if ( mpWindowImpl->mnAbsScreenX != aPtDev.X() || nX != mpWindowImpl->mnX || nOrgX != mpWindowImpl->maPos.X() ) 3338 { 3339 if ( bCopyBits && !pOverlapRegion ) 3340 { 3341 pOverlapRegion = new Region(); 3342 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ), 3343 Size( mnOutWidth, mnOutHeight ) ), 3344 *pOverlapRegion, sal_False, sal_True, sal_True ); 3345 } 3346 mpWindowImpl->mnX = nX; 3347 mpWindowImpl->maPos.X() = nOrgX; 3348 mpWindowImpl->mnAbsScreenX = aPtDev.X(); // --- RTL --- (store real screen pos) 3349 bNewPos = sal_True; 3350 } 3351 } 3352 if ( nFlags & WINDOW_POSSIZE_Y ) 3353 { 3354 // check maPos as well, as it could have been changed for client windows (ImplCallMove()) 3355 if ( nY != mpWindowImpl->mnY || nY != mpWindowImpl->maPos.Y() ) 3356 { 3357 if ( bCopyBits && !pOverlapRegion ) 3358 { 3359 pOverlapRegion = new Region(); 3360 ImplCalcOverlapRegion( Rectangle( Point( mnOutOffX, mnOutOffY ), 3361 Size( mnOutWidth, mnOutHeight ) ), 3362 *pOverlapRegion, sal_False, sal_True, sal_True ); 3363 } 3364 mpWindowImpl->mnY = nY; 3365 mpWindowImpl->maPos.Y() = nY; 3366 bNewPos = sal_True; 3367 } 3368 } 3369 3370 /* if ( nFlags & (WINDOW_POSSIZE_X|WINDOW_POSSIZE_Y) ) 3371 { 3372 POINT aPt; 3373 aPt.x = mpWindowImpl->maPos.X(); 3374 aPt.y = mpWindowImpl->maPos.Y(); 3375 ClientToScreen( mpWindowImpl->mpFrame->maFrameData.mhWnd , &aPt ); 3376 mpWindowImpl->maPos.X() = aPt.x; 3377 mpWindowImpl->maPos.Y() = aPt.y; 3378 } 3379 */ 3380 if ( bNewPos || bNewSize ) 3381 { 3382 sal_Bool bUpdateSysObjPos = sal_False; 3383 if ( bNewPos ) 3384 bUpdateSysObjPos = ImplUpdatePos(); 3385 3386 // the borderwindow always specifies the position for its client window 3387 if ( mpWindowImpl->mpBorderWindow ) 3388 mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos; 3389 3390 if ( mpWindowImpl->mpClientWindow ) 3391 { 3392 mpWindowImpl->mpClientWindow->ImplPosSizeWindow( mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder, 3393 mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder, 3394 mnOutWidth-mpWindowImpl->mpClientWindow->mpWindowImpl->mnLeftBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnRightBorder, 3395 mnOutHeight-mpWindowImpl->mpClientWindow->mpWindowImpl->mnTopBorder-mpWindowImpl->mpClientWindow->mpWindowImpl->mnBottomBorder, 3396 WINDOW_POSSIZE_X | WINDOW_POSSIZE_Y | 3397 WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT ); 3398 // Wenn wir ein ClientWindow haben, dann hat dieses fuer die 3399 // Applikation auch die Position des FloatingWindows 3400 mpWindowImpl->mpClientWindow->mpWindowImpl->maPos = mpWindowImpl->maPos; 3401 if ( bNewPos ) 3402 { 3403 if ( mpWindowImpl->mpClientWindow->IsVisible() ) 3404 { 3405 mpWindowImpl->mpClientWindow->ImplCallMove(); 3406 } 3407 else 3408 { 3409 mpWindowImpl->mpClientWindow->mpWindowImpl->mbCallMove = sal_True; 3410 } 3411 } 3412 } 3413 // else 3414 // { 3415 // if ( mpWindowImpl->mpBorderWindow ) 3416 // mpWindowImpl->maPos = mpWindowImpl->mpBorderWindow->mpWindowImpl->maPos; 3417 // } 3418 3419 // Move()/Resize() werden erst bei Show() gerufen, damit min. eins vor 3420 // einem Show() kommt 3421 if ( IsVisible() ) 3422 { 3423 if ( bNewPos ) 3424 { 3425 ImplCallMove(); 3426 } 3427 if ( bNewSize ) 3428 { 3429 ImplCallResize(); 3430 } 3431 } 3432 else 3433 { 3434 if ( bNewPos ) 3435 mpWindowImpl->mbCallMove = sal_True; 3436 if ( bNewSize ) 3437 mpWindowImpl->mbCallResize = sal_True; 3438 } 3439 3440 sal_Bool bUpdateSysObjClip = sal_False; 3441 if ( IsReallyVisible() ) 3442 { 3443 if ( bNewPos || bNewSize ) 3444 { 3445 // Hintergrund-Sicherung zuruecksetzen 3446 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev ) 3447 ImplDeleteOverlapBackground(); 3448 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 3449 ImplInvalidateAllOverlapBackgrounds(); 3450 // Clip-Flag neu setzen 3451 bUpdateSysObjClip = !ImplSetClipFlag( sal_True ); 3452 } 3453 3454 // Fensterinhalt invalidieren ? 3455 if ( bNewPos || (mnOutWidth > nOldOutWidth) || (mnOutHeight > nOldOutHeight) ) 3456 { 3457 if ( bNewPos ) 3458 { 3459 sal_Bool bInvalidate = sal_False; 3460 sal_Bool bParentPaint = sal_True; 3461 if ( !ImplIsOverlapWindow() ) 3462 bParentPaint = mpWindowImpl->mpParent->IsPaintEnabled(); 3463 if ( bCopyBits && bParentPaint && !HasPaintEvent() ) 3464 { 3465 Point aPoint( mnOutOffX, mnOutOffY ); 3466 Region aRegion( Rectangle( aPoint, 3467 Size( mnOutWidth, mnOutHeight ) ) ); 3468 if ( mpWindowImpl->mbWinRegion ) 3469 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) ); 3470 ImplClipBoundaries( aRegion, sal_False, sal_True ); 3471 if ( !pOverlapRegion->IsEmpty() ) 3472 { 3473 pOverlapRegion->Move( mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY ); 3474 aRegion.Exclude( *pOverlapRegion ); 3475 } 3476 if ( !aRegion.IsEmpty() ) 3477 { 3478 // Paint-Bereiche anpassen 3479 ImplMoveAllInvalidateRegions( Rectangle( Point( nOldOutOffX, nOldOutOffY ), 3480 Size( nOldOutWidth, nOldOutHeight ) ), 3481 mnOutOffX-nOldOutOffX, mnOutOffY-nOldOutOffY, 3482 sal_True ); 3483 SalGraphics* pGraphics = ImplGetFrameGraphics(); 3484 if ( pGraphics ) 3485 { 3486 const bool bSelectClipRegion = ImplSelectClipRegion( aRegion, pGraphics ); 3487 if ( bSelectClipRegion ) 3488 { 3489 pGraphics->CopyArea( mnOutOffX, mnOutOffY, 3490 nOldOutOffX, nOldOutOffY, 3491 nOldOutWidth, nOldOutHeight, 3492 SAL_COPYAREA_WINDOWINVALIDATE, this ); 3493 } 3494 else 3495 bInvalidate = sal_True; 3496 } 3497 else 3498 bInvalidate = sal_True; 3499 if ( !bInvalidate ) 3500 { 3501 if ( !pOverlapRegion->IsEmpty() ) 3502 ImplInvalidateFrameRegion( pOverlapRegion, INVALIDATE_CHILDREN ); 3503 } 3504 } 3505 else 3506 bInvalidate = sal_True; 3507 } 3508 else 3509 bInvalidate = sal_True; 3510 if ( bInvalidate ) 3511 ImplInvalidateFrameRegion( NULL, INVALIDATE_CHILDREN ); 3512 } 3513 else 3514 { 3515 Point aPoint( mnOutOffX, mnOutOffY ); 3516 Region aRegion( Rectangle( aPoint, 3517 Size( mnOutWidth, mnOutHeight ) ) ); 3518 aRegion.Exclude( *pOldRegion ); 3519 if ( mpWindowImpl->mbWinRegion ) 3520 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) ); 3521 ImplClipBoundaries( aRegion, sal_False, sal_True ); 3522 if ( !aRegion.IsEmpty() ) 3523 ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN ); 3524 } 3525 } 3526 3527 // Parent oder Overlaps invalidieren 3528 if ( bNewPos || 3529 (mnOutWidth < nOldOutWidth) || (mnOutHeight < nOldOutHeight) ) 3530 { 3531 Region aRegion( *pOldRegion ); 3532 if ( !mpWindowImpl->mbPaintTransparent ) 3533 ImplExcludeWindowRegion( aRegion ); 3534 ImplClipBoundaries( aRegion, sal_False, sal_True ); 3535 if ( !aRegion.IsEmpty() && !mpWindowImpl->mpBorderWindow ) 3536 ImplInvalidateParentFrameRegion( aRegion ); 3537 } 3538 } 3539 3540 // System-Objekte anpassen 3541 if ( bUpdateSysObjClip ) 3542 ImplUpdateSysObjClip(); 3543 if ( bUpdateSysObjPos ) 3544 ImplUpdateSysObjPos(); 3545 if ( bNewSize && mpWindowImpl->mpSysObj ) 3546 mpWindowImpl->mpSysObj->SetPosSize( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ); 3547 } 3548 3549 if ( pOverlapRegion ) 3550 delete pOverlapRegion; 3551 if ( pOldRegion ) 3552 delete pOldRegion; 3553 } 3554 3555 // ----------------------------------------------------------------------- 3556 3557 void Window::ImplToBottomChild() 3558 { 3559 if ( !ImplIsOverlapWindow() && !mpWindowImpl->mbReallyVisible && (mpWindowImpl->mpParent->mpWindowImpl->mpLastChild != this) ) 3560 { 3561 // Fenster an das Ende der Liste setzen 3562 if ( mpWindowImpl->mpPrev ) 3563 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; 3564 else 3565 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; 3566 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; 3567 mpWindowImpl->mpPrev = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild; 3568 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this; 3569 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; 3570 mpWindowImpl->mpNext = NULL; 3571 } 3572 } 3573 3574 // ----------------------------------------------------------------------- 3575 3576 void Window::ImplCalcToTop( ImplCalcToTopData* pPrevData ) 3577 { 3578 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcToTop(): Is not a OverlapWindow" ); 3579 3580 if ( !mpWindowImpl->mbFrame ) 3581 { 3582 if ( IsReallyVisible() ) 3583 { 3584 // Region berechnen, wo das Fenster mit anderen Fenstern ueberlappt 3585 Point aPoint( mnOutOffX, mnOutOffY ); 3586 Region aRegion( Rectangle( aPoint, 3587 Size( mnOutWidth, mnOutHeight ) ) ); 3588 Region aInvalidateRegion; 3589 ImplCalcOverlapRegionOverlaps( aRegion, aInvalidateRegion ); 3590 3591 if ( !aInvalidateRegion.IsEmpty() ) 3592 { 3593 ImplCalcToTopData* pData = new ImplCalcToTopData; 3594 pPrevData->mpNext = pData; 3595 pData->mpNext = NULL; 3596 pData->mpWindow = this; 3597 pData->mpInvalidateRegion = new Region( aInvalidateRegion ); 3598 } 3599 } 3600 } 3601 } 3602 3603 // ----------------------------------------------------------------------- 3604 3605 void Window::ImplCalcChildOverlapToTop( ImplCalcToTopData* pPrevData ) 3606 { 3607 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplCalcChildOverlapToTop(): Is not a OverlapWindow" ); 3608 3609 ImplCalcToTop( pPrevData ); 3610 if ( pPrevData->mpNext ) 3611 pPrevData = pPrevData->mpNext; 3612 3613 Window* pOverlap = mpWindowImpl->mpFirstOverlap; 3614 while ( pOverlap ) 3615 { 3616 pOverlap->ImplCalcToTop( pPrevData ); 3617 if ( pPrevData->mpNext ) 3618 pPrevData = pPrevData->mpNext; 3619 pOverlap = pOverlap->mpWindowImpl->mpNext; 3620 } 3621 } 3622 3623 // ----------------------------------------------------------------------- 3624 3625 void Window::ImplToTop( sal_uInt16 nFlags ) 3626 { 3627 DBG_ASSERT( ImplIsOverlapWindow(), "Window::ImplToTop(): Is not a OverlapWindow" ); 3628 3629 if ( mpWindowImpl->mbFrame ) 3630 { 3631 // Wenn in das externe Fenster geklickt wird, ist dieses 3632 // dafuer zustaendig dafuer zu sorgen, das unser Frame 3633 // nach vorne kommt 3634 if ( !mpWindowImpl->mpFrameData->mbHasFocus && 3635 !mpWindowImpl->mpFrameData->mbSysObjFocus && 3636 !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl && 3637 !mpWindowImpl->mpFrameData->mbInSysObjToTopHdl ) 3638 { 3639 // do not bring floating windows on the client to top 3640 if( !ImplGetClientWindow() || !(ImplGetClientWindow()->GetStyle() & WB_SYSTEMFLOATWIN) ) 3641 { 3642 sal_uInt16 nSysFlags = 0; 3643 if ( nFlags & TOTOP_RESTOREWHENMIN ) 3644 nSysFlags |= SAL_FRAME_TOTOP_RESTOREWHENMIN; 3645 if ( nFlags & TOTOP_FOREGROUNDTASK ) 3646 nSysFlags |= SAL_FRAME_TOTOP_FOREGROUNDTASK; 3647 if ( nFlags & TOTOP_GRABFOCUSONLY ) 3648 nSysFlags |= SAL_FRAME_TOTOP_GRABFOCUS_ONLY; 3649 mpWindowImpl->mpFrame->ToTop( nSysFlags ); 3650 } 3651 } 3652 } 3653 else 3654 { 3655 if ( mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap != this ) 3656 { 3657 // Fenster aus der Liste entfernen 3658 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; 3659 if ( mpWindowImpl->mpNext ) 3660 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; 3661 else 3662 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; 3663 3664 // AlwaysOnTop beruecksichtigen 3665 sal_Bool bOnTop = IsAlwaysOnTopEnabled(); 3666 Window* pNextWin = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; 3667 if ( !bOnTop ) 3668 { 3669 while ( pNextWin ) 3670 { 3671 if ( !pNextWin->IsAlwaysOnTopEnabled() ) 3672 break; 3673 pNextWin = pNextWin->mpWindowImpl->mpNext; 3674 } 3675 } 3676 3677 // TopLevel abpruefen 3678 sal_uInt8 nTopLevel = mpWindowImpl->mpOverlapData->mnTopLevel; 3679 while ( pNextWin ) 3680 { 3681 if ( (bOnTop != pNextWin->IsAlwaysOnTopEnabled()) || 3682 (nTopLevel <= pNextWin->mpWindowImpl->mpOverlapData->mnTopLevel) ) 3683 break; 3684 pNextWin = pNextWin->mpWindowImpl->mpNext; 3685 } 3686 3687 // Fenster in die Liste wieder eintragen 3688 mpWindowImpl->mpNext = pNextWin; 3689 if ( pNextWin ) 3690 { 3691 mpWindowImpl->mpPrev = pNextWin->mpWindowImpl->mpPrev; 3692 pNextWin->mpWindowImpl->mpPrev = this; 3693 } 3694 else 3695 { 3696 mpWindowImpl->mpPrev = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap; 3697 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this; 3698 } 3699 if ( mpWindowImpl->mpPrev ) 3700 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; 3701 else 3702 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this; 3703 3704 // ClipRegion muss von diesem Fenster und allen weiteren 3705 // ueberlappenden Fenstern neu berechnet werden. 3706 if ( IsReallyVisible() ) 3707 { 3708 // Hintergrund-Sicherung zuruecksetzen 3709 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 3710 ImplInvalidateAllOverlapBackgrounds(); 3711 mpWindowImpl->mpOverlapWindow->ImplSetClipFlagOverlapWindows(); 3712 } 3713 } 3714 } 3715 } 3716 3717 // ----------------------------------------------------------------------- 3718 3719 void Window::ImplStartToTop( sal_uInt16 nFlags ) 3720 { 3721 ImplCalcToTopData aStartData; 3722 ImplCalcToTopData* pCurData; 3723 ImplCalcToTopData* pNextData; 3724 Window* pOverlapWindow; 3725 if ( ImplIsOverlapWindow() ) 3726 pOverlapWindow = this; 3727 else 3728 pOverlapWindow = mpWindowImpl->mpOverlapWindow; 3729 3730 // Zuerst die Paint-Bereiche berechnen 3731 Window* pTempOverlapWindow = pOverlapWindow; 3732 aStartData.mpNext = NULL; 3733 pCurData = &aStartData; 3734 do 3735 { 3736 pTempOverlapWindow->ImplCalcToTop( pCurData ); 3737 if ( pCurData->mpNext ) 3738 pCurData = pCurData->mpNext; 3739 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow; 3740 } 3741 while ( !pTempOverlapWindow->mpWindowImpl->mbFrame ); 3742 // Dann die Paint-Bereiche der ChildOverlap-Windows berechnen 3743 pTempOverlapWindow = mpWindowImpl->mpFirstOverlap; 3744 while ( pTempOverlapWindow ) 3745 { 3746 pTempOverlapWindow->ImplCalcToTop( pCurData ); 3747 if ( pCurData->mpNext ) 3748 pCurData = pCurData->mpNext; 3749 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpNext; 3750 } 3751 3752 // Dann die Fenster-Verkettung aendern 3753 pTempOverlapWindow = pOverlapWindow; 3754 do 3755 { 3756 pTempOverlapWindow->ImplToTop( nFlags ); 3757 pTempOverlapWindow = pTempOverlapWindow->mpWindowImpl->mpOverlapWindow; 3758 } 3759 while ( !pTempOverlapWindow->mpWindowImpl->mbFrame ); 3760 // Und zum Schluss invalidieren wir die ungueltigen Bereiche 3761 pCurData = aStartData.mpNext; 3762 while ( pCurData ) 3763 { 3764 pCurData->mpWindow->ImplInvalidateFrameRegion( pCurData->mpInvalidateRegion, INVALIDATE_CHILDREN ); 3765 pNextData = pCurData->mpNext; 3766 delete pCurData->mpInvalidateRegion; 3767 delete pCurData; 3768 pCurData = pNextData; 3769 } 3770 } 3771 3772 // ----------------------------------------------------------------------- 3773 3774 void Window::ImplFocusToTop( sal_uInt16 nFlags, sal_Bool bReallyVisible ) 3775 { 3776 // Soll Focus auch geholt werden? 3777 if ( !(nFlags & TOTOP_NOGRABFOCUS) ) 3778 { 3779 // Erstes Fenster mit GrabFocus-Activate bekommt den Focus 3780 Window* pFocusWindow = this; 3781 while ( !pFocusWindow->ImplIsOverlapWindow() ) 3782 { 3783 // Nur wenn Fenster kein Border-Fenster hat, da wir 3784 // immer das dazugehoerende BorderFenster finden wollen 3785 if ( !pFocusWindow->mpWindowImpl->mpBorderWindow ) 3786 { 3787 if ( pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS ) 3788 break; 3789 } 3790 pFocusWindow = pFocusWindow->ImplGetParent(); 3791 } 3792 if ( (pFocusWindow->mpWindowImpl->mnActivateMode & ACTIVATE_MODE_GRABFOCUS) && 3793 !pFocusWindow->HasChildPathFocus( sal_True ) ) 3794 pFocusWindow->GrabFocus(); 3795 } 3796 3797 if ( bReallyVisible ) 3798 ImplGenerateMouseMove(); 3799 } 3800 3801 // ----------------------------------------------------------------------- 3802 3803 void Window::ImplShowAllOverlaps() 3804 { 3805 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; 3806 while ( pOverlapWindow ) 3807 { 3808 if ( pOverlapWindow->mpWindowImpl->mbOverlapVisible ) 3809 { 3810 pOverlapWindow->Show( sal_True, SHOW_NOACTIVATE ); 3811 pOverlapWindow->mpWindowImpl->mbOverlapVisible = sal_False; 3812 } 3813 3814 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; 3815 } 3816 } 3817 3818 // ----------------------------------------------------------------------- 3819 3820 void Window::ImplHideAllOverlaps() 3821 { 3822 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; 3823 while ( pOverlapWindow ) 3824 { 3825 if ( pOverlapWindow->IsVisible() ) 3826 { 3827 pOverlapWindow->mpWindowImpl->mbOverlapVisible = sal_True; 3828 pOverlapWindow->Show( sal_False ); 3829 } 3830 3831 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; 3832 } 3833 } 3834 3835 // ----------------------------------------------------------------------- 3836 3837 void Window::ImplCallMouseMove( sal_uInt16 nMouseCode, sal_Bool bModChanged ) 3838 { 3839 if ( mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible ) 3840 { 3841 sal_uLong nTime = Time::GetSystemTicks(); 3842 long nX = mpWindowImpl->mpFrameData->mnLastMouseX; 3843 long nY = mpWindowImpl->mpFrameData->mnLastMouseY; 3844 sal_uInt16 nCode = nMouseCode; 3845 sal_uInt16 nMode = mpWindowImpl->mpFrameData->mnMouseMode; 3846 sal_Bool bLeave; 3847 // Auf MouseLeave testen 3848 if ( ((nX < 0) || (nY < 0) || 3849 (nX >= mpWindowImpl->mpFrameWindow->mnOutWidth) || 3850 (nY >= mpWindowImpl->mpFrameWindow->mnOutHeight)) && 3851 !ImplGetSVData()->maWinData.mpCaptureWin ) 3852 bLeave = sal_True; 3853 else 3854 bLeave = sal_False; 3855 nMode |= MOUSE_SYNTHETIC; 3856 if ( bModChanged ) 3857 nMode |= MOUSE_MODIFIERCHANGED; 3858 ImplHandleMouseEvent( mpWindowImpl->mpFrameWindow, EVENT_MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode ); 3859 } 3860 } 3861 3862 // ----------------------------------------------------------------------- 3863 3864 void Window::ImplGenerateMouseMove() 3865 { 3866 if ( !mpWindowImpl->mpFrameData->mnMouseMoveId ) 3867 Application::PostUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId, LINK( mpWindowImpl->mpFrameWindow, Window, ImplGenerateMouseMoveHdl ) ); 3868 } 3869 3870 // ----------------------------------------------------------------------- 3871 3872 IMPL_LINK( Window, ImplGenerateMouseMoveHdl, void*, EMPTYARG ) 3873 { 3874 mpWindowImpl->mpFrameData->mnMouseMoveId = 0; 3875 Window* pCaptureWin = ImplGetSVData()->maWinData.mpCaptureWin; 3876 if( ! pCaptureWin || 3877 (pCaptureWin->mpWindowImpl && pCaptureWin->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame) 3878 ) 3879 { 3880 ImplCallMouseMove( mpWindowImpl->mpFrameData->mnMouseCode ); 3881 } 3882 return 0; 3883 } 3884 3885 // ----------------------------------------------------------------------- 3886 3887 void Window::ImplInvertFocus( const Rectangle& rRect ) 3888 { 3889 InvertTracking( rRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW ); 3890 } 3891 3892 // ----------------------------------------------------------------------- 3893 3894 void Window::ImplCallFocusChangeActivate( Window* pNewOverlapWindow, 3895 Window* pOldOverlapWindow ) 3896 { 3897 ImplSVData* pSVData = ImplGetSVData(); 3898 Window* pNewRealWindow; 3899 Window* pOldRealWindow; 3900 Window* pLastRealWindow; 3901 sal_Bool bCallActivate = sal_True; 3902 sal_Bool bCallDeactivate = sal_True; 3903 3904 pOldRealWindow = pOldOverlapWindow->ImplGetWindow(); 3905 pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); 3906 if ( (pOldRealWindow->GetType() != WINDOW_FLOATINGWINDOW) || 3907 pOldRealWindow->GetActivateMode() ) 3908 { 3909 if ( (pNewRealWindow->GetType() == WINDOW_FLOATINGWINDOW) && 3910 !pNewRealWindow->GetActivateMode() ) 3911 { 3912 pSVData->maWinData.mpLastDeacWin = pOldOverlapWindow; 3913 bCallDeactivate = sal_False; 3914 } 3915 } 3916 else if ( (pNewRealWindow->GetType() != WINDOW_FLOATINGWINDOW) || 3917 pNewRealWindow->GetActivateMode() ) 3918 { 3919 if ( pSVData->maWinData.mpLastDeacWin ) 3920 { 3921 if ( pSVData->maWinData.mpLastDeacWin == pNewOverlapWindow ) 3922 bCallActivate = sal_False; 3923 else 3924 { 3925 pLastRealWindow = pSVData->maWinData.mpLastDeacWin->ImplGetWindow(); 3926 pSVData->maWinData.mpLastDeacWin->mpWindowImpl->mbActive = sal_False; 3927 pSVData->maWinData.mpLastDeacWin->Deactivate(); 3928 if ( pLastRealWindow != pSVData->maWinData.mpLastDeacWin ) 3929 { 3930 pLastRealWindow->mpWindowImpl->mbActive = sal_True; 3931 pLastRealWindow->Activate(); 3932 } 3933 } 3934 pSVData->maWinData.mpLastDeacWin = NULL; 3935 } 3936 } 3937 3938 if ( bCallDeactivate ) 3939 { 3940 if( pOldOverlapWindow->mpWindowImpl->mbActive ) 3941 { 3942 pOldOverlapWindow->mpWindowImpl->mbActive = sal_False; 3943 pOldOverlapWindow->Deactivate(); 3944 } 3945 if ( pOldRealWindow != pOldOverlapWindow ) 3946 { 3947 if( pOldRealWindow->mpWindowImpl->mbActive ) 3948 { 3949 pOldRealWindow->mpWindowImpl->mbActive = sal_False; 3950 pOldRealWindow->Deactivate(); 3951 } 3952 } 3953 } 3954 if ( bCallActivate && ! pNewOverlapWindow->mpWindowImpl->mbActive ) 3955 { 3956 if( ! pNewOverlapWindow->mpWindowImpl->mbActive ) 3957 { 3958 pNewOverlapWindow->mpWindowImpl->mbActive = sal_True; 3959 pNewOverlapWindow->Activate(); 3960 } 3961 if ( pNewRealWindow != pNewOverlapWindow ) 3962 { 3963 if( ! pNewRealWindow->mpWindowImpl->mbActive ) 3964 { 3965 pNewRealWindow->mpWindowImpl->mbActive = sal_True; 3966 pNewRealWindow->Activate(); 3967 } 3968 } 3969 } 3970 } 3971 3972 static bool IsWindowFocused(const WindowImpl& rWinImpl) 3973 { 3974 if (rWinImpl.mpSysObj) 3975 return true; 3976 3977 if (rWinImpl.mpFrameData->mbHasFocus) 3978 return true; 3979 3980 if (rWinImpl.mbFakeFocusSet) 3981 return true; 3982 3983 return false; 3984 } 3985 3986 // ----------------------------------------------------------------------- 3987 void Window::ImplGrabFocus( sal_uInt16 nFlags ) 3988 { 3989 // #143570# no focus for destructing windows 3990 if( mpWindowImpl->mbInDtor ) 3991 return; 3992 3993 // some event listeners do really bad stuff 3994 // => prepare for the worst 3995 ImplDelData aDogTag( this ); 3996 3997 // Currently the client window should always get the focus 3998 // Should the border window at some point be focusable 3999 // we need to change all GrabFocus() instances in VCL, 4000 // e.g. in ToTop() 4001 4002 if ( mpWindowImpl->mpClientWindow ) 4003 { 4004 // For a lack of design we need a little hack here to 4005 // ensure that dialogs on close pass the focus back to 4006 // the correct window 4007 if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) && 4008 !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) && 4009 mpWindowImpl->mpLastFocusWindow->IsEnabled() && 4010 mpWindowImpl->mpLastFocusWindow->IsInputEnabled() && 4011 ! mpWindowImpl->mpLastFocusWindow->IsInModalMode() 4012 ) 4013 mpWindowImpl->mpLastFocusWindow->GrabFocus(); 4014 else 4015 mpWindowImpl->mpClientWindow->GrabFocus(); 4016 return; 4017 } 4018 else if ( mpWindowImpl->mbFrame ) 4019 { 4020 // For a lack of design we need a little hack here to 4021 // ensure that dialogs on close pass the focus back to 4022 // the correct window 4023 if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) && 4024 !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) && 4025 mpWindowImpl->mpLastFocusWindow->IsEnabled() && 4026 mpWindowImpl->mpLastFocusWindow->IsInputEnabled() && 4027 ! mpWindowImpl->mpLastFocusWindow->IsInModalMode() 4028 ) 4029 { 4030 mpWindowImpl->mpLastFocusWindow->GrabFocus(); 4031 return; 4032 } 4033 } 4034 4035 // If the Window is disabled, then we don't change the focus 4036 if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() ) 4037 return; 4038 4039 // we only need to set the focus if it is not already set 4040 // note: if some other frame is waiting for an asynchrounous focus event 4041 // we also have to post an asynchronous focus event for this frame 4042 // which is done using ToTop 4043 ImplSVData* pSVData = ImplGetSVData(); 4044 4045 sal_Bool bAsyncFocusWaiting = sal_False; 4046 Window *pFrame = pSVData->maWinData.mpFirstFrame; 4047 while( pFrame ) 4048 { 4049 if( pFrame != mpWindowImpl->mpFrameWindow && pFrame->mpWindowImpl->mpFrameData->mnFocusId ) 4050 { 4051 bAsyncFocusWaiting = sal_True; 4052 break; 4053 } 4054 pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame; 4055 } 4056 4057 bool bHasFocus = IsWindowFocused(*mpWindowImpl); 4058 4059 sal_Bool bMustNotGrabFocus = sal_False; 4060 // #100242#, check parent hierarchy if some floater prohibits grab focus 4061 4062 Window *pParent = this; 4063 while( pParent ) 4064 { 4065 // #102158#, ignore grabfocus only if the floating parent grabs keyboard focus by itself (GrabsFocus()) 4066 // otherwise we cannot set the focus in a floating toolbox 4067 if( ( (pParent->mpWindowImpl->mbFloatWin && ((FloatingWindow*)pParent)->GrabsFocus()) || ( pParent->GetStyle() & WB_SYSTEMFLOATWIN ) ) && !( pParent->GetStyle() & WB_MOVEABLE ) ) 4068 { 4069 bMustNotGrabFocus = sal_True; 4070 break; 4071 } 4072 pParent = pParent->mpWindowImpl->mpParent; 4073 } 4074 4075 4076 if ( ( pSVData->maWinData.mpFocusWin != this && ! mpWindowImpl->mbInDtor ) || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) ) 4077 { 4078 // EndExtTextInput if it is not the same window 4079 if ( pSVData->maWinData.mpExtTextInputWin && 4080 (pSVData->maWinData.mpExtTextInputWin != this) ) 4081 pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE ); 4082 4083 // Dieses Fenster als letztes FocusWindow merken 4084 Window* pOverlapWindow = ImplGetFirstOverlapWindow(); 4085 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this; 4086 mpWindowImpl->mpFrameData->mpFocusWin = this; 4087 4088 if( !bHasFocus ) 4089 { 4090 // menue windows never get the system focus 4091 // the application will keep the focus 4092 if( bMustNotGrabFocus ) 4093 return; 4094 else 4095 { 4096 // Hier setzen wir schon den Focus um, da ToTop() den Focus 4097 // nicht auf ein anderes Fenster setzen darf 4098 //DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" ); 4099 mpWindowImpl->mpFrame->ToTop( SAL_FRAME_TOTOP_GRABFOCUS | SAL_FRAME_TOTOP_GRABFOCUS_ONLY ); 4100 return; 4101 } 4102 } 4103 4104 Window* pOldFocusWindow = pSVData->maWinData.mpFocusWin; 4105 ImplDelData aOldFocusDel( pOldFocusWindow ); 4106 4107 pSVData->maWinData.mpFocusWin = this; 4108 4109 if ( pOldFocusWindow ) 4110 { 4111 // Cursor hiden 4112 if ( pOldFocusWindow->mpWindowImpl->mpCursor ) 4113 pOldFocusWindow->mpWindowImpl->mpCursor->ImplHide( true ); 4114 } 4115 4116 // !!!!! Wegen altem SV-Office Activate/Deavtivate Handling 4117 // !!!!! erstmal so wie frueher 4118 if ( pOldFocusWindow ) 4119 { 4120 // Focus merken 4121 Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow(); 4122 Window* pNewOverlapWindow = ImplGetFirstOverlapWindow(); 4123 if ( pOldOverlapWindow != pNewOverlapWindow ) 4124 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow ); 4125 } 4126 else 4127 { 4128 Window* pNewOverlapWindow = ImplGetFirstOverlapWindow(); 4129 Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow(); 4130 pNewOverlapWindow->mpWindowImpl->mbActive = sal_True; 4131 pNewOverlapWindow->Activate(); 4132 if ( pNewRealWindow != pNewOverlapWindow ) 4133 { 4134 pNewRealWindow->mpWindowImpl->mbActive = sal_True; 4135 pNewRealWindow->Activate(); 4136 } 4137 } 4138 /* 4139 // call Deactivate and Activate 4140 Window* pDeactivateParent; 4141 Window* pActivateParent; 4142 Window* pParent; 4143 Window* pLastParent; 4144 pDeactivateParent = pOldFocusWindow; 4145 while ( pDeactivateParent ) 4146 { 4147 pParent = pDeactivateParent; 4148 if ( pParent->ImplIsChild( this ) ) 4149 break; 4150 4151 if ( pDeactivateParent->ImplIsOverlapWindow() ) 4152 { 4153 if ( !pDeactivateParent->mpWindowImpl->mbParentActive ) 4154 break; 4155 } 4156 4157 pDeactivateParent = pDeactivateParent->ImplGetParent(); 4158 } 4159 if ( pOldFocusWindow ) 4160 { 4161 pActivateParent = this; 4162 while ( pActivateParent ) 4163 { 4164 pParent = pActivateParent; 4165 if ( pParent->ImplIsChild( pOldFocusWindow ) ) 4166 break; 4167 4168 if ( pActivateParent->ImplIsOverlapWindow() ) 4169 { 4170 if ( !pActivateParent->mpWindowImpl->mbParentActive ) 4171 break; 4172 } 4173 4174 pActivateParent = pActivateParent->ImplGetParent(); 4175 } 4176 } 4177 else 4178 { 4179 if ( ImplIsOverlapWindow() ) 4180 pActivateParent = this; 4181 else 4182 pActivateParent = mpWindowImpl->mpOverlapWindow; 4183 while ( pActivateParent ) 4184 { 4185 if ( pActivateParent->ImplIsOverlapWindow() ) 4186 { 4187 if ( !pActivateParent->mpWindowImpl->mbParentActive ) 4188 break; 4189 } 4190 4191 pActivateParent = pActivateParent->ImplGetParent(); 4192 } 4193 } 4194 if ( pDeactivateParent ) 4195 { 4196 do 4197 { 4198 pLastParent = pOldFocusWindow; 4199 if ( pLastParent != pDeactivateParent ) 4200 { 4201 pParent = pLastParent->ImplGetParent(); 4202 while ( pParent ) 4203 { 4204 if ( pParent == pDeactivateParent ) 4205 break; 4206 pLastParent = pParent; 4207 pParent = pParent->ImplGetParent(); 4208 } 4209 } 4210 else 4211 pParent = pLastParent; 4212 4213 pParent->mpWindowImpl->mbActive = sal_False; 4214 pParent->Deactivate(); 4215 pDeactivateParent = pLastParent; 4216 } 4217 while ( pDeactivateParent != pOldFocusWindow ); 4218 } 4219 do 4220 { 4221 pLastParent = this; 4222 if ( pLastParent != pActivateParent ) 4223 { 4224 pParent = pLastParent->ImplGetParent(); 4225 while ( pParent ) 4226 { 4227 if ( pParent == pActivateParent ) 4228 break; 4229 pLastParent = pParent; 4230 pParent = pParent->ImplGetParent(); 4231 } 4232 } 4233 else 4234 pParent = pLastParent; 4235 4236 pParent->mpWindowImpl->mbActive = sal_True; 4237 pParent->Activate(); 4238 pActivateParent = pLastParent; 4239 } 4240 while ( pActivateParent != this ); 4241 */ 4242 // call Get- and LoseFocus 4243 if ( pOldFocusWindow && ! aOldFocusDel.IsDelete() ) 4244 { 4245 if ( pOldFocusWindow->IsTracking() && 4246 (pSVData->maWinData.mnTrackFlags & STARTTRACK_FOCUSCANCEL) ) 4247 pOldFocusWindow->EndTracking( ENDTRACK_CANCEL | ENDTRACK_FOCUS ); 4248 NotifyEvent aNEvt( EVENT_LOSEFOCUS, pOldFocusWindow ); 4249 if ( !ImplCallPreNotify( aNEvt ) ) 4250 pOldFocusWindow->LoseFocus(); 4251 pOldFocusWindow->ImplCallDeactivateListeners( this ); 4252 } 4253 4254 if ( pSVData->maWinData.mpFocusWin == this ) 4255 { 4256 if ( mpWindowImpl->mpSysObj ) 4257 { 4258 mpWindowImpl->mpFrameData->mpFocusWin = this; 4259 if ( !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl ) 4260 mpWindowImpl->mpSysObj->GrabFocus(); 4261 } 4262 4263 if ( pSVData->maWinData.mpFocusWin == this ) 4264 { 4265 if ( mpWindowImpl->mpCursor ) 4266 mpWindowImpl->mpCursor->ImplShow(); 4267 mpWindowImpl->mbInFocusHdl = sal_True; 4268 mpWindowImpl->mnGetFocusFlags = nFlags; 4269 // if we're changing focus due to closing a popup floating window 4270 // notify the new focus window so it can restore the inner focus 4271 // eg, toolboxes can select their recent active item 4272 if( pOldFocusWindow && 4273 ! aOldFocusDel.IsDelete() && 4274 ( pOldFocusWindow->GetDialogControlFlags() & WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL ) ) 4275 mpWindowImpl->mnGetFocusFlags |= GETFOCUS_FLOATWIN_POPUPMODEEND_CANCEL; 4276 NotifyEvent aNEvt( EVENT_GETFOCUS, this ); 4277 if ( !ImplCallPreNotify( aNEvt ) && !aDogTag.IsDelete() ) 4278 GetFocus(); 4279 if( !aDogTag.IsDelete() ) 4280 ImplCallActivateListeners( (pOldFocusWindow && ! aOldFocusDel.IsDelete()) ? pOldFocusWindow : NULL ); 4281 if( !aDogTag.IsDelete() ) 4282 { 4283 mpWindowImpl->mnGetFocusFlags = 0; 4284 mpWindowImpl->mbInFocusHdl = sal_False; 4285 } 4286 } 4287 } 4288 4289 GetpApp()->FocusChanged(); 4290 ImplNewInputContext(); 4291 } 4292 } 4293 4294 // ----------------------------------------------------------------------- 4295 4296 void Window::ImplNewInputContext() 4297 { 4298 ImplSVData* pSVData = ImplGetSVData(); 4299 Window* pFocusWin = pSVData->maWinData.mpFocusWin; 4300 if ( !pFocusWin ) 4301 return; 4302 4303 // Is InputContext changed? 4304 const InputContext& rInputContext = pFocusWin->GetInputContext(); 4305 if ( rInputContext == pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext ) 4306 return; 4307 4308 pFocusWin->mpWindowImpl->mpFrameData->maOldInputContext = rInputContext; 4309 4310 SalInputContext aNewContext; 4311 const Font& rFont = rInputContext.GetFont(); 4312 const XubString& rFontName = rFont.GetName(); 4313 ImplFontEntry* pFontEntry = NULL; 4314 aNewContext.mpFont = NULL; 4315 if ( rFontName.Len() ) 4316 { 4317 Size aSize = pFocusWin->ImplLogicToDevicePixel( rFont.GetSize() ); 4318 if ( !aSize.Height() ) 4319 { 4320 // Nur dann Defaultgroesse setzen, wenn Fonthoehe auch in logischen 4321 // Koordinaaten 0 ist 4322 if ( rFont.GetSize().Height() ) 4323 aSize.Height() = 1; 4324 else 4325 aSize.Height() = (12*pFocusWin->mnDPIY)/72; 4326 } 4327 // TODO: No display device uses ImplDirectFontSubstitution thingy, right? => remove it 4328 ImplDirectFontSubstitution* pFontSubst = NULL; 4329 //if( pFocusWin->mpOutDevData ) 4330 // pFontSubst = &pFocusWin->mpOutDevData->maDevFontSubst; 4331 pFontEntry = pFocusWin->mpFontCache->GetFontEntry( pFocusWin->mpFontList, 4332 rFont, aSize, static_cast<float>(aSize.Height()), pFontSubst ); 4333 if ( pFontEntry ) 4334 aNewContext.mpFont = &pFontEntry->maFontSelData; 4335 } 4336 aNewContext.meLanguage = rFont.GetLanguage(); 4337 aNewContext.mnOptions = rInputContext.GetOptions(); 4338 pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext ); 4339 4340 if ( pFontEntry ) 4341 pFocusWin->mpFontCache->Release( pFontEntry ); 4342 } 4343 4344 // ----------------------------------------------------------------------- 4345 4346 Window::Window( WindowType nType ) 4347 { 4348 DBG_CTOR( Window, ImplDbgCheckWindow ); 4349 4350 ImplInitWindowData( nType ); 4351 } 4352 4353 // ----------------------------------------------------------------------- 4354 4355 Window::Window( Window* pParent, WinBits nStyle ) 4356 { 4357 DBG_CTOR( Window, ImplDbgCheckWindow ); 4358 4359 ImplInitWindowData( WINDOW_WINDOW ); 4360 ImplInit( pParent, nStyle, NULL ); 4361 } 4362 4363 // ----------------------------------------------------------------------- 4364 4365 Window::Window( Window* pParent, const ResId& rResId ) 4366 { 4367 DBG_CTOR( Window, ImplDbgCheckWindow ); 4368 4369 ImplInitWindowData( WINDOW_WINDOW ); 4370 rResId.SetRT( RSC_WINDOW ); 4371 WinBits nStyle = ImplInitRes( rResId ); 4372 ImplInit( pParent, nStyle, NULL ); 4373 ImplLoadRes( rResId ); 4374 4375 if ( !(nStyle & WB_HIDE) ) 4376 Show(); 4377 } 4378 4379 // ----------------------------------------------------------------------- 4380 #if OSL_DEBUG_LEVEL > 0 4381 namespace 4382 { 4383 void lcl_appendWindowInfo( ByteString& io_rErrorString, const Window& i_rWindow ) 4384 { 4385 // skip border windows, they don't carry information which helps diagnosing the problem 4386 const Window* pWindow( &i_rWindow ); 4387 while ( pWindow && ( pWindow->GetType() == WINDOW_BORDERWINDOW ) ) 4388 pWindow = pWindow->GetWindow( WINDOW_FIRSTCHILD ); 4389 if ( !pWindow ) 4390 pWindow = &i_rWindow; 4391 4392 io_rErrorString += char(13); 4393 io_rErrorString += typeid( *pWindow ).name(); 4394 io_rErrorString += " (window text: '"; 4395 io_rErrorString += ByteString( pWindow->GetText(), RTL_TEXTENCODING_UTF8 ); 4396 io_rErrorString += "')"; 4397 } 4398 } 4399 #endif 4400 // ----------------------------------------------------------------------- 4401 4402 Window::~Window() 4403 { 4404 ImplFreeExtWindowImpl(); 4405 4406 vcl::LazyDeletor<Window>::Undelete( this ); 4407 4408 DBG_DTOR( Window, ImplDbgCheckWindow ); 4409 DBG_ASSERT( !mpWindowImpl->mbInDtor, "~Window - already in DTOR!" ); 4410 4411 4412 // remove Key and Mouse events issued by Application::PostKey/MouseEvent 4413 Application::RemoveMouseAndKeyEvents( this ); 4414 4415 // Dispose of the canvas implementation (which, currently, has an 4416 // own wrapper window as a child to this one. 4417 uno::Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas ); 4418 if( xCanvas.is() ) 4419 { 4420 uno::Reference < lang::XComponent > xCanvasComponent( xCanvas, 4421 uno::UNO_QUERY ); 4422 if( xCanvasComponent.is() ) 4423 xCanvasComponent->dispose(); 4424 } 4425 4426 mpWindowImpl->mbInDtor = sal_True; 4427 4428 ImplCallEventListeners( VCLEVENT_OBJECT_DYING ); 4429 4430 // do not send child events for frames that were registered as native frames 4431 if( !ImplIsAccessibleNativeFrame() && mpWindowImpl->mbReallyVisible ) 4432 if ( ImplIsAccessibleCandidate() && GetAccessibleParentWindow() ) 4433 GetAccessibleParentWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CHILDDESTROYED, this ); 4434 4435 // remove associated data structures from dockingmanager 4436 ImplGetDockingManager()->RemoveWindow( this ); 4437 4438 4439 // remove ownerdraw decorated windows from list in the top-most frame window 4440 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame ) 4441 { 4442 ::std::vector< Window* >& rList = ImplGetOwnerDrawList(); 4443 ::std::vector< Window* >::iterator p; 4444 p = ::std::find( rList.begin(), rList.end(), this ); 4445 if( p != rList.end() ) 4446 rList.erase( p ); 4447 } 4448 4449 // shutdown drag and drop 4450 ::com::sun::star::uno::Reference < ::com::sun::star::lang::XComponent > xDnDComponent( mpWindowImpl->mxDNDListenerContainer, ::com::sun::star::uno::UNO_QUERY ); 4451 4452 if( xDnDComponent.is() ) 4453 xDnDComponent->dispose(); 4454 4455 if( mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData ) 4456 { 4457 try 4458 { 4459 // deregister drop target listener 4460 if( mpWindowImpl->mpFrameData->mxDropTargetListener.is() ) 4461 { 4462 uno::Reference< XDragGestureRecognizer > xDragGestureRecognizer = 4463 uno::Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY); 4464 if( xDragGestureRecognizer.is() ) 4465 { 4466 xDragGestureRecognizer->removeDragGestureListener( 4467 uno::Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY)); 4468 } 4469 4470 mpWindowImpl->mpFrameData->mxDropTarget->removeDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener ); 4471 mpWindowImpl->mpFrameData->mxDropTargetListener.clear(); 4472 } 4473 4474 // shutdown drag and drop for this frame window 4475 uno::Reference< XComponent > xComponent( mpWindowImpl->mpFrameData->mxDropTarget, UNO_QUERY ); 4476 4477 // DNDEventDispatcher does not hold a reference of the DropTarget, 4478 // so it's ok if it does not support XComponent 4479 if( xComponent.is() ) 4480 xComponent->dispose(); 4481 } 4482 4483 catch ( Exception&) 4484 { 4485 // can be safely ignored here. 4486 } 4487 } 4488 4489 UnoWrapperBase* pWrapper = Application::GetUnoWrapper( sal_False ); 4490 if ( pWrapper ) 4491 pWrapper->WindowDestroyed( this ); 4492 4493 // MT: Must be called after WindowDestroyed! 4494 // Otherwise, if the accessible is a VCLXWindow, it will try to destroy this window again! 4495 // But accessibility implementations from applications need this dispose. 4496 if ( mpWindowImpl->mxAccessible.is() ) 4497 { 4498 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xC( mpWindowImpl->mxAccessible, ::com::sun::star::uno::UNO_QUERY ); 4499 if ( xC.is() ) 4500 xC->dispose(); 4501 } 4502 4503 ImplSVData* pSVData = ImplGetSVData(); 4504 4505 if ( pSVData->maHelpData.mpHelpWin && (pSVData->maHelpData.mpHelpWin->GetParent() == this) ) 4506 ImplDestroyHelpWindow( true ); 4507 4508 DBG_ASSERT( pSVData->maWinData.mpTrackWin != this, 4509 "Window::~Window(): Window is in TrackingMode" ); 4510 DBG_ASSERT( pSVData->maWinData.mpCaptureWin != this, 4511 "Window::~Window(): Window has the mouse captured" ); 4512 // #103442# DefModalDialogParent is now determined on-the-fly, so this pointer is unimportant now 4513 //DBG_ASSERT( pSVData->maWinData.mpDefDialogParent != this, 4514 // "Window::~Window(): Window is DefModalDialogParent" ); 4515 4516 // Wegen alter kompatibilitaet 4517 if ( pSVData->maWinData.mpTrackWin == this ) 4518 EndTracking(); 4519 if ( pSVData->maWinData.mpCaptureWin == this ) 4520 ReleaseMouse(); 4521 if ( pSVData->maWinData.mpDefDialogParent == this ) 4522 pSVData->maWinData.mpDefDialogParent = NULL; 4523 4524 #ifdef DBG_UTIL 4525 if ( sal_True ) // always perform these tests in non-pro versions 4526 { 4527 ByteString aErrorStr; 4528 sal_Bool bError = sal_False; 4529 Window* pTempWin = mpWindowImpl->mpFrameData->mpFirstOverlap; 4530 while ( pTempWin ) 4531 { 4532 if ( ImplIsRealParentPath( pTempWin ) ) 4533 { 4534 bError = sal_True; 4535 lcl_appendWindowInfo( aErrorStr, *pTempWin ); 4536 } 4537 pTempWin = pTempWin->mpWindowImpl->mpNextOverlap; 4538 } 4539 if ( bError ) 4540 { 4541 ByteString aTempStr( "Window (" ); 4542 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); 4543 aTempStr += ") with living SystemWindow(s) destroyed: "; 4544 aTempStr += aErrorStr; 4545 DBG_ERROR( aTempStr.GetBuffer() ); 4546 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed! 4547 } 4548 4549 bError = sal_False; 4550 pTempWin = pSVData->maWinData.mpFirstFrame; 4551 while ( pTempWin ) 4552 { 4553 if ( ImplIsRealParentPath( pTempWin ) ) 4554 { 4555 bError = sal_True; 4556 lcl_appendWindowInfo( aErrorStr, *pTempWin ); 4557 } 4558 pTempWin = pTempWin->mpWindowImpl->mpFrameData->mpNextFrame; 4559 } 4560 if ( bError ) 4561 { 4562 ByteString aTempStr( "Window (" ); 4563 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); 4564 aTempStr += ") with living SystemWindow(s) destroyed: "; 4565 aTempStr += aErrorStr; 4566 DBG_ERROR( aTempStr.GetBuffer() ); 4567 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed! 4568 } 4569 4570 if ( mpWindowImpl->mpFirstChild ) 4571 { 4572 ByteString aTempStr( "Window (" ); 4573 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); 4574 aTempStr += ") with living Child(s) destroyed: "; 4575 pTempWin = mpWindowImpl->mpFirstChild; 4576 while ( pTempWin ) 4577 { 4578 lcl_appendWindowInfo( aTempStr, *pTempWin ); 4579 pTempWin = pTempWin->mpWindowImpl->mpNext; 4580 } 4581 DBG_ERROR( aTempStr.GetBuffer() ); 4582 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed! 4583 } 4584 4585 if ( mpWindowImpl->mpFirstOverlap ) 4586 { 4587 ByteString aTempStr( "Window (" ); 4588 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); 4589 aTempStr += ") with living SystemWindow(s) destroyed: "; 4590 pTempWin = mpWindowImpl->mpFirstOverlap; 4591 while ( pTempWin ) 4592 { 4593 lcl_appendWindowInfo( aTempStr, *pTempWin ); 4594 pTempWin = pTempWin->mpWindowImpl->mpNext; 4595 } 4596 DBG_ERROR( aTempStr.GetBuffer() ); 4597 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed! 4598 } 4599 4600 Window* pMyParent = this; 4601 SystemWindow* pMySysWin = NULL; 4602 4603 while ( pMyParent ) 4604 { 4605 if ( pMyParent->IsSystemWindow() ) 4606 pMySysWin = (SystemWindow*)pMyParent; 4607 pMyParent = pMyParent->GetParent(); 4608 } 4609 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) ) 4610 { 4611 ByteString aTempStr( "Window (" ); 4612 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); 4613 aTempStr += ") still in TaskPanelList!"; 4614 DBG_ERROR( aTempStr.GetBuffer() ); 4615 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed! 4616 } 4617 } 4618 #endif 4619 4620 if( mpWindowImpl->mbIsInTaskPaneList ) 4621 { 4622 Window* pMyParent = this; 4623 SystemWindow* pMySysWin = NULL; 4624 4625 while ( pMyParent ) 4626 { 4627 if ( pMyParent->IsSystemWindow() ) 4628 pMySysWin = (SystemWindow*)pMyParent; 4629 pMyParent = pMyParent->GetParent(); 4630 } 4631 if ( pMySysWin && pMySysWin->ImplIsInTaskPaneList( this ) ) 4632 { 4633 pMySysWin->GetTaskPaneList()->RemoveWindow( this ); 4634 } 4635 else 4636 { 4637 ByteString aTempStr( "Window (" ); 4638 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); 4639 aTempStr += ") not found in TaskPanelList!"; 4640 DBG_ERROR( aTempStr.GetBuffer() ); 4641 } 4642 } 4643 4644 // Fenster hiden, um das entsprechende Paint-Handling auszuloesen 4645 Hide(); 4646 4647 // Mitteilen, das Fenster zerstoert wird 4648 { 4649 NotifyEvent aNEvt( EVENT_DESTROY, this ); 4650 Notify( aNEvt ); 4651 } 4652 4653 // EndExtTextInputMode 4654 if ( pSVData->maWinData.mpExtTextInputWin == this ) 4655 { 4656 EndExtTextInput( EXTTEXTINPUT_END_COMPLETE ); 4657 if ( pSVData->maWinData.mpExtTextInputWin == this ) 4658 pSVData->maWinData.mpExtTextInputWin = NULL; 4659 } 4660 4661 // check if the focus window is our child 4662 sal_Bool bHasFocussedChild = sal_False; 4663 if( pSVData->maWinData.mpFocusWin && ImplIsRealParentPath( pSVData->maWinData.mpFocusWin ) ) 4664 { 4665 // #122232#, this must not happen and is an application bug ! but we try some cleanup to hopefully avoid crashes, see below 4666 bHasFocussedChild = sal_True; 4667 #ifdef DBG_UTIL 4668 ByteString aTempStr( "Window (" ); 4669 aTempStr += ByteString( GetText(), RTL_TEXTENCODING_UTF8 ); 4670 aTempStr += ") with focussed child window destroyed ! THIS WILL LEAD TO CRASHES AND MUST BE FIXED !"; 4671 DBG_ERROR( aTempStr.GetBuffer() ); 4672 GetpApp()->Abort( String( aTempStr, RTL_TEXTENCODING_UTF8 ) ); // abort in non-pro version, this must be fixed! 4673 #endif 4674 } 4675 4676 // Wenn wir den Focus haben, dann den Focus auf ein anderes Fenster setzen 4677 Window* pOverlapWindow = ImplGetFirstOverlapWindow(); 4678 if ( pSVData->maWinData.mpFocusWin == this 4679 || bHasFocussedChild ) // #122232#, see above, try some cleanup 4680 { 4681 if ( mpWindowImpl->mbFrame ) 4682 { 4683 pSVData->maWinData.mpFocusWin = NULL; 4684 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL; 4685 GetpApp()->FocusChanged(); 4686 } 4687 else 4688 { 4689 Window* pParent = GetParent(); 4690 Window* pBorderWindow = mpWindowImpl->mpBorderWindow; 4691 // Bei ueberlappenden Fenstern wird der Focus auf den 4692 // Parent vom naechsten FrameWindow gesetzt 4693 if ( pBorderWindow ) 4694 { 4695 if ( pBorderWindow->ImplIsOverlapWindow() ) 4696 pParent = pBorderWindow->mpWindowImpl->mpOverlapWindow; 4697 } 4698 else if ( ImplIsOverlapWindow() ) 4699 pParent = mpWindowImpl->mpOverlapWindow; 4700 4701 if ( pParent && pParent->IsEnabled() && pParent->IsInputEnabled() && ! pParent->IsInModalMode() ) 4702 pParent->GrabFocus(); 4703 else 4704 mpWindowImpl->mpFrameWindow->GrabFocus(); 4705 4706 // If the focus was set back to 'this' set it to nothing 4707 if ( pSVData->maWinData.mpFocusWin == this ) 4708 { 4709 pSVData->maWinData.mpFocusWin = NULL; 4710 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL; 4711 GetpApp()->FocusChanged(); 4712 } 4713 } 4714 } 4715 4716 4717 if ( pOverlapWindow->mpWindowImpl->mpLastFocusWindow == this ) 4718 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL; 4719 4720 // reset hint for DefModalDialogParent 4721 if( pSVData->maWinData.mpActiveApplicationFrame == this ) 4722 pSVData->maWinData.mpActiveApplicationFrame = NULL; 4723 4724 // gemerkte Fenster zuruecksetzen 4725 if ( mpWindowImpl->mpFrameData->mpFocusWin == this ) 4726 mpWindowImpl->mpFrameData->mpFocusWin = NULL; 4727 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin == this ) 4728 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL; 4729 if ( mpWindowImpl->mpFrameData->mpMouseDownWin == this ) 4730 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL; 4731 4732 // Deactivate-Window zuruecksetzen 4733 if ( pSVData->maWinData.mpLastDeacWin == this ) 4734 pSVData->maWinData.mpLastDeacWin = NULL; 4735 4736 if ( mpWindowImpl->mbFrame ) 4737 { 4738 if ( mpWindowImpl->mpFrameData->mnFocusId ) 4739 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnFocusId ); 4740 if ( mpWindowImpl->mpFrameData->mnMouseMoveId ) 4741 Application::RemoveUserEvent( mpWindowImpl->mpFrameData->mnMouseMoveId ); 4742 } 4743 4744 // release SalGraphics 4745 ImplReleaseGraphics(); 4746 4747 // notify ImplDelData subscribers of this window about the window deletion 4748 ImplDelData* pDelData = mpWindowImpl->mpFirstDel; 4749 while ( pDelData ) 4750 { 4751 pDelData->mbDel = sal_True; 4752 pDelData->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore 4753 pDelData = pDelData->mpNext; 4754 } 4755 4756 // remove window from the lists 4757 ImplRemoveWindow( sal_True ); 4758 4759 // de-register as "top window child" at our parent, if necessary 4760 if ( mpWindowImpl->mbFrame ) 4761 { 4762 sal_Bool bIsTopWindow = mpWindowImpl->mpWinData && ( mpWindowImpl->mpWinData->mnIsTopWindow == 1 ); 4763 if ( mpWindowImpl->mpRealParent && bIsTopWindow ) 4764 { 4765 ImplWinData* pParentWinData = mpWindowImpl->mpRealParent->ImplGetWinData(); 4766 4767 ::std::list< Window* >::iterator myPos = ::std::find( pParentWinData->maTopWindowChildren.begin(), 4768 pParentWinData->maTopWindowChildren.end(), this ); 4769 DBG_ASSERT( myPos != pParentWinData->maTopWindowChildren.end(), "Window::~Window: inconsistency in top window chain!" ); 4770 if ( myPos != pParentWinData->maTopWindowChildren.end() ) 4771 pParentWinData->maTopWindowChildren.erase( myPos ); 4772 } 4773 } 4774 4775 // cleanup Extra Window Data, TODO: add and use ImplWinData destructor 4776 if ( mpWindowImpl->mpWinData ) 4777 { 4778 if ( mpWindowImpl->mpWinData->mpExtOldText ) 4779 delete mpWindowImpl->mpWinData->mpExtOldText; 4780 if ( mpWindowImpl->mpWinData->mpExtOldAttrAry ) 4781 delete mpWindowImpl->mpWinData->mpExtOldAttrAry; 4782 if ( mpWindowImpl->mpWinData->mpCursorRect ) 4783 delete mpWindowImpl->mpWinData->mpCursorRect; 4784 if ( mpWindowImpl->mpWinData->mpFocusRect ) 4785 delete mpWindowImpl->mpWinData->mpFocusRect; 4786 if ( mpWindowImpl->mpWinData->mpTrackRect ) 4787 delete mpWindowImpl->mpWinData->mpTrackRect; 4788 4789 delete mpWindowImpl->mpWinData; 4790 } 4791 4792 // cleanup overlap related window data 4793 if ( mpWindowImpl->mpOverlapData ) 4794 delete mpWindowImpl->mpOverlapData; 4795 4796 // remove BorderWindow or Frame window data 4797 if ( mpWindowImpl->mpBorderWindow ) 4798 delete mpWindowImpl->mpBorderWindow; 4799 else if ( mpWindowImpl->mbFrame ) 4800 { 4801 if ( pSVData->maWinData.mpFirstFrame == this ) 4802 pSVData->maWinData.mpFirstFrame = mpWindowImpl->mpFrameData->mpNextFrame; 4803 else 4804 { 4805 Window* pSysWin = pSVData->maWinData.mpFirstFrame; 4806 while ( pSysWin->mpWindowImpl->mpFrameData->mpNextFrame != this ) 4807 pSysWin = pSysWin->mpWindowImpl->mpFrameData->mpNextFrame; 4808 pSysWin->mpWindowImpl->mpFrameData->mpNextFrame = mpWindowImpl->mpFrameData->mpNextFrame; 4809 } 4810 mpWindowImpl->mpFrame->SetCallback( NULL, NULL ); 4811 pSVData->mpDefInst->DestroyFrame( mpWindowImpl->mpFrame ); 4812 delete mpWindowImpl->mpFrameData; 4813 } 4814 4815 // should be the last statements 4816 delete mpWindowImpl; mpWindowImpl = NULL; 4817 } 4818 4819 // ----------------------------------------------------------------------- 4820 void Window::doLazyDelete() 4821 { 4822 SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this); 4823 DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(this); 4824 if( pSysWin || ( pDockWin && pDockWin->IsFloatingMode() ) ) 4825 { 4826 Show( sal_False ); 4827 SetParent( ImplGetDefaultWindow() ); 4828 } 4829 vcl::LazyDeletor<Window>::Delete( this ); 4830 } 4831 4832 // ----------------------------------------------------------------------- 4833 void Window::InterceptChildWindowKeyDown( sal_Bool bIntercept ) 4834 { 4835 if( mpWindowImpl->mpSysObj ) 4836 mpWindowImpl->mpSysObj->InterceptChildWindowKeyDown( bIntercept ); 4837 } 4838 4839 // ----------------------------------------------------------------------- 4840 4841 void Window::MouseMove( const MouseEvent& rMEvt ) 4842 { 4843 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4844 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4845 } 4846 4847 NotifyEvent aNEvt( EVENT_MOUSEMOVE, this, &rMEvt ); 4848 if ( !Notify( aNEvt ) ) 4849 mpWindowImpl->mbMouseMove = sal_True; 4850 } 4851 4852 // ----------------------------------------------------------------------- 4853 4854 void Window::MouseButtonDown( const MouseEvent& rMEvt ) 4855 { 4856 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4857 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4858 } 4859 4860 NotifyEvent aNEvt( EVENT_MOUSEBUTTONDOWN, this, &rMEvt ); 4861 if ( !Notify( aNEvt ) ) 4862 mpWindowImpl->mbMouseButtonDown = sal_True; 4863 } 4864 4865 // ----------------------------------------------------------------------- 4866 4867 void Window::MouseButtonUp( const MouseEvent& rMEvt ) 4868 { 4869 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4870 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4871 } 4872 4873 NotifyEvent aNEvt( EVENT_MOUSEBUTTONUP, this, &rMEvt ); 4874 if ( !Notify( aNEvt ) ) 4875 mpWindowImpl->mbMouseButtonUp = sal_True; 4876 } 4877 4878 // ----------------------------------------------------------------------- 4879 4880 void Window::KeyInput( const KeyEvent& rKEvt ) 4881 { 4882 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4883 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4884 } 4885 4886 NotifyEvent aNEvt( EVENT_KEYINPUT, this, &rKEvt ); 4887 if ( !Notify( aNEvt ) ) 4888 mpWindowImpl->mbKeyInput = sal_True; 4889 } 4890 4891 // ----------------------------------------------------------------------- 4892 4893 void Window::KeyUp( const KeyEvent& rKEvt ) 4894 { 4895 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4896 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4897 } 4898 4899 NotifyEvent aNEvt( EVENT_KEYUP, this, &rKEvt ); 4900 if ( !Notify( aNEvt ) ) 4901 mpWindowImpl->mbKeyUp = sal_True; 4902 } 4903 4904 // ----------------------------------------------------------------------- 4905 4906 void Window::PrePaint() 4907 { 4908 } 4909 4910 // ----------------------------------------------------------------------- 4911 4912 void Window::Paint( const Rectangle& rRect ) 4913 { 4914 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4915 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4916 } 4917 4918 ImplCallEventListeners( VCLEVENT_WINDOW_PAINT, (void*)&rRect ); 4919 } 4920 4921 // ----------------------------------------------------------------------- 4922 4923 void Window::PostPaint() 4924 { 4925 } 4926 4927 // ----------------------------------------------------------------------- 4928 4929 void Window::Draw( OutputDevice*, const Point&, const Size&, sal_uLong ) 4930 { 4931 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4932 } 4933 4934 // ----------------------------------------------------------------------- 4935 4936 void Window::Move() 4937 { 4938 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4939 } 4940 4941 // ----------------------------------------------------------------------- 4942 4943 void Window::Resize() 4944 { 4945 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4946 } 4947 4948 // ----------------------------------------------------------------------- 4949 4950 void Window::Activate() 4951 { 4952 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4953 } 4954 4955 // ----------------------------------------------------------------------- 4956 4957 void Window::Deactivate() 4958 { 4959 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4960 } 4961 4962 // ----------------------------------------------------------------------- 4963 4964 void Window::GetFocus() 4965 { 4966 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4967 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4968 } 4969 4970 if ( HasFocus() && mpWindowImpl->mpLastFocusWindow && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) ) 4971 { 4972 ImplDelData aDogtag( this ); 4973 mpWindowImpl->mpLastFocusWindow->GrabFocus(); 4974 if( aDogtag.IsDelete() ) 4975 return; 4976 } 4977 4978 NotifyEvent aNEvt( EVENT_GETFOCUS, this ); 4979 Notify( aNEvt ); 4980 } 4981 4982 // ----------------------------------------------------------------------- 4983 4984 void Window::LoseFocus() 4985 { 4986 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4987 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 4988 } 4989 4990 NotifyEvent aNEvt( EVENT_LOSEFOCUS, this ); 4991 Notify( aNEvt ); 4992 } 4993 4994 // ----------------------------------------------------------------------- 4995 4996 void Window::RequestHelp( const HelpEvent& rHEvt ) 4997 { 4998 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 4999 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5000 } 5001 5002 // Wenn Balloon-Help angefordert wird, dann den Balloon mit dem 5003 // gesetzten Hilfetext anzeigen 5004 if ( rHEvt.GetMode() & HELPMODE_BALLOON ) 5005 { 5006 const XubString* pStr = &(GetHelpText()); 5007 if ( !pStr->Len() ) 5008 pStr = &(GetQuickHelpText()); 5009 if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() ) 5010 ImplGetParent()->RequestHelp( rHEvt ); 5011 else 5012 Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), *pStr ); 5013 } 5014 else if ( rHEvt.GetMode() & HELPMODE_QUICK ) 5015 { 5016 const XubString* pStr = &(GetQuickHelpText()); 5017 if ( !pStr->Len() && ImplGetParent() && !ImplIsOverlapWindow() ) 5018 ImplGetParent()->RequestHelp( rHEvt ); 5019 else 5020 { 5021 Point aPos = GetPosPixel(); 5022 if ( ImplGetParent() && !ImplIsOverlapWindow() ) 5023 aPos = ImplGetParent()->OutputToScreenPixel( aPos ); 5024 Rectangle aRect( aPos, GetSizePixel() ); 5025 String aHelpText; 5026 if ( pStr->Len() ) 5027 aHelpText = GetHelpText(); 5028 Help::ShowQuickHelp( this, aRect, *pStr, aHelpText, QUICKHELP_CTRLTEXT ); 5029 } 5030 } 5031 else 5032 { 5033 String aStrHelpId( rtl::OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) ); 5034 if ( aStrHelpId.Len() == 0 && ImplGetParent() ) 5035 ImplGetParent()->RequestHelp( rHEvt ); 5036 else 5037 { 5038 Help* pHelp = Application::GetHelp(); 5039 if ( pHelp ) 5040 { 5041 if( aStrHelpId.Len() > 0 ) 5042 pHelp->Start( aStrHelpId, this ); 5043 else 5044 pHelp->Start( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OOO_HELP_INDEX ) ), this ); 5045 } 5046 } 5047 } 5048 } 5049 5050 // ----------------------------------------------------------------------- 5051 5052 void Window::Command( const CommandEvent& rCEvt ) 5053 { 5054 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 5055 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5056 } 5057 5058 ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, (void*)&rCEvt ); 5059 5060 NotifyEvent aNEvt( EVENT_COMMAND, this, &rCEvt ); 5061 if ( !Notify( aNEvt ) ) 5062 mpWindowImpl->mbCommand = sal_True; 5063 } 5064 5065 // ----------------------------------------------------------------------- 5066 5067 void Window::Tracking( const TrackingEvent& rTEvt ) 5068 { 5069 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5070 5071 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 5072 if( pWrapper ) 5073 pWrapper->Tracking( rTEvt ); 5074 } 5075 5076 // ----------------------------------------------------------------------- 5077 5078 void Window::UserEvent( sal_uLong, void* ) 5079 { 5080 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5081 } 5082 5083 // ----------------------------------------------------------------------- 5084 5085 void Window::StateChanged( StateChangedType ) 5086 { 5087 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5088 } 5089 5090 // ----------------------------------------------------------------------- 5091 5092 void Window::DataChanged( const DataChangedEvent& ) 5093 { 5094 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5095 } 5096 5097 // ----------------------------------------------------------------------- 5098 5099 void Window::ImplNotifyKeyMouseCommandEventListeners( NotifyEvent& rNEvt ) 5100 { 5101 if( rNEvt.GetType() == EVENT_COMMAND ) 5102 { 5103 const CommandEvent* pCEvt = rNEvt.GetCommandEvent(); 5104 if ( pCEvt->GetCommand() != COMMAND_CONTEXTMENU ) 5105 // non context menu events are not to be notified up the chain 5106 // so we return immediately 5107 return; 5108 5109 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5110 { 5111 if ( rNEvt.GetWindow() == this ) 5112 // not interested in: The event listeners are already called in ::Command, 5113 // and calling them here a second time doesn't make sense 5114 ; 5115 else 5116 { 5117 CommandEvent aCommandEvent = ImplTranslateCommandEvent( *pCEvt, rNEvt.GetWindow(), this ); 5118 ImplCallEventListeners( VCLEVENT_WINDOW_COMMAND, &aCommandEvent ); 5119 } 5120 } 5121 } 5122 5123 // #82968# notify event listeners for mouse and key events seperately and 5124 // not in PreNotify ( as for focus listeners ) 5125 // this allows for procesing those events internally first and pass it to 5126 // the toolkit later 5127 5128 ImplDelData aDelData; 5129 ImplAddDel( &aDelData ); 5130 5131 if( rNEvt.GetType() == EVENT_MOUSEMOVE ) 5132 { 5133 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5134 { 5135 if ( rNEvt.GetWindow() == this ) 5136 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() ); 5137 else 5138 { 5139 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ); 5140 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &aMouseEvent ); 5141 } 5142 } 5143 } 5144 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP ) 5145 { 5146 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5147 { 5148 if ( rNEvt.GetWindow() == this ) 5149 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() ); 5150 else 5151 { 5152 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ); 5153 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &aMouseEvent ); 5154 } 5155 } 5156 } 5157 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN ) 5158 { 5159 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5160 { 5161 if ( rNEvt.GetWindow() == this ) 5162 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() ); 5163 else 5164 { 5165 MouseEvent aMouseEvent = ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ); 5166 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &aMouseEvent ); 5167 } 5168 } 5169 } 5170 else if( rNEvt.GetType() == EVENT_KEYINPUT ) 5171 { 5172 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5173 ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() ); 5174 } 5175 else if( rNEvt.GetType() == EVENT_KEYUP ) 5176 { 5177 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5178 ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() ); 5179 } 5180 5181 if ( aDelData.IsDelete() ) 5182 return; 5183 ImplRemoveDel( &aDelData ); 5184 5185 // #106721# check if we're part of a compound control and notify 5186 Window *pParent = ImplGetParent(); 5187 while( pParent ) 5188 { 5189 if( pParent->IsCompoundControl() ) 5190 { 5191 pParent->ImplNotifyKeyMouseCommandEventListeners( rNEvt ); 5192 break; 5193 } 5194 pParent = pParent->ImplGetParent(); 5195 } 5196 } 5197 5198 // ----------------------------------------------------------------------- 5199 5200 long Window::PreNotify( NotifyEvent& rNEvt ) 5201 { 5202 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 5203 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5204 } 5205 5206 long bDone = sal_False; 5207 if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() ) 5208 bDone = mpWindowImpl->mpParent->PreNotify( rNEvt ); 5209 5210 if ( !bDone ) 5211 { 5212 if( rNEvt.GetType() == EVENT_GETFOCUS ) 5213 { 5214 sal_Bool bCompoundFocusChanged = sal_False; 5215 if ( mpWindowImpl->mbCompoundControl && !mpWindowImpl->mbCompoundControlHasFocus && HasChildPathFocus() ) 5216 { 5217 mpWindowImpl->mbCompoundControlHasFocus = sal_True; 5218 bCompoundFocusChanged = sal_True; 5219 } 5220 5221 if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) ) 5222 ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS ); 5223 } 5224 else if( rNEvt.GetType() == EVENT_LOSEFOCUS ) 5225 { 5226 sal_Bool bCompoundFocusChanged = sal_False; 5227 if ( mpWindowImpl->mbCompoundControl && mpWindowImpl->mbCompoundControlHasFocus && !HasChildPathFocus() ) 5228 { 5229 mpWindowImpl->mbCompoundControlHasFocus = sal_False ; 5230 bCompoundFocusChanged = sal_True; 5231 } 5232 5233 if ( bCompoundFocusChanged || ( rNEvt.GetWindow() == this ) ) 5234 ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS ); 5235 } 5236 5237 // #82968# mouse and key events will be notified after processing ( in ImplNotifyKeyMouseCommandEventListeners() )! 5238 // see also ImplHandleMouseEvent(), ImplHandleKey() 5239 5240 /* 5241 else if( rNEvt.GetType() == EVENT_MOUSEMOVE ) 5242 { 5243 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5244 { 5245 if ( rNEvt.GetWindow() == this ) 5246 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, (void*)rNEvt.GetMouseEvent() ); 5247 else 5248 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEMOVE, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) ); 5249 } 5250 } 5251 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONUP ) 5252 { 5253 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5254 { 5255 if ( rNEvt.GetWindow() == this ) 5256 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, (void*)rNEvt.GetMouseEvent() ); 5257 else 5258 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONUP, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) ); 5259 } 5260 } 5261 else if( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN ) 5262 { 5263 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5264 { 5265 if ( rNEvt.GetWindow() == this ) 5266 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, (void*)rNEvt.GetMouseEvent() ); 5267 else 5268 ImplCallEventListeners( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, &ImplTranslateMouseEvent( *rNEvt.GetMouseEvent(), rNEvt.GetWindow(), this ) ); 5269 } 5270 } 5271 else if( rNEvt.GetType() == EVENT_KEYINPUT ) 5272 { 5273 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5274 ImplCallEventListeners( VCLEVENT_WINDOW_KEYINPUT, (void*)rNEvt.GetKeyEvent() ); 5275 } 5276 else if( rNEvt.GetType() == EVENT_KEYUP ) 5277 { 5278 if ( mpWindowImpl->mbCompoundControl || ( rNEvt.GetWindow() == this ) ) 5279 ImplCallEventListeners( VCLEVENT_WINDOW_KEYUP, (void*)rNEvt.GetKeyEvent() ); 5280 } 5281 */ 5282 } 5283 5284 return bDone; 5285 } 5286 5287 // ----------------------------------------------------------------------- 5288 5289 long Window::Notify( NotifyEvent& rNEvt ) 5290 { 5291 { // Klammerung, da in diesem Handler das Window zerstoert werden darf 5292 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5293 } 5294 5295 long nRet = sal_False; 5296 5297 // check for docking window 5298 // but do nothing if window is docked and locked 5299 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 5300 if( pWrapper && !( !pWrapper->IsFloatingMode() && pWrapper->IsLocked() ) ) 5301 { 5302 if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN ) 5303 { 5304 const MouseEvent* pMEvt = rNEvt.GetMouseEvent(); 5305 sal_Bool bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() ); 5306 if ( pMEvt->IsLeft() ) 5307 { 5308 if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) ) 5309 { 5310 // ctrl double click toggles floating mode 5311 pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() ); 5312 return sal_True; 5313 } 5314 else if ( pMEvt->GetClicks() == 1 && bHit) 5315 { 5316 // allow start docking during mouse move 5317 pWrapper->ImplEnableStartDocking(); 5318 return sal_True; 5319 } 5320 } 5321 } 5322 else if ( rNEvt.GetType() == EVENT_MOUSEMOVE ) 5323 { 5324 const MouseEvent* pMEvt = rNEvt.GetMouseEvent(); 5325 sal_Bool bHit = pWrapper->GetDragArea().IsInside( pMEvt->GetPosPixel() ); 5326 if ( pMEvt->IsLeft() ) 5327 { 5328 // check if a single click initiated this sequence ( ImplStartDockingEnabled() ) 5329 // check if window is docked and 5330 if( pWrapper->ImplStartDockingEnabled() && !pWrapper->IsFloatingMode() && 5331 !pWrapper->IsDocking() && bHit ) 5332 { 5333 Point aPos = pMEvt->GetPosPixel(); 5334 Window* pWindow = rNEvt.GetWindow(); 5335 if ( pWindow != this ) 5336 { 5337 aPos = pWindow->OutputToScreenPixel( aPos ); 5338 aPos = ScreenToOutputPixel( aPos ); 5339 } 5340 pWrapper->ImplStartDocking( aPos ); 5341 } 5342 return sal_True; 5343 } 5344 } 5345 else if( rNEvt.GetType() == EVENT_KEYINPUT ) 5346 { 5347 const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode(); 5348 if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() && 5349 rKey.IsShift() && rKey.IsMod1() ) 5350 { 5351 pWrapper->SetFloatingMode( !pWrapper->IsFloatingMode() ); 5352 /* At this point the floating toolbar frame does not have the 5353 * input focus since these frames don't get the focus per default 5354 * To enable keyboard handling of this toolbar set the input focus 5355 * to the frame. This needs to be done with ToTop since GrabFocus 5356 * would not notice any change since "this" already has the focus. 5357 */ 5358 if( pWrapper->IsFloatingMode() ) 5359 ToTop( TOTOP_GRABFOCUSONLY ); 5360 return sal_True; 5361 } 5362 } 5363 } 5364 5365 // Dialog-Steuerung 5366 if ( (GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL ) 5367 { 5368 // Wenn Parent auch DialogSteuerung aktiviert hat, uebernimmt dieser die Steuerung 5369 if ( (rNEvt.GetType() == EVENT_KEYINPUT) || (rNEvt.GetType() == EVENT_KEYUP) ) 5370 { 5371 if ( ImplIsOverlapWindow() || 5372 ((ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) ) 5373 { 5374 nRet = ImplDlgCtrl( *rNEvt.GetKeyEvent(), rNEvt.GetType() == EVENT_KEYINPUT ); 5375 } 5376 } 5377 else if ( (rNEvt.GetType() == EVENT_GETFOCUS) || (rNEvt.GetType() == EVENT_LOSEFOCUS) ) 5378 { 5379 ImplDlgCtrlFocusChanged( rNEvt.GetWindow(), rNEvt.GetType() == EVENT_GETFOCUS ); 5380 if ( (rNEvt.GetWindow() == this) && (rNEvt.GetType() == EVENT_GETFOCUS) && 5381 !(GetStyle() & WB_TABSTOP) && !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) ) 5382 { 5383 sal_uInt16 n = 0; 5384 Window* pFirstChild = ImplGetDlgWindow( n, DLGWINDOW_FIRST ); 5385 if ( pFirstChild ) 5386 pFirstChild->ImplControlFocus(); 5387 } 5388 } 5389 } 5390 5391 if ( !nRet ) 5392 { 5393 if ( mpWindowImpl->mpParent && !ImplIsOverlapWindow() ) 5394 nRet = mpWindowImpl->mpParent->Notify( rNEvt ); 5395 } 5396 5397 return nRet; 5398 } 5399 5400 // IAccessible2 implementation, 2009 5401 void Window::NotifyVCLEvent( sal_uLong nEvent ,void* pData /*= NULL*/) 5402 { 5403 ImplCallEventListeners( nEvent ,pData); 5404 } 5405 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > Window::GetAccFlowToSequence() 5406 { 5407 return ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >(); 5408 } 5409 // ----------------------------------------------------------------------- 5410 5411 void Window::ImplCallEventListeners( sal_uLong nEvent, void* pData ) 5412 { 5413 // The implementation was moved to CallEventListeners(), 5414 // because derived classes in svtools must be able to 5415 // call the event listeners and ImplCallEventListeners() 5416 // is not exported. 5417 // TODO: replace ImplCallEventListeners() by CallEventListeners() in vcl 5418 5419 CallEventListeners( nEvent, pData ); 5420 } 5421 5422 // ----------------------------------------------------------------------- 5423 5424 void Window::CallEventListeners( sal_uLong nEvent, void* pData ) 5425 { 5426 VclWindowEvent aEvent( this, nEvent, pData ); 5427 5428 ImplDelData aDelData; 5429 ImplAddDel( &aDelData ); 5430 5431 ImplGetSVData()->mpApp->ImplCallEventListeners( &aEvent ); 5432 5433 if ( aDelData.IsDelete() ) 5434 return; 5435 5436 if ( !mpWindowImpl->maEventListeners.empty() ) 5437 mpWindowImpl->maEventListeners.Call( &aEvent ); 5438 5439 if ( aDelData.IsDelete() ) 5440 return; 5441 5442 ImplRemoveDel( &aDelData ); 5443 5444 Window* pWindow = this; 5445 while ( pWindow ) 5446 { 5447 pWindow->ImplAddDel( &aDelData ); 5448 5449 if ( !pWindow->mpWindowImpl->maChildEventListeners.empty() ) 5450 pWindow->mpWindowImpl->maChildEventListeners.Call( &aEvent ); 5451 5452 if ( aDelData.IsDelete() ) 5453 return; 5454 5455 pWindow->ImplRemoveDel( &aDelData ); 5456 5457 pWindow = pWindow->GetParent(); 5458 } 5459 } 5460 5461 void Window::FireVclEvent( VclSimpleEvent* pEvent ) 5462 { 5463 ImplGetSVData()->mpApp->ImplCallEventListeners(pEvent); 5464 } 5465 5466 // ----------------------------------------------------------------------- 5467 5468 void Window::AddEventListener( const Link& rEventListener ) 5469 { 5470 mpWindowImpl->maEventListeners.push_back( rEventListener ); 5471 } 5472 5473 // ----------------------------------------------------------------------- 5474 5475 void Window::RemoveEventListener( const Link& rEventListener ) 5476 { 5477 mpWindowImpl->maEventListeners.remove( rEventListener ); 5478 } 5479 5480 // ----------------------------------------------------------------------- 5481 5482 void Window::AddChildEventListener( const Link& rEventListener ) 5483 { 5484 mpWindowImpl->maChildEventListeners.push_back( rEventListener ); 5485 } 5486 5487 // ----------------------------------------------------------------------- 5488 5489 void Window::RemoveChildEventListener( const Link& rEventListener ) 5490 { 5491 mpWindowImpl->maChildEventListeners.remove( rEventListener ); 5492 } 5493 5494 // ----------------------------------------------------------------------- 5495 5496 sal_uLong Window::PostUserEvent( sal_uLong nEvent, void* pEventData ) 5497 { 5498 sal_uLong nEventId; 5499 PostUserEvent( nEventId, nEvent, pEventData ); 5500 return nEventId; 5501 } 5502 5503 // ----------------------------------------------------------------------- 5504 5505 sal_uLong Window::PostUserEvent( const Link& rLink, void* pCaller ) 5506 { 5507 sal_uLong nEventId; 5508 PostUserEvent( nEventId, rLink, pCaller ); 5509 return nEventId; 5510 } 5511 5512 // ----------------------------------------------------------------------- 5513 5514 sal_Bool Window::PostUserEvent( sal_uLong& rEventId, sal_uLong nEvent, void* pEventData ) 5515 { 5516 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5517 5518 ImplSVEvent* pSVEvent = new ImplSVEvent; 5519 pSVEvent->mnEvent = nEvent; 5520 pSVEvent->mpData = pEventData; 5521 pSVEvent->mpLink = NULL; 5522 pSVEvent->mpWindow = this; 5523 pSVEvent->mbCall = sal_True; 5524 ImplAddDel( &(pSVEvent->maDelData) ); 5525 rEventId = (sal_uLong)pSVEvent; 5526 if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) ) 5527 return sal_True; 5528 else 5529 { 5530 rEventId = 0; 5531 ImplRemoveDel( &(pSVEvent->maDelData) ); 5532 delete pSVEvent; 5533 return sal_False; 5534 } 5535 } 5536 5537 // ----------------------------------------------------------------------- 5538 5539 sal_Bool Window::PostUserEvent( sal_uLong& rEventId, const Link& rLink, void* pCaller ) 5540 { 5541 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5542 5543 ImplSVEvent* pSVEvent = new ImplSVEvent; 5544 pSVEvent->mnEvent = 0; 5545 pSVEvent->mpData = pCaller; 5546 pSVEvent->mpLink = new Link( rLink ); 5547 pSVEvent->mpWindow = this; 5548 pSVEvent->mbCall = sal_True; 5549 ImplAddDel( &(pSVEvent->maDelData) ); 5550 rEventId = (sal_uLong)pSVEvent; 5551 if ( mpWindowImpl->mpFrame->PostEvent( pSVEvent ) ) 5552 return sal_True; 5553 else 5554 { 5555 rEventId = 0; 5556 ImplRemoveDel( &(pSVEvent->maDelData) ); 5557 delete pSVEvent; 5558 return sal_False; 5559 } 5560 } 5561 5562 // ----------------------------------------------------------------------- 5563 5564 void Window::RemoveUserEvent( sal_uLong nUserEvent ) 5565 { 5566 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5567 5568 ImplSVEvent* pSVEvent = (ImplSVEvent*)nUserEvent; 5569 5570 DBG_ASSERT( pSVEvent->mpWindow == this, 5571 "Window::RemoveUserEvent(): Event doesn't send to this window or is already removed" ); 5572 DBG_ASSERT( pSVEvent->mbCall, 5573 "Window::RemoveUserEvent(): Event is already removed" ); 5574 5575 if ( pSVEvent->mpWindow ) 5576 { 5577 pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) ); 5578 pSVEvent->mpWindow = NULL; 5579 } 5580 5581 pSVEvent->mbCall = sal_False; 5582 } 5583 5584 // ----------------------------------------------------------------------- 5585 5586 IMPL_LINK( Window, ImplAsyncStateChangedHdl, void*, pState ) 5587 { 5588 StateChanged( (StateChangedType)(sal_uLong)pState ); 5589 return 0; 5590 } 5591 5592 // ----------------------------------------------------------------------- 5593 5594 void Window::PostStateChanged( StateChangedType nState ) 5595 { 5596 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5597 5598 PostUserEvent( LINK( this, Window, ImplAsyncStateChangedHdl ), (void*)(sal_uLong)nState ); 5599 } 5600 5601 // ----------------------------------------------------------------------- 5602 5603 sal_Bool Window::IsLocked( sal_Bool bChilds ) const 5604 { 5605 if ( mpWindowImpl->mnLockCount != 0 ) 5606 return sal_True; 5607 5608 if ( bChilds || mpWindowImpl->mbChildNotify ) 5609 { 5610 Window* pChild = mpWindowImpl->mpFirstChild; 5611 while ( pChild ) 5612 { 5613 if ( pChild->IsLocked( sal_True ) ) 5614 return sal_True; 5615 pChild = pChild->mpWindowImpl->mpNext; 5616 } 5617 } 5618 5619 return sal_False; 5620 } 5621 5622 // ----------------------------------------------------------------------- 5623 5624 void Window::SetStyle( WinBits nStyle ) 5625 { 5626 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5627 5628 if ( mpWindowImpl->mnStyle != nStyle ) 5629 { 5630 mpWindowImpl->mnPrevStyle = mpWindowImpl->mnStyle; 5631 mpWindowImpl->mnStyle = nStyle; 5632 StateChanged( STATE_CHANGE_STYLE ); 5633 } 5634 } 5635 5636 // ----------------------------------------------------------------------- 5637 5638 void Window::SetExtendedStyle( WinBits nExtendedStyle ) 5639 { 5640 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5641 5642 if ( mpWindowImpl->mnExtendedStyle != nExtendedStyle ) 5643 { 5644 Window* pWindow = ImplGetBorderWindow(); 5645 if( ! pWindow ) 5646 pWindow = this; 5647 if( pWindow->mpWindowImpl->mbFrame ) 5648 { 5649 SalExtStyle nExt = 0; 5650 if( (nExtendedStyle & WB_EXT_DOCUMENT) ) 5651 nExt |= SAL_FRAME_EXT_STYLE_DOCUMENT; 5652 if( (nExtendedStyle & WB_EXT_DOCMODIFIED) ) 5653 nExt |= SAL_FRAME_EXT_STYLE_DOCMODIFIED; 5654 5655 pWindow->ImplGetFrame()->SetExtendedFrameStyle( nExt ); 5656 } 5657 mpWindowImpl->mnPrevExtendedStyle = mpWindowImpl->mnExtendedStyle; 5658 mpWindowImpl->mnExtendedStyle = nExtendedStyle; 5659 StateChanged( STATE_CHANGE_EXTENDEDSTYLE ); 5660 } 5661 } 5662 5663 // ----------------------------------------------------------------------- 5664 5665 SystemWindow* Window::GetSystemWindow() const 5666 { 5667 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5668 5669 const Window* pWin = this; 5670 while ( pWin && !pWin->IsSystemWindow() ) 5671 pWin = pWin->GetParent(); 5672 return (SystemWindow*)pWin; 5673 } 5674 5675 // ----------------------------------------------------------------------- 5676 5677 void Window::SetBorderStyle( sal_uInt16 nBorderStyle ) 5678 { 5679 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5680 5681 if ( mpWindowImpl->mpBorderWindow ) 5682 { 5683 if( nBorderStyle == WINDOW_BORDER_REMOVEBORDER && 5684 ! mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && 5685 mpWindowImpl->mpBorderWindow->mpWindowImpl->mpParent 5686 ) 5687 { 5688 // this is a little awkward: some controls (e.g. svtools ProgressBar) 5689 // cannot avoid getting constructed with WB_BORDER but want to disable 5690 // borders in case of NWF drawing. So they need a method to remove their border window 5691 Window* pBorderWin = mpWindowImpl->mpBorderWindow; 5692 // remove us as border window's client 5693 pBorderWin->mpWindowImpl->mpClientWindow = NULL; 5694 mpWindowImpl->mpBorderWindow = NULL; 5695 mpWindowImpl->mpRealParent = pBorderWin->mpWindowImpl->mpParent; 5696 // reparent us above the border window 5697 SetParent( pBorderWin->mpWindowImpl->mpParent ); 5698 // set us to the position and size of our previous border 5699 Point aBorderPos( pBorderWin->GetPosPixel() ); 5700 Size aBorderSize( pBorderWin->GetSizePixel() ); 5701 SetPosSizePixel( aBorderPos.X(), aBorderPos.Y(), aBorderSize.Width(), aBorderSize.Height() ); 5702 // release border window 5703 delete pBorderWin; 5704 5705 // set new style bits 5706 SetStyle( GetStyle() & (~WB_BORDER) ); 5707 } 5708 else 5709 { 5710 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW ) 5711 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetBorderStyle( nBorderStyle ); 5712 else 5713 mpWindowImpl->mpBorderWindow->SetBorderStyle( nBorderStyle ); 5714 } 5715 } 5716 } 5717 5718 // ----------------------------------------------------------------------- 5719 5720 sal_uInt16 Window::GetBorderStyle() const 5721 { 5722 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5723 5724 if ( mpWindowImpl->mpBorderWindow ) 5725 { 5726 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW ) 5727 return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->GetBorderStyle(); 5728 else 5729 return mpWindowImpl->mpBorderWindow->GetBorderStyle(); 5730 } 5731 5732 return 0; 5733 } 5734 5735 // ----------------------------------------------------------------------- 5736 5737 long Window::CalcTitleWidth() const 5738 { 5739 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5740 5741 if ( mpWindowImpl->mpBorderWindow ) 5742 { 5743 if ( mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW ) 5744 return ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->CalcTitleWidth(); 5745 else 5746 return mpWindowImpl->mpBorderWindow->CalcTitleWidth(); 5747 } 5748 else if ( mpWindowImpl->mbFrame && (mpWindowImpl->mnStyle & WB_MOVEABLE) ) 5749 { 5750 // Fuer Frame-Fenster raten wir die Breite, da wir den Border fuer 5751 // externe Dialoge nicht kennen 5752 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 5753 Font aFont = GetFont(); 5754 ((Window*)this)->SetPointFont( rStyleSettings.GetTitleFont() ); 5755 long nTitleWidth = GetTextWidth( GetText() ); 5756 ((Window*)this)->SetFont( aFont ); 5757 nTitleWidth += rStyleSettings.GetTitleHeight() * 3; 5758 nTitleWidth += rStyleSettings.GetBorderSize() * 2; 5759 nTitleWidth += 10; 5760 return nTitleWidth; 5761 } 5762 5763 return 0; 5764 } 5765 5766 // ----------------------------------------------------------------------- 5767 5768 void Window::EnableClipSiblings( sal_Bool bClipSiblings ) 5769 { 5770 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5771 5772 if ( mpWindowImpl->mpBorderWindow ) 5773 mpWindowImpl->mpBorderWindow->EnableClipSiblings( bClipSiblings ); 5774 5775 mpWindowImpl->mbClipSiblings = bClipSiblings; 5776 } 5777 5778 // ----------------------------------------------------------------------- 5779 5780 void Window::SetMouseTransparent( sal_Bool bTransparent ) 5781 { 5782 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5783 5784 if ( mpWindowImpl->mpBorderWindow ) 5785 mpWindowImpl->mpBorderWindow->SetMouseTransparent( bTransparent ); 5786 5787 if( mpWindowImpl->mpSysObj ) 5788 mpWindowImpl->mpSysObj->SetMouseTransparent( bTransparent ); 5789 5790 mpWindowImpl->mbMouseTransparent = bTransparent; 5791 } 5792 5793 // ----------------------------------------------------------------------- 5794 5795 void Window::SetPaintTransparent( sal_Bool bTransparent ) 5796 { 5797 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5798 5799 // transparency is not useful for frames as the background would have to be provided by a different frame 5800 if( bTransparent && mpWindowImpl->mbFrame ) 5801 return; 5802 5803 if ( mpWindowImpl->mpBorderWindow ) 5804 mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent ); 5805 5806 mpWindowImpl->mbPaintTransparent = bTransparent; 5807 } 5808 5809 // ----------------------------------------------------------------------- 5810 5811 void Window::SetInputContext( const InputContext& rInputContext ) 5812 { 5813 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5814 5815 mpWindowImpl->maInputContext = rInputContext; 5816 if ( !mpWindowImpl->mbInFocusHdl && HasFocus() ) 5817 ImplNewInputContext(); 5818 } 5819 5820 // ----------------------------------------------------------------------- 5821 5822 void Window::EndExtTextInput( sal_uInt16 nFlags ) 5823 { 5824 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5825 5826 if ( mpWindowImpl->mbExtTextInput ) 5827 ImplGetFrame()->EndExtTextInput( nFlags ); 5828 } 5829 5830 // ----------------------------------------------------------------------- 5831 5832 void Window::SetCursorRect( const Rectangle* pRect, long nExtTextInputWidth ) 5833 { 5834 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5835 5836 ImplWinData* pWinData = ImplGetWinData(); 5837 if ( pWinData->mpCursorRect ) 5838 { 5839 if ( pRect ) 5840 *pWinData->mpCursorRect = *pRect; 5841 else 5842 { 5843 delete pWinData->mpCursorRect; 5844 pWinData->mpCursorRect = NULL; 5845 } 5846 } 5847 else 5848 { 5849 if ( pRect ) 5850 pWinData->mpCursorRect = new Rectangle( *pRect ); 5851 } 5852 5853 pWinData->mnCursorExtWidth = nExtTextInputWidth; 5854 5855 } 5856 5857 // ----------------------------------------------------------------------- 5858 5859 const Rectangle* Window::GetCursorRect() const 5860 { 5861 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5862 5863 ImplWinData* pWinData = ImplGetWinData(); 5864 return pWinData->mpCursorRect; 5865 } 5866 5867 // ----------------------------------------------------------------------- 5868 5869 long Window::GetCursorExtTextInputWidth() const 5870 { 5871 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5872 5873 ImplWinData* pWinData = ImplGetWinData(); 5874 return pWinData->mnCursorExtWidth; 5875 } 5876 5877 // ----------------------------------------------------------------------- 5878 void Window::SetSettings( const AllSettings& rSettings ) 5879 { 5880 SetSettings( rSettings, sal_False ); 5881 } 5882 5883 void Window::SetSettings( const AllSettings& rSettings, sal_Bool bChild ) 5884 { 5885 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5886 5887 if ( mpWindowImpl->mpBorderWindow ) 5888 { 5889 mpWindowImpl->mpBorderWindow->SetSettings( rSettings, sal_False ); 5890 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) && 5891 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow ) 5892 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->SetSettings( rSettings, sal_True ); 5893 } 5894 5895 AllSettings aOldSettings = maSettings; 5896 OutputDevice::SetSettings( rSettings ); 5897 sal_uLong nChangeFlags = aOldSettings.GetChangeFlags( rSettings ); 5898 5899 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen 5900 ImplInitResolutionSettings(); 5901 5902 if ( nChangeFlags ) 5903 { 5904 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags ); 5905 DataChanged( aDCEvt ); 5906 } 5907 5908 if ( bChild || mpWindowImpl->mbChildNotify ) 5909 { 5910 Window* pChild = mpWindowImpl->mpFirstChild; 5911 while ( pChild ) 5912 { 5913 pChild->SetSettings( rSettings, bChild ); 5914 pChild = pChild->mpWindowImpl->mpNext; 5915 } 5916 } 5917 } 5918 5919 // ----------------------------------------------------------------------- 5920 5921 void Window::UpdateSettings( const AllSettings& rSettings, sal_Bool bChild ) 5922 { 5923 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5924 5925 if ( mpWindowImpl->mpBorderWindow ) 5926 { 5927 mpWindowImpl->mpBorderWindow->UpdateSettings( rSettings, sal_False ); 5928 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) && 5929 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow ) 5930 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->UpdateSettings( rSettings, sal_True ); 5931 } 5932 5933 AllSettings aOldSettings = maSettings; 5934 sal_uLong nChangeFlags = maSettings.Update( maSettings.GetWindowUpdate(), rSettings ); 5935 nChangeFlags |= SETTINGS_IN_UPDATE_SETTINGS; // Set this flag so the receiver of the data changed 5936 // event can distinguish between the changing of global 5937 // setting and a local change ( with SetSettings ) 5938 5939 // AppFont-Aufloesung und DPI-Aufloesung neu berechnen 5940 ImplInitResolutionSettings(); 5941 5942 /* #i73785# 5943 * do not overwrite a WheelBehavior with false 5944 * this looks kind of a hack, but WheelBehavior 5945 * is always a local change, not a system property, 5946 * so we can spare all our users the hassle of reacting on 5947 * this in their respective DataChanged. 5948 */ 5949 MouseSettings aSet( maSettings.GetMouseSettings() ); 5950 aSet.SetWheelBehavior( aOldSettings.GetMouseSettings().GetWheelBehavior() ); 5951 maSettings.SetMouseSettings( aSet ); 5952 5953 if( (nChangeFlags & SETTINGS_STYLE) && IsBackground() ) 5954 { 5955 Wallpaper aWallpaper = GetBackground(); 5956 if( !aWallpaper.IsBitmap() && !aWallpaper.IsGradient() ) 5957 { 5958 if ( mpWindowImpl->mnStyle & WB_3DLOOK ) 5959 SetBackground( Wallpaper( rSettings.GetStyleSettings().GetFaceColor() ) ); 5960 else 5961 SetBackground( Wallpaper( rSettings.GetStyleSettings().GetWindowColor() ) ); 5962 } 5963 } 5964 5965 if ( nChangeFlags ) 5966 { 5967 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags ); 5968 DataChanged( aDCEvt ); 5969 // notify data change handler 5970 ImplCallEventListeners( VCLEVENT_WINDOW_DATACHANGED, &aDCEvt); 5971 } 5972 5973 if ( bChild || mpWindowImpl->mbChildNotify ) 5974 { 5975 Window* pChild = mpWindowImpl->mpFirstChild; 5976 while ( pChild ) 5977 { 5978 pChild->UpdateSettings( rSettings, bChild ); 5979 pChild = pChild->mpWindowImpl->mpNext; 5980 } 5981 } 5982 } 5983 5984 // ----------------------------------------------------------------------- 5985 5986 void Window::NotifyAllChilds( DataChangedEvent& rDCEvt ) 5987 { 5988 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 5989 5990 DataChanged( rDCEvt ); 5991 5992 Window* pChild = mpWindowImpl->mpFirstChild; 5993 while ( pChild ) 5994 { 5995 pChild->NotifyAllChilds( rDCEvt ); 5996 pChild = pChild->mpWindowImpl->mpNext; 5997 } 5998 } 5999 6000 // ----------------------------------------------------------------------- 6001 6002 void Window::SetPointFont( const Font& rFont ) 6003 { 6004 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6005 6006 Font aFont = rFont; 6007 ImplPointToLogic( aFont ); 6008 SetFont( aFont ); 6009 } 6010 6011 // ----------------------------------------------------------------------- 6012 6013 Font Window::GetPointFont() const 6014 { 6015 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6016 6017 Font aFont = GetFont(); 6018 ImplLogicToPoint( aFont ); 6019 return aFont; 6020 } 6021 6022 // ----------------------------------------------------------------------- 6023 6024 // TODO: remove in next incompatible build 6025 void Window::GetFontResolution( sal_Int32& nDPIX, sal_Int32& nDPIY ) const 6026 { 6027 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6028 6029 nDPIX = mpWindowImpl->mpFrameData->mnDPIX; 6030 nDPIY = mpWindowImpl->mpFrameData->mnDPIY; 6031 } 6032 6033 // ----------------------------------------------------------------------- 6034 6035 void Window::SetParentClipMode( sal_uInt16 nMode ) 6036 { 6037 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6038 6039 if ( mpWindowImpl->mpBorderWindow ) 6040 mpWindowImpl->mpBorderWindow->SetParentClipMode( nMode ); 6041 else 6042 { 6043 if ( !ImplIsOverlapWindow() ) 6044 { 6045 mpWindowImpl->mnParentClipMode = nMode; 6046 if ( nMode & PARENTCLIPMODE_CLIP ) 6047 mpWindowImpl->mpParent->mpWindowImpl->mbClipChildren = sal_True; 6048 } 6049 } 6050 } 6051 6052 // ----------------------------------------------------------------------- 6053 6054 sal_uInt16 Window::GetParentClipMode() const 6055 { 6056 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6057 6058 if ( mpWindowImpl->mpBorderWindow ) 6059 return mpWindowImpl->mpBorderWindow->GetParentClipMode(); 6060 else 6061 return mpWindowImpl->mnParentClipMode; 6062 } 6063 6064 // ----------------------------------------------------------------------- 6065 6066 void Window::SetWindowRegionPixel() 6067 { 6068 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6069 6070 if ( mpWindowImpl->mpBorderWindow ) 6071 mpWindowImpl->mpBorderWindow->SetWindowRegionPixel(); 6072 else if( mpWindowImpl->mbFrame ) 6073 { 6074 mpWindowImpl->maWinRegion = Region(true); 6075 mpWindowImpl->mbWinRegion = sal_False; 6076 mpWindowImpl->mpFrame->ResetClipRegion(); 6077 } 6078 else 6079 { 6080 if ( mpWindowImpl->mbWinRegion ) 6081 { 6082 mpWindowImpl->maWinRegion = Region(true); 6083 mpWindowImpl->mbWinRegion = sal_False; 6084 ImplSetClipFlag(); 6085 6086 if ( IsReallyVisible() ) 6087 { 6088 // Hintergrund-Sicherung zuruecksetzen 6089 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev ) 6090 ImplDeleteOverlapBackground(); 6091 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 6092 ImplInvalidateAllOverlapBackgrounds(); 6093 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 6094 Region aRegion( aRect ); 6095 ImplInvalidateParentFrameRegion( aRegion ); 6096 } 6097 } 6098 } 6099 } 6100 6101 // ----------------------------------------------------------------------- 6102 6103 void Window::SetWindowRegionPixel( const Region& rRegion ) 6104 { 6105 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6106 6107 if ( mpWindowImpl->mpBorderWindow ) 6108 mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion ); 6109 else if( mpWindowImpl->mbFrame ) 6110 { 6111 if( !rRegion.IsNull() ) 6112 { 6113 mpWindowImpl->maWinRegion = rRegion; 6114 mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty(); 6115 6116 if( mpWindowImpl->mbWinRegion ) 6117 { 6118 // ClipRegion setzen/updaten 6119 RectangleVector aRectangles; 6120 mpWindowImpl->maWinRegion.GetRegionRectangles(aRectangles); 6121 mpWindowImpl->mpFrame->BeginSetClipRegion(aRectangles.size()); 6122 6123 for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++) 6124 { 6125 mpWindowImpl->mpFrame->UnionClipRegion( 6126 aRectIter->Left(), 6127 aRectIter->Top(), 6128 aRectIter->GetWidth(), // orig nWidth was ((R - L) + 1), same as GetWidth does 6129 aRectIter->GetHeight()); // same for height 6130 } 6131 6132 mpWindowImpl->mpFrame->EndSetClipRegion(); 6133 6134 //long nX; 6135 //long nY; 6136 //long nWidth; 6137 //long nHeight; 6138 //sal_uLong nRectCount; 6139 //ImplRegionInfo aInfo; 6140 //sal_Bool bRegionRect; 6141 // 6142 //nRectCount = mpWindowImpl->maWinRegion.GetRectCount(); 6143 //mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount ); 6144 //bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight ); 6145 //while ( bRegionRect ) 6146 //{ 6147 // mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight ); 6148 // bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight ); 6149 //} 6150 //mpWindowImpl->mpFrame->EndSetClipRegion(); 6151 } 6152 else 6153 SetWindowRegionPixel(); 6154 } 6155 else 6156 SetWindowRegionPixel(); 6157 } 6158 else 6159 { 6160 sal_Bool bInvalidate = sal_False; 6161 6162 if ( rRegion.IsNull() ) 6163 { 6164 if ( mpWindowImpl->mbWinRegion ) 6165 { 6166 mpWindowImpl->maWinRegion = Region(true); 6167 mpWindowImpl->mbWinRegion = sal_False; 6168 ImplSetClipFlag(); 6169 bInvalidate = sal_True; 6170 } 6171 } 6172 else 6173 { 6174 mpWindowImpl->maWinRegion = rRegion; 6175 mpWindowImpl->mbWinRegion = sal_True; 6176 ImplSetClipFlag(); 6177 bInvalidate = sal_True; 6178 } 6179 6180 if ( IsReallyVisible() ) 6181 { 6182 // Hintergrund-Sicherung zuruecksetzen 6183 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev ) 6184 ImplDeleteOverlapBackground(); 6185 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 6186 ImplInvalidateAllOverlapBackgrounds(); 6187 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 6188 Region aRegion( aRect ); 6189 ImplInvalidateParentFrameRegion( aRegion ); 6190 } 6191 } 6192 } 6193 6194 // ----------------------------------------------------------------------- 6195 6196 const Region& Window::GetWindowRegionPixel() const 6197 { 6198 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6199 6200 if ( mpWindowImpl->mpBorderWindow ) 6201 return mpWindowImpl->mpBorderWindow->GetWindowRegionPixel(); 6202 else 6203 return mpWindowImpl->maWinRegion; 6204 } 6205 6206 // ----------------------------------------------------------------------- 6207 6208 sal_Bool Window::IsWindowRegionPixel() const 6209 { 6210 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6211 6212 if ( mpWindowImpl->mpBorderWindow ) 6213 return mpWindowImpl->mpBorderWindow->IsWindowRegionPixel(); 6214 else 6215 return mpWindowImpl->mbWinRegion; 6216 } 6217 6218 // ----------------------------------------------------------------------- 6219 6220 Region Window::GetWindowClipRegionPixel( sal_uInt16 nFlags ) const 6221 { 6222 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6223 6224 Region aWinClipRegion; 6225 6226 if ( nFlags & WINDOW_GETCLIPREGION_NOCHILDREN ) 6227 { 6228 if ( mpWindowImpl->mbInitWinClipRegion ) 6229 ((Window*)this)->ImplInitWinClipRegion(); 6230 aWinClipRegion = mpWindowImpl->maWinClipRegion; 6231 } 6232 else 6233 { 6234 Region* pWinChildClipRegion = ((Window*)this)->ImplGetWinChildClipRegion(); 6235 aWinClipRegion = *pWinChildClipRegion; 6236 // --- RTL --- remirror clip region before passing it to somebody 6237 if( ImplIsAntiparallel() ) 6238 ImplReMirror( aWinClipRegion ); 6239 } 6240 6241 if ( nFlags & WINDOW_GETCLIPREGION_NULL ) 6242 { 6243 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 6244 Region aWinRegion( aWinRect ); 6245 6246 if ( aWinRegion == aWinClipRegion ) 6247 aWinClipRegion.SetNull(); 6248 } 6249 6250 aWinClipRegion.Move( -mnOutOffX, -mnOutOffY ); 6251 6252 return aWinClipRegion; 6253 } 6254 6255 // ----------------------------------------------------------------------- 6256 6257 Region Window::GetPaintRegion() const 6258 { 6259 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6260 6261 if ( mpWindowImpl->mpPaintRegion ) 6262 { 6263 Region aRegion = *mpWindowImpl->mpPaintRegion; 6264 aRegion.Move( -mnOutOffX, -mnOutOffY ); 6265 return PixelToLogic( aRegion ); 6266 } 6267 else 6268 { 6269 Region aPaintRegion(true); 6270 return aPaintRegion; 6271 } 6272 } 6273 6274 // ----------------------------------------------------------------------- 6275 6276 void Window::ExpandPaintClipRegion( const Region& rRegion ) 6277 { 6278 if( mpWindowImpl->mpPaintRegion ) 6279 { 6280 Region aPixRegion = LogicToPixel( rRegion ); 6281 Region aDevPixRegion = ImplPixelToDevicePixel( aPixRegion ); 6282 6283 Region aWinChildRegion = *ImplGetWinChildClipRegion(); 6284 // --- RTL -- only this region is in frame coordinates, so re-mirror it 6285 if( ImplIsAntiparallel() ) 6286 ImplReMirror( aWinChildRegion ); 6287 aDevPixRegion.Intersect( aWinChildRegion ); 6288 if( ! aDevPixRegion.IsEmpty() ) 6289 { 6290 mpWindowImpl->mpPaintRegion->Union( aDevPixRegion ); 6291 mbInitClipRegion = sal_True; 6292 } 6293 } 6294 } 6295 6296 // ----------------------------------------------------------------------- 6297 6298 static SystemWindow *ImplGetLastSystemWindow( Window *pWin ) 6299 { 6300 // get the most top-level system window, the one that contains the taskpanelist 6301 SystemWindow *pSysWin = NULL; 6302 if( !pWin ) 6303 return pSysWin; 6304 Window *pMyParent = pWin; 6305 while ( pMyParent ) 6306 { 6307 if ( pMyParent->IsSystemWindow() ) 6308 pSysWin = (SystemWindow*)pMyParent; 6309 pMyParent = pMyParent->GetParent(); 6310 } 6311 return pSysWin; 6312 } 6313 6314 void Window::SetParent( Window* pNewParent ) 6315 { 6316 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6317 DBG_ASSERT( pNewParent, "Window::SetParent(): pParent == NULL" ); 6318 DBG_ASSERT( pNewParent != this, "someone tried to reparent a window to itself" ); 6319 6320 if( pNewParent == this ) 6321 return; 6322 6323 // check if the taskpanelist would change and move the window pointer accordingly 6324 SystemWindow *pSysWin = ImplGetLastSystemWindow(this); 6325 SystemWindow *pNewSysWin = NULL; 6326 sal_Bool bChangeTaskPaneList = sal_False; 6327 if( pSysWin && pSysWin->ImplIsInTaskPaneList( this ) ) 6328 { 6329 pNewSysWin = ImplGetLastSystemWindow( pNewParent ); 6330 if( pNewSysWin && pNewSysWin != pSysWin ) 6331 { 6332 bChangeTaskPaneList = sal_True; 6333 pSysWin->GetTaskPaneList()->RemoveWindow( this ); 6334 } 6335 } 6336 // remove ownerdraw decorated windows from list in the top-most frame window 6337 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame ) 6338 { 6339 ::std::vector< Window* >& rList = ImplGetOwnerDrawList(); 6340 ::std::vector< Window* >::iterator p; 6341 p = ::std::find( rList.begin(), rList.end(), this ); 6342 if( p != rList.end() ) 6343 rList.erase( p ); 6344 } 6345 6346 ImplSetFrameParent( pNewParent ); 6347 6348 if ( mpWindowImpl->mpBorderWindow ) 6349 { 6350 mpWindowImpl->mpRealParent = pNewParent; 6351 mpWindowImpl->mpBorderWindow->SetParent( pNewParent ); 6352 return; 6353 } 6354 6355 if ( mpWindowImpl->mpParent == pNewParent ) 6356 return; 6357 6358 if ( mpWindowImpl->mbFrame ) 6359 mpWindowImpl->mpFrame->SetParent( pNewParent->mpWindowImpl->mpFrame ); 6360 6361 sal_Bool bVisible = IsVisible(); 6362 Show( sal_False, SHOW_NOFOCUSCHANGE ); 6363 6364 // Testen, ob sich das Overlap-Window aendert 6365 Window* pOldOverlapWindow; 6366 Window* pNewOverlapWindow = NULL; 6367 if ( ImplIsOverlapWindow() ) 6368 pOldOverlapWindow = NULL; 6369 else 6370 { 6371 pNewOverlapWindow = pNewParent->ImplGetFirstOverlapWindow(); 6372 if ( mpWindowImpl->mpOverlapWindow != pNewOverlapWindow ) 6373 pOldOverlapWindow = mpWindowImpl->mpOverlapWindow; 6374 else 6375 pOldOverlapWindow = NULL; 6376 } 6377 6378 // Fenster in der Hirachie umsetzen 6379 sal_Bool bFocusOverlapWin = HasChildPathFocus( sal_True ); 6380 sal_Bool bFocusWin = HasChildPathFocus(); 6381 sal_Bool bNewFrame = pNewParent->mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow; 6382 if ( bNewFrame ) 6383 { 6384 if ( mpWindowImpl->mpFrameData->mpFocusWin ) 6385 { 6386 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpFocusWin ) ) 6387 mpWindowImpl->mpFrameData->mpFocusWin = NULL; 6388 } 6389 if ( mpWindowImpl->mpFrameData->mpMouseMoveWin ) 6390 { 6391 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseMoveWin ) ) 6392 mpWindowImpl->mpFrameData->mpMouseMoveWin = NULL; 6393 } 6394 if ( mpWindowImpl->mpFrameData->mpMouseDownWin ) 6395 { 6396 if ( IsWindowOrChild( mpWindowImpl->mpFrameData->mpMouseDownWin ) ) 6397 mpWindowImpl->mpFrameData->mpMouseDownWin = NULL; 6398 } 6399 } 6400 ImplRemoveWindow( bNewFrame ); 6401 ImplInsertWindow( pNewParent ); 6402 if ( mpWindowImpl->mnParentClipMode & PARENTCLIPMODE_CLIP ) 6403 pNewParent->mpWindowImpl->mbClipChildren = sal_True; 6404 ImplUpdateWindowPtr(); 6405 if ( ImplUpdatePos() ) 6406 ImplUpdateSysObjPos(); 6407 6408 // Wenn sich das Overlap-Window geaendert hat, dann muss getestet werden, 6409 // ob auch OverlapWindow die das Child-Fenster als Parent gehabt haben 6410 // in der Window-Hirachie umgesetzt werden muessen 6411 if ( ImplIsOverlapWindow() ) 6412 { 6413 if ( bNewFrame ) 6414 { 6415 Window* pOverlapWindow = mpWindowImpl->mpFirstOverlap; 6416 while ( pOverlapWindow ) 6417 { 6418 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; 6419 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame ); 6420 pOverlapWindow = pNextOverlapWindow; 6421 } 6422 } 6423 } 6424 else if ( pOldOverlapWindow ) 6425 { 6426 // Focus-Save zuruecksetzen 6427 if ( bFocusWin || 6428 (pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow && 6429 IsWindowOrChild( pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow )) ) 6430 pOldOverlapWindow->mpWindowImpl->mpLastFocusWindow = NULL; 6431 6432 Window* pOverlapWindow = pOldOverlapWindow->mpWindowImpl->mpFirstOverlap; 6433 while ( pOverlapWindow ) 6434 { 6435 Window* pNextOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext; 6436 if ( ImplIsRealParentPath( pOverlapWindow->ImplGetWindow() ) ) 6437 pOverlapWindow->ImplUpdateOverlapWindowPtr( bNewFrame ); 6438 pOverlapWindow = pNextOverlapWindow; 6439 } 6440 6441 // Activate-Status beim naechsten Overlap-Window updaten 6442 if ( HasChildPathFocus( sal_True ) ) 6443 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow ); 6444 } 6445 6446 // Activate-Status mit umsetzen 6447 if ( bNewFrame ) 6448 { 6449 if ( (GetType() == WINDOW_BORDERWINDOW) && 6450 (ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) ) 6451 ((ImplBorderWindow*)this)->SetDisplayActive( mpWindowImpl->mpFrameData->mbHasFocus ); 6452 } 6453 6454 // Focus evtl. auf den neuen Frame umsetzen, wenn FocusWindow mit 6455 // SetParent() umgesetzt wird 6456 if ( bFocusOverlapWin ) 6457 { 6458 mpWindowImpl->mpFrameData->mpFocusWin = Application::GetFocusWindow(); 6459 if ( !mpWindowImpl->mpFrameData->mbHasFocus ) 6460 { 6461 mpWindowImpl->mpFrame->ToTop( 0 ); 6462 } 6463 } 6464 6465 // Assure DragSource and DropTarget members are created 6466 if ( bNewFrame ) 6467 { 6468 GetDropTarget(); 6469 } 6470 6471 if( bChangeTaskPaneList ) 6472 pNewSysWin->GetTaskPaneList()->AddWindow( this ); 6473 6474 if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame ) 6475 ImplGetOwnerDrawList().push_back( this ); 6476 6477 if ( bVisible ) 6478 Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); 6479 } 6480 6481 // ----------------------------------------------------------------------- 6482 6483 void Window::Show( sal_Bool bVisible, sal_uInt16 nFlags ) 6484 { 6485 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6486 6487 if ( mpWindowImpl->mbVisible == bVisible ) 6488 return; 6489 6490 ImplDelData aDogTag( this ); 6491 6492 sal_Bool bRealVisibilityChanged = sal_False; 6493 mpWindowImpl->mbVisible = (bVisible != 0); 6494 6495 if ( !bVisible ) 6496 { 6497 ImplHideAllOverlaps(); 6498 if( aDogTag.IsDelete() ) 6499 return; 6500 6501 if ( mpWindowImpl->mpBorderWindow ) 6502 { 6503 sal_Bool bOldUpdate = mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate; 6504 if ( mpWindowImpl->mbNoParentUpdate ) 6505 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = sal_True; 6506 mpWindowImpl->mpBorderWindow->Show( sal_False, nFlags ); 6507 mpWindowImpl->mpBorderWindow->mpWindowImpl->mbNoParentUpdate = bOldUpdate; 6508 } 6509 else if ( mpWindowImpl->mbFrame ) 6510 { 6511 mpWindowImpl->mbSuppressAccessibilityEvents = sal_True; 6512 mpWindowImpl->mpFrame->Show( sal_False, sal_False ); 6513 } 6514 6515 StateChanged( STATE_CHANGE_VISIBLE ); 6516 6517 if ( mpWindowImpl->mbReallyVisible ) 6518 { 6519 Region aInvRegion; 6520 sal_Bool bSaveBack = sal_False; 6521 6522 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame ) 6523 { 6524 if ( ImplRestoreOverlapBackground( aInvRegion ) ) 6525 bSaveBack = sal_True; 6526 } 6527 6528 if ( !bSaveBack ) 6529 { 6530 if ( mpWindowImpl->mbInitWinClipRegion ) 6531 ImplInitWinClipRegion(); 6532 aInvRegion = mpWindowImpl->maWinClipRegion; 6533 } 6534 6535 if( aDogTag.IsDelete() ) 6536 return; 6537 6538 bRealVisibilityChanged = mpWindowImpl->mbReallyVisible; 6539 ImplResetReallyVisible(); 6540 ImplSetClipFlag(); 6541 6542 if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame ) 6543 { 6544 // Focus umsetzen 6545 if ( !(nFlags & SHOW_NOFOCUSCHANGE) && HasChildPathFocus() ) 6546 { 6547 if ( mpWindowImpl->mpOverlapWindow->IsEnabled() && 6548 mpWindowImpl->mpOverlapWindow->IsInputEnabled() && 6549 ! mpWindowImpl->mpOverlapWindow->IsInModalMode() 6550 ) 6551 mpWindowImpl->mpOverlapWindow->GrabFocus(); 6552 } 6553 } 6554 6555 if ( !mpWindowImpl->mbFrame ) 6556 { 6557 if( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mbEnableNativeWidget ) 6558 { 6559 /* 6560 * #i48371# native theming: some themes draw outside the control 6561 * area we tell them to (bad thing, but we cannot do much about it ). 6562 * On hiding these controls they get invalidated with their window rectangle 6563 * which leads to the parts outside the control area being left and not 6564 * invalidated. Workaround: invalidate an area on the parent, too 6565 */ 6566 const int workaround_border = 5; 6567 Rectangle aBounds( aInvRegion.GetBoundRect() ); 6568 aBounds.Left() -= workaround_border; 6569 aBounds.Top() -= workaround_border; 6570 aBounds.Right() += workaround_border; 6571 aBounds.Bottom() += workaround_border; 6572 aInvRegion = aBounds; 6573 } 6574 if ( !mpWindowImpl->mbNoParentUpdate && !(nFlags & SHOW_NOPARENTUPDATE) ) 6575 { 6576 if ( !aInvRegion.IsEmpty() ) 6577 ImplInvalidateParentFrameRegion( aInvRegion ); 6578 } 6579 ImplGenerateMouseMove(); 6580 } 6581 } 6582 } 6583 else 6584 { 6585 // inherit native widget flag for form controls 6586 // required here, because frames never show up in the child hierarchy - which should be fixed.... 6587 // eg, the drop down of a combobox which is a system floating window 6588 if( mpWindowImpl->mbFrame && GetParent() && GetParent()->IsCompoundControl() && 6589 GetParent()->IsNativeWidgetEnabled() != IsNativeWidgetEnabled() ) 6590 EnableNativeWidget( GetParent()->IsNativeWidgetEnabled() ); 6591 6592 if ( mpWindowImpl->mbCallMove ) 6593 { 6594 ImplCallMove(); 6595 } 6596 if ( mpWindowImpl->mbCallResize ) 6597 { 6598 ImplCallResize(); 6599 } 6600 6601 StateChanged( STATE_CHANGE_VISIBLE ); 6602 6603 Window* pTestParent; 6604 if ( ImplIsOverlapWindow() ) 6605 pTestParent = mpWindowImpl->mpOverlapWindow; 6606 else 6607 pTestParent = ImplGetParent(); 6608 if ( mpWindowImpl->mbFrame || pTestParent->mpWindowImpl->mbReallyVisible ) 6609 { 6610 // Wenn ein Window gerade sichtbar wird, schicken wir allen 6611 // Child-Fenstern ein StateChanged, damit diese sich 6612 // initialisieren koennen 6613 ImplCallInitShow(); 6614 6615 // Wenn es ein SystemWindow ist, dann kommt es auch automatisch 6616 // nach vorne, wenn es gewuenscht ist 6617 if ( ImplIsOverlapWindow() && !(nFlags & SHOW_NOACTIVATE) ) 6618 { 6619 ImplStartToTop(( nFlags & SHOW_FOREGROUNDTASK ) ? TOTOP_FOREGROUNDTASK : 0 ); 6620 ImplFocusToTop( 0, sal_False ); 6621 } 6622 6623 // Hintergrund sichern 6624 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mbSaveBack ) 6625 ImplSaveOverlapBackground(); 6626 // adjust mpWindowImpl->mbReallyVisible 6627 bRealVisibilityChanged = !mpWindowImpl->mbReallyVisible; 6628 ImplSetReallyVisible(); 6629 6630 // Dafuer sorgen, das Clip-Rechtecke neu berechnet werden 6631 ImplSetClipFlag(); 6632 6633 if ( !mpWindowImpl->mbFrame ) 6634 { 6635 sal_uInt16 nInvalidateFlags = INVALIDATE_CHILDREN; 6636 if( ! IsPaintTransparent() ) 6637 nInvalidateFlags |= INVALIDATE_NOTRANSPARENT; 6638 ImplInvalidate( NULL, nInvalidateFlags ); 6639 ImplGenerateMouseMove(); 6640 } 6641 } 6642 6643 if ( mpWindowImpl->mpBorderWindow ) 6644 mpWindowImpl->mpBorderWindow->Show( sal_True, nFlags ); 6645 else if ( mpWindowImpl->mbFrame ) 6646 { 6647 ImplSVData* pSVData = ImplGetSVData(); 6648 // #106431#, hide SplashScreen 6649 if( pSVData->mpIntroWindow && !ImplIsWindowOrChild( pSVData->mpIntroWindow ) ) 6650 pSVData->mpIntroWindow->Hide(); 6651 6652 //DBG_ASSERT( !mpWindowImpl->mbSuppressAccessibilityEvents, "Window::Show() - Frame reactivated"); 6653 mpWindowImpl->mbSuppressAccessibilityEvents = sal_False; 6654 6655 mpWindowImpl->mbPaintFrame = sal_True; 6656 sal_Bool bNoActivate = (nFlags & (SHOW_NOACTIVATE|SHOW_NOFOCUSCHANGE)) ? sal_True : sal_False; 6657 mpWindowImpl->mpFrame->Show( sal_True, bNoActivate ); 6658 if( aDogTag.IsDelete() ) 6659 return; 6660 6661 // Query the correct size of the window, if we are waiting for 6662 // a system resize 6663 if ( mpWindowImpl->mbWaitSystemResize ) 6664 { 6665 long nOutWidth; 6666 long nOutHeight; 6667 mpWindowImpl->mpFrame->GetClientSize( nOutWidth, nOutHeight ); 6668 ImplHandleResize( this, nOutWidth, nOutHeight ); 6669 } 6670 } 6671 6672 if( aDogTag.IsDelete() ) 6673 return; 6674 6675 #ifdef DBG_UTIL 6676 if ( IsDialog() || (GetType() == WINDOW_TABPAGE) || (GetType() == WINDOW_DOCKINGWINDOW) ) 6677 { 6678 DBG_DIALOGTEST( this ); 6679 } 6680 #endif 6681 6682 ImplShowAllOverlaps(); 6683 } 6684 6685 if( aDogTag.IsDelete() ) 6686 return; 6687 // invalidate all saved backgrounds 6688 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 6689 ImplInvalidateAllOverlapBackgrounds(); 6690 6691 // the SHOW/HIDE events also serve as indicators to send child creation/destroy events to the access bridge 6692 // However, the access bridge only uses this event if the data member is not NULL (it's kind of a hack that 6693 // we re-use the SHOW/HIDE events this way, with this particular semantics). 6694 // Since #104887#, the notifications for the access bridge are done in Impl(Set|Reset)ReallyVisible. Here, we 6695 // now only notify with a NULL data pointer, for all other clients except the access bridge. 6696 if ( !bRealVisibilityChanged ) 6697 ImplCallEventListeners( mpWindowImpl->mbVisible ? VCLEVENT_WINDOW_SHOW : VCLEVENT_WINDOW_HIDE, NULL ); 6698 if( aDogTag.IsDelete() ) 6699 return; 6700 6701 // #107575#, if a floating windows is shown that grabs the focus, we have to notify the toolkit about it 6702 // ImplGrabFocus() is not called in this case 6703 // Because this might lead to problems the task will be shifted to 6.y 6704 // Note: top-level context menues are registered at the access bridge after being shown, 6705 // so this will probably not help here.... 6706 /* 6707 if( mpWindowImpl->mbFloatWin && ((FloatingWindow*) this )->GrabsFocus() ) 6708 { 6709 ImplSVData* pSVData = ImplGetSVData(); 6710 if( !mpWindowImpl->mbVisible ) 6711 { 6712 ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS ); 6713 if( pSVData->maWinData.mpFocusWin ) 6714 pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS ); 6715 } 6716 else 6717 { 6718 if( pSVData->maWinData.mpFocusWin ) 6719 pSVData->maWinData.mpFocusWin->ImplCallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS ); 6720 ImplCallEventListeners( VCLEVENT_WINDOW_GETFOCUS ); 6721 } 6722 } 6723 */ 6724 } 6725 6726 // ----------------------------------------------------------------------- 6727 6728 Size Window::GetSizePixel() const 6729 { 6730 // #i43257# trigger pending resize handler to assure correct window sizes 6731 if( mpWindowImpl->mpFrameData->maResizeTimer.IsActive() ) 6732 { 6733 ImplDelData aDogtag( this ); 6734 mpWindowImpl->mpFrameData->maResizeTimer.Stop(); 6735 mpWindowImpl->mpFrameData->maResizeTimer.GetTimeoutHdl().Call( NULL ); 6736 if( aDogtag.IsDelete() ) 6737 return Size(0,0); 6738 } 6739 6740 return Size( mnOutWidth+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder, 6741 mnOutHeight+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ); 6742 } 6743 6744 void Window::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder, 6745 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const 6746 { 6747 rLeftBorder = mpWindowImpl->mnLeftBorder; 6748 rTopBorder = mpWindowImpl->mnTopBorder; 6749 rRightBorder = mpWindowImpl->mnRightBorder; 6750 rBottomBorder = mpWindowImpl->mnBottomBorder; 6751 } 6752 6753 6754 // ----------------------------------------------------------------------- 6755 6756 void Window::Enable( bool bEnable, bool bChild ) 6757 { 6758 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6759 6760 if ( !bEnable ) 6761 { 6762 // Wenn ein Fenster disablte wird, wird automatisch der Tracking-Modus 6763 // beendet oder der Capture geklaut 6764 if ( IsTracking() ) 6765 EndTracking( ENDTRACK_CANCEL ); 6766 if ( IsMouseCaptured() ) 6767 ReleaseMouse(); 6768 // Wenn Fenster den Focus hat und in der Dialog-Steuerung enthalten, 6769 // wird versucht, den Focus auf das naechste Control weiterzuschalten 6770 // mpWindowImpl->mbDisabled darf erst nach Aufruf von ImplDlgCtrlNextWindow() gesetzt 6771 // werden. Ansonsten muss ImplDlgCtrlNextWindow() umgestellt werden 6772 if ( HasFocus() ) 6773 ImplDlgCtrlNextWindow(); 6774 } 6775 6776 if ( mpWindowImpl->mpBorderWindow ) 6777 { 6778 mpWindowImpl->mpBorderWindow->Enable( bEnable, sal_False ); 6779 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) && 6780 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow ) 6781 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->Enable( bEnable, sal_True ); 6782 } 6783 6784 // #i56102# restore app focus win in case the 6785 // window was disabled when the frame focus changed 6786 ImplSVData* pSVData = ImplGetSVData(); 6787 if( bEnable && 6788 pSVData->maWinData.mpFocusWin == NULL && 6789 mpWindowImpl->mpFrameData->mbHasFocus && 6790 mpWindowImpl->mpFrameData->mpFocusWin == this ) 6791 pSVData->maWinData.mpFocusWin = this; 6792 6793 if ( mpWindowImpl->mbDisabled != !bEnable ) 6794 { 6795 mpWindowImpl->mbDisabled = !bEnable; 6796 if ( mpWindowImpl->mpSysObj ) 6797 mpWindowImpl->mpSysObj->Enable( bEnable && !mpWindowImpl->mbInputDisabled ); 6798 // if ( mpWindowImpl->mbFrame ) 6799 // mpWindowImpl->mpFrame->Enable( bEnable && !mpWindowImpl->mbInputDisabled ); 6800 StateChanged( STATE_CHANGE_ENABLE ); 6801 6802 ImplCallEventListeners( bEnable ? VCLEVENT_WINDOW_ENABLED : VCLEVENT_WINDOW_DISABLED ); 6803 } 6804 6805 if ( bChild || mpWindowImpl->mbChildNotify ) 6806 { 6807 Window* pChild = mpWindowImpl->mpFirstChild; 6808 while ( pChild ) 6809 { 6810 pChild->Enable( bEnable, bChild ); 6811 pChild = pChild->mpWindowImpl->mpNext; 6812 } 6813 } 6814 6815 if ( IsReallyVisible() ) 6816 ImplGenerateMouseMove(); 6817 } 6818 6819 // ----------------------------------------------------------------------- 6820 6821 void Window::SetCallHandlersOnInputDisabled( bool bCall ) 6822 { 6823 mpWindowImpl->mbCallHandlersDuringInputDisabled = bCall ? sal_True : sal_False; 6824 6825 Window* pChild = mpWindowImpl->mpFirstChild; 6826 while ( pChild ) 6827 { 6828 pChild->SetCallHandlersOnInputDisabled( bCall ); 6829 pChild = pChild->mpWindowImpl->mpNext; 6830 } 6831 } 6832 6833 // ----------------------------------------------------------------------- 6834 6835 bool Window::IsCallHandlersOnInputDisabled() const 6836 { 6837 return mpWindowImpl->mbCallHandlersDuringInputDisabled ? true : false; 6838 } 6839 6840 // ----------------------------------------------------------------------- 6841 6842 void Window::EnableInput( sal_Bool bEnable, sal_Bool bChild ) 6843 { 6844 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6845 6846 sal_Bool bNotify = (bEnable != mpWindowImpl->mbInputDisabled); 6847 if ( mpWindowImpl->mpBorderWindow ) 6848 { 6849 mpWindowImpl->mpBorderWindow->EnableInput( bEnable, sal_False ); 6850 if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) && 6851 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow ) 6852 ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->EnableInput( bEnable, sal_True ); 6853 } 6854 6855 if ( (! bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled) || 6856 ( bEnable && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled) ) 6857 { 6858 // Wenn ein Fenster disablte wird, wird automatisch der 6859 // Tracking-Modus beendet oder der Capture geklaut 6860 if ( !bEnable ) 6861 { 6862 if ( IsTracking() ) 6863 EndTracking( ENDTRACK_CANCEL ); 6864 if ( IsMouseCaptured() ) 6865 ReleaseMouse(); 6866 } 6867 6868 if ( mpWindowImpl->mbInputDisabled != !bEnable ) 6869 { 6870 mpWindowImpl->mbInputDisabled = !bEnable; 6871 if ( mpWindowImpl->mpSysObj ) 6872 mpWindowImpl->mpSysObj->Enable( !mpWindowImpl->mbDisabled && bEnable ); 6873 // if ( mpWindowImpl->mbFrame ) 6874 // mpWindowImpl->mpFrame->Enable( !mpWindowImpl->mbDisabled && bEnable ); 6875 } 6876 } 6877 6878 // #i56102# restore app focus win in case the 6879 // window was disabled when the frame focus changed 6880 ImplSVData* pSVData = ImplGetSVData(); 6881 if( bEnable && 6882 pSVData->maWinData.mpFocusWin == NULL && 6883 mpWindowImpl->mpFrameData->mbHasFocus && 6884 mpWindowImpl->mpFrameData->mpFocusWin == this ) 6885 pSVData->maWinData.mpFocusWin = this; 6886 6887 if ( bChild || mpWindowImpl->mbChildNotify ) 6888 { 6889 Window* pChild = mpWindowImpl->mpFirstChild; 6890 while ( pChild ) 6891 { 6892 pChild->EnableInput( bEnable, bChild ); 6893 pChild = pChild->mpWindowImpl->mpNext; 6894 } 6895 } 6896 6897 if ( IsReallyVisible() ) 6898 ImplGenerateMouseMove(); 6899 6900 // #104827# notify parent 6901 if ( bNotify ) 6902 { 6903 NotifyEvent aNEvt( bEnable ? EVENT_INPUTENABLE : EVENT_INPUTDISABLE, this ); 6904 Notify( aNEvt ); 6905 } 6906 } 6907 6908 // ----------------------------------------------------------------------- 6909 6910 void Window::EnableInput( sal_Bool bEnable, sal_Bool bChild, sal_Bool bSysWin, 6911 const Window* pExcludeWindow ) 6912 { 6913 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6914 6915 EnableInput( bEnable, bChild ); 6916 if ( bSysWin ) 6917 { 6918 // pExculeWindow is the first Overlap-Frame --> if this 6919 // shouldn't be the case, than this must be changed in dialog.cxx 6920 if( pExcludeWindow ) 6921 pExcludeWindow = pExcludeWindow->ImplGetFirstOverlapWindow(); 6922 Window* pSysWin = mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mpFirstOverlap; 6923 while ( pSysWin ) 6924 { 6925 // Is Window in the path from this window 6926 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pSysWin, sal_True ) ) 6927 { 6928 // Is Window not in the exclude window path or not the 6929 // exclude window, than change the status 6930 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pSysWin, sal_True ) ) 6931 pSysWin->EnableInput( bEnable, bChild ); 6932 } 6933 pSysWin = pSysWin->mpWindowImpl->mpNextOverlap; 6934 } 6935 6936 // enable/disable floating system windows as well 6937 Window* pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame; 6938 while ( pFrameWin ) 6939 { 6940 if( pFrameWin->ImplIsFloatingWindow() ) 6941 { 6942 // Is Window in the path from this window 6943 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( pFrameWin, sal_True ) ) 6944 { 6945 // Is Window not in the exclude window path or not the 6946 // exclude window, than change the status 6947 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( pFrameWin, sal_True ) ) 6948 pFrameWin->EnableInput( bEnable, bChild ); 6949 } 6950 } 6951 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame; 6952 } 6953 6954 // the same for ownerdraw floating windows 6955 if( mpWindowImpl->mbFrame ) 6956 { 6957 ::std::vector< Window* >& rList = mpWindowImpl->mpFrameData->maOwnerDrawList; 6958 ::std::vector< Window* >::iterator p = rList.begin(); 6959 while( p != rList.end() ) 6960 { 6961 // Is Window in the path from this window 6962 if ( ImplGetFirstOverlapWindow()->ImplIsWindowOrChild( (*p), sal_True ) ) 6963 { 6964 // Is Window not in the exclude window path or not the 6965 // exclude window, than change the status 6966 if ( !pExcludeWindow || !pExcludeWindow->ImplIsWindowOrChild( (*p), sal_True ) ) 6967 (*p)->EnableInput( bEnable, bChild ); 6968 } 6969 p++; 6970 } 6971 } 6972 } 6973 } 6974 6975 // ----------------------------------------------------------------------- 6976 6977 void Window::AlwaysEnableInput( sal_Bool bAlways, sal_Bool bChild ) 6978 { 6979 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 6980 6981 if ( mpWindowImpl->mpBorderWindow ) 6982 mpWindowImpl->mpBorderWindow->AlwaysEnableInput( bAlways, sal_False ); 6983 6984 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputEnabled ) 6985 { 6986 mpWindowImpl->meAlwaysInputMode = AlwaysInputEnabled; 6987 6988 if ( bAlways ) 6989 EnableInput( sal_True, sal_False ); 6990 } 6991 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled ) 6992 { 6993 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone; 6994 } 6995 6996 if ( bChild || mpWindowImpl->mbChildNotify ) 6997 { 6998 Window* pChild = mpWindowImpl->mpFirstChild; 6999 while ( pChild ) 7000 { 7001 pChild->AlwaysEnableInput( bAlways, bChild ); 7002 pChild = pChild->mpWindowImpl->mpNext; 7003 } 7004 } 7005 } 7006 7007 // ----------------------------------------------------------------------- 7008 7009 void Window::AlwaysDisableInput( sal_Bool bAlways, sal_Bool bChild ) 7010 { 7011 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7012 7013 if ( mpWindowImpl->mpBorderWindow ) 7014 mpWindowImpl->mpBorderWindow->AlwaysDisableInput( bAlways, sal_False ); 7015 7016 if( bAlways && mpWindowImpl->meAlwaysInputMode != AlwaysInputDisabled ) 7017 { 7018 mpWindowImpl->meAlwaysInputMode = AlwaysInputDisabled; 7019 7020 if ( bAlways ) 7021 EnableInput( sal_False, sal_False ); 7022 } 7023 else if( ! bAlways && mpWindowImpl->meAlwaysInputMode == AlwaysInputDisabled ) 7024 { 7025 mpWindowImpl->meAlwaysInputMode = AlwaysInputNone; 7026 } 7027 7028 if ( bChild || mpWindowImpl->mbChildNotify ) 7029 { 7030 Window* pChild = mpWindowImpl->mpFirstChild; 7031 while ( pChild ) 7032 { 7033 pChild->AlwaysDisableInput( bAlways, bChild ); 7034 pChild = pChild->mpWindowImpl->mpNext; 7035 } 7036 } 7037 } 7038 7039 // ----------------------------------------------------------------------- 7040 7041 void Window::SetActivateMode( sal_uInt16 nMode ) 7042 { 7043 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7044 7045 if ( mpWindowImpl->mpBorderWindow ) 7046 mpWindowImpl->mpBorderWindow->SetActivateMode( nMode ); 7047 7048 if ( mpWindowImpl->mnActivateMode != nMode ) 7049 { 7050 mpWindowImpl->mnActivateMode = nMode; 7051 7052 // Evtl. ein Decativate/Activate ausloesen 7053 if ( mpWindowImpl->mnActivateMode ) 7054 { 7055 if ( (mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW)) && 7056 !HasChildPathFocus( sal_True ) ) 7057 { 7058 mpWindowImpl->mbActive = sal_False; 7059 Deactivate(); 7060 } 7061 } 7062 else 7063 { 7064 if ( !mpWindowImpl->mbActive || (GetType() == WINDOW_BORDERWINDOW) ) 7065 { 7066 mpWindowImpl->mbActive = sal_True; 7067 Activate(); 7068 } 7069 } 7070 } 7071 } 7072 7073 // ----------------------------------------------------------------------- 7074 7075 void Window::ToTop( sal_uInt16 nFlags ) 7076 { 7077 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7078 7079 ImplStartToTop( nFlags ); 7080 ImplFocusToTop( nFlags, IsReallyVisible() ); 7081 } 7082 7083 // ----------------------------------------------------------------------- 7084 7085 void Window::SetZOrder( Window* pRefWindow, sal_uInt16 nFlags ) 7086 { 7087 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7088 7089 if ( mpWindowImpl->mpBorderWindow ) 7090 { 7091 mpWindowImpl->mpBorderWindow->SetZOrder( pRefWindow, nFlags ); 7092 return; 7093 } 7094 7095 if ( nFlags & WINDOW_ZORDER_FIRST ) 7096 { 7097 if ( ImplIsOverlapWindow() ) 7098 pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; 7099 else 7100 pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild; 7101 nFlags |= WINDOW_ZORDER_BEFOR; 7102 } 7103 else if ( nFlags & WINDOW_ZORDER_LAST ) 7104 { 7105 if ( ImplIsOverlapWindow() ) 7106 pRefWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap; 7107 else 7108 pRefWindow = mpWindowImpl->mpParent->mpWindowImpl->mpLastChild; 7109 nFlags |= WINDOW_ZORDER_BEHIND; 7110 } 7111 7112 while ( pRefWindow->mpWindowImpl->mpBorderWindow ) 7113 pRefWindow = pRefWindow->mpWindowImpl->mpBorderWindow; 7114 if ( (pRefWindow == this) || mpWindowImpl->mbFrame ) 7115 return; 7116 7117 DBG_ASSERT( pRefWindow->mpWindowImpl->mpParent == mpWindowImpl->mpParent, "Window::SetZOrder() - pRefWindow has other parent" ); 7118 if ( nFlags & WINDOW_ZORDER_BEFOR ) 7119 { 7120 if ( pRefWindow->mpWindowImpl->mpPrev == this ) 7121 return; 7122 7123 if ( ImplIsOverlapWindow() ) 7124 { 7125 if ( mpWindowImpl->mpPrev ) 7126 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; 7127 else 7128 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; 7129 if ( mpWindowImpl->mpNext ) 7130 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; 7131 else 7132 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; 7133 if ( !pRefWindow->mpWindowImpl->mpPrev ) 7134 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = this; 7135 } 7136 else 7137 { 7138 if ( mpWindowImpl->mpPrev ) 7139 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; 7140 else 7141 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; 7142 if ( mpWindowImpl->mpNext ) 7143 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; 7144 else 7145 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; 7146 if ( !pRefWindow->mpWindowImpl->mpPrev ) 7147 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = this; 7148 } 7149 7150 mpWindowImpl->mpPrev = pRefWindow->mpWindowImpl->mpPrev; 7151 mpWindowImpl->mpNext = pRefWindow; 7152 if ( mpWindowImpl->mpPrev ) 7153 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; 7154 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; 7155 } 7156 else if ( nFlags & WINDOW_ZORDER_BEHIND ) 7157 { 7158 if ( pRefWindow->mpWindowImpl->mpNext == this ) 7159 return; 7160 7161 if ( ImplIsOverlapWindow() ) 7162 { 7163 if ( mpWindowImpl->mpPrev ) 7164 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; 7165 else 7166 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap = mpWindowImpl->mpNext; 7167 if ( mpWindowImpl->mpNext ) 7168 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; 7169 else 7170 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = mpWindowImpl->mpPrev; 7171 if ( !pRefWindow->mpWindowImpl->mpNext ) 7172 mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpLastOverlap = this; 7173 } 7174 else 7175 { 7176 if ( mpWindowImpl->mpPrev ) 7177 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = mpWindowImpl->mpNext; 7178 else 7179 mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild = mpWindowImpl->mpNext; 7180 if ( mpWindowImpl->mpNext ) 7181 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = mpWindowImpl->mpPrev; 7182 else 7183 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = mpWindowImpl->mpPrev; 7184 if ( !pRefWindow->mpWindowImpl->mpNext ) 7185 mpWindowImpl->mpParent->mpWindowImpl->mpLastChild = this; 7186 } 7187 7188 mpWindowImpl->mpPrev = pRefWindow; 7189 mpWindowImpl->mpNext = pRefWindow->mpWindowImpl->mpNext; 7190 if ( mpWindowImpl->mpNext ) 7191 mpWindowImpl->mpNext->mpWindowImpl->mpPrev = this; 7192 mpWindowImpl->mpPrev->mpWindowImpl->mpNext = this; 7193 } 7194 7195 if ( IsReallyVisible() ) 7196 { 7197 // Hintergrund-Sicherung zuruecksetzen 7198 if ( mpWindowImpl->mpFrameData->mpFirstBackWin ) 7199 ImplInvalidateAllOverlapBackgrounds(); 7200 7201 if ( mpWindowImpl->mbInitWinClipRegion || !mpWindowImpl->maWinClipRegion.IsEmpty() ) 7202 { 7203 sal_Bool bInitWinClipRegion = mpWindowImpl->mbInitWinClipRegion; 7204 ImplSetClipFlag(); 7205 7206 // Wenn ClipRegion noch nicht initalisiert wurde, dann 7207 // gehen wir davon aus, das das Fenster noch nicht 7208 // ausgegeben wurde und loesen somit auch keine 7209 // Invalidates aus. Dies ist eine Optimierung fuer 7210 // HTML-Dokumenten mit vielen Controls. Wenn es mal 7211 // Probleme mit dieser Abfrage gibt, sollte man ein 7212 // Flag einfuehren, ob das Fenster nach Show schon 7213 // einmal ausgegeben wurde. 7214 if ( !bInitWinClipRegion ) 7215 { 7216 // Alle nebeneinanderliegen Fenster invalidieren 7217 // Noch nicht komplett implementiert !!! 7218 Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 7219 Window* pWindow = NULL; 7220 if ( ImplIsOverlapWindow() ) 7221 { 7222 if ( mpWindowImpl->mpOverlapWindow ) 7223 pWindow = mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap; 7224 } 7225 else 7226 pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild; 7227 // Alle Fenster, die vor uns liegen und von uns verdeckt wurden, 7228 // invalidieren 7229 while ( pWindow ) 7230 { 7231 if ( pWindow == this ) 7232 break; 7233 Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), 7234 Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); 7235 if ( aWinRect.IsOver( aCompRect ) ) 7236 pWindow->Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); 7237 pWindow = pWindow->mpWindowImpl->mpNext; 7238 } 7239 // Wenn uns ein Fenster welches im Hinterund liegt verdeckt hat, 7240 // dann muessen wir uns neu ausgeben 7241 while ( pWindow ) 7242 { 7243 if ( pWindow != this ) 7244 { 7245 Rectangle aCompRect( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ), 7246 Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) ); 7247 if ( aWinRect.IsOver( aCompRect ) ) 7248 { 7249 Invalidate( INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT ); 7250 break; 7251 } 7252 } 7253 pWindow = pWindow->mpWindowImpl->mpNext; 7254 } 7255 } 7256 } 7257 } 7258 } 7259 7260 // ----------------------------------------------------------------------- 7261 7262 void Window::EnableAlwaysOnTop( sal_Bool bEnable ) 7263 { 7264 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7265 7266 mpWindowImpl->mbAlwaysOnTop = bEnable; 7267 7268 if ( mpWindowImpl->mpBorderWindow ) 7269 mpWindowImpl->mpBorderWindow->EnableAlwaysOnTop( bEnable ); 7270 else if ( bEnable && IsReallyVisible() ) 7271 ToTop(); 7272 7273 if ( mpWindowImpl->mbFrame ) 7274 mpWindowImpl->mpFrame->SetAlwaysOnTop( bEnable ); 7275 } 7276 7277 // ----------------------------------------------------------------------- 7278 7279 void Window::SetPosSizePixel( long nX, long nY, 7280 long nWidth, long nHeight, sal_uInt16 nFlags ) 7281 { 7282 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7283 7284 sal_Bool bHasValidSize = !mpWindowImpl->mbDefSize; 7285 7286 if ( nFlags & WINDOW_POSSIZE_POS ) 7287 mpWindowImpl->mbDefPos = sal_False; 7288 if ( nFlags & WINDOW_POSSIZE_SIZE ) 7289 mpWindowImpl->mbDefSize = sal_False; 7290 7291 // Oberstes BorderWindow ist das Window, welches positioniert werden soll 7292 Window* pWindow = this; 7293 while ( pWindow->mpWindowImpl->mpBorderWindow ) 7294 pWindow = pWindow->mpWindowImpl->mpBorderWindow; 7295 7296 if ( pWindow->mpWindowImpl->mbFrame ) 7297 { 7298 // Note: if we're positioning a frame, the coordinates are interpreted 7299 // as being the top-left corner of the window's client area and NOT 7300 // as the position of the border ! (due to limitations of several UNIX window managers) 7301 long nOldWidth = pWindow->mnOutWidth; 7302 7303 if ( !(nFlags & WINDOW_POSSIZE_WIDTH) ) 7304 nWidth = pWindow->mnOutWidth; 7305 if ( !(nFlags & WINDOW_POSSIZE_HEIGHT) ) 7306 nHeight = pWindow->mnOutHeight; 7307 7308 7309 sal_uInt16 nSysFlags=0; 7310 if( nFlags & WINDOW_POSSIZE_WIDTH ) 7311 nSysFlags |= SAL_FRAME_POSSIZE_WIDTH; 7312 if( nFlags & WINDOW_POSSIZE_HEIGHT ) 7313 nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT; 7314 if( nFlags & WINDOW_POSSIZE_X ) 7315 { 7316 nSysFlags |= SAL_FRAME_POSSIZE_X; 7317 if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) ) 7318 { 7319 Window* pParent = pWindow->GetParent(); 7320 nX += pParent->mnOutOffX; 7321 } 7322 if( GetParent() && GetParent()->ImplIsAntiparallel() ) 7323 { 7324 // --- RTL --- (re-mirror at parent window) 7325 Rectangle aRect( Point ( nX, nY ), Size( nWidth, nHeight ) ); 7326 GetParent()->ImplReMirror( aRect ); 7327 nX = aRect.nLeft; 7328 } 7329 } 7330 if( !(nFlags & WINDOW_POSSIZE_X) && bHasValidSize && pWindow->mpWindowImpl->mpFrame->maGeometry.nWidth ) 7331 { 7332 // --- RTL --- make sure the old right aligned position is not changed 7333 // system windows will always grow to the right 7334 if( pWindow->GetParent() && pWindow->GetParent()->ImplHasMirroredGraphics() ) 7335 { 7336 long myWidth = nOldWidth; 7337 if( !myWidth ) 7338 myWidth = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth; 7339 if( !myWidth ) 7340 myWidth = nWidth; 7341 nFlags |= WINDOW_POSSIZE_X; 7342 nSysFlags |= SAL_FRAME_POSSIZE_X; 7343 nX = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - 7344 mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration; 7345 nX = pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nLeftDecoration + 7346 pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nWidth - myWidth - 1 - mpWindowImpl->mpFrame->GetUnmirroredGeometry().nX; 7347 if(!(nFlags & WINDOW_POSSIZE_Y)) 7348 { 7349 nFlags |= WINDOW_POSSIZE_Y; 7350 nSysFlags |= SAL_FRAME_POSSIZE_Y; 7351 nY = mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY - pWindow->GetParent()->mpWindowImpl->mpFrame->GetUnmirroredGeometry().nY - 7352 mpWindowImpl->mpFrame->GetUnmirroredGeometry().nTopDecoration; 7353 } 7354 } 7355 } 7356 if( nFlags & WINDOW_POSSIZE_Y ) 7357 { 7358 nSysFlags |= SAL_FRAME_POSSIZE_Y; 7359 if( pWindow->GetParent() && (pWindow->GetStyle() & WB_SYSTEMCHILDWINDOW) ) 7360 { 7361 Window* pParent = pWindow->GetParent(); 7362 nY += pParent->mnOutOffY; 7363 } 7364 } 7365 7366 if( nSysFlags & (SAL_FRAME_POSSIZE_WIDTH|SAL_FRAME_POSSIZE_HEIGHT) ) 7367 { 7368 // check for min/max client size and adjust size accordingly 7369 // otherwise it may happen that the resize event is ignored, i.e. the old size remains 7370 // unchanged but ImplHandleResize() is called with the wrong size 7371 SystemWindow *pSystemWindow = dynamic_cast< SystemWindow* >( pWindow ); 7372 if( pSystemWindow ) 7373 { 7374 Size aMinSize = pSystemWindow->GetMinOutputSizePixel(); 7375 Size aMaxSize = pSystemWindow->GetMaxOutputSizePixel(); 7376 if( nWidth < aMinSize.Width() ) 7377 nWidth = aMinSize.Width(); 7378 if( nHeight < aMinSize.Height() ) 7379 nHeight = aMinSize.Height(); 7380 7381 if( nWidth > aMaxSize.Width() ) 7382 nWidth = aMaxSize.Width(); 7383 if( nHeight > aMaxSize.Height() ) 7384 nHeight = aMaxSize.Height(); 7385 } 7386 } 7387 7388 pWindow->mpWindowImpl->mpFrame->SetPosSize( nX, nY, nWidth, nHeight, nSysFlags ); 7389 7390 // Resize should be called directly. If we havn't 7391 // set the correct size, we get a second resize from 7392 // the system with the correct size. This can be happend 7393 // if the size is to small or to large. 7394 ImplHandleResize( pWindow, nWidth, nHeight ); 7395 } 7396 else 7397 { 7398 pWindow->ImplPosSizeWindow( nX, nY, nWidth, nHeight, nFlags ); 7399 if ( IsReallyVisible() ) 7400 ImplGenerateMouseMove(); 7401 } 7402 } 7403 7404 // ----------------------------------------------------------------------- 7405 7406 Point Window::GetPosPixel() const 7407 { 7408 return mpWindowImpl->maPos; 7409 } 7410 7411 // ----------------------------------------------------------------------- 7412 7413 Rectangle Window::GetDesktopRectPixel() const 7414 { 7415 Rectangle rRect; 7416 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrame->GetWorkArea( rRect ); 7417 return rRect; 7418 } 7419 7420 // ----------------------------------------------------------------------- 7421 7422 Point Window::OutputToScreenPixel( const Point& rPos ) const 7423 { 7424 // relative to top level parent 7425 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY ); 7426 } 7427 7428 // ----------------------------------------------------------------------- 7429 7430 Point Window::ScreenToOutputPixel( const Point& rPos ) const 7431 { 7432 // relative to top level parent 7433 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY ); 7434 } 7435 7436 // ----------------------------------------------------------------------- 7437 7438 long Window::ImplGetUnmirroredOutOffX() 7439 { 7440 // revert mnOutOffX changes that were potentially made in ImplPosSizeWindow 7441 long offx = mnOutOffX; 7442 if( ImplHasMirroredGraphics() ) 7443 { 7444 if( mpWindowImpl->mpParent && !mpWindowImpl->mpParent->mpWindowImpl->mbFrame && mpWindowImpl->mpParent->ImplIsAntiparallel() ) 7445 { 7446 if ( !ImplIsOverlapWindow() ) 7447 offx -= mpWindowImpl->mpParent->mnOutOffX; 7448 7449 offx = mpWindowImpl->mpParent->mnOutWidth - mnOutWidth - offx; 7450 7451 if ( !ImplIsOverlapWindow() ) 7452 offx += mpWindowImpl->mpParent->mnOutOffX; 7453 7454 } 7455 } 7456 return offx; 7457 } 7458 7459 // normalized screen pixel are independent of mirroring 7460 Point Window::OutputToNormalizedScreenPixel( const Point& rPos ) const 7461 { 7462 // relative to top level parent 7463 long offx = ((Window*) this)->ImplGetUnmirroredOutOffX(); 7464 return Point( rPos.X()+offx, rPos.Y()+mnOutOffY ); 7465 } 7466 7467 Point Window::NormalizedScreenToOutputPixel( const Point& rPos ) const 7468 { 7469 // relative to top level parent 7470 long offx = ((Window*) this)->ImplGetUnmirroredOutOffX(); 7471 return Point( rPos.X()-offx, rPos.Y()-mnOutOffY ); 7472 } 7473 7474 // ----------------------------------------------------------------------- 7475 7476 Point Window::OutputToAbsoluteScreenPixel( const Point& rPos ) const 7477 { 7478 // relative to the screen 7479 Point p = OutputToScreenPixel( rPos ); 7480 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry(); 7481 p.X() += g.nX; 7482 p.Y() += g.nY; 7483 return p; 7484 } 7485 7486 // ----------------------------------------------------------------------- 7487 7488 Point Window::AbsoluteScreenToOutputPixel( const Point& rPos ) const 7489 { 7490 // relative to the screen 7491 Point p = ScreenToOutputPixel( rPos ); 7492 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry(); 7493 p.X() -= g.nX; 7494 p.Y() -= g.nY; 7495 return p; 7496 } 7497 7498 // ----------------------------------------------------------------------- 7499 7500 Rectangle Window::ImplOutputToUnmirroredAbsoluteScreenPixel( const Rectangle &rRect ) const 7501 { 7502 // this method creates unmirrored screen coordinates to be compared with the desktop 7503 // and is used for positioning of RTL popup windows correctly on the screen 7504 SalFrameGeometry g = mpWindowImpl->mpFrame->GetUnmirroredGeometry(); 7505 7506 Point p1 = OutputToScreenPixel( rRect.TopRight() ); 7507 p1.X() = g.nX+g.nWidth-p1.X(); 7508 p1.Y() += g.nY; 7509 7510 Point p2 = OutputToScreenPixel( rRect.BottomLeft() ); 7511 p2.X() = g.nX+g.nWidth-p2.X(); 7512 p2.Y() += g.nY; 7513 7514 return Rectangle( p1, p2 ); 7515 } 7516 7517 7518 // ----------------------------------------------------------------------- 7519 7520 Rectangle Window::GetWindowExtentsRelative( Window *pRelativeWindow ) const 7521 { 7522 // with decoration 7523 return ImplGetWindowExtentsRelative( pRelativeWindow, sal_False ); 7524 } 7525 7526 Rectangle Window::GetClientWindowExtentsRelative( Window *pRelativeWindow ) const 7527 { 7528 // without decoration 7529 return ImplGetWindowExtentsRelative( pRelativeWindow, sal_True ); 7530 } 7531 7532 // ----------------------------------------------------------------------- 7533 7534 Rectangle Window::ImplGetWindowExtentsRelative( Window *pRelativeWindow, sal_Bool bClientOnly ) const 7535 { 7536 SalFrameGeometry g = mpWindowImpl->mpFrame->GetGeometry(); 7537 // make sure we use the extent of our border window, 7538 // otherwise we miss a few pixels 7539 const Window *pWin = (!bClientOnly && mpWindowImpl->mpBorderWindow) ? mpWindowImpl->mpBorderWindow : this; 7540 7541 Point aPos( pWin->OutputToScreenPixel( Point(0,0) ) ); 7542 aPos.X() += g.nX; 7543 aPos.Y() += g.nY; 7544 Size aSize ( pWin->GetSizePixel() ); 7545 // #104088# do not add decoration to the workwindow to be compatible to java accessibility api 7546 if( !bClientOnly && (mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame && GetType() != WINDOW_WORKWINDOW)) ) 7547 { 7548 aPos.X() -= g.nLeftDecoration; 7549 aPos.Y() -= g.nTopDecoration; 7550 aSize.Width() += g.nLeftDecoration + g.nRightDecoration; 7551 aSize.Height() += g.nTopDecoration + g.nBottomDecoration; 7552 } 7553 if( pRelativeWindow ) 7554 { 7555 // #106399# express coordinates relative to borderwindow 7556 Window *pRelWin = (!bClientOnly && pRelativeWindow->mpWindowImpl->mpBorderWindow) ? pRelativeWindow->mpWindowImpl->mpBorderWindow : pRelativeWindow; 7557 aPos = pRelWin->AbsoluteScreenToOutputPixel( aPos ); 7558 } 7559 return Rectangle( aPos, aSize ); 7560 } 7561 7562 // ----------------------------------------------------------------------- 7563 7564 void Window::Scroll( long nHorzScroll, long nVertScroll, sal_uInt16 nFlags ) 7565 { 7566 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7567 7568 ImplScroll( Rectangle( Point( mnOutOffX, mnOutOffY ), 7569 Size( mnOutWidth, mnOutHeight ) ), 7570 nHorzScroll, nVertScroll, nFlags & ~SCROLL_CLIP ); 7571 } 7572 7573 // ----------------------------------------------------------------------- 7574 7575 void Window::Scroll( long nHorzScroll, long nVertScroll, 7576 const Rectangle& rRect, sal_uInt16 nFlags ) 7577 { 7578 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7579 7580 Rectangle aRect = ImplLogicToDevicePixel( rRect ); 7581 aRect.Intersection( Rectangle( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ) ); 7582 if ( !aRect.IsEmpty() ) 7583 ImplScroll( aRect, nHorzScroll, nVertScroll, nFlags ); 7584 } 7585 7586 // ----------------------------------------------------------------------- 7587 7588 void Window::Invalidate( sal_uInt16 nFlags ) 7589 { 7590 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7591 7592 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) 7593 return; 7594 7595 ImplInvalidate( NULL, nFlags ); 7596 } 7597 7598 // ----------------------------------------------------------------------- 7599 7600 void Window::Invalidate( const Rectangle& rRect, sal_uInt16 nFlags ) 7601 { 7602 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7603 7604 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) 7605 return; 7606 7607 Rectangle aRect = ImplLogicToDevicePixel( rRect ); 7608 if ( !aRect.IsEmpty() ) 7609 { 7610 Region aRegion( aRect ); 7611 ImplInvalidate( &aRegion, nFlags ); 7612 } 7613 } 7614 7615 // ----------------------------------------------------------------------- 7616 7617 void Window::Invalidate( const Region& rRegion, sal_uInt16 nFlags ) 7618 { 7619 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7620 7621 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) 7622 return; 7623 7624 if ( rRegion.IsNull() ) 7625 ImplInvalidate( NULL, nFlags ); 7626 else 7627 { 7628 Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) ); 7629 if ( !aRegion.IsEmpty() ) 7630 ImplInvalidate( &aRegion, nFlags ); 7631 } 7632 } 7633 7634 // ----------------------------------------------------------------------- 7635 7636 void Window::Validate( sal_uInt16 nFlags ) 7637 { 7638 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7639 7640 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) 7641 return; 7642 7643 ImplValidate( NULL, nFlags ); 7644 } 7645 7646 // ----------------------------------------------------------------------- 7647 7648 void Window::Validate( const Rectangle& rRect, sal_uInt16 nFlags ) 7649 { 7650 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7651 7652 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) 7653 return; 7654 7655 Rectangle aRect = ImplLogicToDevicePixel( rRect ); 7656 if ( !aRect.IsEmpty() ) 7657 { 7658 Region aRegion( aRect ); 7659 ImplValidate( &aRegion, nFlags ); 7660 } 7661 } 7662 7663 // ----------------------------------------------------------------------- 7664 7665 void Window::Validate( const Region& rRegion, sal_uInt16 nFlags ) 7666 { 7667 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7668 7669 if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight ) 7670 return; 7671 7672 if ( rRegion.IsNull() ) 7673 ImplValidate( NULL, nFlags ); 7674 else 7675 { 7676 Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) ); 7677 if ( !aRegion.IsEmpty() ) 7678 ImplValidate( &aRegion, nFlags ); 7679 } 7680 } 7681 7682 // ----------------------------------------------------------------------- 7683 7684 sal_Bool Window::HasPaintEvent() const 7685 { 7686 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7687 7688 if ( !mpWindowImpl->mbReallyVisible ) 7689 return sal_False; 7690 7691 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame ) 7692 return sal_True; 7693 7694 if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT ) 7695 return sal_True; 7696 7697 if ( !ImplIsOverlapWindow() ) 7698 { 7699 const Window* pTempWindow = this; 7700 do 7701 { 7702 pTempWindow = pTempWindow->ImplGetParent(); 7703 if ( pTempWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINTCHILDS | IMPL_PAINT_PAINTALLCHILDS) ) 7704 return sal_True; 7705 } 7706 while ( !pTempWindow->ImplIsOverlapWindow() ); 7707 } 7708 7709 return sal_False; 7710 } 7711 7712 // ----------------------------------------------------------------------- 7713 7714 void Window::Update() 7715 { 7716 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7717 7718 if ( mpWindowImpl->mpBorderWindow ) 7719 { 7720 mpWindowImpl->mpBorderWindow->Update(); 7721 return; 7722 } 7723 7724 if ( !mpWindowImpl->mbReallyVisible ) 7725 return; 7726 7727 sal_Bool bFlush = sal_False; 7728 if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame ) 7729 { 7730 Point aPoint( 0, 0 ); 7731 Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) ); 7732 ImplInvalidateOverlapFrameRegion( aRegion ); 7733 if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) 7734 bFlush = sal_True; 7735 } 7736 7737 // Zuerst muessen wir alle Fenster ueberspringen, die Paint-Transparent 7738 // sind 7739 Window* pUpdateWindow = this; 7740 Window* pWindow = pUpdateWindow; 7741 while ( !pWindow->ImplIsOverlapWindow() ) 7742 { 7743 if ( !pWindow->mpWindowImpl->mbPaintTransparent ) 7744 { 7745 pUpdateWindow = pWindow; 7746 break; 7747 } 7748 pWindow = pWindow->ImplGetParent(); 7749 } 7750 // Ein Update wirkt immer auf das Window, wo PAINTALLCHILDS gesetzt 7751 // ist, damit nicht zuviel gemalt wird 7752 pWindow = pUpdateWindow; 7753 do 7754 { 7755 if ( pWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDS ) 7756 pUpdateWindow = pWindow; 7757 if ( pWindow->ImplIsOverlapWindow() ) 7758 break; 7759 pWindow = pWindow->ImplGetParent(); 7760 } 7761 while ( pWindow ); 7762 7763 // Wenn es etwas zu malen gibt, dann ein Paint ausloesen 7764 if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDS) ) 7765 { 7766 // und fuer alle ueber uns stehende System-Fenster auch ein Update 7767 // ausloesen, damit nicht die ganze Zeit luecken stehen bleiben 7768 Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpWindowImpl->mpFirstOverlap; 7769 while ( pUpdateOverlapWindow ) 7770 { 7771 pUpdateOverlapWindow->Update(); 7772 pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext; 7773 } 7774 7775 pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mpWindowImpl->mnPaintFlags ); 7776 } 7777 7778 if ( bFlush ) 7779 Flush(); 7780 } 7781 7782 // ----------------------------------------------------------------------- 7783 7784 void Window::Flush() 7785 { 7786 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7787 7788 const Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) ); 7789 mpWindowImpl->mpFrame->Flush( aWinRect ); 7790 } 7791 7792 // ----------------------------------------------------------------------- 7793 7794 void Window::Sync() 7795 { 7796 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7797 7798 mpWindowImpl->mpFrame->Sync(); 7799 } 7800 7801 // ----------------------------------------------------------------------- 7802 7803 void Window::SetUpdateMode( sal_Bool bUpdate ) 7804 { 7805 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7806 7807 mpWindowImpl->mbNoUpdate = !bUpdate; 7808 StateChanged( STATE_CHANGE_UPDATEMODE ); 7809 } 7810 7811 // ----------------------------------------------------------------------- 7812 7813 void Window::GrabFocus() 7814 { 7815 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7816 7817 ImplGrabFocus( 0 ); 7818 } 7819 7820 // ----------------------------------------------------------------------- 7821 7822 sal_Bool Window::HasFocus() const 7823 { 7824 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7825 7826 // #107575# the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow() 7827 // task was shifted to 6.y, so its commented out 7828 /* 7829 Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat; 7830 if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() ) 7831 pFocusWin = pFocusWin->GetPreferredKeyInputWindow(); 7832 else 7833 pFocusWin = ImplGetSVData()->maWinData.mpFocusWin; 7834 7835 return (this == pFocusWin); 7836 */ 7837 7838 return (this == ImplGetSVData()->maWinData.mpFocusWin); 7839 } 7840 7841 // ----------------------------------------------------------------------- 7842 7843 void Window::GrabFocusToDocument() 7844 { 7845 Window *pWin = this; 7846 while( pWin ) 7847 { 7848 if( !pWin->GetParent() ) 7849 { 7850 pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus(); 7851 return; 7852 } 7853 pWin = pWin->GetParent(); 7854 } 7855 } 7856 7857 void Window::SetFakeFocus( bool bFocus ) 7858 { 7859 ImplGetWindowImpl()->mbFakeFocusSet = bFocus; 7860 } 7861 7862 // ----------------------------------------------------------------------- 7863 7864 sal_Bool Window::HasChildPathFocus( sal_Bool bSystemWindow ) const 7865 { 7866 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7867 7868 // #107575#, the first floating window always has the keyboard focus, see also winproc.cxx: ImplGetKeyInputWindow() 7869 // task was shifted to 6.y, so its commented out 7870 /* 7871 Window* pFocusWin = ImplGetSVData()->maWinData.mpFirstFloat; 7872 if( pFocusWin && pFocusWin->mpWindowImpl->mbFloatWin && ((FloatingWindow *)pFocusWin)->GrabsFocus() ) 7873 pFocusWin = pFocusWin->GetPreferredKeyInputWindow(); 7874 else 7875 pFocusWin = ImplGetSVData()->maWinData.mpFocusWin; 7876 */ 7877 Window* pFocusWin = ImplGetSVData()->maWinData.mpFocusWin; 7878 if ( pFocusWin ) 7879 return ImplIsWindowOrChild( pFocusWin, bSystemWindow ); 7880 return sal_False; 7881 } 7882 7883 // ----------------------------------------------------------------------- 7884 7885 void Window::CaptureMouse() 7886 { 7887 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7888 7889 ImplSVData* pSVData = ImplGetSVData(); 7890 7891 // Tracking evt. beenden 7892 if ( pSVData->maWinData.mpTrackWin != this ) 7893 { 7894 if ( pSVData->maWinData.mpTrackWin ) 7895 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL ); 7896 } 7897 7898 if ( pSVData->maWinData.mpCaptureWin != this ) 7899 { 7900 pSVData->maWinData.mpCaptureWin = this; 7901 mpWindowImpl->mpFrame->CaptureMouse( sal_True ); 7902 } 7903 } 7904 7905 // ----------------------------------------------------------------------- 7906 7907 void Window::ReleaseMouse() 7908 { 7909 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7910 7911 ImplSVData* pSVData = ImplGetSVData(); 7912 7913 DBG_ASSERTWARNING( pSVData->maWinData.mpCaptureWin == this, 7914 "Window::ReleaseMouse(): window doesn't have the mouse capture" ); 7915 7916 if ( pSVData->maWinData.mpCaptureWin == this ) 7917 { 7918 pSVData->maWinData.mpCaptureWin = NULL; 7919 mpWindowImpl->mpFrame->CaptureMouse( sal_False ); 7920 ImplGenerateMouseMove(); 7921 } 7922 } 7923 7924 // ----------------------------------------------------------------------- 7925 7926 sal_Bool Window::IsMouseCaptured() const 7927 { 7928 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7929 7930 return (this == ImplGetSVData()->maWinData.mpCaptureWin); 7931 } 7932 7933 // ----------------------------------------------------------------------- 7934 7935 void Window::SetPointer( const Pointer& rPointer ) 7936 { 7937 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7938 7939 if ( mpWindowImpl->maPointer == rPointer ) 7940 return; 7941 7942 mpWindowImpl->maPointer = rPointer; 7943 7944 // Pointer evt. direkt umsetzen 7945 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) 7946 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() ); 7947 } 7948 7949 // ----------------------------------------------------------------------- 7950 7951 void Window::EnableChildPointerOverwrite( sal_Bool bOverwrite ) 7952 { 7953 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7954 7955 if ( mpWindowImpl->mbChildPtrOverwrite == bOverwrite ) 7956 return; 7957 7958 mpWindowImpl->mbChildPtrOverwrite = bOverwrite; 7959 7960 // Pointer evt. direkt umsetzen 7961 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) 7962 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() ); 7963 } 7964 7965 // ----------------------------------------------------------------------- 7966 7967 void Window::SetPointerPosPixel( const Point& rPos ) 7968 { 7969 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7970 7971 Point aPos = ImplOutputToFrame( rPos ); 7972 if( ImplHasMirroredGraphics() ) 7973 { 7974 if( !IsRTLEnabled() ) 7975 { 7976 // --- RTL --- (re-mirror mouse pos at this window) 7977 ImplReMirror( aPos ); 7978 } 7979 // mirroring is required here, SetPointerPos bypasses SalGraphics 7980 mpGraphics->mirror( aPos.X(), this ); 7981 } 7982 else if( ImplIsAntiparallel() ) 7983 { 7984 ImplReMirror( aPos ); 7985 } 7986 mpWindowImpl->mpFrame->SetPointerPos( aPos.X(), aPos.Y() ); 7987 } 7988 7989 // ----------------------------------------------------------------------- 7990 7991 Point Window::GetPointerPosPixel() 7992 { 7993 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 7994 7995 Point aPos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY ); 7996 if( ImplIsAntiparallel() ) 7997 { 7998 // --- RTL --- (re-mirror mouse pos at this window) 7999 ImplReMirror( aPos ); 8000 } 8001 return ImplFrameToOutput( aPos ); 8002 } 8003 8004 // ----------------------------------------------------------------------- 8005 8006 Point Window::GetLastPointerPosPixel() 8007 { 8008 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8009 8010 Point aPos( mpWindowImpl->mpFrameData->mnBeforeLastMouseX, mpWindowImpl->mpFrameData->mnBeforeLastMouseY ); 8011 if( ImplIsAntiparallel() ) 8012 { 8013 // --- RTL --- (re-mirror mouse pos at this window) 8014 ImplReMirror( aPos ); 8015 } 8016 return ImplFrameToOutput( aPos ); 8017 } 8018 8019 // ----------------------------------------------------------------------- 8020 8021 void Window::ShowPointer( sal_Bool bVisible ) 8022 { 8023 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8024 8025 if ( mpWindowImpl->mbNoPtrVisible != !bVisible ) 8026 { 8027 mpWindowImpl->mbNoPtrVisible = !bVisible; 8028 8029 // Pointer evt. direkt umsetzen 8030 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) 8031 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() ); 8032 } 8033 } 8034 8035 // ----------------------------------------------------------------------- 8036 8037 Window::PointerState Window::GetPointerState() 8038 { 8039 PointerState aState; 8040 aState.mnState = 0; 8041 8042 if (mpWindowImpl->mpFrame) 8043 { 8044 SalFrame::SalPointerState aSalPointerState; 8045 8046 aSalPointerState = mpWindowImpl->mpFrame->GetPointerState(); 8047 if( ImplIsAntiparallel() ) 8048 { 8049 // --- RTL --- (re-mirror mouse pos at this window) 8050 ImplReMirror( aSalPointerState.maPos ); 8051 } 8052 aState.maPos = ImplFrameToOutput( aSalPointerState.maPos ); 8053 aState.mnState = aSalPointerState.mnState; 8054 } 8055 return aState; 8056 } 8057 8058 // ----------------------------------------------------------------------- 8059 8060 sal_Bool Window::IsMouseOver() 8061 { 8062 return ImplGetWinData()->mbMouseOver; 8063 } 8064 8065 // ----------------------------------------------------------------------- 8066 8067 void Window::EnterWait() 8068 { 8069 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8070 8071 mpWindowImpl->mnWaitCount++; 8072 8073 if ( mpWindowImpl->mnWaitCount == 1 ) 8074 { 8075 // Pointer evt. direkt umsetzen 8076 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) 8077 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() ); 8078 } 8079 } 8080 8081 // ----------------------------------------------------------------------- 8082 8083 void Window::LeaveWait() 8084 { 8085 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8086 8087 if ( mpWindowImpl->mnWaitCount ) 8088 { 8089 mpWindowImpl->mnWaitCount--; 8090 8091 if ( !mpWindowImpl->mnWaitCount ) 8092 { 8093 // Pointer evt. direkt umsetzen 8094 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) 8095 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() ); 8096 } 8097 } 8098 } 8099 8100 // ----------------------------------------------------------------------- 8101 8102 void Window::SetCursor( Cursor* pCursor ) 8103 { 8104 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8105 8106 if ( mpWindowImpl->mpCursor != pCursor ) 8107 { 8108 if ( mpWindowImpl->mpCursor ) 8109 mpWindowImpl->mpCursor->ImplHide( true ); 8110 mpWindowImpl->mpCursor = pCursor; 8111 if ( pCursor ) 8112 pCursor->ImplShow(); 8113 } 8114 } 8115 8116 // ----------------------------------------------------------------------- 8117 8118 void Window::SetText( const XubString& rStr ) 8119 { 8120 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8121 8122 String oldTitle( mpWindowImpl->maText ); 8123 mpWindowImpl->maText = rStr; 8124 8125 if ( mpWindowImpl->mpBorderWindow ) 8126 mpWindowImpl->mpBorderWindow->SetText( rStr ); 8127 else if ( mpWindowImpl->mbFrame ) 8128 mpWindowImpl->mpFrame->SetTitle( rStr ); 8129 8130 ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle ); 8131 8132 // #107247# needed for accessibility 8133 // The VCLEVENT_WINDOW_FRAMETITLECHANGED is (mis)used to notify accessible name changes. 8134 // Therefore a window, which is labeled by this window, must also notify an accessible 8135 // name change. 8136 if ( IsReallyVisible() ) 8137 { 8138 Window* pWindow = GetAccessibleRelationLabelFor(); 8139 if ( pWindow && pWindow != this ) 8140 pWindow->ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldTitle ); 8141 } 8142 8143 StateChanged( STATE_CHANGE_TEXT ); 8144 } 8145 8146 // ----------------------------------------------------------------------- 8147 8148 String Window::GetText() const 8149 { 8150 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8151 8152 return mpWindowImpl->maText; 8153 } 8154 8155 // ----------------------------------------------------------------------- 8156 8157 String Window::GetDisplayText() const 8158 { 8159 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8160 8161 return GetText(); 8162 } 8163 8164 // ----------------------------------------------------------------------- 8165 8166 const Wallpaper& Window::GetDisplayBackground() const 8167 { 8168 // FIXME: fix issue 52349, need to fix this really in 8169 // all NWF enabled controls 8170 const ToolBox* pTB = dynamic_cast<const ToolBox*>(this); 8171 if( pTB ) 8172 { 8173 if( IsNativeWidgetEnabled() ) 8174 return pTB->ImplGetToolBoxPrivateData()->maDisplayBackground; 8175 } 8176 8177 if( !IsBackground() ) 8178 { 8179 if( mpWindowImpl->mpParent ) 8180 return mpWindowImpl->mpParent->GetDisplayBackground(); 8181 } 8182 8183 const Wallpaper& rBack = GetBackground(); 8184 if( ! rBack.IsBitmap() && 8185 ! rBack.IsGradient() && 8186 rBack.GetColor().GetColor() == COL_TRANSPARENT && 8187 mpWindowImpl->mpParent ) 8188 return mpWindowImpl->mpParent->GetDisplayBackground(); 8189 return rBack; 8190 } 8191 8192 // ----------------------------------------------------------------------- 8193 8194 const XubString& Window::GetHelpText() const 8195 { 8196 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8197 8198 String aStrHelpId( rtl::OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) ); 8199 bool bStrHelpId = (aStrHelpId.Len() > 0); 8200 8201 if ( !mpWindowImpl->maHelpText.Len() && bStrHelpId ) 8202 { 8203 if ( !IsDialog() && (mpWindowImpl->mnType != WINDOW_TABPAGE) && (mpWindowImpl->mnType != WINDOW_FLOATINGWINDOW) ) 8204 { 8205 Help* pHelp = Application::GetHelp(); 8206 if ( pHelp ) 8207 { 8208 ((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( aStrHelpId, this ); 8209 mpWindowImpl->mbHelpTextDynamic = sal_False; 8210 } 8211 } 8212 } 8213 else if( mpWindowImpl->mbHelpTextDynamic && bStrHelpId ) 8214 { 8215 static const char* pEnv = getenv( "HELP_DEBUG" ); 8216 if( pEnv && *pEnv ) 8217 { 8218 rtl::OUStringBuffer aTxt( 64+mpWindowImpl->maHelpText.Len() ); 8219 aTxt.append( mpWindowImpl->maHelpText ); 8220 aTxt.appendAscii( "\n------------------\n" ); 8221 aTxt.append( rtl::OUString( aStrHelpId ) ); 8222 mpWindowImpl->maHelpText = aTxt.makeStringAndClear(); 8223 } 8224 mpWindowImpl->mbHelpTextDynamic = sal_False; 8225 } 8226 8227 return mpWindowImpl->maHelpText; 8228 } 8229 8230 // ----------------------------------------------------------------------- 8231 8232 Window* Window::FindWindow( const Point& rPos ) const 8233 { 8234 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8235 8236 Point aPos = OutputToScreenPixel( rPos ); 8237 return ((Window*)this)->ImplFindWindow( aPos ); 8238 } 8239 8240 // ----------------------------------------------------------------------- 8241 8242 sal_uInt16 Window::GetChildCount() const 8243 { 8244 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8245 8246 sal_uInt16 nChildCount = 0; 8247 Window* pChild = mpWindowImpl->mpFirstChild; 8248 while ( pChild ) 8249 { 8250 nChildCount++; 8251 pChild = pChild->mpWindowImpl->mpNext; 8252 } 8253 8254 return nChildCount; 8255 } 8256 8257 // ----------------------------------------------------------------------- 8258 8259 Window* Window::GetChild( sal_uInt16 nChild ) const 8260 { 8261 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8262 8263 sal_uInt16 nChildCount = 0; 8264 Window* pChild = mpWindowImpl->mpFirstChild; 8265 while ( pChild ) 8266 { 8267 if ( nChild == nChildCount ) 8268 return pChild; 8269 pChild = pChild->mpWindowImpl->mpNext; 8270 nChildCount++; 8271 } 8272 8273 return NULL; 8274 } 8275 8276 // ----------------------------------------------------------------------- 8277 8278 Window* Window::GetWindow( sal_uInt16 nType ) const 8279 { 8280 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8281 8282 switch ( nType ) 8283 { 8284 case WINDOW_PARENT: 8285 return mpWindowImpl->mpRealParent; 8286 8287 case WINDOW_FIRSTCHILD: 8288 return mpWindowImpl->mpFirstChild; 8289 8290 case WINDOW_LASTCHILD: 8291 return mpWindowImpl->mpLastChild; 8292 8293 case WINDOW_PREV: 8294 return mpWindowImpl->mpPrev; 8295 8296 case WINDOW_NEXT: 8297 return mpWindowImpl->mpNext; 8298 8299 case WINDOW_FIRSTOVERLAP: 8300 return mpWindowImpl->mpFirstOverlap; 8301 8302 case WINDOW_LASTOVERLAP: 8303 return mpWindowImpl->mpLastOverlap; 8304 8305 case WINDOW_OVERLAP: 8306 if ( ImplIsOverlapWindow() ) 8307 return (Window*)this; 8308 else 8309 return mpWindowImpl->mpOverlapWindow; 8310 8311 case WINDOW_PARENTOVERLAP: 8312 if ( ImplIsOverlapWindow() ) 8313 return mpWindowImpl->mpOverlapWindow; 8314 else 8315 return mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpOverlapWindow; 8316 8317 case WINDOW_CLIENT: 8318 return ((Window*)this)->ImplGetWindow(); 8319 8320 case WINDOW_REALPARENT: 8321 return ImplGetParent(); 8322 8323 case WINDOW_FRAME: 8324 return mpWindowImpl->mpFrameWindow; 8325 8326 case WINDOW_BORDER: 8327 if ( mpWindowImpl->mpBorderWindow ) 8328 return mpWindowImpl->mpBorderWindow->GetWindow( WINDOW_BORDER ); 8329 return (Window*)this; 8330 8331 case WINDOW_FIRSTTOPWINDOWCHILD: 8332 return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.begin(); 8333 8334 case WINDOW_LASTTOPWINDOWCHILD: 8335 return ImplGetWinData()->maTopWindowChildren.empty() ? NULL : *ImplGetWinData()->maTopWindowChildren.rbegin(); 8336 8337 case WINDOW_PREVTOPWINDOWSIBLING: 8338 { 8339 if ( !mpWindowImpl->mpRealParent ) 8340 return NULL; 8341 const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren ); 8342 ::std::list< Window* >::const_iterator myPos = 8343 ::std::find( rTopWindows.begin(), rTopWindows.end(), this ); 8344 if ( myPos == rTopWindows.end() ) 8345 return NULL; 8346 if ( myPos == rTopWindows.begin() ) 8347 return NULL; 8348 return *--myPos; 8349 } 8350 8351 case WINDOW_NEXTTOPWINDOWSIBLING: 8352 { 8353 if ( !mpWindowImpl->mpRealParent ) 8354 return NULL; 8355 const ::std::list< Window* >& rTopWindows( mpWindowImpl->mpRealParent->ImplGetWinData()->maTopWindowChildren ); 8356 ::std::list< Window* >::const_iterator myPos = 8357 ::std::find( rTopWindows.begin(), rTopWindows.end(), this ); 8358 if ( ( myPos == rTopWindows.end() ) || ( ++myPos == rTopWindows.end() ) ) 8359 return NULL; 8360 return *myPos; 8361 } 8362 8363 } 8364 8365 return NULL; 8366 } 8367 8368 // ----------------------------------------------------------------------- 8369 8370 sal_Bool Window::IsChild( const Window* pWindow, sal_Bool bSystemWindow ) const 8371 { 8372 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8373 DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow ); 8374 8375 do 8376 { 8377 if ( !bSystemWindow && pWindow->ImplIsOverlapWindow() ) 8378 break; 8379 8380 pWindow = pWindow->ImplGetParent(); 8381 8382 if ( pWindow == this ) 8383 return sal_True; 8384 } 8385 while ( pWindow ); 8386 8387 return sal_False; 8388 } 8389 8390 // ----------------------------------------------------------------------- 8391 8392 sal_Bool Window::IsWindowOrChild( const Window* pWindow, sal_Bool bSystemWindow ) const 8393 { 8394 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8395 DBG_CHKOBJ( pWindow, Window, ImplDbgCheckWindow ); 8396 8397 if ( this == pWindow ) 8398 return sal_True; 8399 return ImplIsChild( pWindow, bSystemWindow ); 8400 } 8401 8402 // ----------------------------------------------------------------------- 8403 8404 const SystemEnvData* Window::GetSystemData() const 8405 { 8406 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8407 8408 return mpWindowImpl->mpFrame ? mpWindowImpl->mpFrame->GetSystemData() : NULL; 8409 } 8410 8411 ::com::sun::star::uno::Any Window::GetSystemDataAny() const 8412 { 8413 ::com::sun::star::uno::Any aRet; 8414 const SystemEnvData* pSysData = GetSystemData(); 8415 if( pSysData ) 8416 { 8417 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)pSysData, pSysData->nSize ); 8418 aRet <<= aSeq; 8419 } 8420 return aRet; 8421 } 8422 8423 // ----------------------------------------------------------------------- 8424 8425 void Window::SetWindowPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer, VCLXWindow* pVCLXWindow ) 8426 { 8427 // be safe against re-entrance: first clear the old ref, then assign the new one 8428 // #133706# / 2006-03-30 / frank.schoenheit@sun.com 8429 mpWindowImpl->mxWindowPeer.clear(); 8430 mpWindowImpl->mxWindowPeer = xPeer; 8431 8432 mpWindowImpl->mpVCLXWindow = pVCLXWindow; 8433 } 8434 8435 // ----------------------------------------------------------------------- 8436 8437 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > Window::GetComponentInterface( sal_Bool bCreate ) 8438 { 8439 if ( !mpWindowImpl->mxWindowPeer.is() && bCreate ) 8440 { 8441 UnoWrapperBase* pWrapper = Application::GetUnoWrapper(); 8442 if ( pWrapper ) 8443 mpWindowImpl->mxWindowPeer = pWrapper->GetWindowInterface( this, sal_True ); 8444 } 8445 return mpWindowImpl->mxWindowPeer; 8446 } 8447 8448 // ----------------------------------------------------------------------- 8449 8450 void Window::SetComponentInterface( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xIFace ) 8451 { 8452 UnoWrapperBase* pWrapper = Application::GetUnoWrapper(); 8453 DBG_ASSERT( pWrapper, "SetComponentInterface: No Wrapper!" ); 8454 if ( pWrapper ) 8455 pWrapper->SetWindowInterface( this, xIFace ); 8456 } 8457 8458 // ----------------------------------------------------------------------- 8459 8460 void Window::ImplCallDeactivateListeners( Window *pNew ) 8461 { 8462 // no deactivation if the the newly activated window is my child 8463 if ( !pNew || !ImplIsChild( pNew ) ) 8464 { 8465 ImplDelData aDogtag( this ); 8466 ImplCallEventListeners( VCLEVENT_WINDOW_DEACTIVATE ); 8467 if( aDogtag.IsDelete() ) 8468 return; 8469 8470 // #100759#, avoid walking the wrong frame's hierarchy 8471 // eg, undocked docking windows (ImplDockFloatWin) 8472 if ( ImplGetParent() && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow ) 8473 ImplGetParent()->ImplCallDeactivateListeners( pNew ); 8474 } 8475 } 8476 8477 // ----------------------------------------------------------------------- 8478 8479 void Window::ImplCallActivateListeners( Window *pOld ) 8480 { 8481 // no activation if the the old active window is my child 8482 if ( !pOld || !ImplIsChild( pOld ) ) 8483 { 8484 ImplDelData aDogtag( this ); 8485 ImplCallEventListeners( VCLEVENT_WINDOW_ACTIVATE, pOld ); 8486 if( aDogtag.IsDelete() ) 8487 return; 8488 8489 // #106298# revoke the change for 105369, because this change 8490 // disabled the activate event for the parent, 8491 // if the parent is a compound control 8492 //if( !GetParent() || !GetParent()->IsCompoundControl() ) 8493 //{ 8494 // #100759#, avoid walking the wrong frame's hierarchy 8495 // eg, undocked docking windows (ImplDockFloatWin) 8496 // #104714#, revert the changes for 100759 because it has a side effect when pOld is a dialog 8497 // additionally the gallery is not dockable anymore, so 100759 canot occur 8498 if ( ImplGetParent() ) /* && mpWindowImpl->mpFrameWindow == ImplGetParent()->mpWindowImpl->mpFrameWindow ) */ 8499 ImplGetParent()->ImplCallActivateListeners( pOld ); 8500 else if( (mpWindowImpl->mnStyle & WB_INTROWIN) == 0 ) 8501 { 8502 // top level frame reached: store hint for DefModalDialogParent 8503 ImplGetSVData()->maWinData.mpActiveApplicationFrame = mpWindowImpl->mpFrameWindow; 8504 } 8505 //} 8506 } 8507 } 8508 8509 // ----------------------------------------------------------------------- 8510 8511 bool Window::ImplStopDnd() 8512 { 8513 bool bRet = false; 8514 if( mpWindowImpl->mpFrameData && mpWindowImpl->mpFrameData->mxDropTargetListener.is() ) 8515 { 8516 bRet = true; 8517 mpWindowImpl->mpFrameData->mxDropTarget.clear(); 8518 mpWindowImpl->mpFrameData->mxDragSource.clear(); 8519 mpWindowImpl->mpFrameData->mxDropTargetListener.clear(); 8520 } 8521 8522 return bRet; 8523 } 8524 8525 // ----------------------------------------------------------------------- 8526 8527 void Window::ImplStartDnd() 8528 { 8529 GetDropTarget(); 8530 } 8531 8532 // ----------------------------------------------------------------------- 8533 8534 uno::Reference< XDropTarget > Window::GetDropTarget() 8535 { 8536 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8537 8538 if( ! mpWindowImpl->mxDNDListenerContainer.is() ) 8539 { 8540 sal_Int8 nDefaultActions = 0; 8541 8542 if( mpWindowImpl->mpFrameData ) 8543 { 8544 if( ! mpWindowImpl->mpFrameData->mxDropTarget.is() ) 8545 { 8546 // initialization is done in GetDragSource 8547 uno::Reference< XDragSource > xDragSource = GetDragSource(); 8548 } 8549 8550 if( mpWindowImpl->mpFrameData->mxDropTarget.is() ) 8551 { 8552 nDefaultActions = mpWindowImpl->mpFrameData->mxDropTarget->getDefaultActions(); 8553 8554 if( ! mpWindowImpl->mpFrameData->mxDropTargetListener.is() ) 8555 { 8556 mpWindowImpl->mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpWindowImpl->mpFrameWindow ); 8557 8558 try 8559 { 8560 mpWindowImpl->mpFrameData->mxDropTarget->addDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener ); 8561 8562 // register also as drag gesture listener if directly supported by drag source 8563 uno::Reference< XDragGestureRecognizer > xDragGestureRecognizer = 8564 uno::Reference< XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY); 8565 8566 if( xDragGestureRecognizer.is() ) 8567 { 8568 xDragGestureRecognizer->addDragGestureListener( 8569 uno::Reference< XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY)); 8570 } 8571 else 8572 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = sal_True; 8573 8574 } 8575 8576 catch( RuntimeException&) 8577 { 8578 // release all instances 8579 mpWindowImpl->mpFrameData->mxDropTarget.clear(); 8580 mpWindowImpl->mpFrameData->mxDragSource.clear(); 8581 } 8582 } 8583 } 8584 8585 } 8586 8587 mpWindowImpl->mxDNDListenerContainer = static_cast < XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) ); 8588 } 8589 8590 // this object is located in the same process, so there will be no runtime exception 8591 return uno::Reference< XDropTarget > ( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY ); 8592 } 8593 8594 // ----------------------------------------------------------------------- 8595 8596 uno::Reference< XDragSource > Window::GetDragSource() 8597 { 8598 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8599 8600 if( mpWindowImpl->mpFrameData ) 8601 { 8602 if( ! mpWindowImpl->mpFrameData->mxDragSource.is() ) 8603 { 8604 try 8605 { 8606 uno::Reference< XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory(); 8607 if ( xFactory.is() ) 8608 { 8609 const SystemEnvData * pEnvData = GetSystemData(); 8610 8611 if( pEnvData ) 8612 { 8613 Sequence< Any > aDragSourceAL( 2 ), aDropTargetAL( 2 ); 8614 OUString aDragSourceSN, aDropTargetSN; 8615 #if defined WNT 8616 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragSource" ); 8617 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDropTarget" ); 8618 aDragSourceAL[ 1 ] = makeAny( (sal_uInt32) pEnvData->hWnd ); 8619 aDropTargetAL[ 0 ] = makeAny( (sal_uInt32) pEnvData->hWnd ); 8620 #elif defined QUARTZ 8621 /* FIXME: Mac OS X specific dnd interface does not exist! * 8622 * Using Windows based dnd as a temporary solution */ 8623 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDragSource" ); 8624 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.OleDropTarget" ); 8625 aDragSourceAL[ 1 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->pView) ) ); 8626 aDropTargetAL[ 0 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->pView) ) ); 8627 #elif defined UNX 8628 aDropTargetAL.realloc( 3 ); 8629 aDragSourceAL.realloc( 3 ); 8630 aDragSourceSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DragSource" ); 8631 aDropTargetSN = OUString::createFromAscii( "com.sun.star.datatransfer.dnd.X11DropTarget" ); 8632 8633 aDragSourceAL[ 0 ] = makeAny( Application::GetDisplayConnection() ); 8634 aDragSourceAL[ 2 ] = makeAny( vcl::createBmpConverter() ); 8635 aDropTargetAL[ 0 ] = makeAny( Application::GetDisplayConnection() ); 8636 aDropTargetAL[ 1 ] = makeAny( (sal_Size)(pEnvData->aShellWindow) ); 8637 aDropTargetAL[ 2 ] = makeAny( vcl::createBmpConverter() ); 8638 #endif 8639 if( aDragSourceSN.getLength() ) 8640 mpWindowImpl->mpFrameData->mxDragSource = uno::Reference< XDragSource > ( xFactory->createInstanceWithArguments( aDragSourceSN, aDragSourceAL ), UNO_QUERY ); 8641 8642 if( aDropTargetSN.getLength() ) 8643 mpWindowImpl->mpFrameData->mxDropTarget = uno::Reference< XDropTarget > ( xFactory->createInstanceWithArguments( aDropTargetSN, aDropTargetAL ), UNO_QUERY ); 8644 } 8645 } 8646 } 8647 8648 // createInstance can throw any exception 8649 catch( Exception&) 8650 { 8651 // release all instances 8652 mpWindowImpl->mpFrameData->mxDropTarget.clear(); 8653 mpWindowImpl->mpFrameData->mxDragSource.clear(); 8654 } 8655 } 8656 8657 return mpWindowImpl->mpFrameData->mxDragSource; 8658 } 8659 8660 return uno::Reference< XDragSource > (); 8661 } 8662 8663 // ----------------------------------------------------------------------- 8664 8665 void Window::GetDragSourceDropTarget(uno::Reference< XDragSource >& xDragSource, uno::Reference< XDropTarget > &xDropTarget ) 8666 // only for RVP transmission 8667 { 8668 if( mpWindowImpl->mpFrameData ) 8669 { 8670 // initialization is done in GetDragSource 8671 xDragSource = GetDragSource(); 8672 xDropTarget = mpWindowImpl->mpFrameData->mxDropTarget; 8673 } 8674 else 8675 { 8676 xDragSource.clear(); 8677 xDropTarget.clear(); 8678 } 8679 } 8680 8681 // ----------------------------------------------------------------------- 8682 8683 uno::Reference< XDragGestureRecognizer > Window::GetDragGestureRecognizer() 8684 { 8685 return uno::Reference< XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY ); 8686 } 8687 8688 // ----------------------------------------------------------------------- 8689 8690 uno::Reference< XClipboard > Window::GetClipboard() 8691 { 8692 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8693 8694 if( mpWindowImpl->mpFrameData ) 8695 { 8696 if( ! mpWindowImpl->mpFrameData->mxClipboard.is() ) 8697 { 8698 try 8699 { 8700 uno::Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() ); 8701 8702 if( xFactory.is() ) 8703 { 8704 mpWindowImpl->mpFrameData->mxClipboard = uno::Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboardExt" ) ), UNO_QUERY ); 8705 8706 if( !mpWindowImpl->mpFrameData->mxClipboard.is() ) 8707 mpWindowImpl->mpFrameData->mxClipboard = uno::Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ) ), UNO_QUERY ); 8708 8709 #if defined(UNX) && !defined(QUARTZ) // unix clipboard needs to be initialized 8710 if( mpWindowImpl->mpFrameData->mxClipboard.is() ) 8711 { 8712 uno::Reference< XInitialization > xInit = uno::Reference< XInitialization >( mpWindowImpl->mpFrameData->mxClipboard, UNO_QUERY ); 8713 8714 if( xInit.is() ) 8715 { 8716 Sequence< Any > aArgumentList( 3 ); 8717 aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() ); 8718 aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "CLIPBOARD" ) ); 8719 aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() ); 8720 8721 xInit->initialize( aArgumentList ); 8722 } 8723 } 8724 #endif 8725 } 8726 } 8727 8728 // createInstance can throw any exception 8729 catch( Exception&) 8730 { 8731 // release all instances 8732 mpWindowImpl->mpFrameData->mxClipboard.clear(); 8733 } 8734 } 8735 8736 return mpWindowImpl->mpFrameData->mxClipboard; 8737 } 8738 8739 return static_cast < XClipboard * > (0); 8740 } 8741 8742 // ----------------------------------------------------------------------- 8743 8744 uno::Reference< XClipboard > Window::GetPrimarySelection() 8745 { 8746 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8747 8748 if( mpWindowImpl->mpFrameData ) 8749 { 8750 if( ! mpWindowImpl->mpFrameData->mxSelection.is() ) 8751 { 8752 try 8753 { 8754 uno::Reference< XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() ); 8755 8756 if( xFactory.is() ) 8757 { 8758 #if defined(UNX) && !defined(QUARTZ) 8759 Sequence< Any > aArgumentList( 3 ); 8760 aArgumentList[ 0 ] = makeAny( Application::GetDisplayConnection() ); 8761 aArgumentList[ 1 ] = makeAny( OUString::createFromAscii( "PRIMARY" ) ); 8762 aArgumentList[ 2 ] = makeAny( vcl::createBmpConverter() ); 8763 8764 mpWindowImpl->mpFrameData->mxSelection = uno::Reference< XClipboard >( xFactory->createInstanceWithArguments( 8765 OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ), aArgumentList ), UNO_QUERY ); 8766 # else 8767 static uno::Reference< XClipboard > s_xSelection; 8768 8769 if ( !s_xSelection.is() ) 8770 s_xSelection = uno::Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboardExt" ) ), UNO_QUERY ); 8771 8772 if ( !s_xSelection.is() ) 8773 s_xSelection = uno::Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboard" ) ), UNO_QUERY ); 8774 8775 mpWindowImpl->mpFrameData->mxSelection = s_xSelection; 8776 # endif 8777 } 8778 } 8779 8780 // createInstance can throw any exception 8781 catch( Exception&) 8782 { 8783 // release all instances 8784 mpWindowImpl->mpFrameData->mxSelection.clear(); 8785 } 8786 } 8787 8788 return mpWindowImpl->mpFrameData->mxSelection; 8789 } 8790 8791 return static_cast < XClipboard * > (0); 8792 } 8793 8794 // ----------------------------------------------------------------------- 8795 // Accessibility 8796 // ----------------------------------------------------------------------- 8797 8798 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::GetAccessible( sal_Bool bCreate ) 8799 { 8800 // do not optimize hierarchy for the top level border win (ie, when there is no parent) 8801 /* // do not optimize accessible hierarchy at all to better reflect real VCL hierarchy 8802 if ( GetParent() && ( GetType() == WINDOW_BORDERWINDOW ) && ( GetChildCount() == 1 ) ) 8803 //if( !ImplIsAccessibleCandidate() ) 8804 { 8805 Window* pChild = GetAccessibleChildWindow( 0 ); 8806 if ( pChild ) 8807 return pChild->GetAccessible(); 8808 } 8809 */ 8810 if ( !mpWindowImpl->mxAccessible.is() && bCreate ) 8811 mpWindowImpl->mxAccessible = CreateAccessible(); 8812 8813 return mpWindowImpl->mxAccessible; 8814 } 8815 8816 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::CreateAccessible() 8817 { 8818 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc( GetComponentInterface( sal_True ), ::com::sun::star::uno::UNO_QUERY ); 8819 return xAcc; 8820 } 8821 8822 void Window::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > x ) 8823 { 8824 mpWindowImpl->mxAccessible = x; 8825 } 8826 8827 // skip all border windows that are no top level frames 8828 sal_Bool Window::ImplIsAccessibleCandidate() const 8829 { 8830 if( !mpWindowImpl->mbBorderWin ) 8831 return sal_True; 8832 else 8833 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menues!) are closeable 8834 if( mpWindowImpl->mbFrame && mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) 8835 return sal_True; 8836 else 8837 return sal_False; 8838 } 8839 8840 sal_Bool Window::ImplIsAccessibleNativeFrame() const 8841 { 8842 if( mpWindowImpl->mbFrame ) 8843 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menues!) are closeable 8844 if( (mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE)) ) 8845 return sal_True; 8846 else 8847 return sal_False; 8848 else 8849 return sal_False; 8850 } 8851 8852 sal_uInt16 Window::ImplGetAccessibleCandidateChildWindowCount( sal_uInt16 nFirstWindowType ) const 8853 { 8854 sal_uInt16 nChildren = 0; 8855 Window* pChild = GetWindow( nFirstWindowType ); 8856 while ( pChild ) 8857 { 8858 if( pChild->ImplIsAccessibleCandidate() ) 8859 nChildren++; 8860 else 8861 nChildren = sal::static_int_cast<sal_uInt16>(nChildren + pChild->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD )); 8862 pChild = pChild->mpWindowImpl->mpNext; 8863 } 8864 return nChildren; 8865 } 8866 8867 Window* Window::ImplGetAccessibleCandidateChild( sal_uInt16 nChild, sal_uInt16& rChildCount, sal_uInt16 nFirstWindowType, sal_Bool bTopLevel ) const 8868 { 8869 DBG_CHKTHIS( Window, ImplDbgCheckWindow ); 8870 8871 if( bTopLevel ) 8872 rChildCount = 0; 8873 8874 Window* pChild = GetWindow( nFirstWindowType ); 8875 while ( pChild ) 8876 { 8877 Window *pTmpChild = pChild; 8878 8879 if( !pChild->ImplIsAccessibleCandidate() ) 8880 pTmpChild = pChild->ImplGetAccessibleCandidateChild( nChild, rChildCount, WINDOW_FIRSTCHILD, sal_False ); 8881 8882 if ( nChild == rChildCount ) 8883 return pTmpChild; 8884 pChild = pChild->mpWindowImpl->mpNext; 8885 rChildCount++; 8886 } 8887 8888 return NULL; 8889 } 8890 8891 /* 8892 Window* Window::GetAccessibleParentWindow() const 8893 { 8894 Window* pParent = GetParent(); 8895 while ( pParent ) 8896 if( pParent->ImplIsAccessibleCandidate() ) 8897 break; 8898 else 8899 pParent = pParent->GetParent(); 8900 return pParent; 8901 } 8902 */ 8903 8904 Window* Window::GetAccessibleParentWindow() const 8905 { 8906 if ( ImplIsAccessibleNativeFrame() ) 8907 return NULL; 8908 8909 Window* pParent = mpWindowImpl->mpParent; 8910 if( GetType() == WINDOW_MENUBARWINDOW ) 8911 { 8912 // report the menubar as a child of THE workwindow 8913 Window *pWorkWin = GetParent()->mpWindowImpl->mpFirstChild; 8914 while( pWorkWin && (pWorkWin == this) ) 8915 pWorkWin = pWorkWin->mpWindowImpl->mpNext; 8916 pParent = pWorkWin; 8917 } 8918 // If this a floating window which has a native boarder window, this one should be reported as 8919 // accessible parent 8920 else if( GetType() == WINDOW_FLOATINGWINDOW && 8921 mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) 8922 { 8923 pParent = mpWindowImpl->mpBorderWindow; 8924 } 8925 else if( pParent && !pParent->ImplIsAccessibleCandidate() ) 8926 { 8927 pParent = pParent->mpWindowImpl->mpParent; 8928 } 8929 return pParent; 8930 } 8931 8932 /* 8933 sal_uInt16 Window::GetAccessibleChildWindowCount() 8934 { 8935 sal_uInt16 nChildren = ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD ); 8936 8937 // Search also for SystemWindows. 8938 Window* pOverlap = GetWindow( WINDOW_OVERLAP ); 8939 nChildren += pOverlap->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTOVERLAP ); 8940 8941 return nChildren; 8942 } 8943 */ 8944 8945 sal_uInt16 Window::GetAccessibleChildWindowCount() 8946 { 8947 sal_uInt16 nChildren = 0; 8948 Window* pChild = mpWindowImpl->mpFirstChild; 8949 while( pChild ) 8950 { 8951 if( pChild->IsVisible() ) 8952 nChildren++; 8953 pChild = pChild->mpWindowImpl->mpNext; 8954 } 8955 8956 // #107176# ignore overlapwindows 8957 // this only affects non-system floating windows 8958 // which are either not accessible (like the HelpAgent) or should be changed to system windows anyway 8959 /* 8960 if( ImplIsOverlapWindow() ) 8961 { 8962 Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP ); 8963 while ( pOverlap ) 8964 { 8965 if( pOverlap->IsVisible() ) 8966 nChildren++; 8967 pOverlap = pOverlap->GetWindow( WINDOW_NEXT ); 8968 } 8969 } 8970 */ 8971 8972 // report the menubarwindow as a child of THE workwindow 8973 if( GetType() == WINDOW_BORDERWINDOW ) 8974 { 8975 if( ((ImplBorderWindow *) this)->mpMenuBarWindow && 8976 ((ImplBorderWindow *) this)->mpMenuBarWindow->IsVisible() 8977 ) 8978 --nChildren; 8979 } 8980 else if( GetType() == WINDOW_WORKWINDOW ) 8981 { 8982 if( ((WorkWindow *) this)->GetMenuBar() && 8983 ((WorkWindow *) this)->GetMenuBar()->GetWindow() && 8984 ((WorkWindow *) this)->GetMenuBar()->GetWindow()->IsVisible() 8985 ) 8986 ++nChildren; 8987 } 8988 8989 return nChildren; 8990 } 8991 8992 /* 8993 Window* Window::GetAccessibleChildWindow( sal_uInt16 n ) 8994 { 8995 sal_uInt16 nChildCount; // will be set in ImplGetAccessibleCandidateChild(...) 8996 Window* pChild = ImplGetAccessibleCandidateChild( n, nChildCount, WINDOW_FIRSTCHILD, sal_True ); 8997 if ( !pChild && ( n >= nChildCount ) ) 8998 { 8999 Window* pOverlap = GetWindow( WINDOW_OVERLAP ); 9000 pChild = pOverlap->ImplGetAccessibleCandidateChild( n, nChildCount, WINDOW_FIRSTOVERLAP, sal_False ); 9001 } 9002 9003 return pChild; 9004 } 9005 */ 9006 9007 Window* Window::GetAccessibleChildWindow( sal_uInt16 n ) 9008 { 9009 // report the menubarwindow as a the first child of THE workwindow 9010 if( GetType() == WINDOW_WORKWINDOW && ((WorkWindow *) this)->GetMenuBar() ) 9011 { 9012 if( n == 0 ) 9013 { 9014 MenuBar *pMenuBar = ((WorkWindow *) this)->GetMenuBar(); 9015 if( pMenuBar->GetWindow() && pMenuBar->GetWindow()->IsVisible() ) 9016 return pMenuBar->GetWindow(); 9017 } 9018 else 9019 --n; 9020 } 9021 9022 // transform n to child number including invisible children 9023 sal_uInt16 nChildren = n; 9024 Window* pChild = mpWindowImpl->mpFirstChild; 9025 while( pChild ) 9026 { 9027 if( pChild->IsVisible() ) 9028 { 9029 if( ! nChildren ) 9030 break; 9031 nChildren--; 9032 } 9033 pChild = pChild->mpWindowImpl->mpNext; 9034 } 9035 9036 if( GetType() == WINDOW_BORDERWINDOW && pChild && pChild->GetType() == WINDOW_MENUBARWINDOW ) 9037 { 9038 do pChild = pChild->mpWindowImpl->mpNext; while( pChild && ! pChild->IsVisible() ); 9039 DBG_ASSERT( pChild, "GetAccessibleChildWindow(): wrong index in border window"); 9040 } 9041 if ( !pChild ) 9042 { 9043 // #107176# ignore overlapwindows 9044 /* 9045 if( ImplIsOverlapWindow() ) 9046 { 9047 Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP ); 9048 while ( !pChild && pOverlap ) 9049 { 9050 if ( !nChildren && pOverlap->IsVisible() ) 9051 { 9052 pChild = pOverlap; 9053 break; 9054 } 9055 pOverlap = pOverlap->GetWindow( WINDOW_NEXT ); 9056 if( pOverlap && pOverlap->IsVisible() ) 9057 nChildren--; 9058 } 9059 } 9060 */ 9061 9062 } 9063 if ( pChild && ( pChild->GetType() == WINDOW_BORDERWINDOW ) && ( pChild->GetChildCount() == 1 ) ) 9064 { 9065 pChild = pChild->GetChild( 0 ); 9066 } 9067 return pChild; 9068 } 9069 9070 9071 void Window::SetAccessibleRole( sal_uInt16 nRole ) 9072 { 9073 if ( !mpWindowImpl->mpAccessibleInfos ) 9074 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos; 9075 9076 DBG_ASSERT( mpWindowImpl->mpAccessibleInfos->nAccessibleRole == 0xFFFF, "AccessibleRole already set!" ); 9077 mpWindowImpl->mpAccessibleInfos->nAccessibleRole = nRole; 9078 } 9079 9080 sal_uInt16 Window::GetAccessibleRole() const 9081 { 9082 using namespace ::com::sun::star; 9083 9084 sal_uInt16 nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF; 9085 if ( nRole == 0xFFFF ) 9086 { 9087 switch ( GetType() ) 9088 { 9089 case WINDOW_MESSBOX: // MT: Would be nice to have special roles! 9090 case WINDOW_INFOBOX: 9091 case WINDOW_WARNINGBOX: 9092 case WINDOW_ERRORBOX: 9093 case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::ALERT; break; 9094 9095 case WINDOW_MODELESSDIALOG: 9096 case WINDOW_MODALDIALOG: 9097 case WINDOW_SYSTEMDIALOG: 9098 case WINDOW_PRINTERSETUPDIALOG: 9099 case WINDOW_PRINTDIALOG: 9100 case WINDOW_TABDIALOG: 9101 case WINDOW_BUTTONDIALOG: 9102 case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break; 9103 9104 case WINDOW_PUSHBUTTON: 9105 case WINDOW_OKBUTTON: 9106 case WINDOW_CANCELBUTTON: 9107 case WINDOW_HELPBUTTON: 9108 case WINDOW_IMAGEBUTTON: 9109 //case WINDOW_MENUBUTTON: 9110 case WINDOW_MOREBUTTON: 9111 case WINDOW_SPINBUTTON: 9112 case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break; 9113 case WINDOW_MENUBUTTON: nRole = accessibility::AccessibleRole::BUTTON_MENU; break; 9114 9115 case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break; 9116 case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break; 9117 case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break; 9118 case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break; 9119 9120 case WINDOW_IMAGERADIOBUTTON: 9121 case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break; 9122 case WINDOW_TRISTATEBOX: 9123 case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break; 9124 9125 case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break; 9126 9127 case WINDOW_PATTERNFIELD: 9128 //IAccessibility2 Impplementaton 2009----- 9129 // Need to set the role of those window control to spinbox 9130 /* 9131 case WINDOW_NUMERICFIELD: 9132 case WINDOW_METRICFIELD: 9133 case WINDOW_CURRENCYFIELD: 9134 case WINDOW_LONGCURRENCYFIELD: 9135 */ 9136 //-----IAccessibility2 Impplementaton 2009 9137 case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break; 9138 9139 case WINDOW_PATTERNBOX: 9140 case WINDOW_NUMERICBOX: 9141 case WINDOW_METRICBOX: 9142 case WINDOW_CURRENCYBOX: 9143 case WINDOW_LONGCURRENCYBOX: 9144 case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBO_BOX; break; 9145 9146 case WINDOW_LISTBOX: 9147 case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break; 9148 9149 case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break; 9150 9151 case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break; 9152 case WINDOW_FIXEDBORDER: 9153 nRole = accessibility::AccessibleRole::SEPARATOR; break; 9154 //IAccessibility2 Impplementaton 2009----- 9155 case WINDOW_FIXEDLINE: 9156 { if( GetText().Len() > 0 ) 9157 nRole = accessibility::AccessibleRole::LABEL; 9158 else 9159 nRole = accessibility::AccessibleRole::SEPARATOR; 9160 break; 9161 } 9162 //case WINDOW_FIXEDLINE: nRole = accessibility::AccessibleRole::SEPARATOR; break; 9163 //-----IAccessibility2 Impplementaton 2009 9164 case WINDOW_FIXEDBITMAP: 9165 case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break; 9166 case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break; 9167 case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break; 9168 9169 case WINDOW_SLIDER: 9170 case WINDOW_SPLITTER: 9171 case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break; 9172 9173 case WINDOW_DATEBOX: 9174 case WINDOW_TIMEBOX: 9175 case WINDOW_DATEFIELD: 9176 case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break; 9177 9178 //IAccessibility2 Impplementaton 2009----- 9179 // Need to set the role of those window control to spinbox 9180 case WINDOW_NUMERICFIELD: 9181 case WINDOW_METRICFIELD: 9182 case WINDOW_CURRENCYFIELD: 9183 case WINDOW_LONGCURRENCYFIELD: 9184 //-----IAccessibility2 Impplementaton 2009 9185 case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break; 9186 9187 case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break; 9188 case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break; 9189 9190 case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break; 9191 case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break; 9192 9193 case WINDOW_DOCKINGWINDOW: 9194 case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME : 9195 accessibility::AccessibleRole::PANEL; break; 9196 9197 case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame || 9198 (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) || 9199 (GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME : 9200 accessibility::AccessibleRole::WINDOW; break; 9201 9202 case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break; 9203 9204 9205 case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break; 9206 9207 case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break; 9208 9209 case WINDOW_RULER: nRole = accessibility::AccessibleRole::RULER; break; 9210 case WINDOW_WINDOW: 9211 case WINDOW_CONTROL: 9212 case WINDOW_BORDERWINDOW: 9213 case WINDOW_SYSTEMCHILDWINDOW: 9214 default: 9215 if (ImplIsAccessibleNativeFrame() ) 9216 nRole = accessibility::AccessibleRole::FRAME; 9217 else if( IsScrollable() ) 9218 nRole = accessibility::AccessibleRole::SCROLL_PANE; 9219 else if( ((Window*)this)->ImplGetWindow()->IsMenuFloatingWindow() ) 9220 nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenues are windows (i.e. toplevel) 9221 else 9222 // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead 9223 // a WINDOW is interpreted as a top-level window, which is typically not the case 9224 //nRole = accessibility::AccessibleRole::WINDOW; 9225 nRole = accessibility::AccessibleRole::PANEL; 9226 } 9227 } 9228 return nRole; 9229 } 9230 9231 void Window::SetAccessibleName( const String& rName ) 9232 { 9233 if ( !mpWindowImpl->mpAccessibleInfos ) 9234 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos; 9235 9236 //IAccessibility2 Implementation 2009----- 9237 String oldName = GetAccessibleName(); 9238 delete mpWindowImpl->mpAccessibleInfos->pAccessibleName; 9239 mpWindowImpl->mpAccessibleInfos->pAccessibleName = new String( rName ); 9240 ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldName ); 9241 //-----IAccessibility2 Implementation 2009 9242 } 9243 9244 String Window::GetAccessibleName() const 9245 { 9246 String aAccessibleName; 9247 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleName ) 9248 { 9249 aAccessibleName = *mpWindowImpl->mpAccessibleInfos->pAccessibleName; 9250 } 9251 else 9252 { 9253 switch ( GetType() ) 9254 { 9255 // case WINDOW_IMAGERADIOBUTTON: 9256 // case WINDOW_RADIOBUTTON: 9257 // case WINDOW_TRISTATEBOX: 9258 // case WINDOW_CHECKBOX: 9259 9260 case WINDOW_MULTILINEEDIT: 9261 case WINDOW_PATTERNFIELD: 9262 case WINDOW_NUMERICFIELD: 9263 case WINDOW_METRICFIELD: 9264 case WINDOW_CURRENCYFIELD: 9265 case WINDOW_LONGCURRENCYFIELD: 9266 case WINDOW_EDIT: 9267 9268 case WINDOW_DATEBOX: 9269 case WINDOW_TIMEBOX: 9270 case WINDOW_CURRENCYBOX: 9271 case WINDOW_LONGCURRENCYBOX: 9272 case WINDOW_DATEFIELD: 9273 case WINDOW_TIMEFIELD: 9274 case WINDOW_SPINFIELD: 9275 9276 case WINDOW_COMBOBOX: 9277 case WINDOW_LISTBOX: 9278 case WINDOW_MULTILISTBOX: 9279 case WINDOW_TREELISTBOX: 9280 case WINDOW_METRICBOX: 9281 { 9282 Window *pLabel = GetAccessibleRelationLabeledBy(); 9283 if ( pLabel && pLabel != this ) 9284 aAccessibleName = pLabel->GetText(); 9285 } 9286 //IAccessibility2 Implementation 2009----- 9287 if ( !aAccessibleName.Len() ) 9288 { 9289 aAccessibleName = GetQuickHelpText(); 9290 } 9291 //-----IAccessibility2 Implementation 2009 9292 break; 9293 9294 case WINDOW_IMAGEBUTTON: 9295 case WINDOW_PUSHBUTTON: 9296 aAccessibleName = GetText(); 9297 if ( !aAccessibleName.Len() ) 9298 { 9299 aAccessibleName = GetQuickHelpText(); 9300 if ( !aAccessibleName.Len() ) 9301 aAccessibleName = GetHelpText(); 9302 } 9303 break; 9304 9305 //IAccessibility2 Implementation 2009----- 9306 case WINDOW_TOOLBOX: 9307 aAccessibleName = GetText(); 9308 if( aAccessibleName.Len() == 0 ) 9309 aAccessibleName =XubString( RTL_CONSTASCII_USTRINGPARAM( "Tool Bar" ) ); 9310 break; 9311 case WINDOW_MOREBUTTON: 9312 aAccessibleName = mpWindowImpl->maText; 9313 break; 9314 //-----IAccessibility2 Implementation 2009 9315 default: 9316 aAccessibleName = GetText(); 9317 break; 9318 } 9319 9320 aAccessibleName = GetNonMnemonicString( aAccessibleName ); 9321 } 9322 9323 return aAccessibleName; 9324 } 9325 9326 void Window::SetAccessibleDescription( const String& rDescription ) 9327 { 9328 if ( ! mpWindowImpl->mpAccessibleInfos ) 9329 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos; 9330 9331 DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleDescription, "AccessibleDescription already set!" ); 9332 delete mpWindowImpl->mpAccessibleInfos->pAccessibleDescription; 9333 mpWindowImpl->mpAccessibleInfos->pAccessibleDescription = new String( rDescription ); 9334 } 9335 9336 String Window::GetAccessibleDescription() const 9337 { 9338 String aAccessibleDescription; 9339 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription ) 9340 { 9341 aAccessibleDescription = *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription; 9342 } 9343 else 9344 { 9345 // Special code for help text windows. ZT asks the border window for the 9346 // description so we have to forward this request to our inner window. 9347 const Window* pWin = ((Window *)this)->ImplGetWindow(); 9348 if ( pWin->GetType() == WINDOW_HELPTEXTWINDOW ) 9349 aAccessibleDescription = pWin->GetHelpText(); 9350 else 9351 aAccessibleDescription = GetHelpText(); 9352 } 9353 9354 return aAccessibleDescription; 9355 } 9356 9357 void Window::SetAccessibleRelationLabeledBy( Window* pLabeledBy ) 9358 { 9359 if ( !mpWindowImpl->mpAccessibleInfos ) 9360 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos; 9361 mpWindowImpl->mpAccessibleInfos->pLabeledByWindow = pLabeledBy; 9362 } 9363 9364 void Window::SetAccessibleRelationLabelFor( Window* pLabelFor ) 9365 { 9366 if ( !mpWindowImpl->mpAccessibleInfos ) 9367 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos; 9368 mpWindowImpl->mpAccessibleInfos->pLabelForWindow = pLabelFor; 9369 } 9370 9371 void Window::SetAccessibleRelationMemberOf( Window* pMemberOfWin ) 9372 { 9373 if ( !mpWindowImpl->mpAccessibleInfos ) 9374 mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos; 9375 mpWindowImpl->mpAccessibleInfos->pMemberOfWindow = pMemberOfWin; 9376 } 9377 9378 sal_Bool Window::IsAccessibilityEventsSuppressed( sal_Bool bTraverseParentPath ) 9379 { 9380 if( !bTraverseParentPath ) 9381 return mpWindowImpl->mbSuppressAccessibilityEvents; 9382 else 9383 { 9384 Window *pParent = this; 9385 while ( pParent && pParent->mpWindowImpl) 9386 { 9387 if( pParent->mpWindowImpl->mbSuppressAccessibilityEvents ) 9388 return sal_True; 9389 else 9390 pParent = pParent->mpWindowImpl->mpParent; // do not use GetParent() to find borderwindows that are frames 9391 } 9392 return sal_False; 9393 } 9394 } 9395 9396 void Window::SetAccessibilityEventsSuppressed(sal_Bool bSuppressed) 9397 { 9398 mpWindowImpl->mbSuppressAccessibilityEvents = bSuppressed; 9399 } 9400 9401 void Window::RecordLayoutData( vcl::ControlLayoutData* pLayout, const Rectangle& rRect ) 9402 { 9403 if( ! mpOutDevData ) 9404 ImplInitOutDevData(); 9405 mpOutDevData->mpRecordLayout = pLayout; 9406 mpOutDevData->maRecordRect = rRect; 9407 Paint( rRect ); 9408 mpOutDevData->mpRecordLayout = NULL; 9409 } 9410 9411 // ----------------------------------------------------------------------- 9412 // ----------------------------------------------------------------------- 9413 9414 9415 // returns background color used in this control 9416 // false: could not determine color 9417 sal_Bool Window::ImplGetCurrentBackgroundColor( Color& rCol ) 9418 { 9419 sal_Bool bRet = sal_True; 9420 9421 switch ( GetType() ) 9422 { 9423 // peform special handling here 9424 case WINDOW_PUSHBUTTON: 9425 case WINDOW_OKBUTTON: 9426 case WINDOW_CANCELBUTTON: 9427 // etc. 9428 default: 9429 if( IsControlBackground() ) 9430 rCol = GetControlBackground(); 9431 else if( IsBackground() ) 9432 { 9433 Wallpaper aWall = GetBackground(); 9434 if( !aWall.IsGradient() && !aWall.IsBitmap() ) 9435 rCol = aWall.GetColor(); 9436 else 9437 bRet = sal_False; 9438 } 9439 else 9440 rCol = GetSettings().GetStyleSettings().GetFaceColor(); 9441 break; 9442 } 9443 return bRet; 9444 } 9445 9446 void Window::DrawSelectionBackground( const Rectangle& rRect, sal_uInt16 highlight, sal_Bool bChecked, sal_Bool bDrawBorder, sal_Bool bDrawExtBorderOnly ) 9447 { 9448 DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, NULL, NULL ); 9449 } 9450 9451 void Window::DrawSelectionBackground( const Rectangle& rRect, sal_uInt16 highlight, sal_Bool bChecked, sal_Bool bDrawBorder, sal_Bool bDrawExtBorderOnly, Color* pSelectionTextColor ) 9452 { 9453 DrawSelectionBackground( rRect, highlight, bChecked, bDrawBorder, bDrawExtBorderOnly, 0, pSelectionTextColor, NULL ); 9454 } 9455 9456 void Window::DrawSelectionBackground( const Rectangle& rRect, 9457 sal_uInt16 highlight, 9458 sal_Bool bChecked, 9459 sal_Bool bDrawBorder, 9460 sal_Bool bDrawExtBorderOnly, 9461 long nCornerRadius, 9462 Color* pSelectionTextColor, 9463 Color* pPaintColor 9464 ) 9465 { 9466 if( rRect.IsEmpty() ) 9467 return; 9468 9469 bool bRoundEdges = nCornerRadius > 0; 9470 9471 const StyleSettings& rStyles = GetSettings().GetStyleSettings(); 9472 9473 9474 // colors used for item highlighting 9475 Color aSelectionBorderCol( pPaintColor ? *pPaintColor : rStyles.GetHighlightColor() ); 9476 Color aSelectionFillCol( aSelectionBorderCol ); 9477 9478 sal_Bool bDark = rStyles.GetFaceColor().IsDark(); 9479 sal_Bool bBright = ( rStyles.GetFaceColor() == Color( COL_WHITE ) ); 9480 9481 int c1 = aSelectionBorderCol.GetLuminance(); 9482 int c2 = GetDisplayBackground().GetColor().GetLuminance(); 9483 9484 if( !bDark && !bBright && abs( c2-c1 ) < (pPaintColor ? 40 : 75) ) 9485 { 9486 // constrast too low 9487 sal_uInt16 h,s,b; 9488 aSelectionFillCol.RGBtoHSB( h, s, b ); 9489 if( b > 50 ) b -= 40; 9490 else b += 40; 9491 aSelectionFillCol.SetColor( Color::HSBtoRGB( h, s, b ) ); 9492 aSelectionBorderCol = aSelectionFillCol; 9493 } 9494 9495 if( bRoundEdges ) 9496 { 9497 if( aSelectionBorderCol.IsDark() ) 9498 aSelectionBorderCol.IncreaseLuminance( 128 ); 9499 else 9500 aSelectionBorderCol.DecreaseLuminance( 128 ); 9501 } 9502 9503 Rectangle aRect( rRect ); 9504 if( bDrawExtBorderOnly ) 9505 { 9506 aRect.nLeft -= 1; 9507 aRect.nTop -= 1; 9508 aRect.nRight += 1; 9509 aRect.nBottom += 1; 9510 } 9511 Color oldFillCol = GetFillColor(); 9512 Color oldLineCol = GetLineColor(); 9513 9514 if( bDrawBorder ) 9515 SetLineColor( bDark ? Color(COL_WHITE) : ( bBright ? Color(COL_BLACK) : aSelectionBorderCol ) ); 9516 else 9517 SetLineColor(); 9518 9519 sal_uInt16 nPercent = 0; 9520 if( !highlight ) 9521 { 9522 if( bDark ) 9523 aSelectionFillCol = COL_BLACK; 9524 else 9525 nPercent = 80; // just checked (light) 9526 } 9527 else 9528 { 9529 if( bChecked && highlight == 2 ) 9530 { 9531 if( bDark ) 9532 aSelectionFillCol = COL_LIGHTGRAY; 9533 else if ( bBright ) 9534 { 9535 aSelectionFillCol = COL_BLACK; 9536 SetLineColor( COL_BLACK ); 9537 nPercent = 0; 9538 } 9539 else 9540 nPercent = bRoundEdges ? 40 : 20; // selected, pressed or checked ( very dark ) 9541 } 9542 else if( bChecked || highlight == 1 ) 9543 { 9544 if( bDark ) 9545 aSelectionFillCol = COL_GRAY; 9546 else if ( bBright ) 9547 { 9548 aSelectionFillCol = COL_BLACK; 9549 SetLineColor( COL_BLACK ); 9550 nPercent = 0; 9551 } 9552 else 9553 nPercent = bRoundEdges ? 60 : 35; // selected, pressed or checked ( very dark ) 9554 } 9555 else 9556 { 9557 if( bDark ) 9558 aSelectionFillCol = COL_LIGHTGRAY; 9559 else if ( bBright ) 9560 { 9561 aSelectionFillCol = COL_BLACK; 9562 SetLineColor( COL_BLACK ); 9563 if( highlight == 3 ) 9564 nPercent = 80; 9565 else 9566 nPercent = 0; 9567 } 9568 else 9569 nPercent = 70; // selected ( dark ) 9570 } 9571 } 9572 9573 if( bDark && bDrawExtBorderOnly ) 9574 { 9575 SetFillColor(); 9576 if( pSelectionTextColor ) 9577 *pSelectionTextColor = rStyles.GetHighlightTextColor(); 9578 } 9579 else 9580 { 9581 SetFillColor( aSelectionFillCol ); 9582 if( pSelectionTextColor ) 9583 { 9584 Color aTextColor = IsControlBackground() ? GetControlForeground() : rStyles.GetButtonTextColor(); 9585 Color aHLTextColor = rStyles.GetHighlightTextColor(); 9586 int nTextDiff = abs(aSelectionFillCol.GetLuminance() - aTextColor.GetLuminance()); 9587 int nHLDiff = abs(aSelectionFillCol.GetLuminance() - aHLTextColor.GetLuminance()); 9588 *pSelectionTextColor = (nHLDiff >= nTextDiff) ? aHLTextColor : aTextColor; 9589 } 9590 } 9591 9592 9593 if( bDark ) 9594 { 9595 DrawRect( aRect ); 9596 } 9597 else 9598 { 9599 if( bRoundEdges ) 9600 { 9601 Polygon aPoly( aRect, nCornerRadius, nCornerRadius ); 9602 PolyPolygon aPolyPoly( aPoly ); 9603 DrawTransparent( aPolyPoly, nPercent ); 9604 } 9605 else 9606 { 9607 Polygon aPoly( aRect ); 9608 PolyPolygon aPolyPoly( aPoly ); 9609 DrawTransparent( aPolyPoly, nPercent ); 9610 } 9611 } 9612 9613 SetFillColor( oldFillCol ); 9614 SetLineColor( oldLineCol ); 9615 } 9616 9617 /* 9618 void Window::DbgAssertNoEventListeners() 9619 { 9620 VclWindowEvent aEvent( this, 0, NULL ); 9621 DBG_ASSERT( mpWindowImpl->maEventListeners.empty(), "Eventlistener: Who is still listening???" ) 9622 if ( !mpWindowImpl->maEventListeners.empty() ) 9623 mpWindowImpl->maEventListeners.Call( &aEvent ); 9624 9625 DBG_ASSERT( mpWindowImpl->maChildEventListeners.empty(), "ChildEventlistener: Who is still listening???" ) 9626 if ( !mpWindowImpl->maChildEventListeners.empty() ) 9627 mpWindowImpl->maChildEventListeners.Call( &aEvent ); 9628 } 9629 */ 9630 9631 // controls should return the window that gets the 9632 // focus by default, so keyevents can be sent to that window directly 9633 Window* Window::GetPreferredKeyInputWindow() 9634 { 9635 return this; 9636 } 9637 9638 9639 sal_Bool Window::IsScrollable() const 9640 { 9641 // check for scrollbars 9642 Window *pChild = mpWindowImpl->mpFirstChild; 9643 while( pChild ) 9644 { 9645 if( pChild->GetType() == WINDOW_SCROLLBAR ) 9646 return true; 9647 else 9648 pChild = pChild->mpWindowImpl->mpNext; 9649 } 9650 return false; 9651 } 9652 9653 sal_Bool Window::IsTopWindow() const 9654 { 9655 if ( mpWindowImpl->mbInDtor ) 9656 return sal_False; 9657 9658 // topwindows must be frames or they must have a borderwindow which is a frame 9659 if( !mpWindowImpl->mbFrame && (!mpWindowImpl->mpBorderWindow || (mpWindowImpl->mpBorderWindow && !mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ) ) 9660 return sal_False; 9661 9662 ImplGetWinData(); 9663 if( mpWindowImpl->mpWinData->mnIsTopWindow == (sal_uInt16)~0) // still uninitialized 9664 { 9665 // #113722#, cache result of expensive queryInterface call 9666 Window *pThisWin = (Window*)this; 9667 uno::Reference< XTopWindow > xTopWindow( pThisWin->GetComponentInterface(), UNO_QUERY ); 9668 pThisWin->mpWindowImpl->mpWinData->mnIsTopWindow = xTopWindow.is() ? 1 : 0; 9669 } 9670 return mpWindowImpl->mpWinData->mnIsTopWindow == 1 ? sal_True : sal_False; 9671 } 9672 9673 void Window::ImplMirrorFramePos( Point &pt ) const 9674 { 9675 pt.X() = mpWindowImpl->mpFrame->maGeometry.nWidth-1-pt.X(); 9676 } 9677 9678 // frame based modal counter (dialogs are not modal to the whole application anymore) 9679 sal_Bool Window::IsInModalMode() const 9680 { 9681 return (mpWindowImpl->mpFrameWindow->mpWindowImpl->mpFrameData->mnModalMode != 0); 9682 } 9683 void Window::ImplIncModalCount() 9684 { 9685 Window* pFrameWindow = mpWindowImpl->mpFrameWindow; 9686 Window* pParent = pFrameWindow; 9687 while( pFrameWindow ) 9688 { 9689 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode++; 9690 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow ) 9691 { 9692 pParent = pParent->GetParent(); 9693 } 9694 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL; 9695 } 9696 } 9697 void Window::ImplDecModalCount() 9698 { 9699 Window* pFrameWindow = mpWindowImpl->mpFrameWindow; 9700 Window* pParent = pFrameWindow; 9701 while( pFrameWindow ) 9702 { 9703 pFrameWindow->mpWindowImpl->mpFrameData->mnModalMode--; 9704 while( pParent && pParent->mpWindowImpl->mpFrameWindow == pFrameWindow ) 9705 { 9706 pParent = pParent->GetParent(); 9707 } 9708 pFrameWindow = pParent ? pParent->mpWindowImpl->mpFrameWindow : NULL; 9709 } 9710 } 9711 sal_Bool Window::ImplIsInTaskPaneList() 9712 { 9713 return mpWindowImpl->mbIsInTaskPaneList; 9714 } 9715 void Window::ImplIsInTaskPaneList( sal_Bool mbIsInTaskList ) 9716 { 9717 mpWindowImpl->mbIsInTaskPaneList = mbIsInTaskList; 9718 } 9719 9720 void Window::ImplNotifyIconifiedState( sal_Bool bIconified ) 9721 { 9722 mpWindowImpl->mpFrameWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE ); 9723 // #109206# notify client window as well to have toolkit topwindow listeners notified 9724 if( mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow && mpWindowImpl->mpFrameWindow != mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow ) 9725 mpWindowImpl->mpFrameWindow->mpWindowImpl->mpClientWindow->ImplCallEventListeners( bIconified ? VCLEVENT_WINDOW_MINIMIZE : VCLEVENT_WINDOW_NORMALIZE ); 9726 } 9727 9728 sal_Bool Window::HasActiveChildFrame() 9729 { 9730 sal_Bool bRet = sal_False; 9731 Window *pFrameWin = ImplGetSVData()->maWinData.mpFirstFrame; 9732 while( pFrameWin ) 9733 { 9734 if( pFrameWin != mpWindowImpl->mpFrameWindow ) 9735 { 9736 sal_Bool bDecorated = sal_False; 9737 Window *pChildFrame = pFrameWin->ImplGetWindow(); 9738 // #i15285# unfortunately WB_MOVEABLE is the same as WB_TABSTOP which can 9739 // be removed for ToolBoxes to influence the keyboard accessibility 9740 // thus WB_MOVEABLE is no indicator for decoration anymore 9741 // but FloatingWindows carry this information in their TitleType... 9742 // TODO: avoid duplicate WinBits !!! 9743 if( pChildFrame && pChildFrame->ImplIsFloatingWindow() ) 9744 bDecorated = ((FloatingWindow*) pChildFrame)->GetTitleType() != FLOATWIN_TITLE_NONE; 9745 if( bDecorated || (pFrameWin->mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) ) ) 9746 if( pChildFrame && pChildFrame->IsVisible() && pChildFrame->IsActive() ) 9747 { 9748 if( ImplIsChild( pChildFrame, sal_True ) ) 9749 { 9750 bRet = sal_True; 9751 break; 9752 } 9753 } 9754 } 9755 pFrameWin = pFrameWin->mpWindowImpl->mpFrameData->mpNextFrame; 9756 } 9757 return bRet; 9758 } 9759 9760 LanguageType Window::GetInputLanguage() const 9761 { 9762 return mpWindowImpl->mpFrame->GetInputLanguage(); 9763 } 9764 9765 void Window::EnableNativeWidget( sal_Bool bEnable ) 9766 { 9767 static const char* pNoNWF = getenv( "SAL_NO_NWF" ); 9768 if( pNoNWF && *pNoNWF ) 9769 bEnable = sal_False; 9770 9771 if( bEnable != ImplGetWinData()->mbEnableNativeWidget ) 9772 { 9773 ImplGetWinData()->mbEnableNativeWidget = bEnable; 9774 9775 // send datachanged event to allow for internal changes required for NWF 9776 // like clipmode, transparency, etc. 9777 DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &maSettings, SETTINGS_STYLE ); 9778 DataChanged( aDCEvt ); 9779 9780 // sometimes the borderwindow is queried, so keep it in sync 9781 if( mpWindowImpl->mpBorderWindow ) 9782 mpWindowImpl->mpBorderWindow->ImplGetWinData()->mbEnableNativeWidget = bEnable; 9783 } 9784 9785 // push down, useful for compound controls 9786 Window *pChild = mpWindowImpl->mpFirstChild; 9787 while( pChild ) 9788 { 9789 pChild->EnableNativeWidget( bEnable ); 9790 pChild = pChild->mpWindowImpl->mpNext; 9791 } 9792 } 9793 9794 sal_Bool Window::IsNativeWidgetEnabled() const 9795 { 9796 return ImplGetWinData()->mbEnableNativeWidget; 9797 } 9798 9799 #ifdef WNT // see #140456# 9800 #include <win/salframe.h> 9801 #endif 9802 9803 uno::Reference< rendering::XCanvas > Window::ImplGetCanvas( const Size& rFullscreenSize, 9804 bool bFullscreen, 9805 bool bSpriteCanvas ) const 9806 { 9807 // try to retrieve hard reference from weak member 9808 uno::Reference< rendering::XCanvas > xCanvas( mpWindowImpl->mxCanvas ); 9809 9810 // canvas still valid? Then we're done. 9811 if( xCanvas.is() ) 9812 return xCanvas; 9813 9814 Sequence< Any > aArg(6); 9815 9816 // Feed any with operating system's window handle 9817 // ============================================== 9818 9819 // common: first any is VCL pointer to window (for VCL canvas) 9820 aArg[ 0 ] = makeAny( reinterpret_cast<sal_Int64>(this) ); 9821 9822 // TODO(Q1): Make GetSystemData method virtual 9823 9824 // check whether we're a SysChild: have to fetch system data 9825 // directly from SystemChildWindow, because the GetSystemData 9826 // method is unfortunately not virtual 9827 const SystemChildWindow* pSysChild = dynamic_cast< const SystemChildWindow* >( this ); 9828 if( pSysChild ) 9829 { 9830 aArg[ 1 ] = pSysChild->GetSystemDataAny(); 9831 aArg[ 5 ] = pSysChild->GetSystemGfxDataAny(); 9832 } 9833 else 9834 { 9835 aArg[ 1 ] = GetSystemDataAny(); 9836 aArg[ 5 ] = GetSystemGfxDataAny(); 9837 } 9838 9839 if( bFullscreen ) 9840 aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( 0, 0, 9841 rFullscreenSize.Width(), 9842 rFullscreenSize.Height() ) ); 9843 else 9844 aArg[ 2 ] = makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) ); 9845 9846 aArg[ 3 ] = makeAny( mpWindowImpl->mbAlwaysOnTop ? sal_True : sal_False ); 9847 aArg[ 4 ] = makeAny( uno::Reference< awt::XWindow >( 9848 const_cast<Window*>(this)->GetComponentInterface(), 9849 uno::UNO_QUERY )); 9850 9851 uno::Reference< XMultiServiceFactory > xFactory = vcl::unohelper::GetMultiServiceFactory(); 9852 9853 // Create canvas instance with window handle 9854 // ========================================= 9855 if ( xFactory.is() ) 9856 { 9857 static ::vcl::DeleteUnoReferenceOnDeinit<lang::XMultiServiceFactory> xStaticCanvasFactory( 9858 uno::Reference<lang::XMultiServiceFactory>( 9859 xFactory->createInstance( 9860 OUString( RTL_CONSTASCII_USTRINGPARAM( 9861 "com.sun.star.rendering.CanvasFactory") ) ), 9862 UNO_QUERY )); 9863 uno::Reference<lang::XMultiServiceFactory> xCanvasFactory(xStaticCanvasFactory.get()); 9864 9865 if(xCanvasFactory.is()) 9866 { 9867 #ifdef WNT 9868 // see #140456# - if we're running on a multiscreen setup, 9869 // request special, multi-screen safe sprite canvas 9870 // implementation (not DX5 canvas, as it cannot cope with 9871 // surfaces spanning multiple displays). Note: canvas 9872 // (without sprite) stays the same) 9873 const sal_uInt32 nDisplay = static_cast< WinSalFrame* >( mpWindowImpl->mpFrame )->mnDisplay; 9874 if( (nDisplay >= Application::GetScreenCount()) ) 9875 { 9876 xCanvas.set( xCanvasFactory->createInstanceWithArguments( 9877 bSpriteCanvas ? 9878 OUString( RTL_CONSTASCII_USTRINGPARAM( 9879 "com.sun.star.rendering.SpriteCanvas.MultiScreen" )) : 9880 OUString( RTL_CONSTASCII_USTRINGPARAM( 9881 "com.sun.star.rendering.Canvas.MultiScreen" )), 9882 aArg ), 9883 UNO_QUERY ); 9884 9885 } 9886 else 9887 { 9888 #endif 9889 xCanvas.set( xCanvasFactory->createInstanceWithArguments( 9890 bSpriteCanvas ? 9891 OUString( RTL_CONSTASCII_USTRINGPARAM( 9892 "com.sun.star.rendering.SpriteCanvas" )) : 9893 OUString( RTL_CONSTASCII_USTRINGPARAM( 9894 "com.sun.star.rendering.Canvas" )), 9895 aArg ), 9896 UNO_QUERY ); 9897 9898 #ifdef WNT 9899 } 9900 #endif 9901 9902 mpWindowImpl->mxCanvas = xCanvas; 9903 } 9904 } 9905 9906 // no factory??? Empty reference, then. 9907 return xCanvas; 9908 } 9909 9910 uno::Reference< rendering::XCanvas > Window::GetCanvas() const 9911 { 9912 return ImplGetCanvas( Size(), false, false ); 9913 } 9914 9915 uno::Reference< rendering::XSpriteCanvas > Window::GetSpriteCanvas() const 9916 { 9917 uno::Reference< rendering::XSpriteCanvas > xSpriteCanvas( 9918 ImplGetCanvas( Size(), false, true ), uno::UNO_QUERY ); 9919 return xSpriteCanvas; 9920 } 9921 9922 uno::Reference< ::com::sun::star::rendering::XSpriteCanvas > Window::GetFullscreenSpriteCanvas( const Size& rFullscreenSize ) const 9923 { 9924 uno::Reference< rendering::XSpriteCanvas > xSpriteCanvas( 9925 ImplGetCanvas( rFullscreenSize, true, true ), uno::UNO_QUERY ); 9926 return xSpriteCanvas; 9927 } 9928 9929 void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos ) 9930 { 9931 sal_Bool bRVisible = mpWindowImpl->mbReallyVisible; 9932 mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible; 9933 sal_Bool bDevOutput = mbDevOutput; 9934 mbDevOutput = sal_True; 9935 9936 long nOldDPIX = ImplGetDPIX(); 9937 long nOldDPIY = ImplGetDPIY(); 9938 mnDPIX = i_pTargetOutDev->ImplGetDPIX(); 9939 mnDPIY = i_pTargetOutDev->ImplGetDPIY(); 9940 sal_Bool bOutput = IsOutputEnabled(); 9941 EnableOutput(); 9942 9943 DBG_ASSERT( GetMapMode().GetMapUnit() == MAP_PIXEL, "MapMode must be PIXEL based" ); 9944 if ( GetMapMode().GetMapUnit() != MAP_PIXEL ) 9945 return; 9946 9947 // preserve graphicsstate 9948 Push(); 9949 Region aClipRegion( GetClipRegion() ); 9950 SetClipRegion(); 9951 9952 GDIMetaFile* pOldMtf = GetConnectMetaFile(); 9953 GDIMetaFile aMtf; 9954 SetConnectMetaFile( &aMtf ); 9955 9956 // put a push action to metafile 9957 Push(); 9958 // copy graphics state to metafile 9959 Font aCopyFont = GetFont(); 9960 if( nOldDPIX != mnDPIX || nOldDPIY != mnDPIY ) 9961 { 9962 aCopyFont.SetHeight( aCopyFont.GetHeight() * mnDPIY / nOldDPIY ); 9963 aCopyFont.SetWidth( aCopyFont.GetWidth() * mnDPIX / nOldDPIX ); 9964 } 9965 SetFont( aCopyFont ); 9966 SetTextColor( GetTextColor() ); 9967 if( IsLineColor() ) 9968 SetLineColor( GetLineColor() ); 9969 else 9970 SetLineColor(); 9971 if( IsFillColor() ) 9972 SetFillColor( GetFillColor() ); 9973 else 9974 SetFillColor(); 9975 if( IsTextLineColor() ) 9976 SetTextLineColor( GetTextLineColor() ); 9977 else 9978 SetTextLineColor(); 9979 if( IsOverlineColor() ) 9980 SetOverlineColor( GetOverlineColor() ); 9981 else 9982 SetOverlineColor(); 9983 if( IsTextFillColor() ) 9984 SetTextFillColor( GetTextFillColor() ); 9985 else 9986 SetTextFillColor(); 9987 SetTextAlign( GetTextAlign() ); 9988 SetRasterOp( GetRasterOp() ); 9989 if( IsRefPoint() ) 9990 SetRefPoint( GetRefPoint() ); 9991 else 9992 SetRefPoint(); 9993 SetLayoutMode( GetLayoutMode() ); 9994 SetDigitLanguage( GetDigitLanguage() ); 9995 Rectangle aPaintRect( Point( 0, 0 ), GetOutputSizePixel() ); 9996 aClipRegion.Intersect( aPaintRect ); 9997 SetClipRegion( aClipRegion ); 9998 9999 // do the actual paint 10000 10001 // background 10002 if( ! IsPaintTransparent() && IsBackground() && ! (GetParentClipMode() & PARENTCLIPMODE_NOCLIP ) ) 10003 Erase(); 10004 // foreground 10005 Paint( aPaintRect ); 10006 // put a pop action to metafile 10007 Pop(); 10008 10009 SetConnectMetaFile( pOldMtf ); 10010 EnableOutput( bOutput ); 10011 mpWindowImpl->mbReallyVisible = bRVisible; 10012 10013 // paint metafile to VDev 10014 VirtualDevice* pMaskedDevice = new VirtualDevice( *i_pTargetOutDev, 0, 0 ); 10015 pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() ); 10016 pMaskedDevice->EnableRTL( IsRTLEnabled() ); 10017 aMtf.WindStart(); 10018 aMtf.Play( pMaskedDevice ); 10019 BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), pMaskedDevice->GetOutputSizePixel() ) ); 10020 i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx ); 10021 // get rid of virtual device now so they don't pile up during recursive calls 10022 delete pMaskedDevice, pMaskedDevice = NULL; 10023 10024 10025 for( Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext ) 10026 { 10027 if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() ) 10028 { 10029 long nDeltaX = pChild->mnOutOffX - mnOutOffX; 10030 if( ImplHasMirroredGraphics() ) 10031 nDeltaX = mnOutWidth - nDeltaX - pChild->mnOutWidth; 10032 long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel(); 10033 Point aPos( i_rPos ); 10034 Point aDelta( nDeltaX, nDeltaY ); 10035 aPos += aDelta; 10036 pChild->ImplPaintToDevice( i_pTargetOutDev, aPos ); 10037 } 10038 } 10039 10040 // restore graphics state 10041 Pop(); 10042 10043 EnableOutput( bOutput ); 10044 mpWindowImpl->mbReallyVisible = bRVisible; 10045 mbDevOutput = bDevOutput; 10046 mnDPIX = nOldDPIX; 10047 mnDPIY = nOldDPIY; 10048 } 10049 10050 void Window::PaintToDevice( OutputDevice* pDev, const Point& rPos, const Size& /*rSize*/ ) 10051 { 10052 // FIXME: scaling: currently this is for pixel copying only 10053 10054 DBG_ASSERT( ! pDev->ImplHasMirroredGraphics(), "PaintToDevice to mirroring graphics" ); 10055 DBG_ASSERT( ! pDev->IsRTLEnabled(), "PaintToDevice to mirroring device" ); 10056 10057 10058 Point aPos = pDev->LogicToPixel( rPos ); 10059 10060 Window* pRealParent = NULL; 10061 if( ! mpWindowImpl->mbVisible ) 10062 { 10063 Window* pTempParent = ImplGetDefaultWindow(); 10064 if( pTempParent ) 10065 pTempParent->EnableChildTransparentMode(); 10066 pRealParent = GetParent(); 10067 SetParent( pTempParent ); 10068 // trigger correct visibility flags for children 10069 Show(); 10070 Hide(); 10071 } 10072 10073 sal_Bool bVisible = mpWindowImpl->mbVisible; 10074 mpWindowImpl->mbVisible = sal_True; 10075 10076 if( mpWindowImpl->mpBorderWindow ) 10077 mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos ); 10078 else 10079 ImplPaintToDevice( pDev, rPos ); 10080 10081 mpWindowImpl->mbVisible = bVisible; 10082 10083 if( pRealParent ) 10084 SetParent( pRealParent ); 10085 } 10086 10087 XubString Window::GetSurroundingText() const 10088 { 10089 return XubString::EmptyString(); 10090 } 10091 10092 Selection Window::GetSurroundingTextSelection() const 10093 { 10094 return Selection( 0, 0 ); 10095 } 10096 10097