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_feature_desktop.h>
22 #include <config_vclplug.h>
24 #include <tools/time.hxx>
26 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
28 #include <vcl/ITiledRenderable.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/cursor.hxx>
32 #include <vcl/sysdata.hxx>
33 #include <vcl/event.hxx>
35 #include <sal/types.h>
41 #include <salframe.hxx>
42 #include <salinst.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>
49 #include <com/sun/star/uno/XComponentContext.hpp>
51 #include <comphelper/processfactory.hxx>
53 using namespace ::com::sun::star::uno
;
57 WindowHitTest
Window::ImplHitTest( const Point
& rFramePos
)
59 Point
aFramePos( rFramePos
);
60 if( GetOutDev()->ImplIsAntiparallel() )
62 const OutputDevice
*pOutDev
= GetOutDev();
63 pOutDev
->ReMirror( aFramePos
);
65 if ( !GetOutputRectPixel().Contains( aFramePos
) )
66 return WindowHitTest::NONE
;
67 if ( mpWindowImpl
->mbWinRegion
)
69 Point aTempPos
= aFramePos
;
70 aTempPos
.AdjustX( -GetOutDev()->mnOutOffX
);
71 aTempPos
.AdjustY( -GetOutDev()->mnOutOffY
);
72 if ( !mpWindowImpl
->maWinRegion
.Contains( aTempPos
) )
73 return WindowHitTest::NONE
;
76 WindowHitTest nHitTest
= WindowHitTest::Inside
;
77 if ( mpWindowImpl
->mbMouseTransparent
)
78 nHitTest
|= WindowHitTest::Transparent
;
82 bool Window::ImplTestMousePointerSet()
84 // as soon as mouse is captured, switch mouse-pointer
85 if ( IsMouseCaptured() )
88 // if the mouse is over the window, switch it
89 tools::Rectangle
aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
90 return aClientRect
.Contains( GetPointerPosPixel() );
93 PointerStyle
Window::ImplGetMousePointer() const
95 PointerStyle ePointerStyle
;
98 if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
99 ePointerStyle
= GetPointer();
101 ePointerStyle
= PointerStyle::Arrow
;
103 const vcl::Window
* pWindow
= this;
106 // when the pointer is not visible stop the search, as
107 // this status should not be overwritten
108 if ( pWindow
->mpWindowImpl
->mbNoPtrVisible
)
109 return PointerStyle::Null
;
113 if ( pWindow
->mpWindowImpl
->mnWaitCount
)
115 ePointerStyle
= PointerStyle::Wait
;
120 if ( pWindow
->mpWindowImpl
->mbChildPtrOverwrite
)
121 ePointerStyle
= pWindow
->GetPointer();
125 if ( pWindow
->ImplIsOverlapWindow() )
128 pWindow
= pWindow
->ImplGetParent();
132 return ePointerStyle
;
135 void Window::ImplCallMouseMove( sal_uInt16 nMouseCode
, bool bModChanged
)
137 if ( !(mpWindowImpl
->mpFrameData
->mbMouseIn
&& mpWindowImpl
->mpFrameWindow
->mpWindowImpl
->mbReallyVisible
) )
140 sal_uInt64 nTime
= tools::Time::GetSystemTicks();
141 tools::Long nX
= mpWindowImpl
->mpFrameData
->mnLastMouseX
;
142 tools::Long nY
= mpWindowImpl
->mpFrameData
->mnLastMouseY
;
143 sal_uInt16 nCode
= nMouseCode
;
144 MouseEventModifiers nMode
= mpWindowImpl
->mpFrameData
->mnMouseMode
;
146 // check for MouseLeave
147 bLeave
= ((nX
< 0) || (nY
< 0) ||
148 (nX
>= mpWindowImpl
->mpFrameWindow
->GetOutDev()->mnOutWidth
) ||
149 (nY
>= mpWindowImpl
->mpFrameWindow
->GetOutDev()->mnOutHeight
)) &&
150 !ImplGetSVData()->mpWinData
->mpCaptureWin
;
151 nMode
|= MouseEventModifiers::SYNTHETIC
;
153 nMode
|= MouseEventModifiers::MODIFIERCHANGED
;
154 ImplHandleMouseEvent( mpWindowImpl
->mpFrameWindow
, NotifyEventType::MOUSEMOVE
, bLeave
, nX
, nY
, nTime
, nCode
, nMode
);
157 void Window::ImplGenerateMouseMove()
159 if ( mpWindowImpl
&& mpWindowImpl
->mpFrameData
&&
160 !mpWindowImpl
->mpFrameData
->mnMouseMoveId
)
161 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= Application::PostUserEvent( LINK( mpWindowImpl
->mpFrameWindow
, Window
, ImplGenerateMouseMoveHdl
), nullptr, true );
164 IMPL_LINK_NOARG(Window
, ImplGenerateMouseMoveHdl
, void*, void)
166 mpWindowImpl
->mpFrameData
->mnMouseMoveId
= nullptr;
167 vcl::Window
* pCaptureWin
= ImplGetSVData()->mpWinData
->mpCaptureWin
;
169 (pCaptureWin
->mpWindowImpl
&& pCaptureWin
->mpWindowImpl
->mpFrame
== mpWindowImpl
->mpFrame
)
172 ImplCallMouseMove( mpWindowImpl
->mpFrameData
->mnMouseCode
);
176 void Window::ImplInvertFocus( const tools::Rectangle
& rRect
)
178 InvertTracking( rRect
, ShowTrackFlags::Small
| ShowTrackFlags::TrackWindow
);
181 static bool IsWindowFocused(const WindowImpl
& rWinImpl
)
183 if (rWinImpl
.mpSysObj
)
186 if (rWinImpl
.mpFrameData
->mbHasFocus
)
189 if (rWinImpl
.mbFakeFocusSet
)
195 void Window::ImplGrabFocus( GetFocusFlags nFlags
)
197 // #143570# no focus for destructing windows
198 if( !mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
201 // some event listeners do really bad stuff
202 // => prepare for the worst
203 VclPtr
<vcl::Window
> xWindow( this );
205 // Currently the client window should always get the focus
206 // Should the border window at some point be focusable
207 // we need to change all GrabFocus() instances in VCL,
210 if ( mpWindowImpl
->mpClientWindow
)
212 // For a lack of design we need a little hack here to
213 // ensure that dialogs on close pass the focus back to
214 // the correct window
215 if ( mpWindowImpl
->mpLastFocusWindow
&& (mpWindowImpl
->mpLastFocusWindow
.get() != this) &&
216 !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) &&
217 mpWindowImpl
->mpLastFocusWindow
->IsEnabled() &&
218 mpWindowImpl
->mpLastFocusWindow
->IsInputEnabled() &&
219 ! mpWindowImpl
->mpLastFocusWindow
->IsInModalMode()
221 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
223 mpWindowImpl
->mpClientWindow
->GrabFocus();
226 else if ( mpWindowImpl
->mbFrame
)
228 // For a lack of design we need a little hack here to
229 // ensure that dialogs on close pass the focus back to
230 // the correct window
231 if ( mpWindowImpl
->mpLastFocusWindow
&& (mpWindowImpl
->mpLastFocusWindow
.get() != this) &&
232 !(mpWindowImpl
->mnDlgCtrlFlags
& DialogControlFlags::WantFocus
) &&
233 mpWindowImpl
->mpLastFocusWindow
->IsEnabled() &&
234 mpWindowImpl
->mpLastFocusWindow
->IsInputEnabled() &&
235 ! mpWindowImpl
->mpLastFocusWindow
->IsInModalMode()
238 mpWindowImpl
->mpLastFocusWindow
->GrabFocus();
243 // If the Window is disabled, then we don't change the focus
244 if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() )
247 // we only need to set the focus if it is not already set
248 // note: if some other frame is waiting for an asynchronous focus event
249 // we also have to post an asynchronous focus event for this frame
250 // which is done using ToTop
251 ImplSVData
* pSVData
= ImplGetSVData();
253 bool bAsyncFocusWaiting
= false;
254 vcl::Window
*pFrame
= pSVData
->maFrameData
.mpFirstFrame
;
255 while( pFrame
&& pFrame
->mpWindowImpl
&& pFrame
->mpWindowImpl
->mpFrameData
)
257 if( pFrame
!= mpWindowImpl
->mpFrameWindow
.get() && pFrame
->mpWindowImpl
->mpFrameData
->mnFocusId
)
259 bAsyncFocusWaiting
= true;
262 pFrame
= pFrame
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
265 bool bHasFocus
= IsWindowFocused(*mpWindowImpl
);
267 bool bMustNotGrabFocus
= false;
268 // #100242#, check parent hierarchy if some floater prohibits grab focus
270 vcl::Window
*pParent
= this;
273 if ((pParent
->GetStyle() & WB_SYSTEMFLOATWIN
) && !(pParent
->GetStyle() & WB_MOVEABLE
))
275 bMustNotGrabFocus
= true;
278 if (!pParent
->mpWindowImpl
)
280 pParent
= pParent
->mpWindowImpl
->mpParent
;
283 if ( !(( pSVData
->mpWinData
->mpFocusWin
.get() != this &&
284 !mpWindowImpl
->mbInDispose
) ||
285 ( bAsyncFocusWaiting
&& !bHasFocus
&& !bMustNotGrabFocus
)) )
288 // EndExtTextInput if it is not the same window
289 if (pSVData
->mpWinData
->mpExtTextInputWin
290 && (pSVData
->mpWinData
->mpExtTextInputWin
.get() != this))
291 pSVData
->mpWinData
->mpExtTextInputWin
->EndExtTextInput();
293 // mark this windows as the last FocusWindow
294 vcl::Window
* pOverlapWindow
= ImplGetFirstOverlapWindow();
295 if (pOverlapWindow
->mpWindowImpl
)
296 pOverlapWindow
->mpWindowImpl
->mpLastFocusWindow
= this;
297 mpWindowImpl
->mpFrameData
->mpFocusWin
= this;
301 // menu windows never get the system focus
302 // the application will keep the focus
303 if( bMustNotGrabFocus
)
307 // here we already switch focus as ToTop()
308 // should not give focus to another window
309 mpWindowImpl
->mpFrame
->ToTop( SalFrameToTop::GrabFocus
| SalFrameToTop::GrabFocusOnly
);
314 VclPtr
<vcl::Window
> pOldFocusWindow
= pSVData
->mpWinData
->mpFocusWin
;
316 pSVData
->mpWinData
->mpFocusWin
= this;
318 if ( pOldFocusWindow
&& pOldFocusWindow
->mpWindowImpl
)
321 if ( pOldFocusWindow
->mpWindowImpl
->mpCursor
)
322 pOldFocusWindow
->mpWindowImpl
->mpCursor
->ImplHide();
325 // !!!!! due to old SV-Office Activate/Deactivate handling
326 // !!!!! first as before
327 if ( pOldFocusWindow
)
330 vcl::Window
* pOldOverlapWindow
= pOldFocusWindow
->ImplGetFirstOverlapWindow();
331 vcl::Window
* pNewOverlapWindow
= ImplGetFirstOverlapWindow();
332 if ( pOldOverlapWindow
!= pNewOverlapWindow
)
333 ImplCallFocusChangeActivate( pNewOverlapWindow
, pOldOverlapWindow
);
337 vcl::Window
* pNewOverlapWindow
= ImplGetFirstOverlapWindow();
338 if ( pNewOverlapWindow
&& pNewOverlapWindow
->mpWindowImpl
)
340 vcl::Window
* pNewRealWindow
= pNewOverlapWindow
->ImplGetWindow();
341 pNewOverlapWindow
->mpWindowImpl
->mbActive
= true;
342 pNewOverlapWindow
->Activate();
343 if ( pNewRealWindow
!= pNewOverlapWindow
&& pNewRealWindow
&& pNewRealWindow
->mpWindowImpl
)
345 pNewRealWindow
->mpWindowImpl
->mbActive
= true;
346 pNewRealWindow
->Activate();
351 // call Get- and LoseFocus
352 if ( pOldFocusWindow
&& ! pOldFocusWindow
->isDisposed() )
354 NotifyEvent
aNEvt( NotifyEventType::LOSEFOCUS
, pOldFocusWindow
);
355 if ( !ImplCallPreNotify( aNEvt
) )
356 pOldFocusWindow
->CompatLoseFocus();
357 pOldFocusWindow
->ImplCallDeactivateListeners( this );
360 if (pSVData
->mpWinData
->mpFocusWin
.get() == this)
362 if ( mpWindowImpl
->mpSysObj
)
364 mpWindowImpl
->mpFrameData
->mpFocusWin
= this;
365 if ( !mpWindowImpl
->mpFrameData
->mbInSysObjFocusHdl
)
366 mpWindowImpl
->mpSysObj
->GrabFocus();
369 if (pSVData
->mpWinData
->mpFocusWin
.get() == this)
371 if ( mpWindowImpl
->mpCursor
)
372 mpWindowImpl
->mpCursor
->ImplShow();
373 mpWindowImpl
->mbInFocusHdl
= true;
374 mpWindowImpl
->mnGetFocusFlags
= nFlags
;
375 // if we're changing focus due to closing a popup floating window
376 // notify the new focus window so it can restore the inner focus
377 // eg, toolboxes can select their recent active item
378 if( pOldFocusWindow
&&
379 ! pOldFocusWindow
->isDisposed() &&
380 ( pOldFocusWindow
->GetDialogControlFlags() & DialogControlFlags::FloatWinPopupModeEndCancel
) )
381 mpWindowImpl
->mnGetFocusFlags
|= GetFocusFlags::FloatWinPopupModeEndCancel
;
382 NotifyEvent
aNEvt( NotifyEventType::GETFOCUS
, this );
383 if ( !ImplCallPreNotify( aNEvt
) && !xWindow
->isDisposed() )
385 if( !xWindow
->isDisposed() )
386 ImplCallActivateListeners( (pOldFocusWindow
&& ! pOldFocusWindow
->isDisposed()) ? pOldFocusWindow
: nullptr );
387 if( !xWindow
->isDisposed() )
389 mpWindowImpl
->mnGetFocusFlags
= GetFocusFlags::NONE
;
390 mpWindowImpl
->mbInFocusHdl
= false;
395 ImplNewInputContext();
399 void Window::ImplGrabFocusToDocument( GetFocusFlags nFlags
)
401 vcl::Window
*pWin
= this;
404 if( !pWin
->GetParent() )
406 pWin
->mpWindowImpl
->mpFrame
->GrabFocus();
407 pWin
->ImplGetFrameWindow()->GetWindow( GetWindowType::Client
)->ImplGrabFocus(nFlags
);
410 pWin
= pWin
->GetParent();
414 void Window::MouseMove( const MouseEvent
& rMEvt
)
416 NotifyEvent
aNEvt( NotifyEventType::MOUSEMOVE
, this, &rMEvt
);
420 void Window::MouseButtonDown( const MouseEvent
& rMEvt
)
422 NotifyEvent
aNEvt( NotifyEventType::MOUSEBUTTONDOWN
, this, &rMEvt
);
423 if (!EventNotify(aNEvt
) && mpWindowImpl
)
424 mpWindowImpl
->mbMouseButtonDown
= true;
427 void Window::MouseButtonUp( const MouseEvent
& rMEvt
)
429 NotifyEvent
aNEvt( NotifyEventType::MOUSEBUTTONUP
, this, &rMEvt
);
430 if (!EventNotify(aNEvt
) && mpWindowImpl
)
431 mpWindowImpl
->mbMouseButtonUp
= true;
434 void Window::SetMouseTransparent( bool bTransparent
)
437 if ( mpWindowImpl
->mpBorderWindow
)
438 mpWindowImpl
->mpBorderWindow
->SetMouseTransparent( bTransparent
);
440 if( mpWindowImpl
->mpSysObj
)
441 mpWindowImpl
->mpSysObj
->SetMouseTransparent( bTransparent
);
443 mpWindowImpl
->mbMouseTransparent
= bTransparent
;
446 void Window::LocalStartDrag()
448 ImplGetFrameData()->mbDragging
= true;
451 void Window::CaptureMouse()
453 ImplSVData
* pSVData
= ImplGetSVData();
455 // possibly stop tracking
456 if (pSVData
->mpWinData
->mpTrackWin
.get() != this)
458 if (pSVData
->mpWinData
->mpTrackWin
)
459 pSVData
->mpWinData
->mpTrackWin
->EndTracking(TrackingEventFlags::Cancel
);
462 if (pSVData
->mpWinData
->mpCaptureWin
.get() != this)
464 pSVData
->mpWinData
->mpCaptureWin
= this;
465 mpWindowImpl
->mpFrame
->CaptureMouse( true );
469 void Window::ReleaseMouse()
471 if (IsMouseCaptured())
473 ImplSVData
* pSVData
= ImplGetSVData();
474 pSVData
->mpWinData
->mpCaptureWin
= nullptr;
475 if (mpWindowImpl
&& mpWindowImpl
->mpFrame
)
476 mpWindowImpl
->mpFrame
->CaptureMouse( false );
477 ImplGenerateMouseMove();
481 bool Window::IsMouseCaptured() const
483 return (this == ImplGetSVData()->mpWinData
->mpCaptureWin
);
486 void Window::SetPointer( PointerStyle nPointer
)
488 if ( mpWindowImpl
->maPointer
== nPointer
)
491 mpWindowImpl
->maPointer
= nPointer
;
493 // possibly immediately move pointer
494 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
495 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
498 void Window::EnableChildPointerOverwrite( bool bOverwrite
)
501 if ( mpWindowImpl
->mbChildPtrOverwrite
== bOverwrite
)
504 mpWindowImpl
->mbChildPtrOverwrite
= bOverwrite
;
506 // possibly immediately move pointer
507 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
508 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
511 void Window::SetPointerPosPixel( const Point
& rPos
)
513 Point aPos
= ImplOutputToFrame( rPos
);
514 const OutputDevice
*pOutDev
= GetOutDev();
515 if( pOutDev
->HasMirroredGraphics() )
517 if( !IsRTLEnabled() )
519 pOutDev
->ReMirror( aPos
);
521 // mirroring is required here, SetPointerPos bypasses SalGraphics
522 aPos
.setX( GetOutDev()->mpGraphics
->mirror2( aPos
.X(), *GetOutDev() ) );
524 else if( GetOutDev()->ImplIsAntiparallel() )
526 pOutDev
->ReMirror( aPos
);
528 mpWindowImpl
->mpFrame
->SetPointerPos( aPos
.X(), aPos
.Y() );
531 void Window::SetLastMousePos(const Point
& rPos
)
533 // Do this conversion, so when GetPointerPosPixel() calls
534 // ImplFrameToOutput(), we get back the original position.
535 Point aPos
= ImplOutputToFrame(rPos
);
536 mpWindowImpl
->mpFrameData
->mnLastMouseX
= aPos
.X();
537 mpWindowImpl
->mpFrameData
->mnLastMouseY
= aPos
.Y();
540 Point
Window::GetPointerPosPixel()
543 Point
aPos( mpWindowImpl
->mpFrameData
->mnLastMouseX
, mpWindowImpl
->mpFrameData
->mnLastMouseY
);
544 if( GetOutDev()->ImplIsAntiparallel() )
546 const OutputDevice
*pOutDev
= GetOutDev();
547 pOutDev
->ReMirror( aPos
);
549 return ImplFrameToOutput( aPos
);
552 Point
Window::GetLastPointerPosPixel()
555 Point
aPos( mpWindowImpl
->mpFrameData
->mnBeforeLastMouseX
, mpWindowImpl
->mpFrameData
->mnBeforeLastMouseY
);
556 if( GetOutDev()->ImplIsAntiparallel() )
558 const OutputDevice
*pOutDev
= GetOutDev();
559 pOutDev
->ReMirror( aPos
);
561 return ImplFrameToOutput( aPos
);
564 void Window::ShowPointer( bool bVisible
)
567 if ( mpWindowImpl
->mbNoPtrVisible
!= !bVisible
)
569 mpWindowImpl
->mbNoPtrVisible
= !bVisible
;
571 // possibly immediately move pointer
572 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
573 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
577 Window::PointerState
Window::GetPointerState()
582 if (mpWindowImpl
->mpFrame
)
584 SalFrame::SalPointerState aSalPointerState
= mpWindowImpl
->mpFrame
->GetPointerState();
585 if( GetOutDev()->ImplIsAntiparallel() )
587 const OutputDevice
*pOutDev
= GetOutDev();
588 pOutDev
->ReMirror( aSalPointerState
.maPos
);
590 aState
.maPos
= ImplFrameToOutput( aSalPointerState
.maPos
);
591 aState
.mnState
= aSalPointerState
.mnState
;
596 bool Window::IsMouseOver() const
598 return ImplGetWinData()->mbMouseOver
;
601 void Window::EnterWait()
604 mpWindowImpl
->mnWaitCount
++;
606 if ( mpWindowImpl
->mnWaitCount
== 1 )
608 // possibly immediately move pointer
609 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
610 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
614 void Window::LeaveWait()
619 if ( mpWindowImpl
->mnWaitCount
)
621 mpWindowImpl
->mnWaitCount
--;
623 if ( !mpWindowImpl
->mnWaitCount
)
625 // possibly immediately move pointer
626 if ( !mpWindowImpl
->mpFrameData
->mbInMouseMove
&& ImplTestMousePointerSet() )
627 mpWindowImpl
->mpFrame
->SetPointer( ImplGetMousePointer() );
632 bool Window::ImplStopDnd()
635 if( mpWindowImpl
->mpFrameData
&& mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
638 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
639 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
640 mpWindowImpl
->mpFrameData
->mxDropTargetListener
.clear();
646 void Window::ImplStartDnd()
651 Reference
< css::datatransfer::dnd::XDropTarget
> Window::GetDropTarget()
654 return Reference
< css::datatransfer::dnd::XDropTarget
>();
656 if( ! mpWindowImpl
->mxDNDListenerContainer
.is() )
658 sal_Int8 nDefaultActions
= 0;
660 if( mpWindowImpl
->mpFrameData
)
662 if( ! mpWindowImpl
->mpFrameData
->mxDropTarget
.is() )
664 // initialization is done in GetDragSource
668 if( mpWindowImpl
->mpFrameData
->mxDropTarget
.is() )
670 nDefaultActions
= mpWindowImpl
->mpFrameData
->mxDropTarget
->getDefaultActions();
672 if( ! mpWindowImpl
->mpFrameData
->mxDropTargetListener
.is() )
674 mpWindowImpl
->mpFrameData
->mxDropTargetListener
= new DNDEventDispatcher( mpWindowImpl
->mpFrameWindow
);
678 mpWindowImpl
->mpFrameData
->mxDropTarget
->addDropTargetListener( mpWindowImpl
->mpFrameData
->mxDropTargetListener
);
680 // register also as drag gesture listener if directly supported by drag source
681 Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> xDragGestureRecognizer(
682 mpWindowImpl
->mpFrameData
->mxDragSource
, UNO_QUERY
);
684 if( xDragGestureRecognizer
.is() )
686 xDragGestureRecognizer
->addDragGestureListener(
687 Reference
< css::datatransfer::dnd::XDragGestureListener
> (mpWindowImpl
->mpFrameData
->mxDropTargetListener
, UNO_QUERY
));
690 mpWindowImpl
->mpFrameData
->mbInternalDragGestureRecognizer
= true;
693 catch (const RuntimeException
&)
695 // release all instances
696 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
697 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
704 mpWindowImpl
->mxDNDListenerContainer
= static_cast < css::datatransfer::dnd::XDropTarget
* > ( new DNDListenerContainer( nDefaultActions
) );
707 // this object is located in the same process, so there will be no runtime exception
708 return Reference
< css::datatransfer::dnd::XDropTarget
> ( mpWindowImpl
->mxDNDListenerContainer
, UNO_QUERY
);
711 Reference
< css::datatransfer::dnd::XDragSource
> Window::GetDragSource()
713 #if HAVE_FEATURE_DESKTOP
714 const SystemEnvData
* pEnvData
= GetSystemData();
715 if (!mpWindowImpl
->mpFrameData
|| !pEnvData
)
716 return Reference
<css::datatransfer::dnd::XDragSource
>();
717 if (mpWindowImpl
->mpFrameData
->mxDragSource
.is())
718 return mpWindowImpl
->mpFrameData
->mxDragSource
;
722 SalInstance
* pInst
= ImplGetSVData()->mpDefInst
;
723 mpWindowImpl
->mpFrameData
->mxDragSource
.set(pInst
->CreateDragSource(pEnvData
), UNO_QUERY
);
724 mpWindowImpl
->mpFrameData
->mxDropTarget
.set(pInst
->CreateDropTarget(pEnvData
), UNO_QUERY
);
726 catch (const Exception
&)
728 mpWindowImpl
->mpFrameData
->mxDropTarget
.clear();
729 mpWindowImpl
->mpFrameData
->mxDragSource
.clear();
731 return mpWindowImpl
->mpFrameData
->mxDragSource
;
733 return Reference
< css::datatransfer::dnd::XDragSource
> ();
737 Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> Window::GetDragGestureRecognizer()
739 return Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> ( GetDropTarget(), UNO_QUERY
);
742 } /* namespace vcl */
744 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */