diff options
author | Rüdiger Timm <rt@openoffice.org> | 2008-02-18 13:47:00 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2008-02-18 13:47:00 +0000 |
commit | 2423f28f6ea6951d9f37f7ca8528d3c7d111ec71 (patch) | |
tree | 0f01d173c89861f7ea68e05380ae47ab56ca9ca0 /dtrans/source/aqua | |
parent | 9a7c7bfbbc58932a2b77fa514228ba517c762af8 (diff) |
INTEGRATION: CWS macosxdnd (1.1.2); FILE ADDED
2008/01/30 06:02:18 obr 1.1.2.9: WaE: initialize tmp
2008/01/21 19:37:48 tra 1.1.2.8: Make code warning free, add support for FileList data type
2008/01/05 19:57:03 tra 1.1.2.7: Finally supporting NSDragOperationGeneric (command key pressed during D&D) which now hopefully satisfies all parties
2008/01/05 14:12:12 tra 1.1.2.6: More sophisticated default action determination
2008/01/04 20:15:37 tra 1.1.2.5: Some cleanup and removal of obsolete files
2008/01/03 21:11:15 tra 1.1.2.4: Improved drag action selection
2008/01/02 20:37:30 tra 1.1.2.3: #i79620# Cocoa based DnD implementation, not perfect yet but we wanna save what we have so far
2007/12/04 21:22:50 tra 1.1.2.2: Clipboard transition to Cocoa
2007/11/13 10:11:19 tra 1.1.2.1: #i79620# experimental Carbon based D&D implementation, no need to optimize - will be replaced by Cocoa version
Diffstat (limited to 'dtrans/source/aqua')
-rw-r--r-- | dtrans/source/aqua/DragSource.cxx | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/dtrans/source/aqua/DragSource.cxx b/dtrans/source/aqua/DragSource.cxx new file mode 100644 index 000000000000..f7571546e762 --- /dev/null +++ b/dtrans/source/aqua/DragSource.cxx @@ -0,0 +1,373 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DragSource.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2008-02-18 14:47:00 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +#ifndef _COM_SUN_STAR_DATATRANSFER_DND_DNDCONSTANTS_HPP_ +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> +#endif +#ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_ +#include <com/sun/star/datatransfer/XTransferable.hpp> +#endif +#ifndef _COM_SUN_STAR_AWT_MOUSEBUTTON_HPP_ +#include <com/sun/star/awt/MouseButton.hpp> +#endif + +#ifndef _RTL_UNLOAD_H_ +#include <rtl/unload.h> +#endif + +#ifndef COMPHELPER_MAKESEQUENCE_HXX_INCLUDED +#include "comphelper/makesequence.hxx" +#endif + +#include "DragSource.hxx" +#include "DragSourceContext.hxx" +#include "aqua_clipboard.hxx" +#include "DragActionConversion.hxx" + +#include <rtl/ustring.h> +#include <memory> + + +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::clipboard; +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; +using namespace com::sun::star::uno; +using namespace com::sun::star::awt::MouseButton; +using namespace com::sun::star::awt; +using namespace com::sun::star::lang; +using namespace comphelper; +using namespace std; + + +extern rtl_StandardModuleCount g_moduleCount; + + +// For OOo internal D&D we provide the Transferable without NSDragPboard +// interference as a shortcut +Reference<XTransferable> g_XTransferable = Reference<XTransferable>(); +NSView* g_DragSourceView = nil; + + +OUString dragSource_getImplementationName() +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.datatransfer.dnd.OleDragSource_V1")); +} + +Sequence<OUString> dragSource_getSupportedServiceNames() +{ + return makeSequence(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.dnd.OleDragSource"))); +} + + +@implementation DragSourceHelper; + +-(DragSourceHelper*)initWithDragSource: (DragSource*) pds +{ + self = [super init]; + + if (self) + { + mDragSource = pds; + } + + return self; +} + + +-(void)mouseDown: (NSEvent*)theEvent +{ + mDragSource->saveMouseEvent(theEvent); +} + + +-(void)mouseDragged: (NSEvent*)theEvent +{ + mDragSource->saveMouseEvent(theEvent); +} + + +-(unsigned int)draggingSourceOperationMaskForLocal: (MacOSBOOL)isLocal +{ + return mDragSource->getSupportedDragOperations(isLocal); +} + + +-(void)draggedImage:(NSImage*)anImage beganAt:(NSPoint)aPoint +{ + DragSourceDragEvent dsde(static_cast<OWeakObject*>(mDragSource), + new DragSourceContext(mDragSource), + mDragSource, + DNDConstants::ACTION_COPY, + DNDConstants::ACTION_COPY); + + mDragSource->mXDragSrcListener->dragEnter(dsde); +} + + +-(void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation +{ + DragSourceDropEvent dsde(static_cast<OWeakObject*>(mDragSource), + new DragSourceContext(mDragSource), + static_cast< XDragSource* >(mDragSource), + SystemToOfficeDragActions(operation), + operation != NSDragOperationNone); + + mDragSource->mXDragSrcListener->dragDropEnd(dsde); + mDragSource->mXDragSrcListener = Reference<XDragSourceListener>(); +} + + +-(void)draggedImage:(NSImage *)draggedImage movedTo:(NSPoint)screenPoint +{ + DragSourceDragEvent dsde(static_cast<OWeakObject*>(mDragSource), + new DragSourceContext(mDragSource), + mDragSource, + DNDConstants::ACTION_COPY, + DNDConstants::ACTION_COPY); + + mDragSource->mXDragSrcListener->dragOver(dsde); +} + +@end + + +DragSource::DragSource( const Reference<XComponentContext>& context): + WeakComponentImplHelper3<XDragSource, XInitialization, XServiceInfo>(m_aMutex), + mXComponentContext(context), + mView(NULL), + mLastMouseEventBeforeStartDrag(nil), + m_MouseButton(0) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt); +} + + +DragSource::~DragSource() +{ + [(id <MouseEventListener>)mView unregisterMouseEventListener: mDragSourceHelper]; + [mDragSourceHelper release]; + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + + +void SAL_CALL DragSource::initialize(const Sequence< Any >& aArguments) + throw(Exception) +{ + if (aArguments.getLength() < 2) + { + throw Exception(OUString(RTL_CONSTASCII_USTRINGPARAM("DragSource::initialize: Not enough parameter.")), + static_cast<OWeakObject*>(this)); + } + + Any pNSView = aArguments[1]; + sal_uInt64 tmp = 0; + pNSView >>= tmp; + mView = (NSView*)tmp; + + /* All SalFrameView the base class for all VCL system views inherits from + NSView in order to get mouse and other events. This is the only way to + get these events. In order to start a drag operation we need to provide + the mouse event which was the trigger. SalFrameView therefor implements + a hook mechanism so that we can get mouse events for our purpose. + */ + if (![mView respondsToSelector: @selector(registerMouseEventListener:)] || + ![mView respondsToSelector: @selector(unregisterMouseEventListener:)]) + { + throw Exception(OUString(RTL_CONSTASCII_USTRINGPARAM("DragSource::initialize: Provided view doesn't support mouse listener")), + static_cast<OWeakObject*>(this)); + } + + mDragSourceHelper = [[DragSourceHelper alloc] initWithDragSource: this]; + + if (mDragSourceHelper == nil) + { + throw Exception(OUString(RTL_CONSTASCII_USTRINGPARAM("DragSource::initialize: Cannot initialize DragSource")), + static_cast<OWeakObject*>(this)); + } + + [(id <MouseEventListener>)mView registerMouseEventListener: mDragSourceHelper]; +} + + +//---------------------------------------------------- +// XDragSource +//---------------------------------------------------- + +sal_Bool SAL_CALL DragSource::isDragImageSupported( ) + throw(RuntimeException) +{ + return true; +} + + +sal_Int32 SAL_CALL DragSource::getDefaultCursor( sal_Int8 /*dragAction*/ ) + throw( IllegalArgumentException, RuntimeException) +{ + return 0; +} + + +void SAL_CALL DragSource::startDrag(const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 cursor, + sal_Int32 image, + const Reference<XTransferable >& transferable, + const Reference<XDragSourceListener >& listener ) + throw( RuntimeException) +{ + MutexGuard guard(m_aMutex); + + OSL_ASSERT(listener.is() && "DragSource::startDrag: No XDragSourceListener provided\n"); + OSL_ASSERT(transferable.is() && "DragSource::startDrag: No transferable provided\n"); + + trigger.Event >>= mMouseEvent; + m_MouseButton= mMouseEvent.Buttons; + mXDragSrcListener = listener; + mXCurrentContext = static_cast<XDragSourceContext*>(new DragSourceContext(this)); + auto_ptr<AquaClipboard> clipb(new AquaClipboard(this->mXComponentContext, NULL, false)); + g_XTransferable = transferable; + clipb->setContents(g_XTransferable, Reference<XClipboardOwner>()); + mDragSourceActions = sourceActions; + g_DragSourceView = mView; + + NSSize sz; + sz.width = 5; + sz.height = 5; + + NSImage* dragImage; + dragImage = [[NSImage alloc] initWithSize: sz]; + + NSRect bounds; + bounds.origin = NSMakePoint(0,0); + bounds.size = sz; + + [dragImage lockFocus]; + [[NSColor blackColor] set]; + [NSBezierPath fillRect: bounds]; + [dragImage unlockFocus]; + + NSPoint pInWnd = [mLastMouseEventBeforeStartDrag locationInWindow]; + NSPoint p; + p = [mView convertPoint: pInWnd fromView: nil]; + p.x = p.x - sz.width/2; + p.y = p.y - sz.height/2; + + [mView dragImage: dragImage + at: p + offset: NSMakeSize(0,0) + event: mLastMouseEventBeforeStartDrag + pasteboard: clipb->getPasteboard() + source: mDragSourceHelper + slideBack: 1]; + + [dragImage release]; + + g_XTransferable = Reference<XTransferable>(); + g_DragSourceView = nil; +} + + +// In order to initiate a D&D operation we need to +// provide the triggering mouse event which we get +// from the SalFrameView that is associated with +// this DragSource +void DragSource::saveMouseEvent(NSEvent* theEvent) +{ + if (mLastMouseEventBeforeStartDrag != nil) + { + [mLastMouseEventBeforeStartDrag release]; + } + + mLastMouseEventBeforeStartDrag = theEvent; +} + + +/* isLocal indicates whether or not the DnD operation is OOo + internal. + */ +unsigned int DragSource::getSupportedDragOperations(bool isLocal) const +{ + unsigned int srcActions = OfficeToSystemDragActions(mDragSourceActions); + + if (isLocal) + { + // Support NSDragOperation generic which means we can + // decide which D&D operation to choose. We map + // NSDragOperationGenric to DNDConstants::ACTION_DEFAULT + // in SystemToOfficeDragActions to signal this and + // use it in DropTarget::determineDropAction + srcActions |= NSDragOperationGeneric; + } + else + { + // Mask out link and move operations on external DnD + srcActions &= ~(NSDragOperationMove | NSDragOperationLink); + } + + return srcActions; +} + + +//################################ +// XServiceInfo +//################################ + +OUString SAL_CALL DragSource::getImplementationName( ) throw (RuntimeException) +{ + return dragSource_getImplementationName(); +} + + +sal_Bool SAL_CALL DragSource::supportsService( const OUString& ServiceName ) throw (RuntimeException) +{ + return ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.dnd.OleDragSource"))); +} + + +Sequence< OUString > SAL_CALL DragSource::getSupportedServiceNames() throw (RuntimeException) +{ + return dragSource_getSupportedServiceNames(); +} + + + + |