|
// Copyright (C) 2011 Fog Creek Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
#include "THgShell_h.h"
#include "TortoiseUtils.h"
#include "TortoiseHgDropHandler.h"
// According to http://msdn.microsoft.com/en-us/library/bb776094%28VS.85%29.aspx
// the help texts for the commands should be reasonably short (under 40 characters)
static const CMenuDescription CDndMenuDescList[] =
{
{ "drag_move", L"Hg Move versioned items here",
L"Moves the selected items, updating the Mercurial repository.",
"hg.ico", 0 },
{ "drag_copy", L"Hg Copy versioned items here",
L"Copies the selected items, updating the Mercurial repository.",
"hg.ico", 0 },
// Add new items here.
// Template:
// { "cmdname", L"Display Name",
// L"Status bar prompt.",
// "iconfile.ico", 0 },
};
static const LPCTSTR DropMenu[] =
{
"drag_move",
"drag_copy",
};
#define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i)))
// IContextMenu
STDMETHODIMP CTortoiseHgDropHandler::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
ATLTRACE("CShellExtDnd::QueryContextMenu\n");
if ((uFlags & CMF_DEFAULTONLY) != 0)
return S_OK; //we don't change the default action
if ((uFlags & 0x000f) != CMF_NORMAL && !(uFlags & CMF_EXPLORE) &&
!(uFlags & CMF_VERBSONLY))
{
return S_OK;
}
UINT idCmd = idCmdFirst;
InitMenuMaps(CDndMenuDescList, sizeof(CDndMenuDescList) / sizeof(CMenuDescription));
for (int i = 0; i < sizeof(DropMenu) / sizeof(LPCTSTR); i++)
{
InsertMenuItemByName(hMenu, DropMenu[i], indexMenu++, idCmd++, idCmdFirst, L"");
}
// separator
if (idCmd != idCmdFirst)
::InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
TweakMenuForVista(hMenu);
return ResultFromShort(idCmd - idCmdFirst);
}
STDMETHODIMP CTortoiseHgDropHandler::Initialize(LPCITEMIDLIST pIDFolder,
LPDATAOBJECT pDataObj, HKEY hRegKey)
{
TCHAR szName[MAX_PATH + 1];
#ifdef _DEBUG
PrintDebugHeader(pIDFolder, pDataObj);
#endif
m_strFolder.Empty();
m_listFiles.RemoveAll();
// if a directory background
if (pIDFolder)
{
::SHGetPathFromIDList(pIDFolder, szName);
ATLTRACE(" Folder '%s'\n", szName);
m_strFolder = szName;
}
CString strRoot;
// short circuit if we're dragging into a non-Hg repository
if (m_strFolder.IsEmpty() || (strRoot = GetHgRepoRoot(m_strFolder)).IsEmpty())
{
ATLTRACE(" drag into a non-Hg repos directory\n");
return E_FAIL;
}
if (pDataObj)
{
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
if (SUCCEEDED(pDataObj->GetData(&fmt, &stg)) && stg.hGlobal)
{
HDROP hDrop = (HDROP)::GlobalLock(stg.hGlobal);
if (hDrop)
{
UINT uNumFiles = ::DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
ATLTRACE(" hDrop uNumFiles = %d\n", uNumFiles);
for (UINT i = 0; i < uNumFiles; ++i)
{
if (::DragQueryFile(hDrop, i, szName, MAX_PATH) > 0)
{
ATLTRACE(" DragQueryFile [%d] = '%s'\n", i, szName);
if (GetHgRepoRoot(szName) != strRoot)
{
ATLTRACE(" '%s' isn't in target dir repository\n", szName);
m_listFiles.RemoveAll();
break;
}
m_listFiles.AddTail(szName);
}
}
}
else
{
ATLTRACE(" hDrop is NULL\n");
}
::GlobalUnlock(stg.hGlobal);
if (stg.pUnkForRelease)
{
IUnknown* relInterface = (IUnknown*) stg.pUnkForRelease;
relInterface->Release();
}
}
else
{
ATLTRACE(" pDataObj->GetData failed\n");
}
}
// disable context menu if neither the folder nor the files
// have been found
if (m_listFiles.IsEmpty())
{
ATLTRACE(" shell extension not available on this object\n");
return E_FAIL;
}
else
{
return S_OK;
}
}
CTortoiseHgDropHandler::CTortoiseHgDropHandler()
{
}
|
Loading...