1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <config_features.h>
23 #include <tools/time.hxx>
25 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
27 #include <vcl/ITiledRenderable.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/salgtype.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/floatwin.hxx>
32 #include <vcl/cursor.hxx>
33 #include <vcl/sysdata.hxx>
35 #include <sal/types.h>
42 #include <salframe.hxx>
44 #include "dndlistenercontainer.hxx"
45 #include "dndeventdispatcher.hxx"
47 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
48 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
50 #include <comphelper/processfactory.hxx>
52 using namespace ::com::sun::star::uno
;
56 WindowHitTest
Window::ImplHitTest( const Point
& rFramePos
)
58 Point
aFramePos( rFramePos
);
59 if( ImplIsAntiparallel() )
61 // - RTL - re-mirror frame pos at this window
62 const OutputDevice
*pOutDev
= GetOutDev();
63 pOutDev
->ReMirror( aFramePos
);
65 Rectangle
aRect( Point( mnOutOffX
, mnOutOffY
), Size( mnOutWidth
, mnOutHeight
) );
66 if ( !aRect
.IsInside( aFramePos
) )
67 return WindowHitTest::NONE
;
68 if ( mpWindowImpl
->mbWinRegion
)
70 Point aTempPos
= aFramePos
;
71 aTempPos
.X() -= mnOutOffX
;
72 aTempPos
.Y() -= mnOutOffY
;
73 if ( !mpWindowImpl
->maWinRegion
.IsInside( aTempPos
) )
74 return WindowHitTest::NONE
;
77 WindowHitTest nHitTest
= WindowHitTest::Inside
;
78 if ( mpWindowImpl
->mbMouseTransparent
)
79 nHitTest
|= WindowHitTest::Transparent
;
83 bool Window::ImplTestMousePointerSet()
85 // as soon as mouse is captured, switch mouse-pointer
86 if ( IsMouseCaptured() )
89 // if the mouse is over the window, switch it
90 Rectangle
aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
91 if ( aClientRect
.IsInside( GetPointerPosPixel() ) )
97 PointerStyle
Window::ImplGetMousePointer() const
99 PointerStyle ePointerStyle
;
102 if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
103 ePointerStyle
= GetPointer().GetStyle();
105 ePointerStyle
= PointerStyle::Arrow
;
107 const vcl::Window
* pWindow
= this;
110 // when the pointer is not visible stop the search, as
111 // this status should not be overwritten
112 if ( pWindow
->mpWindowImpl
->mbNoPtrVisible
)
113 return PointerStyle::Null
;
117 if ( pWindow
->mpWindowImpl
->mnWaitCount
)
119 ePointerStyle
= PointerStyle::Wait
;
124 if ( pWindow
->mpWindowImpl
->mbChildPtrOverwrite
)
125 ePointerStyle
= pWindow
->GetPointer().GetStyle();
129 if ( pWindow
->ImplIsOverlapWindow() )
132 pWindow
= pWindow
->ImplGetParent();
136 return ePointerStyle
;
139 void Window::ImplCallMouseMove( sal_uInt16 nMouseCode
, bool bModChanged
)
141 if ( mpWindowImpl
->mpFrameData
->mbMouseIn
&& mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mbReallyVisible
)
143 sal_uInt64 nTime
= tools::Time::GetSystemTicks();
144 long nX
= mpWindowImpl
->mpFrameData
->mnLastMouseX
;
145 long nY
= mpWindowImpl
->mpFrameData
->mnLastMouseY
;
146 sal_uInt16 nCode
= nMouseCode
;
147 MouseEventModifiers nMode
= mpWindowImpl
->mpFrameData
->mnMouseMode
;
149 // check for MouseLeave
150 if ( ((nX
< 0) || (nY
< 0) ||
151 (nX
>= mpWindowImpl
->mpFrameWindow
->mnOutWidth
) ||
152 (nY
>= mpWindowImpl
->mpFrameWindow
->mnOutHeight
)) &&
153 !ImplGetSVData()->maWinData
.mpCaptureWin
)
157 nMode
|= MouseEventModifiers::SYNTHETIC
;
159 nMode
|= MouseEventModifiers::MODIFIERCHANGED
;
160 ImplHandleMouseEvent( mpWindowImpl
->mpFrameWindow
, MouseNotifyEvent::MOUSEMOVE
, bLeave
, nX
, nY
, nTime
, nCode
, nMode
);
164 void Window::ImplGenerateMouseMove()
166 if ( mpWindowImpl
&& mpWindowImpl
->mpFrameData
&&
167 !mpWindowImpl
->mpFrameData
->mnMouseMoveId
)
168 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= Application::PostUserEvent( LINK( mpWindowImpl
->mpFrameWindow
, Window
, ImplGenerateMouseMoveHdl
), nullptr, true );
171 IMPL_LINK_NOARG(Window
, ImplGenerateMouseMoveHdl
, void*, void)
173 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= nullptr;
174 vcl::Window
* pCaptureWin
= ImplGetSVData()->maWinData
.mpCaptureWin
;
176 (pCaptureWin
->mpWindowImpl
&& pCaptureWin
->mpWindowImpl
->mpFrame
== mpWindowImpl
->mpFrame
)
179 ImplCallMouseMove( mpWindowImpl
->mpFrameData
->mnMouseCode
);
183 void Window::ImplInvertFocus( const Rectangle
& rRect
)
185 InvertTracking( rRect
, ShowTrackFlags::Small
| ShowTrackFlags::TrackWindow
);
188 static bool IsWindowFocused(const WindowImpl
& rWinImpl
)
190 if (rWinImpl
.mpSysObj
)
193 if (rWinImpl
.mpFrameData
->mbHasFocus
)
196 if (rWinImpl
.mbFakeFocusSet
)
202 void Window::ImplGrabFocus( GetFocusFlags nFlags
)
204 // #143570# no focus for destructing windows
205 if( !mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
208 // some event listeners do really bad stuff
209 // => prepare for the worst
210 VclPtr
<vcl::Window
> xWindow( this );
212 // Currently the client window should always get the focus
213 // Should the border window at some point be focusable
214 // we need to change all GrabFocus() instances in VCL,
217 if ( mpWindowImpl
->mpClientWindow
)
219 // For a lack of design we need a little hack here to
220 // ensure that dialogs on close pass the focus back to
221 // the correct window
222 if ( mpWindowImpl
->mpLastFocusWindow
&& (mpWindowImpl
->mpLastFocusWindow
.get() != this) &&
223 !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) &&
224 mpWindowImpl
->mpLastFocusWindow
->IsEnabled() &&
225 mpWindowImpl
->mpLastFocusWindow
->IsInputEnabled() &&
226 ! mpWindowImpl
->mpLastFocusWindow
->IsInModalMode()
228 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
230 mpWindowImpl
->mpClientWindow
->GrabFocus();
233 else if ( mpWindowImpl
->mbFrame
)
235 // For a lack of design we need a little hack here to
236 // ensure that dialogs on close pass the focus back to
237 // the correct window
238 if ( mpWindowImpl
->mpLastFocusWindow
&& (mpWindowImpl
->mpLastFocusWindow
.get() != this) &&
239 !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) &&
240 mpWindowImpl
->mpLastFocusWindow
->IsEnabled() &&
241 mpWindowImpl
->mpLastFocusWindow
->IsInputEnabled() &&
242 ! mpWindowImpl
->mpLastFocusWindow
->IsInModalMode()
245 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
250 // If the Window is disabled, then we don't change the focus
251 if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() )
254 // we only need to set the focus if it is not already set
255 // note: if some other frame is waiting for an asynchronous focus event
256 // we also have to post an asynchronous focus event for this frame
257 // which is done using ToTop
258 ImplSVData
* pSVData
= ImplGetSVData();
260 bool bAsyncFocusWaiting
= false;
261 vcl::Window
*pFrame
= pSVData
->maWinData
.mpFirstFrame
;
264 if( pFrame
!= mpWindowImpl
->mpFrameWindow
.get() && pFrame
->mpWindowImpl
->mpFrameData
->mnFocusId
)
266 bAsyncFocusWaiting
= true;
269 pFrame
= pFrame
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
272 bool bHasFocus
= IsWindowFocused(*mpWindowImpl
);
274 bool bMustNotGrabFocus
= false;
275 // #100242#, check parent hierarchy if some floater prohibits grab focus
277 vcl::Window
*pParent
= this;
280 if ((pParent
->GetStyle() & WB_SYSTEMFLOATWIN
) && !(pParent
->GetStyle() & WB_MOVEABLE
))
282 bMustNotGrabFocus
= true;
285 pParent
= pParent
->mpWindowImpl
->mpParent
;
288 if ( ( pSVData
->maWinData
.mpFocusWin
.get() != this &&
289 !mpWindowImpl
->mbInDispose
) ||
290 ( bAsyncFocusWaiting
&& !bHasFocus
&& !bMustNotGrabFocus
) )
292 // EndExtTextInput if it is not the same window
293 if ( pSVData
->maWinData
.mpExtTextInputWin
&&
294 (pSVData
->maWinData
.mpExtTextInputWin
.get() != this) )
295 pSVData
->maWinData
.mpExtTextInputWin
->EndExtTextInput();
297 // mark this windows as the last FocusWindow
298 vcl::Window
* pOverlapWindow
= ImplGetFirstOverlapWindow();
299 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= this;
300 mpWindowImpl
->mpFrameData
->mpFocusWin
= this;
304 // menu windows never get the system focus
305 // the application will keep the focus
306 if( bMustNotGrabFocus
)
310 // here we already switch focus as ToTop()
311 // should not give focus to another window
312 mpWindowImpl
->mpFrame
->ToTop( SalFrameToTop::GrabFocus
| SalFrameToTop::GrabFocusOnly
);
317 VclPtr
<vcl::Window
> pOldFocusWindow
= pSVData
->maWinData
.mpFocusWin
;
319 pSVData
->maWinData
.mpFocusWin
= this;
321 if ( pOldFocusWindow
)
324 if ( pOldFocusWindow
->mpWindowImpl
->mpCursor
)
325 pOldFocusWindow
->mpWindowImpl
->mpCursor
->ImplHide();
328 // !!!!! due to old SV-Office Activate/Deactivate handling
329 // !!!!! first as before
330 if ( pOldFocusWindow
)
333 vcl::Window
* pOldOverlapWindow
= pOldFocusWindow
->ImplGetFirstOverlapWindow();
334 vcl::Window
* pNewOverlapWindow
= ImplGetFirstOverlapWindow();
335 if ( pOldOverlapWindow
!= pNewOverlapWindow
)
336 ImplCallFocusChangeActivate( pNewOverlapWindow
, pOldOverlapWindow
);
340 vcl::Window
* pNewOverlapWindow
= ImplGetFirstOverlapWindow();
341 vcl::Window
* pNewRealWindow
= pNewOverlapWindow
->ImplGetWindow();
342 pNewOverlapWindow
->mpWindowImpl
->mbActive
= true;
343 pNewOverlapWindow
->Activate();
344 if ( pNewRealWindow
!= pNewOverlapWindow
)
346 pNewRealWindow
->mpWindowImpl
->mbActive
= true;
347 pNewRealWindow
->Activate();
351 // call Get- and LoseFocus
352 if ( pOldFocusWindow
&& ! pOldFocusWindow
->IsDisposed() )
354 if ( pOldFocusWindow
->IsTracking() &&
355 (pSVData
->maWinData
.mnTrackFlags
& StartTrackingFlags::FocusCancel
) )
356 pOldFocusWindow
->EndTracking( TrackingEventFlags::Cancel
| TrackingEventFlags::Focus
);
357 NotifyEvent
aNEvt( MouseNotifyEvent::LOSEFOCUS
, pOldFocusWindow
);
358 if ( !ImplCallPreNotify( aNEvt
) )
359 pOldFocusWindow
->CompatLoseFocus();
360 pOldFocusWindow
->ImplCallDeactivateListeners( this );
363 if ( pSVData
->maWinData
.mpFocusWin
.get() == this )
365 if ( mpWindowImpl
->mpSysObj
)
367 mpWindowImpl
->mpFrameData
->mpFocusWin
= this;
368 if ( !mpWindowImpl
->mpFrameData
->mbInSysObjFocusHdl
)
369 mpWindowImpl
->mpSysObj
->GrabFocus();
372 if ( pSVData
->maWinData
.mpFocusWin
.get() == this )
374 if ( mpWindowImpl
->mpCursor
)
375 mpWindowImpl
->mpCursor
->ImplShow();
376 mpWindowImpl
->mbInFocusHdl
= true;
377 mpWindowImpl
->mnGetFocusFlags
= nFlags
;
378 // if we're changing focus due to closing a popup floating window
379 // notify the new focus window so it can restore the inner focus
380 // eg, toolboxes can select their recent active item
381 if( pOldFocusWindow
&&
382 ! pOldFocusWindow
->IsDisposed() &&
383 ( pOldFocusWindow
->GetDialogControlFlags() & DialogControlFlags::FloatWinPopupModeEndCancel
) )
384 mpWindowImpl
->mnGetFocusFlags
|= GetFocusFlags::FloatWinPopupModeEndCancel
;
385 NotifyEvent
aNEvt( MouseNotifyEvent::GETFOCUS
, this );
386 if ( !ImplCallPreNotify( aNEvt
) && !xWindow
->IsDisposed() )
388 if( !xWindow
->IsDisposed() )
389 ImplCallActivateListeners( (pOldFocusWindow
&& ! pOldFocusWindow
->IsDisposed()) ? pOldFocusWindow
: nullptr );
390 if( !xWindow
->IsDisposed() )
392 mpWindowImpl
->mnGetFocusFlags
= GetFocusFlags::NONE
;
393 mpWindowImpl
->mbInFocusHdl
= false;
398 ImplNewInputContext();
402 void Window::ImplGrabFocusToDocument( GetFocusFlags nFlags
)
404 vcl::Window
*pWin
= this;
407 if( !pWin
->GetParent() )
409 pWin
->ImplGetFrameWindow()->GetWindow( GetWindowType::Client
)->ImplGrabFocus(nFlags
);
412 pWin
= pWin
->GetParent();
416 void Window::MouseMove( const MouseEvent
& rMEvt
)
418 NotifyEvent
aNEvt( MouseNotifyEvent::MOUSEMOVE
, this, &rMEvt
);
419 if (!EventNotify(aNEvt
))
420 mpWindowImpl
->mbMouseMove
= true;
423 void Window::MouseButtonDown( const MouseEvent
& rMEvt
)
425 NotifyEvent
aNEvt( MouseNotifyEvent::MOUSEBUTTONDOWN
, this, &rMEvt
);
426 if (!EventNotify(aNEvt
))
427 mpWindowImpl
->mbMouseButtonDown
= true;
430 void Window::MouseButtonUp( const MouseEvent
& rMEvt
)
432 NotifyEvent
aNEvt( MouseNotifyEvent::MOUSEBUTTONUP
, this, &rMEvt
);
433 if (!EventNotify(aNEvt
))
434 mpWindowImpl
->mbMouseButtonUp
= true;
437 void Window::SetMouseTransparent( bool bTransparent
)
440 if ( mpWindowImpl
->mpBorderWindow
)
441 mpWindowImpl
->mpBorderWindow
->SetMouseTransparent( bTransparent
);
443 if( mpWindowImpl
->mpSysObj
)
444 mpWindowImpl
->mpSysObj
->SetMouseTransparent( bTransparent
);
446 mpWindowImpl
->mbMouseTransparent
= bTransparent
;
449 void Window::CaptureMouse()
452 ImplSVData
* pSVData
= ImplGetSVData();
454 // possibly stop tracking
455 if ( pSVData
->maWinData
.mpTrackWin
.get() != this )
457 if ( pSVData
->maWinData
.mpTrackWin
)
458 pSVData
->maWinData
.mpTrackWin
->EndTracking( TrackingEventFlags::Cancel
);
461 if ( pSVData
->maWinData
.mpCaptureWin
.get() != this )
463 pSVData
->maWinData
.mpCaptureWin
= this;
464 mpWindowImpl
->mpFrame
->CaptureMouse( true );
468 void Window::ReleaseMouse()
471 ImplSVData
* pSVData
= ImplGetSVData();
473 SAL_WARN_IF(!IsMouseCaptured(), "vcl",
474 "Window::ReleaseMouse(): window doesn't have the mouse capture" );
476 if (IsMouseCaptured())
478 pSVData
->maWinData
.mpCaptureWin
= nullptr;
479 mpWindowImpl
->mpFrame
->CaptureMouse( false );
480 ImplGenerateMouseMove();
484 bool Window::IsMouseCaptured() const
487 return (this == ImplGetSVData()->maWinData
.mpCaptureWin
);
490 void Window::SetPointer( const Pointer
& rPointer
)
493 if ( mpWindowImpl
->maPointer
== rPointer
)
496 mpWindowImpl
->maPointer
= rPointer
;
498 // possibly immediately move pointer
499 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
500 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
502 if (VclPtr
<vcl::Window
> pWin
= GetParentWithLOKNotifier())
504 Pointer aPointer
= GetPointer();
505 // We don't map all possible pointers hence we need a default
506 OString aPointerString
= "default";
507 auto aIt
= vcl::gaLOKPointerMap
.find(aPointer
.GetStyle());
508 if (aIt
!= vcl::gaLOKPointerMap
.end())
510 aPointerString
= aIt
->second
;
513 // issue mouse pointer events only for document windows
514 // Doc windows' immediate parent SfxFrameViewWindow_Impl is the one with
515 // parent notifier set during initialization
516 if (GetParent()->ImplGetWindowImpl()->mbLOKParentNotifier
&&
517 GetParent()->ImplGetWindowImpl()->mnLOKWindowId
== 0)
519 pWin
->GetLOKNotifier()->libreOfficeKitViewCallback(LOK_CALLBACK_MOUSE_POINTER
, aPointerString
.getStr());
524 void Window::EnableChildPointerOverwrite( bool bOverwrite
)
527 if ( mpWindowImpl
->mbChildPtrOverwrite
== bOverwrite
)
530 mpWindowImpl
->mbChildPtrOverwrite
= bOverwrite
;
532 // possibly immediately move pointer
533 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
534 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
537 void Window::SetPointerPosPixel( const Point
& rPos
)
539 Point aPos
= ImplOutputToFrame( rPos
);
540 const OutputDevice
*pOutDev
= GetOutDev();
541 if( pOutDev
->HasMirroredGraphics() )
543 if( !IsRTLEnabled() )
545 // --- RTL --- (re-mirror mouse pos at this window)
546 pOutDev
->ReMirror( aPos
);
548 // mirroring is required here, SetPointerPos bypasses SalGraphics
549 mpGraphics
->mirror( aPos
.X(), this );
551 else if( ImplIsAntiparallel() )
553 pOutDev
->ReMirror( aPos
);
555 mpWindowImpl
->mpFrame
->SetPointerPos( aPos
.X(), aPos
.Y() );
558 void Window::SetLastMousePos(const Point
& rPos
)
560 // Do this conversion, so when GetPointerPosPixel() calls
561 // ImplFrameToOutput(), we get back the original position.
562 Point aPos
= ImplOutputToFrame(rPos
);
563 mpWindowImpl
->mpFrameData
->mnLastMouseX
= aPos
.X();
564 mpWindowImpl
->mpFrameData
->mnLastMouseY
= aPos
.Y();
567 Point
Window::GetPointerPosPixel()
570 Point
aPos( mpWindowImpl
->mpFrameData
->mnLastMouseX
, mpWindowImpl
->mpFrameData
->mnLastMouseY
);
571 if( ImplIsAntiparallel() )
573 // --- RTL --- (re-mirror mouse pos at this window)
574 const OutputDevice
*pOutDev
= GetOutDev();
575 pOutDev
->ReMirror( aPos
);
577 return ImplFrameToOutput( aPos
);
580 Point
Window::GetLastPointerPosPixel()
583 Point
aPos( mpWindowImpl
->mpFrameData
->mnBeforeLastMouseX
, mpWindowImpl
->mpFrameData
->mnBeforeLastMouseY
);
584 if( ImplIsAntiparallel() )
586 // --- RTL --- (re-mirror mouse pos at this window)
587 const OutputDevice
*pOutDev
= GetOutDev();
588 pOutDev
->ReMirror( aPos
);
590 return ImplFrameToOutput( aPos
);
593 void Window::ShowPointer( bool bVisible
)
596 if ( mpWindowImpl
->mbNoPtrVisible
!= !bVisible
)
598 mpWindowImpl
->mbNoPtrVisible
= !bVisible
;
600 // possibly immediately move pointer
601 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
602 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
606 Window::PointerState
Window::GetPointerState()
611 if (mpWindowImpl
->mpFrame
)
613 SalFrame::SalPointerState aSalPointerState
;
615 aSalPointerState
= mpWindowImpl
->mpFrame
->GetPointerState();
616 if( ImplIsAntiparallel() )
618 // --- RTL --- (re-mirror mouse pos at this window)
619 const OutputDevice
*pOutDev
= GetOutDev();
620 pOutDev
->ReMirror( aSalPointerState
.maPos
);
622 aState
.maPos
= ImplFrameToOutput( aSalPointerState
.maPos
);
623 aState
.mnState
= aSalPointerState
.mnState
;
628 bool Window::IsMouseOver()
630 return ImplGetWinData()->mbMouseOver
;
633 void Window::EnterWait()
636 mpWindowImpl
->mnWaitCount
++;
638 if ( mpWindowImpl
->mnWaitCount
== 1 )
640 // possibly immediately move pointer
641 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
642 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
646 void Window::LeaveWait()
649 if ( mpWindowImpl
->mnWaitCount
)
651 mpWindowImpl
->mnWaitCount
--;
653 if ( !mpWindowImpl
->mnWaitCount
)
655 // possibly immediately move pointer
656 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
657 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
662 bool Window::ImplStopDnd()
665 if( mpWindowImpl
->mpFrameData
&& mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
668 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
669 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
670 mpWindowImpl
->mpFrameData
->mxDropTargetListener
.clear();
676 void Window::ImplStartDnd()
681 Reference
< css::datatransfer::dnd::XDropTarget
> Window::GetDropTarget()
684 return Reference
< css::datatransfer::dnd::XDropTarget
>();
686 if( ! mpWindowImpl
->mxDNDListenerContainer
.is() )
688 sal_Int8 nDefaultActions
= 0;
690 if( mpWindowImpl
->mpFrameData
)
692 if( ! mpWindowImpl
->mpFrameData
->mxDropTarget
.is() )
694 // initialization is done in GetDragSource
695 Reference
< css::datatransfer::dnd::XDragSource
> xDragSource
= GetDragSource();
698 if( mpWindowImpl
->mpFrameData
->mxDropTarget
.is() )
700 nDefaultActions
= mpWindowImpl
->mpFrameData
->mxDropTarget
->getDefaultActions();
702 if( ! mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
704 mpWindowImpl
->mpFrameData
->mxDropTargetListener
= new DNDEventDispatcher( mpWindowImpl
->mpFrameWindow
);
708 mpWindowImpl
->mpFrameData
->mxDropTarget
->addDropTargetListener( mpWindowImpl
->mpFrameData
->mxDropTargetListener
);
710 // register also as drag gesture listener if directly supported by drag source
711 Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> xDragGestureRecognizer
=
712 Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> (mpWindowImpl
->mpFrameData
->mxDragSource
, UNO_QUERY
);
714 if( xDragGestureRecognizer
.is() )
716 xDragGestureRecognizer
->addDragGestureListener(
717 Reference
< css::datatransfer::dnd::XDragGestureListener
> (mpWindowImpl
->mpFrameData
->mxDropTargetListener
, UNO_QUERY
));
720 mpWindowImpl
->mpFrameData
->mbInternalDragGestureRecognizer
= true;
723 catch (const RuntimeException
&)
725 // release all instances
726 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
727 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
734 mpWindowImpl
->mxDNDListenerContainer
= static_cast < css::datatransfer::dnd::XDropTarget
* > ( new DNDListenerContainer( nDefaultActions
) );
737 // this object is located in the same process, so there will be no runtime exception
738 return Reference
< css::datatransfer::dnd::XDropTarget
> ( mpWindowImpl
->mxDNDListenerContainer
, UNO_QUERY
);
741 Reference
< css::datatransfer::dnd::XDragSource
> Window::GetDragSource()
744 #if HAVE_FEATURE_DESKTOP
746 if( mpWindowImpl
->mpFrameData
)
748 if( ! mpWindowImpl
->mpFrameData
->mxDragSource
.is() )
752 Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
753 const SystemEnvData
* pEnvData
= GetSystemData();
757 Sequence
< Any
> aDragSourceAL( 2 ), aDropTargetAL( 2 );
758 OUString aDragSourceSN
, aDropTargetSN
;
760 aDragSourceSN
= "com.sun.star.datatransfer.dnd.OleDragSource";
761 aDropTargetSN
= "com.sun.star.datatransfer.dnd.OleDropTarget";
762 aDragSourceAL
[ 1 ] = makeAny( static_cast<sal_uInt64
>( reinterpret_cast<sal_IntPtr
>(pEnvData
->hWnd
) ) );
763 aDropTargetAL
[ 0 ] = makeAny( static_cast<sal_uInt64
>( reinterpret_cast<sal_IntPtr
>(pEnvData
->hWnd
) ) );
765 /* FIXME: Mac OS X specific dnd interface does not exist! *
766 * Using Windows based dnd as a temporary solution */
767 aDragSourceSN
= "com.sun.star.datatransfer.dnd.OleDragSource";
768 aDropTargetSN
= "com.sun.star.datatransfer.dnd.OleDropTarget";
769 aDragSourceAL
[ 1 ] = makeAny( static_cast<sal_uInt64
>( reinterpret_cast<sal_IntPtr
>(pEnvData
->mpNSView
) ) );
770 aDropTargetAL
[ 0 ] = makeAny( static_cast<sal_uInt64
>( reinterpret_cast<sal_IntPtr
>(pEnvData
->mpNSView
) ) );
771 #elif HAVE_FEATURE_X11
772 aDragSourceSN
= "com.sun.star.datatransfer.dnd.X11DragSource";
773 aDropTargetSN
= "com.sun.star.datatransfer.dnd.X11DropTarget";
775 aDragSourceAL
[ 0 ] = makeAny( Application::GetDisplayConnection() );
776 aDragSourceAL
[ 1 ] = makeAny(static_cast<sal_IntPtr
>(pEnvData
->aShellWindow
));
777 aDropTargetAL
[ 0 ] = makeAny( Application::GetDisplayConnection() );
778 aDropTargetAL
[ 1 ] = makeAny(static_cast<sal_IntPtr
>(pEnvData
->aShellWindow
));
780 if( !aDragSourceSN
.isEmpty() )
781 mpWindowImpl
->mpFrameData
->mxDragSource
.set(
782 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( aDragSourceSN
, aDragSourceAL
, xContext
),
785 if( !aDropTargetSN
.isEmpty() )
786 mpWindowImpl
->mpFrameData
->mxDropTarget
.set(
787 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( aDropTargetSN
, aDropTargetAL
, xContext
),
792 // createInstance can throw any exception
793 catch (const Exception
&)
795 // release all instances
796 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
797 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
801 return mpWindowImpl
->mpFrameData
->mxDragSource
;
804 return Reference
< css::datatransfer::dnd::XDragSource
> ();
807 Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> Window::GetDragGestureRecognizer()
809 return Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> ( GetDropTarget(), UNO_QUERY
);
812 } /* namespace vcl */
814 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */