Added IDropTarget interface. Still lots of cleanup but this works ok.

You can drag over from Firefox or IE onto a prim
meow-7.2.2
callum 2009-10-27 17:52:04 -07:00
parent b680aaf61d
commit caa631bf5b
8 changed files with 4057 additions and 3679 deletions

View File

@ -0,0 +1,295 @@
/**
* @file lldragdrop32.cpp
* @brief Handler for Windows specific drag and drop (OS to client) code
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#if LL_WINDOWS
#include "linden_common.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "llwindowwin32.h"
#include "llkeyboardwin32.h"
#include "lldragdropwin32.h"
#include "llwindowcallbacks.h"
#include <windows.h>
#include <ole2.h>
#include <shlobj.h>
#include <shellapi.h>
#include <shlwapi.h>
// FIXME: this should be done in CMake
#pragma comment( lib, "shlwapi.lib" )
class LLDragDropWin32Target:
public IDropTarget
{
public:
LLDragDropWin32Target( HWND hWnd ) :
mWindowHandle( hWnd ),
mRefCount( 0 )
{
strcpy(szFileDropped,"");
bDropTargetValid = false;
bTextDropped = false;
};
/* IUnknown methods */
STDMETHOD_( ULONG, AddRef )( void )
{
return ++mRefCount;
};
STDMETHOD_( ULONG, Release )( void )
{
if ( --mRefCount == 0 )
{
delete this;
return 0;
}
return mRefCount;
};
STDMETHOD ( QueryInterface )( REFIID iid, void ** ppvObject )
{
if ( iid == IID_IUnknown || iid == IID_IDropTarget )
{
*ppvObject = this;
AddRef();
return S_OK;
};
*ppvObject = NULL;
return E_NOINTERFACE;
};
/* IDropTarget methods */
STDMETHOD (DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
HRESULT hr = E_INVALIDARG;
bDropTargetValid = false;
bTextDropped = false;
*pdwEffect=DROPEFFECT_NONE;
FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM medium;
if (pDataObj && SUCCEEDED (pDataObj->GetData (&fmte, &medium)))
{
// We can Handle Only one File At a time !!!
if (1 == DragQueryFile ((HDROP)medium.hGlobal,0xFFFFFFFF,NULL,0 ))
{
// Get the File Name
if (DragQueryFileA((HDROP)medium.hGlobal, 0, szFileDropped,MAX_PATH))
{
if (!PathIsDirectoryA(szFileDropped))
{
char szTempFile[MAX_PATH];
_splitpath(szFileDropped,NULL,NULL,NULL,szTempFile);
// if (!stricmp(szTempFile,".lnk"))
// {
// if (ResolveLink(szFileDropped,szTempFile))
// {
// strcpy(szFileDropped,szTempFile);
// *pdwEffect=DROPEFFECT_COPY;
// We Want to Create a Copy
// bDropTargetValid = true;
// hr = S_OK;
// }
// }
// else
// {
*pdwEffect=DROPEFFECT_COPY;
//We Want to Create a Copy
bDropTargetValid = true;
hr = S_OK;
// }
}
}
}
if (medium.pUnkForRelease)
medium.pUnkForRelease->Release ();
else
GlobalFree (medium.hGlobal);
}
else
{
fmte.cfFormat = CF_TEXT;
fmte.ptd = NULL;
fmte.dwAspect = DVASPECT_CONTENT;
fmte.lindex = -1;
fmte.tymed = TYMED_HGLOBAL;
// Does the drag source provide CF_TEXT ?
if (NOERROR == pDataObj->QueryGetData(&fmte))
{
bDropTargetValid = true;
bTextDropped = true;
*pdwEffect=DROPEFFECT_COPY;
hr = S_OK;
}
}
return hr;
};
STDMETHOD (DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
HRESULT hr = S_OK;
if (bDropTargetValid)
*pdwEffect=DROPEFFECT_COPY;
return hr;
};
STDMETHOD (DragLeave)(void)
{
HRESULT hr = S_OK;
strcpy(szFileDropped,"");
return hr;
};
STDMETHOD (Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
HRESULT hr = S_OK;
if (bDropTargetValid)
{
*pdwEffect=DROPEFFECT_COPY;
FORMATETC fmte;
STGMEDIUM medium;
if (bTextDropped)
{
fmte.cfFormat = CF_TEXT;
fmte.ptd = NULL;
fmte.dwAspect = DVASPECT_CONTENT;
fmte.lindex = -1;
fmte.tymed = TYMED_HGLOBAL;
hr = pDataObj->GetData(&fmte, &medium);
HGLOBAL hText = medium.hGlobal;
LPSTR lpszText = (LPSTR)GlobalLock(hText);
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mWindowHandle, GWL_USERDATA);
if (NULL != window_imp)
{
LLCoordGL gl_coord( pt.x, pt.y);
LLCoordWindow cursor_coord_window( pt.x, pt.y );
window_imp->convertCoords(cursor_coord_window, &gl_coord);
llinfos << "### (Drop) URL is: " << lpszText << llendl;
llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl;
llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl;
llinfos << llendl;
MASK mask = gKeyboard->currentMask(TRUE);
window_imp->completeDropRequest( gl_coord, mask, std::string( lpszText ) );
};
GlobalUnlock(hText);
ReleaseStgMedium(&medium);
}
}
return hr;
};
private:
ULONG mRefCount;
HWND mWindowHandle;
char szFileDropped[1024];
bool bDropTargetValid;
bool bTextDropped;
friend class LLWindowWin32;
};
LLDragDropWin32::LLDragDropWin32() :
mDropTarget( NULL ),
mDropWindowHandle( NULL )
{
}
LLDragDropWin32::~LLDragDropWin32()
{
}
bool LLDragDropWin32::init( HWND hWnd )
{
if (NOERROR != OleInitialize(NULL))
return FALSE;
mDropTarget = new LLDragDropWin32Target( hWnd );
if ( mDropTarget )
{
HRESULT result = CoLockObjectExternal( mDropTarget, TRUE, TRUE );
if ( S_OK == result )
{
result = RegisterDragDrop( hWnd, mDropTarget );
if ( S_OK != result )
{
// RegisterDragDrop failed
return false;
};
// all ok
mDropWindowHandle = hWnd;
}
else
{
// Unable to lock OLE object
return false;
};
};
// success
return true;
}
void LLDragDropWin32::reset()
{
if ( mDropTarget )
{
CoLockObjectExternal( mDropTarget, FALSE, TRUE );
RevokeDragDrop( mDropWindowHandle );
mDropTarget->Release();
};
OleUninitialize();
}
#endif

