update emoji autocorrect entries from po-files
[LibreOffice.git] / vcl / osx / DropTarget.cxx
blob2b90bd52f709b972066debe96a2f69b8e1a198ef
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 .
20 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
21 #include <com/sun/star/datatransfer/XTransferable.hpp>
22 #include <com/sun/star/datatransfer/dnd/DropTargetDragEnterEvent.hpp>
23 #include "comphelper/makesequence.hxx"
24 #include <cppuhelper/interfacecontainer.hxx>
25 #include "clipboard.hxx"
26 #include "DropTarget.hxx"
27 #include "DragActionConversion.hxx"
28 #include "DragSource.hxx"
29 #include <rtl/ustring.h>
30 #include <stdio.h>
31 #include <premac.h>
32 #include <Carbon/Carbon.h>
33 #include <postmac.h>
34 #include <osx/salframe.h>
35 #include <osx/salframeview.h>
36 #include <cppuhelper/supportsservice.hxx>
38 using namespace cppu;
39 using namespace osl;
40 using namespace com::sun::star::datatransfer;
41 using namespace com::sun::star::datatransfer::dnd;
42 using namespace com::sun::star::datatransfer::dnd::DNDConstants;
43 using namespace com::sun::star::datatransfer::clipboard;
44 using namespace com::sun::star::lang;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star;
47 using namespace comphelper;
49 OUString dropTarget_getImplementationName()
51 return OUString("com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1");
54 Sequence<OUString> dropTarget_getSupportedServiceNames()
56 return makeSequence(OUString("com.sun.star.datatransfer.dnd.OleDropTarget"));
59 namespace /* private */
61 // Cocoa's coordinate system has its origin lower-left, VCL's
62 // coordinate system upper-left hence we need to transform
63 // coordinates
65 inline void CocoaToVCL(NSPoint& rPoint, const NSRect& bounds)
67 rPoint.y = bounds.size.height - rPoint.y;
71 @implementation DropTargetHelper
73 -(DropTargetHelper*)initWithDropTarget:(DropTarget*)pdt
75 self = [super init];
77 if (self)
79 mDropTarget = pdt;
82 return self;
85 -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
87 return mDropTarget->draggingEntered(sender);
90 -(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
92 return mDropTarget->draggingUpdated(sender);
95 -(void)draggingExited:(id <NSDraggingInfo>)sender
97 mDropTarget->draggingExited(sender);
100 -(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
102 (void) sender;
103 return DropTarget::prepareForDragOperation();
106 -(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
108 (void) sender;
109 return mDropTarget->performDragOperation();
112 -(void)concludeDragOperation:(id <NSDraggingInfo>)sender
114 mDropTarget->concludeDragOperation(sender);
117 @end
119 DropTarget::DropTarget() :
120 WeakComponentImplHelper5<XInitialization, XDropTarget, XDropTargetDragContext, XDropTargetDropContext, XServiceInfo>(m_aMutex),
121 mView(nil),
122 mpFrame(NULL),
123 mDropTargetHelper(nil),
124 mbActive(false),
125 mDragSourceSupportedActions(DNDConstants::ACTION_NONE),
126 mSelectedDropAction(DNDConstants::ACTION_NONE),
127 mDefaultActions(DNDConstants::ACTION_COPY_OR_MOVE | DNDConstants::ACTION_LINK | DNDConstants::ACTION_DEFAULT)
129 mDataFlavorMapper = DataFlavorMapperPtr_t(new DataFlavorMapper());
132 DropTarget::~DropTarget()
134 if( AquaSalFrame::isAlive( mpFrame ) )
135 [(id <DraggingDestinationHandler>)mView unregisterDraggingDestinationHandler:mDropTargetHelper];
136 [mDropTargetHelper release];
139 sal_Int8 DropTarget::determineDropAction(sal_Int8 dropActions, id sender) const
141 sal_Int8 dropAct = dropActions;
142 bool srcAndDestEqual = false;
144 if ([sender draggingSource] != nil)
146 // Internal DnD
147 NSView* destView = [[sender draggingDestinationWindow] contentView];
148 srcAndDestEqual = (DragSource::g_DragSourceView == destView);
151 // If ACTION_DEFAULT is set this means NSDragOperationGeneric
152 // has been set and we map this to ACTION_MOVE or ACTION_COPY
153 // depending on whether or not source and dest are equal,
154 // this hopefully satisfies all parties
155 if( (dropActions == DNDConstants::ACTION_DEFAULT)
156 || ((dropActions == mDragSourceSupportedActions)
157 && !(~mDragSourceSupportedActions & DNDConstants::ACTION_COPY_OR_MOVE ) ) )
159 dropAct = srcAndDestEqual ? DNDConstants::ACTION_MOVE :
160 DNDConstants::ACTION_COPY;
162 // if more than one drop actions have been specified
163 // set ACTION_DEFAULT in order to let the drop target
164 // decide which one to use
165 else if (dropActions != DNDConstants::ACTION_NONE &&
166 dropActions != DNDConstants::ACTION_MOVE &&
167 dropActions != DNDConstants::ACTION_COPY &&
168 dropActions != DNDConstants::ACTION_LINK)
170 if (srcAndDestEqual)
172 dropAct = dropActions;
174 else // source and destination are different
176 if (dropActions & DNDConstants::ACTION_COPY)
177 dropAct = DNDConstants::ACTION_COPY;
178 else if (dropActions & DNDConstants::ACTION_MOVE)
179 dropAct = DNDConstants::ACTION_MOVE;
180 else if (dropActions & DNDConstants::ACTION_LINK)
181 dropAct = DNDConstants::ACTION_LINK;
184 dropAct |= DNDConstants::ACTION_DEFAULT;
187 return dropAct;
190 NSDragOperation DropTarget::draggingEntered(id sender)
192 // Initially when DnD will be started no modifier key can be pressed yet
193 // thus we are getting all actions that the drag source supports, we save
194 // this value because later the system masks the drag source actions if
195 // a modifier key will be pressed
196 mDragSourceSupportedActions = SystemToOfficeDragActions([sender draggingSourceOperationMask]);
198 // Only if the drop target is really interessted in the drag actions
199 // supported by the source
200 if (mDragSourceSupportedActions & mDefaultActions)
202 sal_Int8 currentAction = determineDropAction(mDragSourceSupportedActions, sender);
204 NSRect bounds = [mView bounds];
205 NSPoint mouseLoc = [NSEvent mouseLocation];
207 id wnd = [mView window];
208 NSPoint dragLocation = [mView convertPoint:[wnd convertScreenToBase:mouseLoc] fromView:nil];
210 CocoaToVCL(dragLocation, bounds);
212 sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x);
213 sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y);
215 NSPasteboard* dragPboard = [sender draggingPasteboard];
216 mXCurrentDragClipboard = new AquaClipboard(dragPboard, false);
218 uno::Reference<XTransferable> xTransferable = DragSource::g_XTransferable.is() ?
219 DragSource::g_XTransferable : mXCurrentDragClipboard->getContents();
221 DropTargetDragEnterEvent dtdee(static_cast<OWeakObject*>(this),
223 this,
224 currentAction,
225 posX,
226 posY,
227 mDragSourceSupportedActions,
228 xTransferable->getTransferDataFlavors());
230 fire_dragEnter(dtdee);
233 return OfficeToSystemDragActions(mSelectedDropAction);
236 NSDragOperation DropTarget::draggingUpdated(id sender)
238 sal_Int8 currentDragSourceActions =
239 SystemToOfficeDragActions([sender draggingSourceOperationMask]);
240 NSDragOperation dragOp = NSDragOperationNone;
242 if (currentDragSourceActions & mDefaultActions)
244 sal_Int8 currentAction = determineDropAction(currentDragSourceActions, sender);
245 NSRect bounds = [mView bounds];
246 NSPoint mouseLoc = [NSEvent mouseLocation];
248 id wnd = [mView window];
249 NSPoint dragLocation = [mView convertPoint:[wnd convertScreenToBase:mouseLoc] fromView:nil];
251 CocoaToVCL(dragLocation, bounds);
253 sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x);
254 sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y);
256 DropTargetDragEvent dtde(static_cast<OWeakObject*>(this),
258 this,
259 currentAction,
260 posX,
261 posY,
262 mDragSourceSupportedActions);
264 fire_dragOver(dtde);
266 // drag over callbacks likely have rendered something
267 [mView setNeedsDisplay: TRUE];
269 dragOp = OfficeToSystemDragActions(mSelectedDropAction);
271 //NSLog(@"Drag update: Source actions: %x proposed action %x selected action %x", mDragSourceSupportedActions, currentAction, mSelectedDropAction);
274 if (dragOp == NSDragOperationNone)
275 [[NSCursor operationNotAllowedCursor] set];
276 else if (dragOp == NSDragOperationCopy)
277 [[NSCursor dragCopyCursor] set];
278 else
279 [[NSCursor arrowCursor] set];
281 return dragOp;
284 void DropTarget::draggingExited(id /*sender*/)
286 DropTargetEvent dte(static_cast<OWeakObject*>(this), 0);
287 fire_dragExit(dte);
288 mDragSourceSupportedActions = DNDConstants::ACTION_NONE;
289 mSelectedDropAction = DNDConstants::ACTION_NONE;
290 [[NSCursor arrowCursor] set];
293 BOOL DropTarget::prepareForDragOperation()
295 return 1;
298 BOOL DropTarget::performDragOperation()
300 bool bSuccess = false;
302 if (mSelectedDropAction != DNDConstants::ACTION_NONE)
304 uno::Reference<XTransferable> xTransferable = DragSource::g_XTransferable;
306 if (!DragSource::g_XTransferable.is())
308 xTransferable = mXCurrentDragClipboard->getContents();
311 NSRect bounds = [mView bounds];
312 NSPoint mouseLoc = [NSEvent mouseLocation];
314 id wnd = [mView window];
315 NSPoint dragLocation = [mView convertPoint:[wnd convertScreenToBase:mouseLoc] fromView:nil];
317 CocoaToVCL(dragLocation, bounds);
319 sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x);
320 sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y);
322 DropTargetDropEvent dtde(static_cast<OWeakObject*>(this),
324 this,
325 mSelectedDropAction,
326 posX,
327 posY,
328 mDragSourceSupportedActions,
329 xTransferable);
331 fire_drop(dtde);
333 bSuccess = true;
336 return bSuccess;
339 void DropTarget::concludeDragOperation(id /*sender*/)
341 mDragSourceSupportedActions = DNDConstants::ACTION_NONE;
342 mSelectedDropAction = DNDConstants::ACTION_NONE;
343 mXCurrentDragClipboard = uno::Reference<XClipboard>();
344 [[NSCursor arrowCursor] set];
347 // called from WeakComponentImplHelperX::dispose
348 // WeakComponentImplHelper calls disposing before it destroys
349 // itself.
350 void SAL_CALL DropTarget::disposing()
354 void SAL_CALL DropTarget::initialize(const Sequence< Any >& aArguments)
355 throw(Exception, std::exception)
357 if (aArguments.getLength() < 2)
359 throw RuntimeException("DropTarget::initialize: Cannot install window event handler",
360 static_cast<OWeakObject*>(this));
363 Any pNSView = aArguments[0];
364 sal_uInt64 tmp = 0;
365 pNSView >>= tmp;
366 mView = reinterpret_cast<id>(tmp);
367 mpFrame = [(SalFrameView*)mView getSalFrame];
369 mDropTargetHelper = [[DropTargetHelper alloc] initWithDropTarget: this];
371 [(id <DraggingDestinationHandler>)mView registerDraggingDestinationHandler:mDropTargetHelper];
372 [mView registerForDraggedTypes: DataFlavorMapper::getAllSupportedPboardTypes()];
374 id wnd = [mView window];
375 NSWindow* parentWnd = [wnd parentWindow];
376 unsigned int topWndStyle = (NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask);
377 unsigned int wndStyles = [wnd styleMask] & topWndStyle;
379 if (parentWnd == nil && (wndStyles == topWndStyle))
381 [wnd registerDraggingDestinationHandler:mDropTargetHelper];
382 [wnd registerForDraggedTypes: [NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
386 void SAL_CALL DropTarget::addDropTargetListener(const uno::Reference<XDropTargetListener>& dtl)
387 throw(RuntimeException, std::exception)
389 rBHelper.addListener(cppu::UnoType<decltype(dtl)>::get(), dtl);
392 void SAL_CALL DropTarget::removeDropTargetListener(const uno::Reference<XDropTargetListener>& dtl)
393 throw(RuntimeException, std::exception)
395 rBHelper.removeListener(cppu::UnoType<decltype(dtl)>::get(), dtl);
398 sal_Bool SAL_CALL DropTarget::isActive( ) throw(RuntimeException, std::exception)
400 return mbActive;
403 void SAL_CALL DropTarget::setActive(sal_Bool active) throw(RuntimeException, std::exception)
405 mbActive = active;
408 sal_Int8 SAL_CALL DropTarget::getDefaultActions() throw(RuntimeException, std::exception)
410 return mDefaultActions;
413 void SAL_CALL DropTarget::setDefaultActions(sal_Int8 actions) throw(RuntimeException, std::exception)
415 OSL_ENSURE( actions < 8, "No valid default actions");
416 mDefaultActions= actions;
419 void SAL_CALL DropTarget::acceptDrag(sal_Int8 dragOperation) throw (RuntimeException, std::exception)
421 mSelectedDropAction = dragOperation;
424 void SAL_CALL DropTarget::rejectDrag() throw (RuntimeException, std::exception)
426 mSelectedDropAction = DNDConstants::ACTION_NONE;
429 void SAL_CALL DropTarget::acceptDrop(sal_Int8 dropOperation) throw( RuntimeException, std::exception)
431 mSelectedDropAction = dropOperation;
434 void SAL_CALL DropTarget::rejectDrop() throw (RuntimeException, std::exception)
436 mSelectedDropAction = DNDConstants::ACTION_NONE;
439 void SAL_CALL DropTarget::dropComplete(sal_Bool success) throw (RuntimeException, std::exception)
441 // Reset the internal transferable used as shortcut in case this is
442 // an internal D&D operation
443 DragSource::g_XTransferable = uno::Reference<XTransferable>();
444 DragSource::g_DropSuccessSet = true;
445 DragSource::g_DropSuccess = success;
448 void DropTarget::fire_drop( const DropTargetDropEvent& dte)
450 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
451 if( pContainer)
453 OInterfaceIteratorHelper iter( *pContainer);
454 while( iter.hasMoreElements())
456 uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
458 try { listener->drop( dte); }
459 catch(RuntimeException&) {}
464 void DropTarget::fire_dragEnter(const DropTargetDragEnterEvent& e)
466 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
467 if( pContainer)
469 OInterfaceIteratorHelper iter( *pContainer);
470 while( iter.hasMoreElements())
472 uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
474 try { listener->dragEnter( e); }
475 catch (RuntimeException&) {}
480 void DropTarget::fire_dragExit(const DropTargetEvent& dte)
482 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
484 if( pContainer)
486 OInterfaceIteratorHelper iter( *pContainer);
487 while( iter.hasMoreElements())
489 uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
491 try { listener->dragExit( dte); }
492 catch (RuntimeException&) {}
497 void DropTarget::fire_dragOver(const DropTargetDragEvent& dtde)
499 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
500 if( pContainer)
502 OInterfaceIteratorHelper iter( *pContainer );
503 while( iter.hasMoreElements())
505 uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
507 try { listener->dragOver( dtde); }
508 catch (RuntimeException&) {}
513 void DropTarget::fire_dropActionChanged(const DropTargetDragEvent& dtde)
515 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( cppu::UnoType<XDropTargetListener>::get());
516 if( pContainer)
518 OInterfaceIteratorHelper iter( *pContainer);
519 while( iter.hasMoreElements())
521 uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
523 try { listener->dropActionChanged( dtde); }
524 catch (RuntimeException&) {}
529 OUString SAL_CALL DropTarget::getImplementationName() throw (RuntimeException, std::exception)
531 return dropTarget_getImplementationName();
534 sal_Bool SAL_CALL DropTarget::supportsService( const OUString& ServiceName ) throw (RuntimeException, std::exception)
536 return cppu::supportsService(this, ServiceName);
539 Sequence< OUString > SAL_CALL DropTarget::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
541 return dropTarget_getSupportedServiceNames();
544 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */