by
Changes to 61 files · Browse files at 093431cbccdf Showing diff from parent af1e7e35ef12 f9d400caa71b Diff from another changeset...
|
|
@@ -1,990 +0,0 @@ - #include "stdafx.h"
-#include "TortoiseUtils.h"
-#include "StringUtils.h"
-#include "Thgstatus.h"
-#include "Winstat.h"
-#include "InitStatus.h"
-#include "SysInfo.h"
-#include "ShellExt.h"
-#include "RegistryConfig.h"
-#include "TortoiseIconBitmap.h"
-#include "ThgVersion.h"
-
-#include "Msi.h"
-
-#include "CShellExtCMenu.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 MenuDescription CMenuMenuDescList[] =
-{
- {"commit", L"Commit...",
- L"Commit changes in repository",
- "menucommit.ico", 0},
- {"init", L"Create Repository Here",
- L"Create a new repository",
- "menucreaterepos.ico", 0},
- {"clone", L"Clone...",
- L"Create clone here from source",
- "menuclone.ico", 0},
- {"shelve", L"Shelve Changes",
- L"Shelve or unshelve file changes",
- "shelve.ico", 0},
- {"status", L"View File Status",
- L"Repository status & changes",
- "menushowchanged.ico", 0},
- {"add", L"Add Files...",
- L"Add files to version control",
- "menuadd.ico", 0},
- {"revert", L"Revert Files...",
- L"Revert file changes",
- "menurevert.ico", 0},
- {"remove", L"Remove Files...",
- L"Remove files from version control",
- "menudelete.ico", 0},
- {"rename", L"Rename File...",
- L"Rename file or directory",
- "general.ico", 0},
- {"workbench", L"Workbench",
- L"View change history of repository",
- "menulog.ico", 0},
- {"log", L"Revision History",
- L"View change history of selected files",
- "menulog.ico", 0},
- {"synch", L"Synchronize",
- L"Synchronize with remote repository",
- "menusynch.ico", 0},
- {"serve", L"Web Server",
- L"Start web server for this repository",
- "proxy.ico", 0},
- {"update", L"Update...",
- L"Update working directory",
- "menucheckout.ico", 0},
- {"thgstatus", L"Update Icons",
- L"Update icons for this repository",
- "refresh_overlays.ico", 0},
- {"userconf", L"Global Settings",
- L"Configure user wide settings",
- "settings_user.ico", 0},
- {"repoconf", L"Repository Settings",
- L"Configure repository settings",
- "settings_repo.ico", 0},
- {"about", L"About TortoiseHg",
- L"Show About Dialog",
- "menuabout.ico", 0},
- {"annotate", L"Annotate Files",
- L"Changeset information per file line",
- "menublame.ico", 0},
- {"vdiff", L"Visual Diff",
- L"View changes using GUI diff tool",
- "TortoiseMerge.ico", 0},
- {"hgignore", L"Edit Ignore Filter",
- L"Edit repository ignore filter",
- "ignore.ico", 0},
- {"guess", L"Guess Renames",
- L"Detect renames and copies",
- "detect_rename.ico", 0},
- {"grep", L"Search History",
- L"Search file revisions for patterns",
- "menurepobrowse.ico", 0},
- {"forget", L"Forget Files...",
- L"Remove files from version control",
- "menudelete.ico", 0},
- {"shellconf", L"Explorer Extension Settings",
- L"Configure Explorer extension",
- "settings_repo.ico", 0},
-
- /* Add new items here */
-
- // template
- //{"", L"", L"", ".ico", 0},
-};
-
-static const char* const RepoNoFilesMenu =
- "commit status shelve vdiff sep"
- " add revert rename forget remove sep"
- " workbench update grep sep"
- " synch serve clone init thgstatus sep"
- " hgignore guess sep"
- " shellconf repoconf userconf sep"
- " about"
-;
-
-static const char* const RepoFilesMenu =
- "commit status vdiff sep"
- " add revert rename forget remove sep"
- " log annotate sep"
- " about"
-;
-
-static const char* const NoRepoMenu =
- "clone init shellconf userconf thgstatus sep"
- " workbench sep"
- " about"
-;
-
-
-void CShellExtCMenu::AddMenuList(UINT idCmd, const std::string& name)
-{
- TDEBUG_TRACE("AddMenuList: idCmd = " << idCmd << " name = " << name);
- myMenuIdMap[idCmd] = myDescMap[name];
-}
-
-
-void GetCMenuTranslation(
- const std::string& lang,
- const std::string& name,
- std::wstring& menuText,
- std::wstring& helpText
-)
-{
- std::wstring subkey = L"Software\\TortoiseHg\\CMenu\\";
- subkey += MultibyteToWide(lang);
- subkey += L"\\";
- subkey += MultibyteToWide(name);
-
- TDEBUG_TRACEW(L"GetCMenuTranslation: " << subkey);
-
- HKEY hkey = 0;
- LONG rv = RegOpenKeyExW(
- HKEY_CURRENT_USER, subkey.c_str(), 0, KEY_READ, &hkey);
-
- if (rv == ERROR_SUCCESS && hkey)
- {
- GetRegSZValueW(hkey, L"menuText", menuText);
- GetRegSZValueW(hkey, L"helpText", helpText);
- }
- else
- {
- TDEBUG_TRACEW(
- L"GetCMenuTranslation: RegOpenKeyExW(\""
- << subkey << "\") failed"
- );
- }
-
- if (hkey)
- RegCloseKey(hkey);
-}
-
-void CShellExtCMenu::InitMenuMaps(const MenuDescription *menuDescs, std::size_t sz)
-{
- if (myDescMap.empty())
- {
- std::string lang;
- GetRegistryConfig("CMenuLang", lang);
-
- for (std::size_t i = 0; i < sz; i++)
- {
- MenuDescription md = menuDescs[i];
-
- if (md.name.empty())
- {
- TDEBUG_TRACE("**** InitMenuMaps: ignoring entry with empty name");
- break;
- }
-
- TDEBUG_TRACE("InitMenuMaps: adding " << md.name);
-
- // Look for translation of menu and help text
- if (!lang.empty())
- GetCMenuTranslation(lang, md.name, md.menuText, md.helpText);
-
- myDescMap[md.name] = md;
- }
-
- }
-
- myMenuIdMap.clear();
-}
-
-
-void InsertMenuItemWithIcon1(
- HMENU hMenu, UINT indexMenu, UINT idCmd,
- const std::wstring& menuText, const std::string& iconName)
-{
- // MFT_STRING is obsolete and should not be used (replaced by MIIM_STRING
- // from Win2K onward)
- MENUITEMINFOW mi;
- memset(&mi, 0, sizeof(mi));
- mi.cbSize = sizeof(mi);
- mi.fMask = MIIM_ID | MIIM_STRING;
- mi.dwTypeData = const_cast<wchar_t*>(menuText.c_str());
- mi.cch = static_cast<UINT>(menuText.length());
- mi.wID = idCmd;
-
- if (SysInfo::Instance().IsVistaOrLater())
- {
- HBITMAP hBmp = GetTortoiseIconBitmap(iconName);
- if (hBmp)
- {
- mi.fMask |= MIIM_BITMAP;
- mi.hbmpItem = hBmp;
- }
- else
- {
- TDEBUG_TRACE(" ***** InsertMenuItemWithIcon1: can't find " + iconName);
- }
- }
- else
- {
- HICON h = GetTortoiseIcon(iconName);
- if (h)
- {
- mi.fMask |= MIIM_BITMAP | MIIM_DATA;
- mi.dwItemData = (ULONG_PTR) h;
- mi.hbmpItem = HBMMENU_CALLBACK;
- }
- else
- {
- TDEBUG_TRACE(" ***** InsertMenuItemWithIcon1: can't find " + iconName);
- }
- }
- InsertMenuItemW(hMenu, indexMenu, TRUE, &mi);
-
- TDEBUG_TRACEW(
- L"InsertMenuItemWithIcon1(\"" << menuText << L"\") finished");
-}
-
-
-void InsertSubMenuItemWithIcon2(
- HMENU hMenu, HMENU hSubMenu, UINT indexMenu, UINT idCmd,
- const std::wstring& menuText, const std::string& iconName)
-{
- // MFT_STRING is obsolete and should not be used (replaced by MIIM_STRING
- // from Win2K onward)
- MENUITEMINFOW mi;
- memset(&mi, 0, sizeof(mi));
- mi.cbSize = sizeof(mi);
- mi.fMask = MIIM_SUBMENU | MIIM_ID | MIIM_STRING;
- mi.dwTypeData = const_cast<wchar_t*>(menuText.c_str());
- mi.cch = static_cast<UINT>(menuText.length());
- mi.wID = idCmd;
- mi.hSubMenu = hSubMenu;
-
- if (SysInfo::Instance().IsVistaOrLater())
- {
- HBITMAP hBmp = GetTortoiseIconBitmap(iconName);
- if (hBmp)
- {
- mi.fMask |= MIIM_BITMAP;
- mi.hbmpItem = hBmp;
- }
- else
- {
- TDEBUG_TRACE(" ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
- }
- }
- else
- {
- HICON h = GetTortoiseIcon(iconName);
- if (h)
- {
- mi.fMask |= MIIM_BITMAP | MIIM_DATA;
- mi.dwItemData = (ULONG_PTR) h;
- mi.hbmpItem = HBMMENU_CALLBACK;
- }
- else
- {
- TDEBUG_TRACE(" ***** InsertSubMenuItemWithIcon2: can't find " + iconName);
- }
- }
-
- InsertMenuItemW(hMenu, indexMenu, TRUE, &mi);
-
- TDEBUG_TRACEW(
- L"InsertMenuItemWithIcon2(\"" << menuText << L"\") finished");
-}
-
-
-void CShellExtCMenu::InsertMenuItemByName(
- HMENU hMenu, const std::string& name, UINT indexMenu,
- UINT idCmd, UINT idCmdFirst, const std::wstring& prefix)
-{
- MenuDescriptionMap::iterator iter = myDescMap.find(name);
- if (iter == myDescMap.end())
- {
- TDEBUG_TRACE("***** InsertMenuItemByName: can't find menu info for " << name);
- return;
- }
-
-
- MenuDescription md = iter->second;
- AddMenuList(idCmd - idCmdFirst, name);
- InsertMenuItemWithIcon1(
- hMenu, indexMenu, idCmd, prefix + md.menuText, md.iconName);
-}
-
-
-const std::wstring TortoiseHgMenuEntryString = L"TortoiseHg";
-
-int HasTortoiseMenu(HMENU hMenu, bool& hasmenu)
-// returns -1 on error, 0 otherwise
-{
- hasmenu = false;
-
- const int count = ::GetMenuItemCount(hMenu);
- if (count == -1)
- {
- TDEBUG_TRACE("***** HasTortoiseMenu: GetMenuItemCount returned -1");
- return -1;
- }
-
- MENUITEMINFOW mii;
- for (int i = 0; i < count; ++i)
- {
- memset(&mii, 0, sizeof(MENUITEMINFOW));
- mii.cbSize = sizeof(MENUITEMINFOW);
-
- // first GetMenuItemInfoW call: get size of menu item string
- mii.fMask = MIIM_STRING;
- BOOL res = ::GetMenuItemInfoW(hMenu, i, true, &mii);
- if (res == 0) {
- TDEBUG_TRACE("HasTortoiseMenu: "
- << "first GetMenuItemInfo returned 0");
- continue;
- }
-
- if (mii.dwTypeData != MFT_STRING)
- {
- // not a string
- continue;
- }
-
- // allocate buffer for the string
- std::vector<wchar_t> text(mii.cch + 1);
-
- // second GetMenuItemInfoW call: get string into buffer
- mii.dwTypeData = &text[0];
- ++mii.cch; // size of buffer is one more than length of string
- res = ::GetMenuItemInfoW(hMenu, i, true, &mii);
- if (res == 0) {
- TDEBUG_TRACE("HasTortoiseMenu: "
- << "second GetMenuItemInfo returned 0");
- continue;
- }
-
- const std::wstring menuitemtext(&text[0]);
- //TDEBUG_TRACEW(L"HasTortoiseMenu: "
- // << L"menuitemtext is '" << menuitemtext << L"'");
-
- if (menuitemtext == TortoiseHgMenuEntryString)
- {
- TDEBUG_TRACE("HasTortoiseMenu: FOUND TortoiseHg menu entry");
- hasmenu = true;
- return 0;
- }
- }
-
- TDEBUG_TRACE("HasTortoiseMenu: TortoiseHg menu entry NOT found");
- return 0;
-}
-
-void
-CShellExtCMenu::TweakMenuForVista(HMENU hMenu)
-{
- if (!SysInfo::Instance().IsVistaOrLater())
- return;
-
- MENUINFO MenuInfo = {};
- MenuInfo.cbSize = sizeof(MenuInfo);
- MenuInfo.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS;
- MenuInfo.dwStyle = MNS_CHECKORBMP;
-
- SetMenuInfo(hMenu, &MenuInfo);
-}
-
-#define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i)))
-
-// IContextMenu
-STDMETHODIMP
-CShellExtCMenu::QueryContextMenu(
- HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
-{
- TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu");
-
- UINT idCmd = idCmdFirst;
- BOOL bAppendItems = TRUE;
-
- if ((uFlags & 0x000F) == CMF_NORMAL)
- bAppendItems = TRUE;
- else if (uFlags & CMF_VERBSONLY)
- bAppendItems = TRUE;
- else if (uFlags & CMF_EXPLORE)
- bAppendItems = TRUE;
- else
- bAppendItems = FALSE;
-
- if (!bAppendItems)
- return S_OK;
-
- bool hasthgmenu = false;
- if (HasTortoiseMenu(hMenu, hasthgmenu) == 0 && hasthgmenu)
- {
- TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu: "
- << "TortoiseHg menu entry already in menu -> skipping");
- return S_OK;
- }
-
- InitMenuMaps(CMenuMenuDescList, sizeof(CMenuMenuDescList) / sizeof(MenuDescription));
-
- typedef std::vector<std::string> entriesT;
- typedef entriesT::const_iterator entriesIter;
-
- std::string promoted_string = "commit,workbench"; // default value if key not found
- GetRegistryConfig("PromotedItems", promoted_string);
-
- entriesT promoted;
- Tokenize(promoted_string, promoted, ",");
-
- // Select menu to show
- bool fileMenu = !myFiles.empty();
- bool isHgrepo = false;
- std::string cwd;
- if (!myFolder.empty())
- {
- cwd = myFolder;
- }
- else if (fileMenu)
- {
- cwd = IsDirectory(myFiles[0])? myFiles[0] : DirName(myFiles[0]);
- }
-
- if (!cwd.empty())
- {
- // check if target directory is a Mercurial repository
- std::string root = GetHgRepoRoot(cwd);
- isHgrepo = !root.empty();
- if (myFiles.size() == 1 && root == myFiles[0])
- {
- fileMenu = false;
- myFolder = cwd;
- myFiles.clear();
- }
- }
-
- if ((uFlags & CMF_EXTENDEDVERBS) == 0)
- {
- // shift key is not down
- if (!isHgrepo)
- {
- // we are not inside a repo
- std::string cval;
- if (GetRegistryConfig("HideMenuOutsideRepo", cval) != 0 && cval == "1")
- {
- return S_OK; // don't show thg cmenu entries
- }
- }
- }
-
- TDEBUG_TRACE(
- "CShellExtCMenu::QueryContextMenu: isHgrepo = "
- << isHgrepo << ", fileMenu = " << fileMenu
- );
-
- /* We have three menu types: files-selected, no-files-selected, no-repo */
- const char* entries_string = 0;
- if (isHgrepo)
- if (fileMenu)
- entries_string = RepoFilesMenu;
- else
- entries_string = RepoNoFilesMenu;
- else
- entries_string = NoRepoMenu;
-
- // start building TortoiseHg menus and submenus
- InsertMenu(hMenu, indexMenu++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
-
- entriesT entries;
- Tokenize(entries_string, entries, " ");
-
- for (entriesIter i = entries.begin(); i != entries.end(); i++)
- {
- std::string name = *i;
- if (contains(promoted, name))
- {
- InsertMenuItemByName(
- hMenu, name, indexMenu++,
- idCmd++, idCmdFirst, L"Hg "
- );
- }
- }
-
- const HMENU hSubMenu = CreatePopupMenu();
- if (hSubMenu)
- {
- UINT indexSubMenu = 0;
- bool isSeparator = true;
- for (entriesIter i = entries.begin(); i != entries.end(); i++)
- {
- std::string name = *i;
- if (name == "sep")
- {
- if (!isSeparator)
- {
- InsertMenu(
- hSubMenu, indexSubMenu++,
- MF_SEPARATOR | MF_BYPOSITION, 0, NULL
- );
- isSeparator = true;
- }
- }
- else
- {
- if (!contains(promoted, name))
- {
- InsertMenuItemByName(
- hSubMenu, name,
- indexSubMenu++, idCmd++, idCmdFirst, L""
- );
- isSeparator = false;
- }
- }
- }
- if (isSeparator && indexSubMenu > 0)
- RemoveMenu(hSubMenu, indexSubMenu - 1, MF_BYPOSITION);
-
- TweakMenuForVista(hSubMenu);
-
- }
-
- TDEBUG_TRACE(" CShellExtCMenu::QueryContextMenu: adding main THG menu");
- InsertSubMenuItemWithIcon2(hMenu, hSubMenu, indexMenu++, idCmd++,
- TortoiseHgMenuEntryString, "hg.ico");
-
- InsertMenu(hMenu, indexMenu++, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
-
- InitStatus::check();
-
- TweakMenuForVista(hMenu);
-
- return ResultFromShort(idCmd - idCmdFirst);
-}
-
-
-STDMETHODIMP
-CShellExtCMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
-{
- TDEBUG_TRACE("CShellExtCMenu::InvokeCommand");
-
- HRESULT hr = E_INVALIDARG;
- if (!HIWORD(lpcmi->lpVerb))
- {
- UINT idCmd = LOWORD(lpcmi->lpVerb);
- TDEBUG_TRACE("CShellExtCMenu::InvokeCommand: idCmd = " << idCmd);
- MenuIdCmdMap::iterator iter = myMenuIdMap.find(idCmd);
- if (iter != myMenuIdMap.end())
- {
- RunDialog(iter->second.name);
- hr = S_OK;
- }
- else
- {
- TDEBUG_TRACE(
- "***** CShellExtCMenu::InvokeCommand: action not found for idCmd "
- << idCmd
- );
- }
- }
- return hr;
-}
-
-
-STDMETHODIMP
-CShellExtCMenu::GetCommandString(
- UINT_PTR idCmd, UINT uFlags, UINT FAR *reserved,
- LPSTR pszName, UINT cchMax)
-{
- // see http://msdn.microsoft.com/en-us/library/bb776094%28VS.85%29.aspx
-
- HRESULT res = S_FALSE;
-
- const char* psz = "";
- const wchar_t* pszw = 0;
-
- std::string sflags = "?";
- switch (uFlags)
- {
- case GCS_HELPTEXTW:
- sflags = "GCS_HELPTEXTW"; break;
- case GCS_HELPTEXTA:
- sflags = "GCS_HELPTEXTA"; break;
- case GCS_VALIDATEW:
- sflags = "GCS_VALIDATEW"; break;
- case GCS_VALIDATEA:
- sflags = "GCS_VALIDATEA"; break;
- case GCS_VERBW:
- sflags = "GCS_VERBW"; break;
- case GCS_VERBA:
- sflags = "GCS_VERBA"; break;
- }
-
- TDEBUG_TRACE(
- "CShellExtCMenu::GetCommandString: idCmd = " << idCmd
- << ", uFlags = " << uFlags << " (" << sflags << ")"
- << ", cchMax = " << cchMax
- );
-
- MenuIdCmdMap::iterator iter = myMenuIdMap.find(static_cast<UINT>(idCmd));
- if (iter == myMenuIdMap.end())
- {
- TDEBUG_TRACE("***** CShellExtCMenu::GetCommandString: idCmd not found");
- }
- else
- {
- TDEBUG_TRACE(
- "CShellExtCMenu::GetCommandString: name = \"" << iter->second.name << "\"");
-
- if (uFlags == GCS_HELPTEXTW)
- {
- pszw = iter->second.helpText.c_str();
- res = S_OK;
-
- size_t size = iter->second.helpText.size();
- if (size >= 40)
- {
- TDEBUG_TRACE(
- "***** CShellExtCMenu::GetCommandString: warning:"
- << " length of help text is " << size
- << ", which is not reasonably short (<40)");
- }
- }
- else if (uFlags == GCS_HELPTEXTA)
- {
- // we don't provide ansi help texts
- psz = "";
- res = S_OK;
- }
- else if (uFlags == GCS_VERBW || uFlags == GCS_VERBA)
- {
-#if 0
- psz = iter->second.name.c_str();
-#else
- // bugfix: don't provide verbs ("rename" conflicted with rename of explorer)
- psz = "";
-#endif
- res = S_OK;
- }
- else if (uFlags == GCS_VALIDATEW || uFlags == GCS_VALIDATEA)
- {
- res = S_OK;
- }
- }
-
- if (cchMax < 1)
- {
- TDEBUG_TRACE("CShellExtCMenu::GetCommandString: cchMax = "
- << cchMax << " (is <1)");
- return res;
- }
-
- size_t size = 0;
-
- if (uFlags & GCS_UNICODE)
- {
- wchar_t* const dest = reinterpret_cast<wchar_t*>(pszName);
- std::wstring wpsz = MultibyteToWide(psz);
- const wchar_t* const src = pszw ? pszw : wpsz.c_str();
-
- wcsncpy(dest, src, cchMax-1);
- *(dest + cchMax-1) = 0;
-
- size = wcslen(src);
-
- TDEBUG_TRACEW(L"CShellExtCMenu::GetCommandString: res = " << int(res)
- << L", pszName (wide) = \"" << dest << L"\"");
- }
- else
- {
- strncpy(pszName, psz, cchMax-1);
- *(pszName + cchMax-1) = 0;
-
- size = strlen(psz);
-
- TDEBUG_TRACE("CShellExtCMenu::GetCommandString: res = " << int(res)
- << ", pszName = \"" << psz << "\"");
- }
-
- if (size > cchMax-1)
- {
- TDEBUG_TRACE(
- "***** CShellExtCMenu::GetCommandString: string was truncated: size = "
- << size << ", cchMax = " << cchMax);
- }
-
- return res;
-}
-
-
-STDMETHODIMP
-CShellExtCMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- LRESULT res;
- return HandleMenuMsg2(uMsg, wParam, lParam, &res);
-}
-
-
-STDMETHODIMP
-CShellExtCMenu::HandleMenuMsg2(
- UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
-{
- // A great tutorial on owner drawn menus in shell extension can be found
- // here: http://www.codeproject.com/shell/shellextguide7.asp
-
- LRESULT res;
- if (!pResult)
- pResult = &res;
- *pResult = FALSE;
-
- switch (uMsg)
- {
- case WM_MEASUREITEM:
- {
- MEASUREITEMSTRUCT* lpmis = (MEASUREITEMSTRUCT*)lParam;
- if (lpmis==NULL)
- break;
- lpmis->itemWidth += 2;
- if(lpmis->itemHeight < 16)
- lpmis->itemHeight = 16;
- *pResult = TRUE;
- }
- break;
-
- case WM_DRAWITEM:
- {
- DRAWITEMSTRUCT* lpdis = (DRAWITEMSTRUCT*)lParam;
- if (!lpdis || (lpdis->CtlType != ODT_MENU) || !lpdis->itemData)
- break; //not for a menu
- DrawIconEx(
- lpdis->hDC,
- lpdis->rcItem.left - 16,
- lpdis->rcItem.top
- + (lpdis->rcItem.bottom - lpdis->rcItem.top - 16) / 2,
- (HICON) lpdis->itemData, 16, 16,
- 0, 0, DI_NORMAL
- );
- *pResult = TRUE;
- }
- break;
-
- default:
- return S_OK;
- }
-
- return S_OK;
-}
-
-
-void CShellExtCMenu::RunDialog(const std::string &cmd)
-{
- std::string dir = GetTHgProgRoot();
- if (dir.empty())
- {
- TDEBUG_TRACE("RunDialog: THG root is empty");
- return;
- }
- std::string hgcmd = dir + "\\thgw.exe";
-
- WIN32_FIND_DATAA data;
- HANDLE hfind = FindFirstFileA(hgcmd.c_str(), &data);
- if (hfind == INVALID_HANDLE_VALUE)
- {
- hgcmd = dir + "\\hgtk.exe";
- hfind = FindFirstFileA(hgcmd.c_str(), &data);
- if (hfind == INVALID_HANDLE_VALUE)
- hgcmd = dir + "\\thg.cmd";
- else
- FindClose(hfind);
- }
- else
- FindClose(hfind);
-
- hgcmd = Quote(hgcmd) + " --nofork " + cmd;
-
- std::string cwd;
- if (!myFolder.empty())
- {
- cwd = myFolder;
- }
- else if (!myFiles.empty())
- {
- cwd = IsDirectory(myFiles[0]) ? myFiles[0] : DirName(myFiles[0]);
- }
- else
- {
- TDEBUG_TRACE("***** RunDialog: can't get cwd");
- return;
- }
-
- if (cmd == "thgstatus")
- {
- if (Thgstatus::remove(cwd) != 0)
- {
- std::string p = dir + "\\TortoiseHgOverlayServer.exe";
- LaunchCommand(Quote(p), dir);
- }
- InitStatus::check();
- return;
- }
-
- if (!myFiles.empty())
- {
- const std::string tempfile = GetTemporaryFile();
- if (tempfile.empty())
- {
- TDEBUG_TRACE("***** RunDialog: error: GetTemporaryFile returned empty string");
- return;
- }
-
- TDEBUG_TRACE("RunDialog: temp file = " << tempfile);
- HANDLE tempfileHandle = CreateFileA(
- tempfile.c_str(), GENERIC_WRITE,
- FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
- );
-
- if (tempfileHandle == INVALID_HANDLE_VALUE)
- {
- TDEBUG_TRACE("***** RunDialog: error: failed to create file " << tempfile);
- return;
- }
-
- typedef std::vector<std::string>::size_type ST;
- for (ST i = 0; i < myFiles.size(); i++)
- {
- DWORD dwWritten;
- TDEBUG_TRACE("RunDialog: temp file adding " << myFiles[i]);
- WriteFile(
- tempfileHandle, myFiles[i].c_str(),
- static_cast<DWORD>(myFiles[i].size()), &dwWritten, 0
- );
- WriteFile(tempfileHandle, "\n", 1, &dwWritten, 0);
- }
- CloseHandle(tempfileHandle);
- hgcmd += " --listfile " + Quote(tempfile);
- }
-
- LaunchCommand(hgcmd, cwd);
- InitStatus::check();
-}
-
-void CShellExtCMenu::PrintDebugHeader(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj)
-{
- TDEBUG_TRACE("CShellExtCMenu::Initialize");
-
- // get installed MSI product id (for debugging purposes for now)
-#ifdef _M_X64
- const char* shellexid = "{D5D1E532-CDAD-4FFD-9695-757B8A29B4BA}";
-#else
- const char* shellexid = "{728E8840-5878-4EA7-918F-281C2697ABB1}";
-#endif
- std::vector<char> product_id(50, 0);
- UINT msires = ::MsiGetProductCodeA(shellexid, &product_id[0]);
- TDEBUG_TRACE("MSI shellexid: " << shellexid);
- TDEBUG_TRACE("MSI msires: " << msires);
- TDEBUG_TRACE("MSI installed product id: " << &product_id[0]);
-
- DWORD busize = 300;
- std::vector<char> buf(busize, 0);
- msires = ::MsiGetProductInfoA(
- &product_id[0], INSTALLPROPERTY_INSTALLLOCATION, &buf[0], &busize);
- if (msires == ERROR_SUCCESS)
- {
- TDEBUG_TRACE("MSI install location: " << &buf[0]);
- }
- else
- {
- TDEBUG_TRACE("MSI install location: error " << msires);
- }
-
- TDEBUG_TRACEW(
- L"---- TortoiseHg shell extension version "
- << ThgVersion::get() << L"----"
- );
-
- TDEBUG_TRACE(" pIDFolder: " << pIDFolder);
- TDEBUG_TRACE(" pDataObj: " << pDataObj);
-}
-
-STDMETHODIMP CShellExtCMenu::Initialize(
- LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey)
-{
- TCHAR name[MAX_PATH+1];
-
- PrintDebugHeader(pIDFolder, pDataObj);
-
- myFolder.clear();
- myFiles.clear();
-
- 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);
- TDEBUG_TRACE(" hDrop uNumFiles = " << uNumFiles);
- for (UINT i = 0; i < uNumFiles; ++i) {
- if (DragQueryFile(hDrop, i, name, MAX_PATH) > 0)
- {
- TDEBUG_TRACE(" DragQueryFile [" << i << "] = " << name);
- myFiles.push_back(name);
- }
- }
- }
- else
- {
- TDEBUG_TRACE(" hDrop is NULL ");
- }
-
- GlobalUnlock(stg.hGlobal);
- if (stg.pUnkForRelease)
- {
- IUnknown* relInterface = (IUnknown*) stg.pUnkForRelease;
- relInterface->Release();
- }
- }
- else
- {
- TDEBUG_TRACE(" pDataObj->GetData failed");
- }
- }
-
- // if a directory background
- if (pIDFolder)
- {
- SHGetPathFromIDList(pIDFolder, name);
- TDEBUG_TRACE(" Folder " << name);
- myFolder = name;
- }
-
- // disable context menu if neither the folder nor the files
- // have been found
- if (myFolder.empty() && myFiles.empty()) {
- TDEBUG_TRACE(" shell extension not available on this object");
- return E_FAIL;
- } else {
- return S_OK;
- }
-}
-
-
-CShellExtCMenu::CShellExtCMenu(const char dummy)
-{
- CShellExt::IncDllRef();
- ADDIFACE(IShellExtInit);
- ADDIFACE(IContextMenu);
- ADDIFACE(IContextMenu2);
- ADDIFACE(IContextMenu3);
-}
-
-
-CShellExtCMenu::~CShellExtCMenu()
-{
- CShellExt::DecDllRef();
-}
-
-IMPLEMENT_UNKNOWN(CShellExtCMenu)
|
|
@@ -1,68 +0,0 @@ - #ifndef _CShellExtCMenu_h_
-#define _CShellExtCMenu_h_
-
-#include <vector>
-#include <string>
-#include <map>
-
-#include "SimpleUnknown.h"
-
-struct MenuDescription
-{
- std::string name;
- std::wstring menuText;
- std::wstring helpText;
- std::string iconName;
- UINT idCmd;
-};
-
-typedef std::map<std::string, MenuDescription> MenuDescriptionMap;
-
-typedef std::map<UINT, MenuDescription> MenuIdCmdMap;
-
-
-class CShellExtCMenu: public CSimpleUnknown, IContextMenu3, IShellExtInit
-{
-
-protected:
- ULONG m_cRef;
- std::vector<std::string> myFiles;
- std::string myFolder;
- MenuDescriptionMap myDescMap;
- MenuIdCmdMap myMenuIdMap;
-
- virtual void RunDialog(const std::string&);
-
- void TweakMenuForVista(HMENU menu);
- void PrintDebugHeader(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj);
- void InitMenuMaps(const MenuDescription *menuDescs, std::size_t sz);
- void InsertMenuItemByName(
- HMENU hMenu, const std::string& name, UINT indexMenu,
- UINT idCmd, UINT idCmdFirst, const std::wstring& prefix);
- void AddMenuList(UINT idCmd, const std::string& name);
-
-public:
- explicit CShellExtCMenu(const char dummy);
- ~CShellExtCMenu();
-
- DECLARE_UNKNOWN()
-
- // IContextMenu3
- STDMETHOD(QueryContextMenu)(
- HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast,
- UINT uFlags);
- STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpcmi);
- STDMETHOD(GetCommandString)(
- UINT_PTR idCmd, UINT uFlags, UINT FAR* reserved,LPSTR pszName,
- UINT cchMax);
- STDMETHOD(HandleMenuMsg)(UINT uMsg, WPARAM wParam, LPARAM lParam);
- STDMETHOD(HandleMenuMsg2)(
- UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
-
- // IShellExtInit
- STDMETHOD(Initialize)(
- LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hKeyID);
-};
-
-
-#endif
|
|
|
@@ -1,174 +0,0 @@ - #include "stdafx.h"
-#include "TortoiseUtils.h"
-
-#include "CShellExtDnd.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 MenuDescription CDndMenuDescList[] =
-{
- {"drag_move", L"Hg Move versioned item(s) here",
- L"", "hg.ico", 0},
- {"drag_copy", L"Hg Copy versioned item(s) here",
- L"", "hg.ico", 0},
- /* Add new items here */
-
- // template
- //{"", L"", L"", ".ico", 0},
-};
-
-
-static const char* const DropMenu =
- "drag_move drag_copy"
-;
-
-
-#define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i)))
-
-// IContextMenu
-STDMETHODIMP
-CShellExtDnd::QueryContextMenu(
- HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
-{
- TDEBUG_TRACE("CShellExtDnd::QueryContextMenu");
-
- 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(MenuDescription));
-
- typedef std::vector<std::string> entriesT;
- typedef entriesT::const_iterator entriesIter;
-
- const char* entries_string = DropMenu;
- entriesT entries;
- Tokenize(entries_string, entries, " ");
-
- for (entriesIter i = entries.begin(); i != entries.end(); i++)
- {
- std::string name = *i;
- InsertMenuItemByName(
- hMenu, name, indexMenu++,
- idCmd++, idCmdFirst, L""
- );
- }
-
- // separator
- if (idCmd != idCmdFirst)
- InsertMenu(hMenu, indexMenu++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL);
-
- TweakMenuForVista(hMenu);
-
- return ResultFromShort(idCmd - idCmdFirst);
-}
-
-
-void CShellExtDnd::RunDialog(const std::string &cmd)
-{
- if (cmd == "drag_move" || cmd == "drag_copy") {
- //Append the current directory as the dest
- myFiles.push_back(myFolder);
- }
- CShellExtCMenu::RunDialog(cmd);
-}
-
-
-STDMETHODIMP CShellExtDnd::Initialize(
- LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey)
-{
- TCHAR name[MAX_PATH+1];
-
- PrintDebugHeader(pIDFolder, pDataObj);
-
- myFolder.clear();
- myFiles.clear();
-
- // if a directory background
- if (pIDFolder)
- {
- SHGetPathFromIDList(pIDFolder, name);
- TDEBUG_TRACE(" Folder " << name);
- myFolder = name;
- }
-
- std::string root;
-
- //short circuit if we're dragging into a non-Hg repository
- if (myFolder.empty() || (root = GetHgRepoRoot(myFolder)).empty())
- {
- TDEBUG_TRACE(" drag into a non-Hg repos directory");
- 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);
- TDEBUG_TRACE(" hDrop uNumFiles = " << uNumFiles);
- for (UINT i = 0; i < uNumFiles; ++i) {
- if (DragQueryFile(hDrop, i, name, MAX_PATH) > 0)
- {
- TDEBUG_TRACE(" DragQueryFile [" << i << "] = " << name);
- if (GetHgRepoRoot(name) != root)
- {
- TDEBUG_TRACE(" " << name << " isn't in target dir repository");
- myFiles.clear();
- break;
- }
- myFiles.push_back(name);
- }
- }
- }
- else
- {
- TDEBUG_TRACE(" hDrop is NULL ");
- }
-
- GlobalUnlock(stg.hGlobal);
- if (stg.pUnkForRelease)
- {
- IUnknown* relInterface = (IUnknown*) stg.pUnkForRelease;
- relInterface->Release();
- }
- }
- else
- {
- TDEBUG_TRACE(" pDataObj->GetData failed");
- }
- }
-
- // disable context menu if neither the folder nor the files
- // have been found
- if (myFiles.empty()) {
- TDEBUG_TRACE(" shell extension not available on this object");
- return E_FAIL;
- } else {
- return S_OK;
- }
-}
-
-
-CShellExtDnd::CShellExtDnd(const char dummy) :
- CShellExtCMenu(dummy)
-{
-}
-
-
-CShellExtDnd::~CShellExtDnd()
-{
-}
|
|
@@ -1,29 +0,0 @@ - #ifndef _CShellExtDnd_h_
-#define _CShellExtDnd_h_
-
-#include "CShellExtCMenu.h"
-
-
-//CShellExtCMenu implements IContextMenu3, IShellExtInit
-class CShellExtDnd: public CShellExtCMenu
-{
-
-protected:
- virtual void RunDialog(const std::string&);
-
-public:
- explicit CShellExtDnd(const char dummy);
- ~CShellExtDnd();
-
- // IContextMenu3
- STDMETHOD(QueryContextMenu)(
- HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast,
- UINT uFlags);
-
- // IShellExtInit
- STDMETHOD(Initialize)(
- LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hKeyID);
-};
-
-
-#endif
|
|
@@ -1,90 +0,0 @@ - #include "stdafx.h"
-#include "ShellExt.h"
-#include "TortoiseUtils.h"
-#include "StringUtils.h"
-#include "QueryDirstate.h"
-#include "RegistryConfig.h"
-#include "CShellExtOverlay.h"
-
-#include <shlwapi.h>
-
-
-STDMETHODIMP CShellExtOverlay::GetOverlayInfo(
- LPWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags)
-{
- TDEBUG_TRACE("CShellExtOverlay::GetOverlayInfo: myTortoiseClass = " << myTortoiseClass);
- // icons are determined by TortoiseOverlays shim
- *pIndex = 0;
- *pdwFlags = 0;
- *pwszIconFile = 0;
- return S_OK;
-}
-
-
-STDMETHODIMP CShellExtOverlay::GetPriority(int *pPriority)
-{
- *pPriority = 1;
- return S_OK;
-}
-
-
-STDMETHODIMP CShellExtOverlay::IsMemberOf(LPCWSTR pwszPath, DWORD /* dwAttrib */)
-{
- ThgCriticalSection cs(CShellExt::GetCriticalSection());
-
- std::string cval;
- if (GetRegistryConfig("EnableOverlays", cval) != 0 && cval == "0")
- return S_FALSE;
-
- // This overlay handler processes all filenames in lowercase, so that a path
- // "C:\FOO\BAR\Baz.TXT" will be considered equal to "C:\foo\bar\baz.txt"
- // (note that mercurial preserves the case of filenames in .hg/dirstate)
-
- std::wstring lowerpath(pwszPath);
- ::CharLowerW(const_cast<wchar_t*>(lowerpath.c_str()));
-
- std::string path = WideToMultibyte(lowerpath.c_str());
-
- if (GetRegistryConfig("LocalDisksOnly", cval) != 0 && cval != "0")
- {
- if (::PathIsNetworkPath(path.c_str()))
- return S_FALSE;
-
- if (path.size() > 2 && path[1] == ':')
- {
- std::string t = "C:\\";
- t[0] = path[0];
- if (::GetDriveType(t.c_str()) == 4)
- return S_FALSE;
- }
- }
-
- char filterStatus = 0;
- if (myTortoiseClass == 'A')
- filterStatus = 'A';
-
- char status = 0;
- if (!HgQueryDirstate(myTortoiseClass, path, filterStatus, status))
- return S_FALSE;
-
- if (status == myTortoiseClass)
- return S_OK;
-
- return S_FALSE;
-}
-
-
-CShellExtOverlay::CShellExtOverlay(char tortoiseClass) :
- myTortoiseClass(tortoiseClass)
-{
- CShellExt::IncDllRef();
- ADDIFACE(IShellIconOverlayIdentifier);
-}
-
-
-CShellExtOverlay::~CShellExtOverlay()
-{
- CShellExt::DecDllRef();
-}
-
-IMPLEMENT_UNKNOWN(CShellExtOverlay)
\ No newline at end of file |
|
@@ -1,24 +0,0 @@ - #ifndef _CShellExtOverlay_h_
-#define _CShellExtOverlay_h_
-
-#include "SimpleUnknown.h"
-
-class CShellExtOverlay: public CSimpleUnknown, public IShellIconOverlayIdentifier
-{
- const char myTortoiseClass;
-
-public:
- explicit CShellExtOverlay(char Class);
- ~CShellExtOverlay();
-
- DECLARE_UNKNOWN()
-
- // IShellIconOverlayIdentifier
- STDMETHOD(GetOverlayInfo)(
- LPWSTR pwszIconFile, int cchMax, int* pIndex, DWORD* pdwFlags);
- STDMETHOD(GetPriority)(int* pPriority);
- STDMETHOD(IsMemberOf)(LPCWSTR pwszPath, DWORD dwAttrib);
-};
-
-
-#endif
|
|
@@ -1,4 +0,0 @@ - Windows Registry Editor Version 5.00
-
-[HKEY_CURRENT_USER\Software\TortoiseHg]
-"DebugShellExt"="1"
|
|
|
@@ -1,240 +0,0 @@ -
-// Copyright (C) 2009 Benjamin Pollack
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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 <time.h>
-
-#include "stdafx.h"
-
-#include "Directory.h"
-#include "Winstat.h"
-
-
-Directory::Directory(
- Directory* p, const std::string& n, const std::string& basepath
-):
- parent_(p), name_(n)
-{
- if (n.empty())
- path_ = basepath;
- else if (basepath.empty())
- path_ = n;
- else
- path_ = basepath + '/' + n;
-}
-
-
-Directory::~Directory()
-{
- for (DirsT::iterator i = subdirs_.begin(); i != subdirs_.end(); ++i)
- {
- delete *i;
- }
-}
-
-
-int splitbase(const std::string& n, std::string& base, std::string& rest)
-{
- if (n.empty())
- return 0;
-
- size_t x = n.find_first_of ('/');
- if (x == std::string::npos)
- {
- base.clear();
- rest = n;
- return 1;
- }
-
- if (x == 0 || x == n.length()-1)
- return 0;
-
- base = n.substr(0, x);
- rest = n.substr(x+1);
-
- return 1;
-}
-
-
-int Directory::add(const std::string& n_in, Direntry& e)
-{
- std::string base;
- std::string rest;
-
- std::string n = n_in;
- Directory* cur = this;
-
- for (;;)
- {
-
- if (!splitbase(n, base, rest)) {
- TDEBUG_TRACE("Directory(" << path() << ")::add(" << n_in
- << "): splitbase returned 0");
- return 0;
- }
-
- if (base.empty())
- {
- e.name = n;
- cur->files_.push_back(e);
- return 1;
- }
-
- Directory* d = 0;
- for (DirsT::iterator i = cur->subdirs_.begin();
- i != cur->subdirs_.end(); ++i)
- {
- if ((*i)->name_ == base) {
- d = *i;
- break;
- }
- }
-
- if (!d)
- {
- d = new Directory(cur, base, cur->path());
- cur->subdirs_.push_back(d);
- }
-
- n = rest;
- cur = d;
- }
-}
-
-
-const Direntry* Directory::get(const std::string& n_in) const
-{
- std::string base;
- std::string rest;
-
- std::string n = n_in;
- const Directory* cur = this;
-
- for (;;)
- {
- loopstart:
-
- if (!splitbase(n, base, rest))
- {
- TDEBUG_TRACE("Directory(" << path() << ")::get("
- << n_in << "): splitbase returned 0");
- return 0;
- }
-
- if (base.empty())
- {
- for (FilesT::const_iterator i = cur->files_.begin();
- i != cur->files_.end(); ++i)
- {
- if (i->name == n)
- return &(*i);
- }
- return 0;
- }
-
- for (DirsT::const_iterator i = cur->subdirs_.begin();
- i != cur->subdirs_.end(); ++i)
- {
- if ((*i)->name_ == base)
- {
- cur = *i;
- n = rest;
- goto loopstart;
- }
- }
-
- return 0;
- }
-}
-
-
-Directory* Directory::getdir(const std::string& n_in)
-{
- std::string base;
- std::string rest;
-
- std::string n = n_in;
- const Directory* cur = this;
-
- for (;;)
- {
- loopstart:
-
- if (!splitbase(n, base, rest))
- {
- TDEBUG_TRACE("Directory(" << path() << ")::getdir("
- << n_in << "): splitbase returned 0");
- return 0;
- }
-
- const bool leaf = base.empty();
- const std::string& searchstr = (leaf ? n : base);
-
- for (DirsT::const_iterator i = cur->subdirs_.begin();
- i != cur->subdirs_.end(); ++i)
- {
- if ((*i)->name_ == searchstr)
- {
- if (leaf)
- return *i;
- cur = *i;
- n = rest;
- goto loopstart;
- }
- }
-
- return 0;
- }
-}
-
-
-void Directory::print() const
-{
- for (DirsT::const_iterator i = subdirs_.begin(); i != subdirs_.end(); ++i)
- {
- const Directory* d = *i;
- if (!d)
- {
- TDEBUG_TRACE("Directory(" << path() << ")::print: error: d is 0");
- return;
- }
- d->print();
- }
-
- std::string base = path();
-
- time_t t;
- std::string s;
- char* ctime_res = 0;
-
- for (FilesT::const_iterator i = files_.begin(); i != files_.end(); ++i)
- {
- std::string p = (!base.empty() ? base + "/" + i->name : i->name);
- t = i->mtime;
- ctime_res = ctime(&t);
- if (ctime_res) {
- s = ctime_res;
- s.resize(s.size() - 1); // strip ending '\n'
- }
- else {
- s = "unset";
- }
- printf(
- "%c %6o %10u %-24s %s\n",
- i->state, i->mode, i->size, s.c_str(), p.c_str()
- );
- }
-}
|
|
@@ -1,54 +0,0 @@ -
-// Copyright (C) 2009 Benjamin Pollack
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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/>.
-
-#ifndef DIRECTORY_H
-#define DIRECTORY_H
-
-#include "Direntry.h"
-
-#include <vector>
-#include <string>
-
-
-class Directory
-{
- typedef std::vector<Directory*> DirsT;
- typedef std::vector<Direntry> FilesT;
-
- Directory* const parent_;
- const std::string name_;
- std::string path_;
-
- DirsT subdirs_;
- FilesT files_;
-
-public:
- Directory(Directory* p, const std::string& n, const std::string& basepath);
- ~Directory();
-
- const std::string& path() const { return path_; }
-
- int add(const std::string& relpath, Direntry& e);
-
- const Direntry* get(const std::string& relpath) const;
- Directory* getdir(const std::string& n);
-
- void print() const;
-};
-
-#endif
-
|
|
|
@@ -1,167 +0,0 @@ -
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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 "DirectoryStatus.h"
-#include "Thgstatus.h"
-#include "TortoiseUtils.h"
-
-
-char DirectoryStatus::status(const std::string& relpath_) const
-{
- char res = 'C';
- bool added = false;
- bool modified = false;
-
- const std::string relpath = relpath_ + '/';
-
- for (V::const_iterator i = v_.begin(); i != v_.end(); ++i)
- {
- const E& e = *i;
- if (relpath_.empty() ||
- e.path_.compare(0, relpath.length(), relpath) == 0)
- {
- if (e.status_ == 'm' || e.status_ == 'r')
- {
- modified = true;
- break;
- }
- if (e.status_ == 'a')
- added = true;
- }
- }
-
- if (modified)
- res = 'M';
- else if (added)
- res = 'A';
- else
- res = 'C';
-
- return res;
-}
-
-
-int DirectoryStatus::read(const std::string& hgroot, const std::string& cwd)
-{
- v_.clear();
- noicons_ = false;
-
- std::string p = hgroot + "\\.hg\\thgstatus";
-
- FILE *f = fopenReadRenameAllowed(p.c_str());
- if (!f)
- {
- TDEBUG_TRACE("DirectoryStatus::read: can't open '" << p << "'");
- std::string p = (cwd.size() < hgroot.size() ? hgroot : cwd);
- Thgstatus::update(p);
- return 0;
- }
-
- DirectoryStatus::E e;
-
- int res = 1;
- const std::string noicons = "@@noicons";
-
- std::vector<char> vline(200);
-
- for (;;)
- {
- vline.clear();
- char t;
-
- for (;;)
- {
- if (fread(&t, sizeof(t), 1, f) != 1)
- goto close;
- if (t == '\n')
- break;
- vline.push_back(t);
- if (vline.size() > 1000)
- {
- res = 0;
- goto close;
- }
- }
- vline.push_back(0);
-
- std::string line = &vline[0];
-
- if (line.substr(0, noicons.size()) == noicons)
- {
- noicons_ = true;
- goto close;
- }
-
- if (line.empty())
- goto close;
-
- e.status_ = line[0];
-
- std::string path;
- if (line.size() > 1)
- {
- path = line.c_str() + 1;
- ::CharLower(const_cast<char*>(path.c_str()));
- }
- path.push_back('/');
-
- e.path_ = path;
-
- v_.push_back(e);
- }
-
-close:
- fclose(f);
-
- TDEBUG_TRACE("DirectoryStatus::read(" << hgroot << "): done. "
- << v_.size() << " entries read. noicons_ = " << noicons_ );
-
- return res;
-}
-
-
-struct CacheEntry
-{
- std::string hgroot_;
- DirectoryStatus ds_;
- bool readfailed_;
- unsigned tickcount_;
-
- CacheEntry(): readfailed_(false), tickcount_(0) {};
-};
-
-
-DirectoryStatus* DirectoryStatus::get(
- const std::string& hgroot, const std::string& cwd)
-{
- static CacheEntry ce;
-
- unsigned tc = GetTickCount();
-
- if (ce.hgroot_ != hgroot || (tc - ce.tickcount_) > 2000)
- {
- ce.hgroot_.clear();
- ce.readfailed_ = (ce.ds_.read(hgroot, cwd) == 0);
- ce.hgroot_ = hgroot;
- ce.tickcount_ = GetTickCount();
- }
-
- return (ce.readfailed_ ? 0 : &ce.ds_);
-}
-
-
|
|
@@ -1,45 +0,0 @@ -
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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 <string>
-#include <vector>
-
-
-class DirectoryStatus
-{
- struct E
- {
- std::string path_;
- char status_;
-
- E(): status_(0) {}
- };
-
- typedef std::vector<E> V;
- V v_;
- bool noicons_;
-
-public:
- DirectoryStatus(): noicons_(false) {}
-
- static DirectoryStatus* get(
- const std::string& hgroot, const std::string& cwd);
- char status(const std::string& relpath) const;
- bool noicons() const { return noicons_; }
-
-private:
- int read(const std::string& hgroot, const std::string& cwd);
-};
|
|
@@ -1,71 +0,0 @@ -
-// Copyright (C) 2009 Benjamin Pollack
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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 "Direntry.h"
-#include "Winstat.h"
-
-
-int Direntry::read(FILE* f, std::vector<char>& relpath)
-{
- if (fread(&state, sizeof(state), 1, f) != 1)
- return 0;
-
- unsigned length = 0;
-
- fread(&mode, sizeof(mode), 1, f);
- fread(&size, sizeof(size), 1, f);
- fread(&mtime, sizeof(mtime), 1, f);
- fread(&length, sizeof(length), 1, f);
-
- mode = ntohl(mode);
- size = ntohl(size);
- mtime = ntohl(mtime);
- length = ntohl(length);
-
- relpath.resize(length + 1, 0);
- fread(&relpath[0], sizeof(char), length, f);
- relpath[length] = 0;
-
- ::CharLowerBuff(&relpath[0], length);
-
- return 1;
-}
-
-
-char Direntry::status(const Winstat& stat) const
-{
- switch (this->state)
- {
- case 'n':
- if (this->size != (unsigned)stat.size)
- return 'M'; // modified
- if (this->mtime == (unsigned)stat.mtime)
- return 'C'; // clean
- return 'P'; // must peek into file contents
- case 'm':
- return 'M';
- case 'r':
- return 'R';
- case 'a':
- return 'A';
- default:
- return '?';
- }
-}
-
|
|
@@ -1,58 +0,0 @@ -
-// Copyright (C) 2009 Benjamin Pollack
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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/>.
-
-#ifndef DIRENTRY_H
-#define DIRENTRY_H
-
-#include <vector>
-
-// Visual Studio has UINT32 instead of uint32_t
-#ifndef uint32_t
-#define uint32_t UINT32
-#endif
-
-class Winstat;
-
-class Direntry
-{
-public:
- unsigned char state;
- unsigned mode;
- unsigned size;
- unsigned mtime;
-
- std::string name;
-
- int read(FILE* f, std::vector<char>& relpath);
- char status(const Winstat& stat) const;
-
- bool unset() const {
- return (state == 'n') && (mode == 0) && (size == -1) && (mtime == -1);
- }
-
-private:
- static uint32_t ntohl(uint32_t x)
- {
- return ((x & 0x000000ffUL) << 24) |
- ((x & 0x0000ff00UL) << 8) |
- ((x & 0x00ff0000UL) >> 8) |
- ((x & 0xff000000UL) >> 24);
- }
-};
-
-#endif
-
|
|
|
@@ -1,180 +0,0 @@ -
-// Copyright (C) 2009 Benjamin Pollack
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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 "Dirstatecache.h"
-#include "dirstate.h"
-#include "Winstat64.h"
-#include "Thgstatus.h"
-
-
-std::list<Dirstatecache::E>& Dirstatecache::cache()
-{
- static std::list<Dirstatecache::E> c;
- return c;
-}
-
-
-Dirstate* Dirstatecache::get(
- const std::string& hgroot, const std::string& cwd, bool& unset)
-{
- unset = false;
-
- typedef std::list<E>::iterator Iter;
-
- Iter iter = cache().begin();
- for (;iter != cache().end(); ++iter)
- {
- if (hgroot == iter->hgroot)
- break;
- }
-
- Winstat64 stat;
- std::string path = hgroot + "\\.hg\\dirstate";
-
- unsigned tc = GetTickCount();
- bool new_stat = false;
-
- if (iter == cache().end())
- {
- if (stat.lstat(path.c_str()) != 0)
- {
- TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") failed");
- return 0;
- }
- TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") ok ");
- new_stat = true;
-
- if (cache().size() >= 10)
- {
- TDEBUG_TRACE("Dirstatecache::get: dropping "
- << cache().back().hgroot);
- delete cache().back().dstate;
- cache().back().dstate = 0;
- cache().pop_back();
- }
-
- E e;
- e.hgroot = hgroot;
- cache().push_front(e);
- iter = cache().begin();
- iter->tickcount = tc;
- }
-
- if (!new_stat && tc - iter->tickcount > 500)
- {
- if (0 != stat.lstat(path.c_str()))
- {
- TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") failed");
- TDEBUG_TRACE("Dirstatecache::get: dropping " << iter->hgroot);
- delete iter->dstate;
- iter->dstate = 0;
- cache().erase(iter);
- return 0;
- }
- iter->tickcount = tc;
- TDEBUG_TRACE("Dirstatecache::get: lstat(" << path <<") ok ");
- new_stat = true;
- }
-
- if (iter->dstate)
- {
- unset = iter->unset;
-
- if (!new_stat)
- return iter->dstate;
-
- if (iter->dstate_mtime == stat.mtime
- && iter->dstate_size == stat.size)
- {
- return iter->dstate;
- }
-
- TDEBUG_TRACE("Dirstatecache::get: refreshing " << hgroot);
- }
- else
- {
- TDEBUG_TRACE("Dirstatecache::get: reading " << hgroot);
- }
-
- unset = false;
- unsigned tc0 = GetTickCount();
- std::auto_ptr<Dirstate> ds = Dirstate::read(path, unset);
- unsigned tc1 = GetTickCount();
-
- bool request_thgstatus_update = true;
-
- if (unset)
- {
- if (iter->unset)
- {
- TDEBUG_TRACE(
- "Dirstatecache::get: **** old and new have unset entries");
- request_thgstatus_update = false;
- }
- else
- {
- TDEBUG_TRACE("Dirstatecache::get: new has unset entries");
- }
- }
-
- iter->unset = unset;
-
- delete iter->dstate;
- iter->dstate = ds.release();
-
- unsigned delta = tc1 - tc0;
- TDEBUG_TRACE("Dirstatecache::get: read done in " << delta << " ticks, "
- << cache().size() << " repos in cache");
-
- iter->dstate_mtime = stat.mtime;
- iter->dstate_size = stat.size;
-
- if (request_thgstatus_update)
- {
- TDEBUG_TRACE("Dirstatecache::get: calling Thgstatus::update");
- Thgstatus::update(cwd);
- }
- else
- {
- TDEBUG_TRACE("Dirstatecache::get: omitting Thgstatus::update");
- }
-
- return iter->dstate;
-}
-
-
-void Dirstatecache::invalidate(const std::string& hgroot)
-{
- typedef std::list<E>::iterator Iter;
-
- if (hgroot.empty())
- return;
-
- for (Iter i = cache().begin(); i != cache().end(); ++i)
- {
- if (hgroot == i->hgroot)
- {
- delete i->dstate;
- i->dstate = 0;
- cache().erase(i);
- TDEBUG_TRACE("Dirstatecache::invalidate(" << hgroot << ")");
- break;
- }
- }
-}
|
|
@@ -1,55 +0,0 @@ -
-// Copyright (C) 2009 Benjamin Pollack
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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/>.
-
-#ifndef _DIRSTATECACHE_H
-#define _DIRSTATECACHE_H
-
-#include <string>
-#include <list>
-
-class Dirstate;
-
-class Dirstatecache
-{
- struct E
- {
- Dirstate* dstate;
- __int64 dstate_mtime;
- __int64 dstate_size;
-
- std::string hgroot;
- unsigned tickcount;
- bool unset;
-
- E():
- dstate(0),
- dstate_mtime(0),
- dstate_size(0),
- tickcount(0),
- unset(false)
- {}
- };
-
- static std::list<E>& cache();
-
-public:
- static Dirstate* get(
- const std::string& hgroot, const std::string& cwd, bool& unset);
- static void invalidate(const std::string& hgroot);
-};
-
-#endif
|
|
|
@@ -1,283 +0,0 @@ - // TortoiseSVN - a Windows shell extension for easy version control
-
-// Copyright (C) 2009 - TortoiseSVN
-
-// 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, write to the Free Software Foundation,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-// Adapted for use in TortoiseHg by Veniamin Albaev
-//
-#include "stdafx.h"
-#include "IconBitmapUtils.h"
-#include "SysInfo.h"
-
-IconBitmapUtils::IconBitmapUtils()
- : hUxTheme(NULL)
-{
- if (SysInfo::Instance().IsVistaOrLater())
- {
- hUxTheme = LoadLibrary(_T("UXTHEME.DLL"));
-
- if (hUxTheme)
- {
- pfnGetBufferedPaintBits = (FN_GetBufferedPaintBits)::GetProcAddress(hUxTheme, "GetBufferedPaintBits");
- pfnBeginBufferedPaint = (FN_BeginBufferedPaint)::GetProcAddress(hUxTheme, "BeginBufferedPaint");
- pfnEndBufferedPaint = (FN_EndBufferedPaint)::GetProcAddress(hUxTheme, "EndBufferedPaint");
- }
- }
-}
-
-IconBitmapUtils::~IconBitmapUtils()
-{
- if (hUxTheme)
- FreeLibrary(hUxTheme);
-}
-
-HBITMAP IconBitmapUtils::IconToBitmap(HICON hIcon)
-{
- if (!hIcon)
- return NULL;
-
- RECT rect;
-
- rect.right = ::GetSystemMetrics(SM_CXMENUCHECK);
- rect.bottom = ::GetSystemMetrics(SM_CYMENUCHECK);
-
- rect.left = rect.top = 0;
-
- HWND desktop = ::GetDesktopWindow();
- if (desktop == NULL)
- return NULL;
-
- HDC screen_dev = ::GetDC(desktop);
- if (screen_dev == NULL)
- return NULL;
-
- // Create a compatible DC
- HDC dst_hdc = ::CreateCompatibleDC(screen_dev);
- if (dst_hdc == NULL)
- {
- ::ReleaseDC(desktop, screen_dev);
- return NULL;
- }
-
- // Create a new bitmap of icon size
- HBITMAP bmp = ::CreateCompatibleBitmap(screen_dev, rect.right, rect.bottom);
- if (bmp == NULL)
- {
- ::DeleteDC(dst_hdc);
- ::ReleaseDC(desktop, screen_dev);
- return NULL;
- }
-
- // Select it into the compatible DC
- HBITMAP old_dst_bmp = (HBITMAP)::SelectObject(dst_hdc, bmp);
- if (old_dst_bmp == NULL)
- return NULL;
-
- // Fill the background of the compatible DC with the white color
- // that is taken by menu routines as transparent
- ::SetBkColor(dst_hdc, RGB(255, 255, 255));
- ::ExtTextOut(dst_hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
-
- // Draw the icon into the compatible DC
- ::DrawIconEx(dst_hdc, 0, 0, hIcon, rect.right, rect.bottom, 0, NULL, DI_NORMAL);
-
- // Restore settings
- ::SelectObject(dst_hdc, old_dst_bmp);
- ::DeleteDC(dst_hdc);
- ::ReleaseDC(desktop, screen_dev);
-
- return bmp;
-}
-
-HBITMAP IconBitmapUtils::IconToBitmapPARGB32(HICON hIcon)
-{
- if (!hIcon)
- return NULL;
-
- if (pfnBeginBufferedPaint == NULL || pfnEndBufferedPaint == NULL || pfnGetBufferedPaintBits == NULL)
- {
- TDEBUG_TRACE(" IconBitmapUtils::IconToBitmapPARGB32: Theme functions not found, returns NULL");
- return NULL;
- }
-
- SIZE sizIcon;
- sizIcon.cx = GetSystemMetrics(SM_CXSMICON);
- sizIcon.cy = GetSystemMetrics(SM_CYSMICON);
-
- RECT rcIcon;
- SetRect(&rcIcon, 0, 0, sizIcon.cx, sizIcon.cy);
- HBITMAP hBmp = NULL;
-
- HDC hdcDest = CreateCompatibleDC(NULL);
- if (hdcDest)
- {
- if (SUCCEEDED(Create32BitHBITMAP(hdcDest, &sizIcon, NULL, &hBmp)))
- {
- HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDest, hBmp);
- if (hbmpOld)
- {
- BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
- BP_PAINTPARAMS paintParams = {0};
- paintParams.cbSize = sizeof(paintParams);
- paintParams.dwFlags = BPPF_ERASE;
- paintParams.pBlendFunction = &bfAlpha;
-
- HDC hdcBuffer;
- HPAINTBUFFER hPaintBuffer = pfnBeginBufferedPaint(hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer);
- if (hPaintBuffer)
- {
- if (DrawIconEx(hdcBuffer, 0, 0, hIcon, sizIcon.cx, sizIcon.cy, 0, NULL, DI_NORMAL))
- //if (FillRect(hdcBuffer, &rcIcon, (HBRUSH) (0x000000FF)) != 0)
- {
- // If icon did not have an alpha channel we need to convert buffer to PARGB
- ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sizIcon);
- }
- // This will write the buffer contents to the destination bitmap
- pfnEndBufferedPaint(hPaintBuffer, TRUE);
- }
-
- SelectObject(hdcDest, hbmpOld);
- }
- }
-
- DeleteDC(hdcDest);
- }
-
- return hBmp;
-}
-
-HRESULT IconBitmapUtils::Create32BitHBITMAP(HDC hdc, const SIZE *psize, __deref_opt_out void **ppvBits, __out HBITMAP* phBmp)
-{
- *phBmp = NULL;
-
- BITMAPINFO bmi;
- SecureZeroMemory(&bmi, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biCompression = BI_RGB;
-
- bmi.bmiHeader.biWidth = psize->cx;
- bmi.bmiHeader.biHeight = psize->cy;
- bmi.bmiHeader.biBitCount = 32;
-
- HDC hdcUsed = hdc ? hdc : GetDC(NULL);
- if (hdcUsed)
- {
- *phBmp = CreateDIBSection(hdcUsed, &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0);
- if (hdc != hdcUsed)
- {
- ReleaseDC(NULL, hdcUsed);
- }
- }
- return (NULL == *phBmp) ? E_OUTOFMEMORY : S_OK;
-}
-
-HRESULT IconBitmapUtils::ConvertBufferToPARGB32(HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hicon, SIZE& sizIcon)
-{
- RGBQUAD *prgbQuad;
- int cxRow;
- HRESULT hr = pfnGetBufferedPaintBits(hPaintBuffer, &prgbQuad, &cxRow);
- if (SUCCEEDED(hr))
- {
- Gdiplus::ARGB *pargb = reinterpret_cast<Gdiplus::ARGB *>(prgbQuad);
- if (!HasAlpha(pargb, sizIcon, cxRow))
- {
- ICONINFO info;
- if (GetIconInfo(hicon, &info))
- {
- if (info.hbmMask)
- {
- hr = ConvertToPARGB32(hdc, pargb, info.hbmMask, sizIcon, cxRow);
- }
-
- DeleteObject(info.hbmColor);
- DeleteObject(info.hbmMask);
- }
- }
- }
-
- return hr;
-}
-
-bool IconBitmapUtils::HasAlpha(__in Gdiplus::ARGB *pargb, SIZE& sizImage, int cxRow)
-{
- ULONG cxDelta = cxRow - sizImage.cx;
- for (ULONG y = sizImage.cy; y; --y)
- {
- for (ULONG x = sizImage.cx; x; --x)
- {
- if (*pargb++ & 0xFF000000)
- {
- return true;
- }
- }
-
- pargb += cxDelta;
- }
-
- return false;
-}
-
-HRESULT IconBitmapUtils::ConvertToPARGB32(HDC hdc, __inout Gdiplus::ARGB *pargb, HBITMAP hbmp, SIZE& sizImage, int cxRow)
-{
- BITMAPINFO bmi;
- SecureZeroMemory(&bmi, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biCompression = BI_RGB;
-
- bmi.bmiHeader.biWidth = sizImage.cx;
- bmi.bmiHeader.biHeight = sizImage.cy;
- bmi.bmiHeader.biBitCount = 32;
-
- HRESULT hr = E_OUTOFMEMORY;
- HANDLE hHeap = GetProcessHeap();
- void *pvBits = HeapAlloc(hHeap, 0, bmi.bmiHeader.biWidth * 4 * bmi.bmiHeader.biHeight);
- if (pvBits)
- {
- hr = E_UNEXPECTED;
- if (GetDIBits(hdc, hbmp, 0, bmi.bmiHeader.biHeight, pvBits, &bmi, DIB_RGB_COLORS) == bmi.bmiHeader.biHeight)
- {
- ULONG cxDelta = cxRow - bmi.bmiHeader.biWidth;
- Gdiplus::ARGB *pargbMask = static_cast<Gdiplus::ARGB *>(pvBits);
-
- for (ULONG y = bmi.bmiHeader.biHeight; y; --y)
- {
- for (ULONG x = bmi.bmiHeader.biWidth; x; --x)
- {
- if (*pargbMask++)
- {
- // transparent pixel
- *pargb++ = 0;
- }
- else
- {
- // opaque pixel
- *pargb++ |= 0xFF000000;
- }
- }
-
- pargb += cxDelta;
- }
-
- hr = S_OK;
- }
-
- HeapFree(hHeap, 0, pvBits);
- }
-
- return hr;
-}
|
|
@@ -1,56 +0,0 @@ - // TortoiseSVN - a Windows shell extension for easy version control
-
-// Copyright (C) 2009 - TortoiseSVN
-
-// 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, write to the Free Software Foundation,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-
-// Adapted for use in TortoiseHg by Veniamin Albaev
-//
-#pragma once
-#include <Uxtheme.h>
-#include <GdiPlus.h>
-#include <map>
-
-typedef HRESULT (WINAPI *FN_GetBufferedPaintBits) (HPAINTBUFFER hBufferedPaint, RGBQUAD **ppbBuffer, int *pcxRow);
-typedef HPAINTBUFFER (WINAPI *FN_BeginBufferedPaint) (HDC hdcTarget, const RECT *prcTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS *pPaintParams, HDC *phdc);
-typedef HRESULT (WINAPI *FN_EndBufferedPaint) (HPAINTBUFFER hBufferedPaint, BOOL fUpdateTarget);
-
-
-/**
- * \ingroup utils
- * provides helper functions for converting icons to bitmaps
- */
-class IconBitmapUtils
-{
-public:
- IconBitmapUtils(void);
- ~IconBitmapUtils(void);
-
- HBITMAP IconToBitmap(HICON hIcon);
- HBITMAP IconToBitmapPARGB32(HICON hIcon);
- HRESULT Create32BitHBITMAP(HDC hdc, const SIZE *psize, __deref_opt_out void **ppvBits, __out HBITMAP* phBmp);
- HRESULT ConvertBufferToPARGB32(HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hicon, SIZE& sizIcon);
- bool HasAlpha(__in Gdiplus::ARGB *pargb, SIZE& sizImage, int cxRow);
- HRESULT ConvertToPARGB32(HDC hdc, __inout Gdiplus::ARGB *pargb, HBITMAP hbmp, SIZE& sizImage, int cxRow);
-
-
-private:
- HMODULE hUxTheme;
-
- FN_GetBufferedPaintBits pfnGetBufferedPaintBits;
- FN_BeginBufferedPaint pfnBeginBufferedPaint;
- FN_EndBufferedPaint pfnEndBufferedPaint;
-};
|
|
@@ -1,60 +0,0 @@ -
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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 "InitStatus.h"
-#include "Thgstatus.h"
-
-
-InitStatus& InitStatus::inst()
-{
- static InitStatus s;
- return s;
-}
-
-
-void InitStatus::add(std::string& s, const char* missing)
-{
- if (!s.empty())
- s += ", ";
- s += missing;
-}
-
-
-std::string InitStatus::check()
-{
- const InitStatus& self = inst();
- std::string missing;
-
- if (self.unchanged_ == 0)
- add(missing, "unchanged");
- if (self.added_ == 0)
- add(missing, "added");
- if (self.modified_ == 0)
- add(missing, "modified");
- if (self.notinrepo_ == 0)
- add(missing, "notinrepo");
-
- if (missing.empty())
- return "";
-
- std::string reason = "uninitialized handlers: " + missing;
- Thgstatus::error(reason);
- std::string res = "InitStatus: error: " + reason;
- TDEBUG_TRACE("***** " << res);
- return res;
-}
|
|
@@ -1,35 +0,0 @@ -
-// Copyright (C) 2009 Adrian Buehlmann
-//
-// 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 <string>
-
-class InitStatus
-{
-public:
- int unchanged_;
- int added_;
- int modified_;
- int notinrepo_;
-
- static InitStatus& inst();
- static std::string check();
-
-private:
- InitStatus()
- : unchanged_(0), added_(0), modified_(0), notinrepo_(0) {}
-
- static void add(std::string& s, const char* missing);
-};
|
|
@@ -1,68 +0,0 @@ -
-OBJECTS_DIRSTATE = TortoiseUtils.obj \
- Direntry.obj \
- Directory.obj \
- Winstat.obj \
- RegistryConfig.obj \
- ThgDebug.obj
-
-OBJECTS_THGSGELL = $(OBJECTS_DIRSTATE) \
- InitStatus.obj \
- CShellExtCMenu.obj \
- CShellExtDnd.obj \
- CShellExtOverlay.obj \
- TortoiseIconBitmap.obj \
- IconBitmapUtils.obj \
- ShellExt.obj \
- StringUtils.obj \
- SysInfo.obj \
- dirstate.obj \
- Winstat64.obj \
- Dirstatecache.obj \
- DirectoryStatus.obj \
- Thgstatus.obj \
- QueryDirstate.obj \
- ThgVersion.obj \
- SimpleUnknown.obj
-
-OBJECTS_TERMINATE = Thgstatus.obj \
- RegistryConfig.obj \
- ThgDebug.obj
-
-LIBS = shlwapi.lib gdiplus.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Msi.lib
-DEFFILE = ShellExt.def
-
-
-# /MT = statically linked runtime libraries /MD = dynamically linked
-# THG_EXTRA_CPPFLAGS is taken from environment (may be undefined)
-CPPFLAGS = /nologo /Ox /W2 /EHsc /MT /DAPPMAIN /DTHG_DEBUG $(THG_EXTRA_CPPFLAGS)
-BASE_LDFLAGS = /nologo /INCREMENTAL:NO /MANIFEST $(LIBS)
-LDFLAGS_THGSHELL = $(BASE_LDFLAGS) /DLL /DEF:$(DEFFILE)
-LDFLAGS_DIRSTATE = $(BASE_LDFLAGS) /SUBSYSTEM:CONSOLE
-LDFLAGS_TERMINATE = $(BASE_LDFLAGS) /DLL /DEF:terminate.def
-
-
-THGSHELL_TARGET = THgShell$(THG_PLATFORM).dll
-TERMINATE_TARGET = terminate-$(THG_PLATFORM).dll
-
-all: $(THGSHELL_TARGET) $(TERMINATE_TARGET)
-
-clean:
- del *.obj *.dll *.exe *.lib *.exp *.manifest *.res parentid.h ThgCLSIDs.wxi
-
-ThgVersion:
- create-parentid-h.cmd
-
-$(THGSHELL_TARGET): ThgVersion $(OBJECTS_THGSGELL)
- cl /EP ThgCLSIDs-template.wxi > ThgCLSIDs.wxi
- rc /dTHG_SHELL_FNAME="$@" $(THG_EXTRA_RCFLAGS) shellext.rc
- link /OUT:$@ $(LDFLAGS_THGSHELL) $(OBJECTS_THGSGELL) shellext.res
- mt -nologo -manifest $@.manifest -outputresource:"$@;#2"
-
-dirstate.exe: dirstate.obj $(OBJECTS_DIRSTATE)
- link /OUT:$@ $(LDFLAGS_DIRSTATE) $**
- mt -nologo -manifest $@.manifest -outputresource:"$@;#1"
-
-$(TERMINATE_TARGET): terminate.obj $(OBJECTS_TERMINATE)
- link /OUT:$@ $(LDFLAGS_TERMINATE) $**
- mt -nologo -manifest $@.manifest -outputresource:"$@;#1"
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -1,13 +0,0 @@ - #ifndef _QUERY_DIRSTATE_H
-#define _QUERY_DIRSTATE_H
-
-#include <string>
-
-int HgQueryDirstate(
- const char myClass,
- const std::string& path,
- const char& filterStatus,
- char& outStatus
-);
-
-#endif
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -1,30 +0,0 @@ - #include "stdafx.h"
-#include "RegistryConfig.h"
-
-int GetRegistryConfig(const std::string& name, std::string& res)
-{
- const char* const subkey = "Software\\TortoiseHg";
-
- HKEY hkey = 0;
- LONG rv = RegOpenKeyExA(
- HKEY_CURRENT_USER, subkey, 0, KEY_READ, &hkey);
-
- if (rv != ERROR_SUCCESS || hkey == 0)
- return 0;
-
- BYTE Data[MAX_PATH] = "";
- DWORD cbData = MAX_PATH * sizeof(BYTE);
-
- rv = RegQueryValueExA(
- hkey, name.c_str(), 0, 0, Data, &cbData);
-
- int ret = 0;
- if (rv == ERROR_SUCCESS)
- {
- res = reinterpret_cast<const char*>(&Data);
- ret = 1;
- }
-
- RegCloseKey(hkey);
- return ret;
-}
|
|
@@ -1,8 +0,0 @@ - #ifndef REGISTRY_CONFIG_H_
-#define REGISTRY_CONFIG_H_
-
-#include <string>
-
-int GetRegistryConfig(const std::string& name, std::string& res);
-
-#endif
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -1,5 +0,0 @@ - ; shellext: Declares the module parameters for the DLL.
-
-EXPORTS
- DllCanUnloadNow PRIVATE
- DllGetClassObject PRIVATE
|
|
@@ -1,38 +0,0 @@ - #ifndef _SHELL_EXT_H_
-#define _SHELL_EXT_H_
-
-
-class CShellExt
-{
- static CRITICAL_SECTION cs_;
- static HMODULE hModule_;
- static UINT cRef_;
-
-public:
- static LPCRITICAL_SECTION GetCriticalSection() { return &cs_; }
- static UINT GetRefCount() { return cRef_; }
- static void IncDllRef() { ::InterlockedIncrement(&cRef_); }
- static void DecDllRef() { ::InterlockedDecrement(&cRef_); }
-
- friend BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
-};
-
-
-class ThgCriticalSection
-{
- LPCRITICAL_SECTION cs_;
-
-public:
- ThgCriticalSection(LPCRITICAL_SECTION cs): cs_(cs)
- {
- ::EnterCriticalSection(cs_);
- }
-
- ~ThgCriticalSection()
- {
- ::LeaveCriticalSection(cs_);
- }
-};
-
-
-#endif // _SHELL_EXT_H_
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -1,69 +0,0 @@ - // Copyright (C) 2002 - Torsten Martinsen
-// <torsten@tiscali.dk> - September 2002
-
-// 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, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-#include "StringUtils.h"
-
-#include <vector>
-
-
-// Quotes a string
-std::string Quote(const std::string& str)
-{
- std::string sResult = "\"" + str + "\"";
- return sResult;
-}
-
-
-// Convert Unicode string to multibyte string
-std::string WideToMultibyte(const std::wstring& wide, UINT CodePage)
-{
- // Determine length of string
- int ret = WideCharToMultiByte(
- CodePage, 0, wide.c_str(), static_cast<int>(wide.length()),
- NULL, 0, NULL, NULL
- );
-
- std::vector<CHAR> narrow(ret + 1);
-
- ret = WideCharToMultiByte(
- CodePage, 0, wide.c_str(), static_cast<int>(wide.length()),
- &narrow[0], ret, NULL, NULL
- );
- narrow[ret] = '\0';
-
- return &narrow[0];
-}
-
-
-// Convert multibyte string to Unicode string
-std::wstring MultibyteToWide(const std::string& multibyte, UINT CodePage)
-{
- int ret = MultiByteToWideChar(
- CodePage, 0, multibyte.c_str(),
- static_cast<int>(multibyte.length()), 0, 0
- );
-
- std::vector<wchar_t> wide(ret + 1);
-
- ret = MultiByteToWideChar(
- CodePage, 0, multibyte.c_str(),
- static_cast<int>(multibyte.length()), &wide[0], ret
- );
- wide[ret] = L'\0';
-
- return &wide[0];
-}
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
Loading...