nss: upgrade to release 3.73
[LibreOffice.git] / vcl / source / window / mouse.cxx
blobfbe81aed74996486e42813d7de31e881dbb4bd1d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <config_feature_desktop.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>
37 #include <window.h>
38 #include <svdata.hxx>
39 #include <salobj.hxx>
40 #include <salgdi.hxx>
41 #include <salframe.hxx>
43 #include <dndlistenercontainer.hxx>
44 #include <dndeventdispatcher.hxx>
46 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
47 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
48 #include <com/sun/star/uno/XComponentContext.hpp>
50 #include <comphelper/processfactory.hxx>
52 using namespace ::com::sun::star::uno;
54 namespace vcl {
56 WindowHitTest Window::ImplHitTest( const Point& rFramePos )
58 Point aFramePos( rFramePos );
59 if( ImplIsAntiparallel() )
61 const OutputDevice *pOutDev = GetOutDev();
62 pOutDev->ReMirror( aFramePos );
64 tools::Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
65 if ( !aRect.IsInside( aFramePos ) )
66 return WindowHitTest::NONE;
67 if ( mpWindowImpl->mbWinRegion )
69 Point aTempPos = aFramePos;
70 aTempPos.AdjustX( -mnOutOffX );
71 aTempPos.AdjustY( -mnOutOffY );
72 if ( !mpWindowImpl->maWinRegion.IsInside( aTempPos ) )
73 return WindowHitTest::NONE;
76 WindowHitTest nHitTest = WindowHitTest::Inside;
77 if ( mpWindowImpl->mbMouseTransparent )
78 nHitTest |= WindowHitTest::Transparent;
79 return nHitTest;
82 bool Window::ImplTestMousePointerSet()
84 // as soon as mouse is captured, switch mouse-pointer
85 if ( IsMouseCaptured() )
86 return true;
88 // if the mouse is over the window, switch it
89 tools::Rectangle aClientRect( Point( 0, 0 ), GetOutputSizePixel() );
90 return aClientRect.IsInside( GetPointerPosPixel() );
93 PointerStyle Window::ImplGetMousePointer() const
95 PointerStyle ePointerStyle;
96 bool bWait = false;
98 if ( IsEnabled() && IsInputEnabled() && ! IsInModalMode() )
99 ePointerStyle = GetPointer();
100 else
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;
111 if ( !bWait )
113 if ( pWindow->mpWindowImpl->mnWaitCount )
115 ePointerStyle = PointerStyle::Wait;
116 bWait = true;
118 else
120 if ( pWindow->mpWindowImpl->mbChildPtrOverwrite )
121 ePointerStyle = pWindow->GetPointer();
125 if ( pWindow->ImplIsOverlapWindow() )
126 break;
128 pWindow = pWindow->ImplGetParent();
130 while ( pWindow );
132 return ePointerStyle;
135 void Window::ImplCallMouseMove( sal_uInt16 nMouseCode, bool bModChanged )
137 if ( !(mpWindowImpl->mpFrameData->mbMouseIn && mpWindowImpl->mpFrameWindow->mpWindowImpl->mbReallyVisible) )
138 return;
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;
145 bool bLeave;
146 // check for MouseLeave
147 bLeave = ((nX < 0) || (nY < 0) ||
148 (nX >= mpWindowImpl->mpFrameWindow->mnOutWidth) ||
149 (nY >= mpWindowImpl->mpFrameWindow->mnOutHeight)) &&
150 !ImplGetSVData()->mpWinData->mpCaptureWin;
151 nMode |= MouseEventModifiers::SYNTHETIC;
152 if ( bModChanged )
153 nMode |= MouseEventModifiers::MODIFIERCHANGED;
154 ImplHandleMouseEvent( mpWindowImpl->mpFrameWindow, MouseNotifyEvent::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;
168 if( ! pCaptureWin ||
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)
184 return true;
186 if (rWinImpl.mpFrameData->mbHasFocus)
187 return true;
189 if (rWinImpl.mbFakeFocusSet)
190 return true;
192 return false;
195 void Window::ImplGrabFocus( GetFocusFlags nFlags )
197 // #143570# no focus for destructing windows
198 if( !mpWindowImpl || mpWindowImpl->mbInDispose )
199 return;
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,
208 // e.g. in ToTop()
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();
222 else
223 mpWindowImpl->mpClientWindow->GrabFocus();
224 return;
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();
239 return;
243 // If the Window is disabled, then we don't change the focus
244 if ( !IsEnabled() || !IsInputEnabled() || IsInModalMode() )
245 return;
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 )
257 if( pFrame != mpWindowImpl->mpFrameWindow.get() && pFrame->mpWindowImpl->mpFrameData->mnFocusId )
259 bAsyncFocusWaiting = true;
260 break;
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;
271 while( pParent )
273 if ((pParent->GetStyle() & WB_SYSTEMFLOATWIN) && !(pParent->GetStyle() & WB_MOVEABLE))
275 bMustNotGrabFocus = true;
276 break;
278 pParent = pParent->mpWindowImpl->mpParent;
281 if ( !(( pSVData->mpWinData->mpFocusWin.get() != this &&
282 !mpWindowImpl->mbInDispose ) ||
283 ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus )) )
284 return;
286 // EndExtTextInput if it is not the same window
287 if (pSVData->mpWinData->mpExtTextInputWin
288 && (pSVData->mpWinData->mpExtTextInputWin.get() != this))
289 pSVData->mpWinData->mpExtTextInputWin->EndExtTextInput();
291 // mark this windows as the last FocusWindow
292 vcl::Window* pOverlapWindow = ImplGetFirstOverlapWindow();
293 pOverlapWindow->mpWindowImpl->mpLastFocusWindow = this;
294 mpWindowImpl->mpFrameData->mpFocusWin = this;
296 if( !bHasFocus )
298 // menu windows never get the system focus
299 // the application will keep the focus
300 if( bMustNotGrabFocus )
301 return;
302 else
304 // here we already switch focus as ToTop()
305 // should not give focus to another window
306 mpWindowImpl->mpFrame->ToTop( SalFrameToTop::GrabFocus | SalFrameToTop::GrabFocusOnly );
307 return;
311 VclPtr<vcl::Window> pOldFocusWindow = pSVData->mpWinData->mpFocusWin;
313 pSVData->mpWinData->mpFocusWin = this;
315 if ( pOldFocusWindow && pOldFocusWindow->mpWindowImpl )
317 // Cursor hidden
318 if ( pOldFocusWindow->mpWindowImpl->mpCursor )
319 pOldFocusWindow->mpWindowImpl->mpCursor->ImplHide();
322 // !!!!! due to old SV-Office Activate/Deactivate handling
323 // !!!!! first as before
324 if ( pOldFocusWindow )
326 // remember Focus
327 vcl::Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
328 vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
329 if ( pOldOverlapWindow != pNewOverlapWindow )
330 ImplCallFocusChangeActivate( pNewOverlapWindow, pOldOverlapWindow );
332 else
334 vcl::Window* pNewOverlapWindow = ImplGetFirstOverlapWindow();
335 vcl::Window* pNewRealWindow = pNewOverlapWindow->ImplGetWindow();
336 pNewOverlapWindow->mpWindowImpl->mbActive = true;
337 pNewOverlapWindow->Activate();
338 if ( pNewRealWindow != pNewOverlapWindow )
340 pNewRealWindow->mpWindowImpl->mbActive = true;
341 pNewRealWindow->Activate();
345 // call Get- and LoseFocus
346 if ( pOldFocusWindow && ! pOldFocusWindow->IsDisposed() )
348 NotifyEvent aNEvt( MouseNotifyEvent::LOSEFOCUS, pOldFocusWindow );
349 if ( !ImplCallPreNotify( aNEvt ) )
350 pOldFocusWindow->CompatLoseFocus();
351 pOldFocusWindow->ImplCallDeactivateListeners( this );
354 if (pSVData->mpWinData->mpFocusWin.get() == this)
356 if ( mpWindowImpl->mpSysObj )
358 mpWindowImpl->mpFrameData->mpFocusWin = this;
359 if ( !mpWindowImpl->mpFrameData->mbInSysObjFocusHdl )
360 mpWindowImpl->mpSysObj->GrabFocus();
363 if (pSVData->mpWinData->mpFocusWin.get() == this)
365 if ( mpWindowImpl->mpCursor )
366 mpWindowImpl->mpCursor->ImplShow();
367 mpWindowImpl->mbInFocusHdl = true;
368 mpWindowImpl->mnGetFocusFlags = nFlags;
369 // if we're changing focus due to closing a popup floating window
370 // notify the new focus window so it can restore the inner focus
371 // eg, toolboxes can select their recent active item
372 if( pOldFocusWindow &&
373 ! pOldFocusWindow->IsDisposed() &&
374 ( pOldFocusWindow->GetDialogControlFlags() & DialogControlFlags::FloatWinPopupModeEndCancel ) )
375 mpWindowImpl->mnGetFocusFlags |= GetFocusFlags::FloatWinPopupModeEndCancel;
376 NotifyEvent aNEvt( MouseNotifyEvent::GETFOCUS, this );
377 if ( !ImplCallPreNotify( aNEvt ) && !xWindow->IsDisposed() )
378 CompatGetFocus();
379 if( !xWindow->IsDisposed() )
380 ImplCallActivateListeners( (pOldFocusWindow && ! pOldFocusWindow->IsDisposed()) ? pOldFocusWindow : nullptr );
381 if( !xWindow->IsDisposed() )
383 mpWindowImpl->mnGetFocusFlags = GetFocusFlags::NONE;
384 mpWindowImpl->mbInFocusHdl = false;
389 ImplNewInputContext();
393 void Window::ImplGrabFocusToDocument( GetFocusFlags nFlags )
395 vcl::Window *pWin = this;
396 while( pWin )
398 if( !pWin->GetParent() )
400 pWin->mpWindowImpl->mpFrame->GrabFocus();
401 pWin->ImplGetFrameWindow()->GetWindow( GetWindowType::Client )->ImplGrabFocus(nFlags);
402 return;
404 pWin = pWin->GetParent();
408 void Window::MouseMove( const MouseEvent& rMEvt )
410 NotifyEvent aNEvt( MouseNotifyEvent::MOUSEMOVE, this, &rMEvt );
411 EventNotify(aNEvt);
414 void Window::MouseButtonDown( const MouseEvent& rMEvt )
416 NotifyEvent aNEvt( MouseNotifyEvent::MOUSEBUTTONDOWN, this, &rMEvt );
417 if (!EventNotify(aNEvt))
418 mpWindowImpl->mbMouseButtonDown = true;
421 void Window::MouseButtonUp( const MouseEvent& rMEvt )
423 NotifyEvent aNEvt( MouseNotifyEvent::MOUSEBUTTONUP, this, &rMEvt );
424 if (!EventNotify(aNEvt))
425 mpWindowImpl->mbMouseButtonUp = true;
428 void Window::SetMouseTransparent( bool bTransparent )
431 if ( mpWindowImpl->mpBorderWindow )
432 mpWindowImpl->mpBorderWindow->SetMouseTransparent( bTransparent );
434 if( mpWindowImpl->mpSysObj )
435 mpWindowImpl->mpSysObj->SetMouseTransparent( bTransparent );
437 mpWindowImpl->mbMouseTransparent = bTransparent;
440 void Window::CaptureMouse()
442 ImplSVData* pSVData = ImplGetSVData();
444 // possibly stop tracking
445 if (pSVData->mpWinData->mpTrackWin.get() != this)
447 if (pSVData->mpWinData->mpTrackWin)
448 pSVData->mpWinData->mpTrackWin->EndTracking(TrackingEventFlags::Cancel);
451 if (pSVData->mpWinData->mpCaptureWin.get() != this)
453 pSVData->mpWinData->mpCaptureWin = this;
454 mpWindowImpl->mpFrame->CaptureMouse( true );
458 void Window::ReleaseMouse()
460 if (IsMouseCaptured())
462 ImplSVData* pSVData = ImplGetSVData();
463 pSVData->mpWinData->mpCaptureWin = nullptr;
464 mpWindowImpl->mpFrame->CaptureMouse( false );
465 ImplGenerateMouseMove();
469 bool Window::IsMouseCaptured() const
471 return (this == ImplGetSVData()->mpWinData->mpCaptureWin);
474 void Window::SetPointer( PointerStyle nPointer )
476 if ( mpWindowImpl->maPointer == nPointer )
477 return;
479 mpWindowImpl->maPointer = nPointer;
481 // possibly immediately move pointer
482 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
483 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
485 VclPtr<vcl::Window> pWin = GetParentWithLOKNotifier();
486 if (!pWin)
487 return;
489 PointerStyle aPointer = GetPointer();
490 // We don't map all possible pointers hence we need a default
491 OString aPointerString = "default";
492 auto aIt = vcl::gaLOKPointerMap.find(aPointer);
493 if (aIt != vcl::gaLOKPointerMap.end())
495 aPointerString = aIt->second;
498 // issue mouse pointer events only for document windows
499 // Doc windows' immediate parent SfxFrameViewWindow_Impl is the one with
500 // parent notifier set during initialization
501 if (GetParent()->ImplGetWindowImpl()->mbLOKParentNotifier &&
502 GetParent()->ImplGetWindowImpl()->mnLOKWindowId == 0)
504 pWin->GetLOKNotifier()->libreOfficeKitViewCallback(LOK_CALLBACK_MOUSE_POINTER, aPointerString.getStr());
508 void Window::EnableChildPointerOverwrite( bool bOverwrite )
511 if ( mpWindowImpl->mbChildPtrOverwrite == bOverwrite )
512 return;
514 mpWindowImpl->mbChildPtrOverwrite = bOverwrite;
516 // possibly immediately move pointer
517 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
518 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
521 void Window::SetPointerPosPixel( const Point& rPos )
523 Point aPos = ImplOutputToFrame( rPos );
524 const OutputDevice *pOutDev = GetOutDev();
525 if( pOutDev->HasMirroredGraphics() )
527 if( !IsRTLEnabled() )
529 pOutDev->ReMirror( aPos );
531 // mirroring is required here, SetPointerPos bypasses SalGraphics
532 aPos.setX( mpGraphics->mirror2( aPos.X(), this ) );
534 else if( ImplIsAntiparallel() )
536 pOutDev->ReMirror( aPos );
538 mpWindowImpl->mpFrame->SetPointerPos( aPos.X(), aPos.Y() );
541 void Window::SetLastMousePos(const Point& rPos)
543 // Do this conversion, so when GetPointerPosPixel() calls
544 // ImplFrameToOutput(), we get back the original position.
545 Point aPos = ImplOutputToFrame(rPos);
546 mpWindowImpl->mpFrameData->mnLastMouseX = aPos.X();
547 mpWindowImpl->mpFrameData->mnLastMouseY = aPos.Y();
550 Point Window::GetPointerPosPixel()
553 Point aPos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
554 if( ImplIsAntiparallel() )
556 const OutputDevice *pOutDev = GetOutDev();
557 pOutDev->ReMirror( aPos );
559 return ImplFrameToOutput( aPos );
562 Point Window::GetLastPointerPosPixel()
565 Point aPos( mpWindowImpl->mpFrameData->mnBeforeLastMouseX, mpWindowImpl->mpFrameData->mnBeforeLastMouseY );
566 if( ImplIsAntiparallel() )
568 const OutputDevice *pOutDev = GetOutDev();
569 pOutDev->ReMirror( aPos );
571 return ImplFrameToOutput( aPos );
574 void Window::ShowPointer( bool bVisible )
577 if ( mpWindowImpl->mbNoPtrVisible != !bVisible )
579 mpWindowImpl->mbNoPtrVisible = !bVisible;
581 // possibly immediately move pointer
582 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
583 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
587 Window::PointerState Window::GetPointerState()
589 PointerState aState;
590 aState.mnState = 0;
592 if (mpWindowImpl->mpFrame)
594 SalFrame::SalPointerState aSalPointerState = mpWindowImpl->mpFrame->GetPointerState();
595 if( ImplIsAntiparallel() )
597 const OutputDevice *pOutDev = GetOutDev();
598 pOutDev->ReMirror( aSalPointerState.maPos );
600 aState.maPos = ImplFrameToOutput( aSalPointerState.maPos );
601 aState.mnState = aSalPointerState.mnState;
603 return aState;
606 bool Window::IsMouseOver() const
608 return ImplGetWinData()->mbMouseOver;
611 void Window::EnterWait()
614 mpWindowImpl->mnWaitCount++;
616 if ( mpWindowImpl->mnWaitCount == 1 )
618 // possibly immediately move pointer
619 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
620 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
624 void Window::LeaveWait()
627 if ( mpWindowImpl->mnWaitCount )
629 mpWindowImpl->mnWaitCount--;
631 if ( !mpWindowImpl->mnWaitCount )
633 // possibly immediately move pointer
634 if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() )
635 mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() );
640 bool Window::ImplStopDnd()
642 bool bRet = false;
643 if( mpWindowImpl->mpFrameData && mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
645 bRet = true;
646 mpWindowImpl->mpFrameData->mxDropTarget.clear();
647 mpWindowImpl->mpFrameData->mxDragSource.clear();
648 mpWindowImpl->mpFrameData->mxDropTargetListener.clear();
651 return bRet;
654 void Window::ImplStartDnd()
656 GetDropTarget();
659 Reference< css::datatransfer::dnd::XDropTarget > Window::GetDropTarget()
661 if( !mpWindowImpl )
662 return Reference< css::datatransfer::dnd::XDropTarget >();
664 if( ! mpWindowImpl->mxDNDListenerContainer.is() )
666 sal_Int8 nDefaultActions = 0;
668 if( mpWindowImpl->mpFrameData )
670 if( ! mpWindowImpl->mpFrameData->mxDropTarget.is() )
672 // initialization is done in GetDragSource
673 GetDragSource();
676 if( mpWindowImpl->mpFrameData->mxDropTarget.is() )
678 nDefaultActions = mpWindowImpl->mpFrameData->mxDropTarget->getDefaultActions();
680 if( ! mpWindowImpl->mpFrameData->mxDropTargetListener.is() )
682 mpWindowImpl->mpFrameData->mxDropTargetListener = new DNDEventDispatcher( mpWindowImpl->mpFrameWindow );
686 mpWindowImpl->mpFrameData->mxDropTarget->addDropTargetListener( mpWindowImpl->mpFrameData->mxDropTargetListener );
688 // register also as drag gesture listener if directly supported by drag source
689 Reference< css::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer(
690 mpWindowImpl->mpFrameData->mxDragSource, UNO_QUERY);
692 if( xDragGestureRecognizer.is() )
694 xDragGestureRecognizer->addDragGestureListener(
695 Reference< css::datatransfer::dnd::XDragGestureListener > (mpWindowImpl->mpFrameData->mxDropTargetListener, UNO_QUERY));
697 else
698 mpWindowImpl->mpFrameData->mbInternalDragGestureRecognizer = true;
701 catch (const RuntimeException&)
703 // release all instances
704 mpWindowImpl->mpFrameData->mxDropTarget.clear();
705 mpWindowImpl->mpFrameData->mxDragSource.clear();
712 mpWindowImpl->mxDNDListenerContainer = static_cast < css::datatransfer::dnd::XDropTarget * > ( new DNDListenerContainer( nDefaultActions ) );
715 // this object is located in the same process, so there will be no runtime exception
716 return Reference< css::datatransfer::dnd::XDropTarget > ( mpWindowImpl->mxDNDListenerContainer, UNO_QUERY );
719 Reference< css::datatransfer::dnd::XDragSource > Window::GetDragSource()
722 #if HAVE_FEATURE_DESKTOP
724 if( mpWindowImpl->mpFrameData )
726 if( ! mpWindowImpl->mpFrameData->mxDragSource.is() )
730 Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
731 const SystemEnvData * pEnvData = GetSystemData();
733 if( pEnvData )
735 Sequence< Any > aDragSourceAL( 2 ), aDropTargetAL( 2 );
736 OUString aDragSourceSN, aDropTargetSN;
737 #if defined(_WIN32)
738 aDragSourceSN = "com.sun.star.datatransfer.dnd.OleDragSource";
739 aDropTargetSN = "com.sun.star.datatransfer.dnd.OleDropTarget";
740 aDragSourceAL[ 1 ] <<= static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->hWnd) );
741 aDropTargetAL[ 0 ] <<= static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->hWnd) );
742 #elif defined MACOSX
743 /* FIXME: macOS specific dnd interface does not exist! *
744 * Using Windows based dnd as a temporary solution */
745 aDragSourceSN = "com.sun.star.datatransfer.dnd.OleDragSource";
746 aDropTargetSN = "com.sun.star.datatransfer.dnd.OleDropTarget";
747 aDragSourceAL[ 1 ] <<= static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->mpNSView) );
748 aDropTargetAL[ 0 ] <<= static_cast<sal_uInt64>( reinterpret_cast<sal_IntPtr>(pEnvData->mpNSView) );
749 #elif HAVE_FEATURE_X11
750 aDragSourceSN = "com.sun.star.datatransfer.dnd.X11DragSource";
751 aDropTargetSN = "com.sun.star.datatransfer.dnd.X11DropTarget";
753 aDragSourceAL[ 0 ] <<= Application::GetDisplayConnection();
754 aDragSourceAL[ 1 ] <<= pEnvData->aShellWindow;
755 aDropTargetAL[ 0 ] <<= Application::GetDisplayConnection();
756 aDropTargetAL[ 1 ] <<= pEnvData->aShellWindow;
757 #endif
758 if( !aDragSourceSN.isEmpty() )
759 mpWindowImpl->mpFrameData->mxDragSource.set(
760 xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDragSourceSN, aDragSourceAL, xContext ),
761 UNO_QUERY );
763 if( !aDropTargetSN.isEmpty() )
764 mpWindowImpl->mpFrameData->mxDropTarget.set(
765 xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aDropTargetSN, aDropTargetAL, xContext ),
766 UNO_QUERY );
770 // createInstance can throw any exception
771 catch (const Exception&)
773 // release all instances
774 mpWindowImpl->mpFrameData->mxDropTarget.clear();
775 mpWindowImpl->mpFrameData->mxDragSource.clear();
779 return mpWindowImpl->mpFrameData->mxDragSource;
781 #endif
782 return Reference< css::datatransfer::dnd::XDragSource > ();
785 Reference< css::datatransfer::dnd::XDragGestureRecognizer > Window::GetDragGestureRecognizer()
787 return Reference< css::datatransfer::dnd::XDragGestureRecognizer > ( GetDropTarget(), UNO_QUERY );
790 } /* namespace vcl */
792 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */