Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <config_features.h>
22 :
23 : #include <tools/time.hxx>
24 :
25 : #include <vcl/svapp.hxx>
26 : #include <vcl/salgtype.hxx>
27 : #include <vcl/window.hxx>
28 : #include <vcl/floatwin.hxx>
29 : #include <vcl/cursor.hxx>
30 : #include <vcl/sysdata.hxx>
31 :
32 : #include <sal/types.h>
33 :
34 : #include <window.h>
35 : #include <outdev.h>
36 : #include <svdata.hxx>
37 : #include <salobj.hxx>
38 : #include <salgdi.hxx>
39 : #include <salframe.hxx>
40 : #include <dndlcon.hxx>
41 : #include <dndevdis.hxx>
42 :
43 : #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
44 : #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
45 :
46 : #include <comphelper/processfactory.hxx>
47 :
48 : using namespace ::com::sun::star::uno;
49 :
50 : namespace vcl {
51 :
52 0 : sal_uInt16 Window::ImplHitTest( const Point& rFramePos )
53 : {
54 0 : Point aFramePos( rFramePos );
55 0 : if( ImplIsAntiparallel() )
56 : {
57 : // - RTL - re-mirror frame pos at this window
58 0 : const OutputDevice *pOutDev = GetOutDev();
59 0 : pOutDev->ReMirror( aFramePos );
60 : }
61 0 : Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
62 0 : if ( !aRect.IsInside( aFramePos ) )
63 0 : return 0;
64 0 : if ( mpWindowImpl->mbWinRegion )
65 : {
66 0 : Point aTempPos = aFramePos;
67 0 : aTempPos.X() -= mnOutOffX;
68 0 : aTempPos.Y() -= mnOutOffY;
69 0 : if ( !mpWindowImpl->maWinRegion.IsInside( aTempPos ) )
70 0 : return 0;
71 : }
72 :
73 0 : sal_uInt16 nHitTest = WINDOW_HITTEST_INSIDE;
74 0 : if ( mpWindowImpl->mbMouseTransparent )
75 0 : nHitTest |= WINDOW_HITTEST_TRANSPARENT;
76 0 : return nHitTest;
77 : }
78 :
79 57101 : bool Window::ImplTestMousePointerSet()
80 : {
81 : // as soon as mouse is captured, switch mouse-pointer
82 57101 : if ( IsMouseCaptured() )
83 0 : return true;
84 :
85 : // if the mouse is over the window, switch it
86 57101 : Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
87 57101 : if ( aClientRect.IsInside( GetPointerPosPixel() ) )
88 0 : return true;
89 :
90 57101 : return false;
91 : }
92 :
93 0 : PointerStyle Window::ImplGetMousePointer() const
94 : {
95 : PointerStyle ePointerStyle;
96 0 : bool bWait = false;
97 :
98 0 : if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
99 0 : ePointerStyle = GetPointer().GetStyle();
100 : else
101 0 : ePointerStyle = POINTER_ARROW;
102 :
103 0 : const vcl::Window* pWindow = this;
104 0 : do
105 : {
106 : // when the pointer is not visible stop the search, as
107 : // this status should not be overwritten
108 0 : if ( pWindow->mpWindowImpl->mbNoPtrVisible )
109 0 : return POINTER_NULL;
110 :
111 0 : if ( !bWait )
112 : {
113 0 : if ( pWindow->mpWindowImpl->mnWaitCount )
114 : {
115 0 : ePointerStyle = POINTER_WAIT;
116 0 : bWait = true;
117 : }
118 : else
119 : {
120 0 : if ( pWindow->mpWindowImpl->mbChildPtrOverwrite )
121 0 : ePointerStyle = pWindow->GetPointer().GetStyle();
122 : }
123 : }
124 :
125 0 : if ( pWindow->ImplIsOverlapWindow() )
126 0 : break;
127 :
128 0 : pWindow = pWindow->ImplGetParent();
129 : }
130 : while ( pWindow );
131 :
132 0 : return ePointerStyle;
133 : }
134 :
135 9983 : void Window::ImplCallMouseMove( sal_uInt16 nMouseCode, bool bModChanged )
136 : {
137 9983 : if ( mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible )
138 : {
139 0 : sal_uLong nTime = tools::Time::GetSystemTicks();
140 0 : long nX = mpWindowImpl->mpFrameData->mnLastMouseX;
141 0 : long nY = mpWindowImpl->mpFrameData->mnLastMouseY;
142 0 : sal_uInt16 nCode = nMouseCode;
143 0 : sal_uInt16 nMode = mpWindowImpl->mpFrameData->mnMouseMode;
144 : bool bLeave;
145 : // check for MouseLeave
146 0 : if ( ((nX < 0) || (nY < 0) ||
147 0 : (nX >= mpWindowImpl->mpFrameWindow->mnOutWidth) ||
148 0 : (nY >= mpWindowImpl->mpFrameWindow->mnOutHeight)) &&
149 0 : !ImplGetSVData()->maWinData.mpCaptureWin )
150 0 : bLeave = true;
151 : else
152 0 : bLeave = false;
153 0 : nMode |= MOUSE_SYNTHETIC;
154 0 : if ( bModChanged )
155 0 : nMode |= MOUSE_MODIFIERCHANGED;
156 0 : ImplHandleMouseEvent( mpWindowImpl->mpFrameWindow, EVENT_MOUSEMOVE, bLeave, nX, nY, nTime, nCode, nMode );
157 : }
158 9983 : }
159 :
160 814481 : void Window::ImplGenerateMouseMove()
161 : {
162 814481 : if ( !mpWindowImpl->mpFrameData->mnMouseMoveId )
163 15452 : mpWindowImpl->mpFrameData->mnMouseMoveId = Application::PostUserEvent( LINK( mpWindowImpl->mpFrameWindow, Window, ImplGenerateMouseMoveHdl ) );
164 814481 : }
165 :
166 19966 : IMPL_LINK_NOARG(Window, ImplGenerateMouseMoveHdl)
167 : {
168 9983 : mpWindowImpl->mpFrameData->mnMouseMoveId = 0;
169 9983 : vcl::Window* pCaptureWin = ImplGetSVData()->maWinData.mpCaptureWin;
170 9983 : if( ! pCaptureWin ||
171 0 : (pCaptureWin->mpWindowImpl && pCaptureWin->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame)
172 : )
173 : {
174 9983 : ImplCallMouseMove( mpWindowImpl->mpFrameData->mnMouseCode );
175 : }
176 9983 : return 0;
177 : }
178 :
179 499 : void Window::ImplInvertFocus( const Rectangle& rRect )
180 : {
181 499 : InvertTracking( rRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
182 499 : }
183 :
184 36109 : static bool IsWindowFocused(const WindowImpl& rWinImpl)
185 : {
186 36109 : if (rWinImpl.mpSysObj)
187 0 : return true;
188 :
189 36109 : if (rWinImpl.mpFrameData->mbHasFocus)
190 30504 : return true;
191 :
192 5605 : if (rWinImpl.mbFakeFocusSet)
193 0 : return true;
194 :
195 5605 : return false;
196 : }
197 :
198 51503 : void Window::ImplGrabFocus( sal_uInt16 nFlags )
199 : {
200 : // #143570# no focus for destructing windows
201 51503 : if( mpWindowImpl->mbInDtor )
202 25984 : return;
203 :
204 : // some event listeners do really bad stuff
205 : // => prepare for the worst
206 46518 : ImplDelData aDogTag( this );
207 :
208 : // Currently the client window should always get the focus
209 : // Should the border window at some point be focusable
210 : // we need to change all GrabFocus() instances in VCL,
211 : // e.g. in ToTop()
212 :
213 46518 : if ( mpWindowImpl->mpClientWindow )
214 : {
215 : // For a lack of design we need a little hack here to
216 : // ensure that dialogs on close pass the focus back to
217 : // the correct window
218 20517 : if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
219 10110 : !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
220 10110 : mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
221 20515 : mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
222 5053 : ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
223 : )
224 5053 : mpWindowImpl->mpLastFocusWindow->GrabFocus();
225 : else
226 5354 : mpWindowImpl->mpClientWindow->GrabFocus();
227 10407 : return;
228 : }
229 36111 : else if ( mpWindowImpl->mbFrame )
230 : {
231 : // For a lack of design we need a little hack here to
232 : // ensure that dialogs on close pass the focus back to
233 : // the correct window
234 30 : if ( mpWindowImpl->mpLastFocusWindow && (mpWindowImpl->mpLastFocusWindow != this) &&
235 0 : !(mpWindowImpl->mnDlgCtrlFlags & WINDOW_DLGCTRL_WANTFOCUS) &&
236 0 : mpWindowImpl->mpLastFocusWindow->IsEnabled() &&
237 18 : mpWindowImpl->mpLastFocusWindow->IsInputEnabled() &&
238 0 : ! mpWindowImpl->mpLastFocusWindow->IsInModalMode()
239 : )
240 : {
241 0 : mpWindowImpl->mpLastFocusWindow->GrabFocus();
242 0 : return;
243 : }
244 : }
245 :
246 : // If the Window is disabled, then we don't change the focus
247 36111 : if ( !IsEnabled() || !IsInputEnabled() || IsInModalNonRefMode() )
248 2 : return;
249 :
250 : // we only need to set the focus if it is not already set
251 : // note: if some other frame is waiting for an asynchrounous focus event
252 : // we also have to post an asynchronous focus event for this frame
253 : // which is done using ToTop
254 36109 : ImplSVData* pSVData = ImplGetSVData();
255 :
256 36109 : bool bAsyncFocusWaiting = false;
257 36109 : vcl::Window *pFrame = pSVData->maWinData.mpFirstFrame;
258 168947 : while( pFrame )
259 : {
260 96730 : if( pFrame != mpWindowImpl->mpFrameWindow && pFrame->mpWindowImpl->mpFrameData->mnFocusId )
261 : {
262 1 : bAsyncFocusWaiting = true;
263 1 : break;
264 : }
265 96729 : pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
266 : }
267 :
268 36109 : bool bHasFocus = IsWindowFocused(*mpWindowImpl);
269 :
270 36109 : bool bMustNotGrabFocus = false;
271 : // #100242#, check parent hierarchy if some floater prohibits grab focus
272 :
273 36109 : vcl::Window *pParent = this;
274 204405 : while( pParent )
275 : {
276 : // #102158#, ignore grabfocus only if the floating parent grabs keyboard focus by itself (GrabsFocus())
277 : // otherwise we cannot set the focus in a floating toolbox
278 132187 : if( ( (pParent->mpWindowImpl->mbFloatWin && static_cast<FloatingWindow*>(pParent)->GrabsFocus()) || ( pParent->GetStyle() & WB_SYSTEMFLOATWIN ) ) && !( pParent->GetStyle() & WB_MOVEABLE ) )
279 : {
280 0 : bMustNotGrabFocus = true;
281 0 : break;
282 : }
283 132187 : pParent = pParent->mpWindowImpl->mpParent;
284 : }
285 :
286 36109 : if ( ( pSVData->maWinData.mpFocusWin != this && ! mpWindowImpl->mbInDtor ) || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
287 : {
288 : // EndExtTextInput if it is not the same window
289 36045 : if ( pSVData->maWinData.mpExtTextInputWin &&
290 0 : (pSVData->maWinData.mpExtTextInputWin != this) )
291 0 : pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
292 :
293 : // mark this windows as the last FocusWindow
294 36045 : vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow();
295 36045 : pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this;
296 36045 : mpWindowImpl->mpFrameData->mpFocusWin = this;
297 :
298 36045 : if( !bHasFocus )
299 : {
300 : // menu windows never get the system focus
301 : // the application will keep the focus
302 5605 : if( bMustNotGrabFocus )
303 5605 : return;
304 : else
305 : {
306 : // here we already switch focus as ToTop()
307 : // should not give focus to another window
308 : //DBG_WARNING( "Window::GrabFocus() - Frame doesn't have the focus" );
309 5605 : mpWindowImpl->mpFrame->ToTop( SAL_FRAME_TOTOP_GRABFOCUS | SAL_FRAME_TOTOP_GRABFOCUS_ONLY );
310 5605 : return;
311 : }
312 : }
313 :
314 30440 : vcl::Window* pOldFocusWindow = pSVData->maWinData.mpFocusWin;
315 30440 : ImplDelData aOldFocusDel( pOldFocusWindow );
316 :
317 30440 : pSVData->maWinData.mpFocusWin = this;
318 :
319 30440 : if ( pOldFocusWindow )
320 : {
321 : // Cursor hidden
322 25397 : if ( pOldFocusWindow->mpWindowImpl->mpCursor )
323 4212 : pOldFocusWindow->mpWindowImpl->mpCursor->ImplHide( true );
324 : }
325 :
326 : // !!!!! due to old SV-Office Activate/Deactivate handling
327 : // !!!!! first as before
328 30440 : if ( pOldFocusWindow )
329 : {
330 : // remember Focus
331 25397 : vcl::Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
332 25397 : vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
333 25397 : if ( pOldOverlapWindow != pNewOverlapWindow )
334 0 : ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
335 : }
336 : else
337 : {
338 5043 : vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
339 5043 : vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
340 5043 : pNewOverlapWindow->mpWindowImpl->mbActive = true;
341 5043 : pNewOverlapWindow->Activate();
342 5043 : if ( pNewRealWindow != pNewOverlapWindow )
343 : {
344 5037 : pNewRealWindow->mpWindowImpl->mbActive = true;
345 5037 : pNewRealWindow->Activate();
346 : }
347 : }
348 :
349 : // call Get- and LoseFocus
350 30440 : if ( pOldFocusWindow && ! aOldFocusDel.IsDead() )
351 : {
352 25397 : if ( pOldFocusWindow->IsTracking() &&
353 0 : (pSVData->maWinData.mnTrackFlags & STARTTRACK_FOCUSCANCEL) )
354 0 : pOldFocusWindow->EndTracking( ENDTRACK_CANCEL | ENDTRACK_FOCUS );
355 25397 : NotifyEvent aNEvt( EVENT_LOSEFOCUS, pOldFocusWindow );
356 25397 : if ( !ImplCallPreNotify( aNEvt ) )
357 25397 : pOldFocusWindow->LoseFocus();
358 25397 : pOldFocusWindow->ImplCallDeactivateListeners( this );
359 : }
360 :
361 30440 : if ( pSVData->maWinData.mpFocusWin == this )
362 : {
363 30440 : if ( mpWindowImpl->mpSysObj )
364 : {
365 0 : mpWindowImpl->mpFrameData->mpFocusWin = this;
366 0 : if ( !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl )
367 0 : mpWindowImpl->mpSysObj->GrabFocus();
368 : }
369 :
370 30440 : if ( pSVData->maWinData.mpFocusWin == this )
371 : {
372 30440 : if ( mpWindowImpl->mpCursor )
373 4250 : mpWindowImpl->mpCursor->ImplShow();
374 30440 : mpWindowImpl->mbInFocusHdl = true;
375 30440 : mpWindowImpl->mnGetFocusFlags = nFlags;
376 : // if we're changing focus due to closing a popup floating window
377 : // notify the new focus window so it can restore the inner focus
378 : // eg, toolboxes can select their recent active item
379 55837 : if( pOldFocusWindow &&
380 55837 : ! aOldFocusDel.IsDead() &&
381 25397 : ( pOldFocusWindow->GetDialogControlFlags() & WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL ) )
382 0 : mpWindowImpl->mnGetFocusFlags |= GETFOCUS_FLOATWIN_POPUPMODEEND_CANCEL;
383 30440 : NotifyEvent aNEvt( EVENT_GETFOCUS, this );
384 30440 : if ( !ImplCallPreNotify( aNEvt ) && !aDogTag.IsDead() )
385 30440 : GetFocus();
386 30440 : if( !aDogTag.IsDead() )
387 30440 : ImplCallActivateListeners( (pOldFocusWindow && ! aOldFocusDel.IsDead()) ? pOldFocusWindow : NULL );
388 30440 : if( !aDogTag.IsDead() )
389 : {
390 30440 : mpWindowImpl->mnGetFocusFlags = 0;
391 30440 : mpWindowImpl->mbInFocusHdl = false;
392 : }
393 : }
394 : }
395 :
396 30440 : GetpApp()->FocusChanged();
397 30440 : ImplNewInputContext();
398 30504 : }
399 : }
400 :
401 4 : void Window::ImplGrabFocusToDocument( sal_uInt16 nFlags )
402 : {
403 4 : vcl::Window *pWin = this;
404 12 : while( pWin )
405 : {
406 8 : if( !pWin->GetParent() )
407 : {
408 4 : pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->ImplGrabFocus(nFlags);
409 8 : return;
410 : }
411 4 : pWin = pWin->GetParent();
412 : }
413 : }
414 :
415 0 : void Window::MouseMove( const MouseEvent& rMEvt )
416 : {
417 0 : NotifyEvent aNEvt( EVENT_MOUSEMOVE, this, &rMEvt );
418 0 : if ( !Notify( aNEvt ) )
419 0 : mpWindowImpl->mbMouseMove = true;
420 0 : }
421 :
422 0 : void Window::MouseButtonDown( const MouseEvent& rMEvt )
423 : {
424 0 : NotifyEvent aNEvt( EVENT_MOUSEBUTTONDOWN, this, &rMEvt );
425 0 : if ( !Notify( aNEvt ) )
426 0 : mpWindowImpl->mbMouseButtonDown = true;
427 0 : }
428 :
429 0 : void Window::MouseButtonUp( const MouseEvent& rMEvt )
430 : {
431 0 : NotifyEvent aNEvt( EVENT_MOUSEBUTTONUP, this, &rMEvt );
432 0 : if ( !Notify( aNEvt ) )
433 0 : mpWindowImpl->mbMouseButtonUp = true;
434 0 : }
435 :
436 230 : void Window::SetMouseTransparent( bool bTransparent )
437 : {
438 :
439 230 : if ( mpWindowImpl->mpBorderWindow )
440 43 : mpWindowImpl->mpBorderWindow->SetMouseTransparent( bTransparent );
441 :
442 230 : if( mpWindowImpl->mpSysObj )
443 0 : mpWindowImpl->mpSysObj->SetMouseTransparent( bTransparent );
444 :
445 230 : mpWindowImpl->mbMouseTransparent = bTransparent;
446 230 : }
447 :
448 0 : void Window::CaptureMouse()
449 : {
450 :
451 0 : ImplSVData* pSVData = ImplGetSVData();
452 :
453 : // possibly stop tracking
454 0 : if ( pSVData->maWinData.mpTrackWin != this )
455 : {
456 0 : if ( pSVData->maWinData.mpTrackWin )
457 0 : pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
458 : }
459 :
460 0 : if ( pSVData->maWinData.mpCaptureWin != this )
461 : {
462 0 : pSVData->maWinData.mpCaptureWin = this;
463 0 : mpWindowImpl->mpFrame->CaptureMouse( true );
464 : }
465 0 : }
466 :
467 2800 : void Window::ReleaseMouse()
468 : {
469 :
470 2800 : ImplSVData* pSVData = ImplGetSVData();
471 :
472 : DBG_ASSERTWARNING( pSVData->maWinData.mpCaptureWin == this,
473 : "Window::ReleaseMouse(): window doesn't have the mouse capture" );
474 :
475 2800 : if ( pSVData->maWinData.mpCaptureWin == this )
476 : {
477 0 : pSVData->maWinData.mpCaptureWin = NULL;
478 0 : mpWindowImpl->mpFrame->CaptureMouse( false );
479 0 : ImplGenerateMouseMove();
480 : }
481 2800 : }
482 :
483 172473 : bool Window::IsMouseCaptured() const
484 : {
485 :
486 172473 : return (this == ImplGetSVData()->maWinData.mpCaptureWin);
487 : }
488 :
489 48987 : void Window::SetPointer( const Pointer& rPointer )
490 : {
491 :
492 48987 : if ( mpWindowImpl->maPointer == rPointer )
493 52359 : return;
494 :
495 45615 : mpWindowImpl->maPointer = rPointer;
496 :
497 : // possibly immediately move pointer
498 45615 : if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
499 0 : mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
500 : }
501 :
502 0 : void Window::EnableChildPointerOverwrite( bool bOverwrite )
503 : {
504 :
505 0 : if ( mpWindowImpl->mbChildPtrOverwrite == bOverwrite )
506 0 : return;
507 :
508 0 : mpWindowImpl->mbChildPtrOverwrite = bOverwrite;
509 :
510 : // possibly immediately move pointer
511 0 : if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
512 0 : mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
513 : }
514 :
515 0 : void Window::SetPointerPosPixel( const Point& rPos )
516 : {
517 0 : Point aPos = ImplOutputToFrame( rPos );
518 0 : const OutputDevice *pOutDev = GetOutDev();
519 0 : if( pOutDev->HasMirroredGraphics() )
520 : {
521 0 : if( !IsRTLEnabled() )
522 : {
523 : // --- RTL --- (re-mirror mouse pos at this window)
524 0 : pOutDev->ReMirror( aPos );
525 : }
526 : // mirroring is required here, SetPointerPos bypasses SalGraphics
527 0 : mpGraphics->mirror( aPos.X(), this );
528 : }
529 0 : else if( ImplIsAntiparallel() )
530 : {
531 0 : pOutDev->ReMirror( aPos );
532 : }
533 0 : mpWindowImpl->mpFrame->SetPointerPos( aPos.X(), aPos.Y() );
534 0 : }
535 :
536 80039 : Point Window::GetPointerPosPixel()
537 : {
538 :
539 80039 : Point aPos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
540 80039 : if( ImplIsAntiparallel() )
541 : {
542 : // --- RTL --- (re-mirror mouse pos at this window)
543 6 : const OutputDevice *pOutDev = GetOutDev();
544 6 : pOutDev->ReMirror( aPos );
545 : }
546 80039 : return ImplFrameToOutput( aPos );
547 : }
548 :
549 0 : Point Window::GetLastPointerPosPixel()
550 : {
551 :
552 0 : Point aPos( mpWindowImpl->mpFrameData->mnBeforeLastMouseX, mpWindowImpl->mpFrameData->mnBeforeLastMouseY );
553 0 : if( ImplIsAntiparallel() )
554 : {
555 : // --- RTL --- (re-mirror mouse pos at this window)
556 0 : const OutputDevice *pOutDev = GetOutDev();
557 0 : pOutDev->ReMirror( aPos );
558 : }
559 0 : return ImplFrameToOutput( aPos );
560 : }
561 :
562 0 : void Window::ShowPointer( bool bVisible )
563 : {
564 :
565 0 : if ( mpWindowImpl->mbNoPtrVisible != !bVisible )
566 : {
567 0 : mpWindowImpl->mbNoPtrVisible = !bVisible;
568 :
569 : // possibly immediately move pointer
570 0 : if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
571 0 : mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
572 : }
573 0 : }
574 :
575 427 : Window::PointerState Window::GetPointerState()
576 : {
577 427 : PointerState aState;
578 427 : aState.mnState = 0;
579 :
580 427 : if (mpWindowImpl->mpFrame)
581 : {
582 427 : SalFrame::SalPointerState aSalPointerState;
583 :
584 427 : aSalPointerState = mpWindowImpl->mpFrame->GetPointerState();
585 427 : if( ImplIsAntiparallel() )
586 : {
587 : // --- RTL --- (re-mirror mouse pos at this window)
588 0 : const OutputDevice *pOutDev = GetOutDev();
589 0 : pOutDev->ReMirror( aSalPointerState.maPos );
590 : }
591 427 : aState.maPos = ImplFrameToOutput( aSalPointerState.maPos );
592 427 : aState.mnState = aSalPointerState.mnState;
593 : }
594 427 : return aState;
595 : }
596 :
597 40504 : bool Window::IsMouseOver()
598 : {
599 40504 : return ImplGetWinData()->mbMouseOver;
600 : }
601 :
602 10437 : void Window::EnterWait()
603 : {
604 :
605 10437 : mpWindowImpl->mnWaitCount++;
606 :
607 10437 : if ( mpWindowImpl->mnWaitCount == 1 )
608 : {
609 : // possibly immediately move pointer
610 5743 : if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
611 0 : mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
612 : }
613 10437 : }
614 :
615 10437 : void Window::LeaveWait()
616 : {
617 :
618 10437 : if ( mpWindowImpl->mnWaitCount )
619 : {
620 10437 : mpWindowImpl->mnWaitCount--;
621 :
622 10437 : if ( !mpWindowImpl->mnWaitCount )
623 : {
624 : // possibly immediately move pointer
625 5743 : if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
626 0 : mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
627 : }
628 : }
629 10437 : }
630 :
631 0 : bool Window::ImplStopDnd()
632 : {
633 0 : bool bRet = false;
634 0 : if( mpWindowImpl->mpFrameData && mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
635 : {
636 0 : bRet = true;
637 0 : mpWindowImpl->mpFrameData->mxDropTarget.clear();
638 0 : mpWindowImpl->mpFrameData->mxDragSource.clear();
639 0 : mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
640 : }
641 :
642 0 : return bRet;
643 : }
644 :
645 0 : void Window::ImplStartDnd()
646 : {
647 0 : GetDropTarget();
648 0 : }
649 :
650 263298 : Reference< css::datatransfer::dnd::XDropTarget > Window::GetDropTarget()
651 : {
652 :
653 263298 : if( ! mpWindowImpl->mxDNDListenerContainer.is() )
654 : {
655 42280 : sal_Int8 nDefaultActions = 0;
656 :
657 42280 : if( mpWindowImpl->mpFrameData )
658 : {
659 42280 : if( ! mpWindowImpl->mpFrameData->mxDropTarget.is() )
660 : {
661 : // initialization is done in GetDragSource
662 15308 : Reference< css::datatransfer::dnd::XDragSource > xDragSource = GetDragSource();
663 : }
664 :
665 42280 : if( mpWindowImpl->mpFrameData->mxDropTarget.is() )
666 : {
667 29364 : nDefaultActions = mpWindowImpl->mpFrameData->mxDropTarget->getDefaultActions();
668 :
669 29364 : if( ! mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
670 : {
671 2392 : mpWindowImpl->mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpWindowImpl->mpFrameWindow );
672 :
673 : try
674 : {
675 2392 : mpWindowImpl->mpFrameData->mxDropTarget->addDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
676 :
677 : // register also as drag gesture listener if directly supported by drag source
678 : Reference< css::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer =
679 2392 : Reference< css::datatransfer::dnd::XDragGestureRecognizer > (mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
680 :
681 2392 : if( xDragGestureRecognizer.is() )
682 : {
683 0 : xDragGestureRecognizer->addDragGestureListener(
684 0 : Reference< css::datatransfer::dnd::XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
685 : }
686 : else
687 2392 : mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = true;
688 :
689 : }
690 0 : catch (const RuntimeException&)
691 : {
692 : // release all instances
693 0 : mpWindowImpl->mpFrameData->mxDropTarget.clear();
694 0 : mpWindowImpl->mpFrameData->mxDragSource.clear();
695 : }
696 : }
697 : }
698 :
699 : }
700 :
701 42280 : mpWindowImpl->mxDNDListenerContainer = static_cast < css::datatransfer::dnd::XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) );
702 : }
703 :
704 : // this object is located in the same process, so there will be no runtime exception
705 263298 : return Reference< css::datatransfer::dnd::XDropTarget > ( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );
706 : }
707 :
708 15310 : Reference< css::datatransfer::dnd::XDragSource > Window::GetDragSource()
709 : {
710 :
711 : #if HAVE_FEATURE_DESKTOP
712 :
713 15310 : if( mpWindowImpl->mpFrameData )
714 : {
715 15310 : if( ! mpWindowImpl->mpFrameData->mxDragSource.is() )
716 : {
717 : try
718 : {
719 15308 : Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
720 15308 : const SystemEnvData * pEnvData = GetSystemData();
721 :
722 15308 : if( pEnvData )
723 : {
724 30616 : Sequence< Any > aDragSourceAL( 2 ), aDropTargetAL( 2 );
725 30616 : OUString aDragSourceSN, aDropTargetSN;
726 : #if defined WNT
727 : aDragSourceSN = "com.sun.star.datatransfer.dnd.OleDragSource";
728 : aDropTargetSN = "com.sun.star.datatransfer.dnd.OleDropTarget";
729 : aDragSourceAL[ 1 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->hWnd) ) );
730 : aDropTargetAL[ 0 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->hWnd) ) );
731 : #elif defined MACOSX
732 : /* FIXME: Mac OS X specific dnd interface does not exist! *
733 : * Using Windows based dnd as a temporary solution */
734 : aDragSourceSN = "com.sun.star.datatransfer.dnd.OleDragSource";
735 : aDropTargetSN = "com.sun.star.datatransfer.dnd.OleDropTarget";
736 : aDragSourceAL[ 1 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->mpNSView) ) );
737 : aDropTargetAL[ 0 ] = makeAny( static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->mpNSView) ) );
738 : #elif HAVE_FEATURE_X11
739 15308 : aDragSourceSN = "com.sun.star.datatransfer.dnd.X11DragSource";
740 15308 : aDropTargetSN = "com.sun.star.datatransfer.dnd.X11DropTarget";
741 :
742 15308 : aDragSourceAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
743 15308 : aDropTargetAL[ 0 ] = makeAny( Application::GetDisplayConnection() );
744 15308 : aDropTargetAL[ 1 ] = makeAny( (sal_Size)(pEnvData->aShellWindow) );
745 : #endif
746 15308 : if( !aDragSourceSN.isEmpty() )
747 : mpWindowImpl->mpFrameData->mxDragSource.set(
748 30616 : xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDragSourceSN, aDragSourceAL, xContext ),
749 15308 : UNO_QUERY );
750 :
751 15308 : if( !aDropTargetSN.isEmpty() )
752 : mpWindowImpl->mpFrameData->mxDropTarget.set(
753 30616 : xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDropTargetSN, aDropTargetAL, xContext ),
754 30616 : UNO_QUERY );
755 15308 : }
756 : }
757 :
758 : // createInstance can throw any exception
759 0 : catch (const Exception&)
760 : {
761 : // release all instances
762 0 : mpWindowImpl->mpFrameData->mxDropTarget.clear();
763 0 : mpWindowImpl->mpFrameData->mxDragSource.clear();
764 : }
765 : }
766 :
767 15310 : return mpWindowImpl->mpFrameData->mxDragSource;
768 : }
769 : #endif
770 0 : return Reference< css::datatransfer::dnd::XDragSource > ();
771 : }
772 :
773 85320 : Reference< css::datatransfer::dnd::XDragGestureRecognizer > Window::GetDragGestureRecognizer()
774 : {
775 85320 : return Reference< css::datatransfer::dnd::XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY );
776 : }
777 :
778 1233 : } /* namespace vcl */
779 :
780 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|