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
This commit is contained in:
parent
9a7c7bfbbc
commit
2423f28f6e
1 changed files with 373 additions and 0 deletions
373
dtrans/source/aqua/DragSource.cxx
Normal file
373
dtrans/source/aqua/DragSource.cxx
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue