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