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