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