From e2e7d544b6a114e70e3b46f516a4f0e8d7db4bd1 Mon Sep 17 00:00:00 2001 From: callum Date: Tue, 24 Nov 2009 20:20:53 -0800 Subject: Added support for dropping SURLs onto viewer Does right thing when logged in - needs some work at login page Removed (commented out) WM_DROPFILES code for now --- indra/llwindow/lldragdropwin32.cpp | 103 ++++++++++++++++++---------------- indra/llwindow/llwindowcallbacks.cpp | 2 +- indra/llwindow/llwindowcallbacks.h | 2 +- indra/llwindow/llwindowwin32.cpp | 105 ++++++++++++++++++----------------- indra/llwindow/llwindowwin32.h | 2 +- indra/newview/llviewerwindow.cpp | 10 +++- indra/newview/llviewerwindow.h | 2 +- 7 files changed, 121 insertions(+), 105 deletions(-) diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp index 6024931092..74f96f6da3 100644 --- a/indra/llwindow/lldragdropwin32.cpp +++ b/indra/llwindow/lldragdropwin32.cpp @@ -54,6 +54,10 @@ class LLDragDropWin32Target: { }; + virtual ~LLDragDropWin32Target() + { + }; + //////////////////////////////////////////////////////////////////////////////// // ULONG __stdcall AddRef( void ) @@ -105,6 +109,20 @@ class LLDragDropWin32Target: if ( S_OK == pDataObject->QueryGetData( &fmtetc ) ) { mAllowDrop = true; + mDropUrl = std::string(); + mIsSlurl = false; + + STGMEDIUM stgmed; + if( S_OK == pDataObject->GetData( &fmtetc, &stgmed ) ) + { + PVOID data = GlobalLock( stgmed.hGlobal ); + mDropUrl = std::string( (char*)data ); + + mIsSlurl = ( mDropUrl.find( "slurl.com" ) != std::string::npos ); + + GlobalUnlock( stgmed.hGlobal ); + ReleaseStgMedium( &stgmed ); + }; *pdwEffect = DROPEFFECT_COPY; @@ -125,8 +143,6 @@ class LLDragDropWin32Target: { if ( mAllowDrop ) { - bool allowed_to_drop = false; - // XXX MAJOR MAJOR HACK! LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(mAppWindowHandle, GWL_USERDATA); if (NULL != window_imp) @@ -141,13 +157,17 @@ class LLDragDropWin32Target: LLCoordWindow cursor_coord_window( pt2.x, pt2.y ); window_imp->convertCoords(cursor_coord_window, &gl_coord); MASK mask = gKeyboard->currentMask(TRUE); - allowed_to_drop = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ) ); - } - if ( allowed_to_drop ) - *pdwEffect = DROPEFFECT_COPY; - else - *pdwEffect = DROPEFFECT_NONE; + bool allowed_to_drop = window_imp->completeDragNDropRequest( gl_coord, mask, FALSE, std::string( "" ), mIsSlurl ); + if ( allowed_to_drop ) + *pdwEffect = DROPEFFECT_COPY; + else + *pdwEffect = DROPEFFECT_NONE; + + // special case for SLURLs - you can always drop them on the client window and we need a different cursor + if ( mIsSlurl ) + *pdwEffect = DROPEFFECT_LINK; + }; } else { @@ -161,6 +181,7 @@ class LLDragDropWin32Target: // HRESULT __stdcall DragLeave( void ) { + mDropUrl = std::string(); return S_OK; }; @@ -170,48 +191,30 @@ class LLDragDropWin32Target: { if ( mAllowDrop ) { - // construct a FORMATETC object - FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - - // do we have text? - if( S_OK == pDataObject->QueryGetData( &fmtetc ) ) + // window impl stored in Window data (neat!) + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong( mAppWindowHandle, GWL_USERDATA ); + if ( NULL != window_imp ) { - STGMEDIUM stgmed; - if( S_OK == pDataObject->GetData( &fmtetc, &stgmed ) ) - { - // note: data is in an HGLOBAL - not 'regular' memory - PVOID data = GlobalLock( stgmed.hGlobal ); - - // window impl stored in Window data (neat!) - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong( mAppWindowHandle, GWL_USERDATA ); - if ( NULL != window_imp ) - { - LLCoordGL gl_coord( 0, 0 ); - - POINT pt_client; - pt_client.x = pt.x; - pt_client.y = pt.y; - ScreenToClient( mAppWindowHandle, &pt_client ); - - LLCoordWindow cursor_coord_window( pt_client.x, pt_client.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); - llinfos << "### (Drop) URL is: " << data << llendl; - llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; - llinfos << "### client coords are: " << pt_client.x << " x " << pt_client.y << llendl; - llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl; - llinfos << llendl; - - // no keyboard modifier option yet but we could one day - MASK mask = gKeyboard->currentMask( TRUE ); - - // actually do the drop - window_imp->completeDragNDropRequest( gl_coord, mask, TRUE, std::string( (char*)data ) ); - }; - - GlobalUnlock( stgmed.hGlobal ); - - ReleaseStgMedium( &stgmed ); - }; + LLCoordGL gl_coord( 0, 0 ); + + POINT pt_client; + pt_client.x = pt.x; + pt_client.y = pt.y; + ScreenToClient( mAppWindowHandle, &pt_client ); + + LLCoordWindow cursor_coord_window( pt_client.x, pt_client.y ); + window_imp->convertCoords(cursor_coord_window, &gl_coord); + llinfos << "### (Drop) URL is: " << mDropUrl << llendl; + llinfos << "### raw coords are: " << pt.x << " x " << pt.y << llendl; + llinfos << "### client coords are: " << pt_client.x << " x " << pt_client.y << llendl; + llinfos << "### GL coords are: " << gl_coord.mX << " x " << gl_coord.mY << llendl; + llinfos << llendl; + + // no keyboard modifier option yet but we could one day + MASK mask = gKeyboard->currentMask( TRUE ); + + // actually do the drop + window_imp->completeDragNDropRequest( gl_coord, mask, TRUE, mDropUrl, mIsSlurl ); }; *pdwEffect = DROPEFFECT_COPY; @@ -230,6 +233,8 @@ class LLDragDropWin32Target: LONG mRefCount; HWND mAppWindowHandle; bool mAllowDrop; + std::string mDropUrl; + bool mIsSlurl; friend class LLWindowWin32; }; diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index b8927a1ac4..3b0aeeab1f 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -163,7 +163,7 @@ void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *da { } -BOOL LLWindowCallbacks::handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data ) +BOOL LLWindowCallbacks::handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data, BOOL is_slurl ) { return FALSE; } diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 8e7605a650..1b4a6cbda2 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -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 handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data); + virtual BOOL handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data, BOOL is_slurl); virtual BOOL handleTimerEvent(LLWindow *window); virtual BOOL handleDeviceChange(LLWindow *window); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index eda8cf15b0..78bc3b9c58 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2355,57 +2355,60 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ }; return 0; - case WM_DROPFILES: - { - // HDROP contains what we need - HDROP hdrop = (HDROP)w_param; - - // get location in window space where drop occured and convert to OpenGL coordinate space - POINT pt; - DragQueryPoint( hdrop, &pt ); - LLCoordGL gl_coord; - LLCoordWindow cursor_coord_window( pt.x, pt.y ); - window_imp->convertCoords(cursor_coord_window, &gl_coord); - - // get payload (eventually, this needs to more advanced and grab size of payload dynamically - static char file_name[ 1024 ]; - DragQueryFileA( hdrop, 0, file_name, 1024 ); - void* url = (void*)( file_name ); - - // if it's a .URL or .lnk ("shortcut") file - if ( std::string( file_name ).find( ".lnk" ) != std::string::npos || - std::string( file_name ).find( ".URL" ) != std::string::npos ) - { - // read through file - looks like a 2 line file with second line URL= but who knows.. - std::ifstream file_handle( file_name ); - if ( file_handle.is_open() ) - { - std::string line; - while ( ! file_handle.eof() ) - { - std::getline( file_handle, line ); - if ( ! file_handle.eof() ) - { - std::string prefix( "URL=" ); - if ( line.find( prefix, 0 ) != std::string::npos ) - { - line = line.substr( 4 ); // skip off the URL= bit - strcpy( (char*)url, line.c_str() ); - break; - }; - }; - }; - file_handle.close(); - }; - }; + // only useful for droppnig files - could be used for file upload dialog one day + //case WM_DROPFILES: + // { + // // HDROP contains what we need + // HDROP hdrop = (HDROP)w_param; + + // // get location in window space where drop occured and convert to OpenGL coordinate space + // POINT pt; + // DragQueryPoint( hdrop, &pt ); + // LLCoordGL gl_coord; + // LLCoordWindow cursor_coord_window( pt.x, pt.y ); + // window_imp->convertCoords(cursor_coord_window, &gl_coord); + + // // get payload (eventually, this needs to more advanced and grab size of payload dynamically + // static char file_name[ 1024 ]; + // DragQueryFileA( hdrop, 0, file_name, 1024 ); + // void* url = (void*)( file_name ); + + // // if it's a .URL or .lnk ("shortcut") file + // if ( std::string( file_name ).find( ".lnk" ) != std::string::npos || + // std::string( file_name ).find( ".URL" ) != std::string::npos ) + // { + // // read through file - looks like a 2 line file with second line URL= but who knows.. + // std::ifstream file_handle( file_name ); + // if ( file_handle.is_open() ) + // { + // std::string line; + // while ( ! file_handle.eof() ) + // { + // std::getline( file_handle, line ); + // if ( ! file_handle.eof() ) + // { + // std::string prefix( "URL=" ); + // if ( line.find( prefix, 0 ) != std::string::npos ) + // { + // line = line.substr( 4 ); // skip off the URL= bit + // strcpy( (char*)url, line.c_str() ); + // break; + // }; + // }; + // }; + // file_handle.close(); + // }; + // }; + + // MASK mask = gKeyboard->currentMask(TRUE); + + // if ( window_imp->completeDragNDropRequest( gl_coord, mask, true, (char*)url, false ) ) + // { + // return 0; + // }; + // } - MASK mask = gKeyboard->currentMask(TRUE); - if ( window_imp->completeDragNDropRequest( gl_coord, mask, true, (char*)url ) ) - { - return 0; - }; - } break; } @@ -3578,9 +3581,9 @@ static LLWString find_context(const LLWString & wtext, S32 focus, S32 focus_leng // final stage of handling drop requests - both from WM_DROPFILES message // for files and via IDropTarget interface requests. -BOOL LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ) +BOOL LLWindowWin32::completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url, BOOL is_slurl ) { - return mCallbacks->handleDragNDrop( this, gl_coord, mask, drop, url ); + return mCallbacks->handleDragNDrop( this, gl_coord, mask, drop, url, is_slurl ); } // Handle WM_IME_REQUEST message. diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index e99c26b7f1..7f7acd5751 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -113,7 +113,7 @@ public: /*virtual*/ void interruptLanguageTextInput(); /*virtual*/ void spawnWebBrowser(const std::string& escaped_url); - BOOL completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url ); + BOOL completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, BOOL drop, const std::string url, BOOL is_slurl ); static std::vector getDynamicFallbackFontList(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 17b9490f63..dd84140d5b 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -80,6 +80,7 @@ #include "llviewermenu.h" #include "lltooltip.h" #include "llmediaentry.h" +#include "llurldispatcher.h" // newview includes #include "llagent.h" @@ -819,11 +820,18 @@ BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MAS return TRUE; } -BOOL LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data ) +BOOL LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data, BOOL slurl ) { BOOL result = FALSE; if (gSavedSettings.getBOOL("PrimMediaDragNDrop")) { + // special case SLURLs + if ( slurl ) + { + LLURLDispatcher::dispatch( data, NULL, true ); + return TRUE; + }; + LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY, TRUE /*BOOL pick_transparent*/ ); LLUUID object_id = pick_info.getObjectID(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 428c602b73..4296495067 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -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 handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data); + /*virtual*/ BOOL handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, BOOL drop, std::string data, BOOL slurl); void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ void handleMouseLeave(LLWindow *window); /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y); -- cgit v1.2.3