View File

@ -0,0 +1,55 @@
/**
* @file lldragdrop32.cpp
* @brief Handler for Windows specific drag and drop (OS to client) code
*
* $LicenseInfo:firstyear=2004&license=viewergpl$
*
* Copyright (c) 2004-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLDRAGDROP32_H
#define LL_LLDRAGDROP32_H
#include <windows.h>
#include <ole2.h>
#include <shlobj.h>
#include <shlwapi.h>
class LLDragDropWin32
{
public:
LLDragDropWin32();
~LLDragDropWin32();
bool init( HWND hWnd );
void reset();
private:
IDropTarget* mDropTarget;
HWND mDropWindowHandle;
};
#endif

View File

@ -163,7 +163,7 @@ void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *da
{
}
BOOL LLWindowCallbacks::handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, void *data)
BOOL LLWindowCallbacks::handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, std::string data )
{
return FALSE;
}

View File

@ -68,7 +68,7 @@ public:
virtual void handleWindowBlock(LLWindow *window); // window is taking over CPU for a while
virtual void handleWindowUnblock(LLWindow *window); // window coming back after taking over CPU for a while
virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data);
virtual BOOL handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, void *data);
virtual BOOL handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, std::string data);
virtual BOOL handleTimerEvent(LLWindow *window);
virtual BOOL handleDeviceChange(LLWindow *window);

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,7 @@
#include <windows.h>
#include "llwindow.h"
#include "lldragdropwin32.h"
// Hack for async host by name
#define LL_WM_HOST_RESOLVED (WM_APP + 1)
@ -112,6 +113,8 @@ public:
/*virtual*/ void interruptLanguageTextInput();
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url);
BOOL completeDropRequest( const LLCoordGL gl_coord, const MASK mask, const std::string url );
static std::vector<std::string> getDynamicFallbackFontList();
protected:
@ -206,6 +209,8 @@ protected:
LLPreeditor *mPreeditor;
LLDragDropWin32* mDragDrop;
friend class LLWindowManager;
};

View File

@ -817,7 +817,7 @@ BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MAS
return TRUE;
}
BOOL LLViewerWindow::handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, void* data)
BOOL LLViewerWindow::handleDrop( LLWindow *window, LLCoordGL pos, MASK mask, std::string data )
{
if (gSavedSettings.getBOOL("PrimMediaDragNDrop"))
{
@ -825,7 +825,7 @@ BOOL LLViewerWindow::handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, voi
LLUUID object_id = pick_info.getObjectID();
S32 object_face = pick_info.mObjectFace;
std::string url = std::string( (char*)data );
std::string url = data;
llinfos << "### Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << llendl;

View File

@ -170,7 +170,7 @@ public:
/*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ BOOL handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, void* data);
/*virtual*/ BOOL handleDrop(LLWindow *window, LLCoordGL pos, MASK mask, std::string data);
void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ void handleMouseLeave(LLWindow *window);
/*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y);