Ejemplo n.º 1
0
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);

    SetDllDirectory(L"");
    SetTaskIDPerUUID();
    CRegStdDWORD loc = CRegStdDWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);
    long langId = loc;

    CLangDll langDLL;
    hResource = langDLL.Init(_T("TortoiseIDiff"), langId);
    if (hResource == NULL)
        hResource = hInstance;

    CCmdLineParser parser(lpCmdLine);

    if (parser.HasKey(_T("?")) || parser.HasKey(_T("help")))
    {
        TCHAR buf[1024];
        LoadString(hResource, IDS_COMMANDLINEHELP, buf, _countof(buf));
        MessageBox(NULL, buf, _T("TortoiseIDiff"), MB_ICONINFORMATION);
        langDLL.Close();
        return 0;
    }


    MSG msg;
    HACCEL hAccelTable;

    hInst = hInstance;

    INITCOMMONCONTROLSEX used = {
        sizeof(INITCOMMONCONTROLSEX),
        ICC_STANDARD_CLASSES | ICC_BAR_CLASSES | ICC_WIN95_CLASSES
    };
    InitCommonControlsEx(&used);

    // load the cursors we need
    curHand = (HCURSOR)LoadImage(hInst, MAKEINTRESOURCE(IDC_PANCUR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);
    curHandDown = (HCURSOR)LoadImage(hInst, MAKEINTRESOURCE(IDC_PANDOWNCUR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);

    CMainWindow mainWindow(hResource);
    mainWindow.SetRegistryPath(_T("Software\\TortoiseGit\\TortoiseIDiffWindowPos"));
    std::wstring leftfile = parser.HasVal(_T("left")) ? parser.GetVal(_T("left")) : _T("");
    if ((leftfile.size() == 0)&&(lpCmdLine[0] != 0))
    {
        leftfile = lpCmdLine;
    }
    mainWindow.SetLeft(leftfile.c_str(), parser.HasVal(_T("lefttitle")) ? parser.GetVal(_T("lefttitle")) : _T(""));
    mainWindow.SetRight(parser.HasVal(_T("right")) ? parser.GetVal(_T("right")) : _T(""), parser.HasVal(_T("righttitle")) ? parser.GetVal(_T("righttitle")) : _T(""));
    if (mainWindow.RegisterAndCreateWindow())
    {
        hAccelTable = LoadAccelerators(hResource, MAKEINTRESOURCE(IDR_TORTOISEIDIFF));
        if (!parser.HasVal(_T("left")))
        {
            PostMessage(mainWindow, WM_COMMAND, ID_FILE_OPEN, 0);
        }
        if (parser.HasKey(_T("overlay")))
        {
            PostMessage(mainWindow, WM_COMMAND, ID_VIEW_OVERLAPIMAGES, 0);
        }
        if (parser.HasKey(_T("fit")))
        {
            PostMessage(mainWindow, WM_COMMAND, ID_VIEW_FITTOGETHER, 0);
        }
        if (parser.HasKey(_T("showinfo")))
        {
            PostMessage(mainWindow, WM_COMMAND, ID_VIEW_IMAGEINFO, 0);
        }
        // Main message loop:
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (!TranslateAccelerator(mainWindow, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        return (int) msg.wParam;
    }
    langDLL.Close();
    DestroyCursor(curHand);
    DestroyCursor(curHandDown);
    return 1;
}
Ejemplo n.º 2
0
void CMainWindow::SetupColors(bool recolorize)
{
	SendEditor(SCI_STYLESETFORE, STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOWTEXT));
	SendEditor(SCI_STYLESETBACK, STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOW));
	SendEditor(SCI_SETSELFORE, TRUE, ::GetSysColor(COLOR_HIGHLIGHTTEXT));
	SendEditor(SCI_SETSELBACK, TRUE, ::GetSysColor(COLOR_HIGHLIGHT));
	SendEditor(SCI_SETCARETFORE, ::GetSysColor(COLOR_WINDOWTEXT));

	SendEditor(SCI_SETWHITESPACEFORE, true, ::GetSysColor(COLOR_3DSHADOW));

	SendEditor(SCI_CLEARDOCUMENTSTYLE, 0, 0);

	HIGHCONTRAST highContrast = { 0 };
	highContrast.cbSize = sizeof(HIGHCONTRAST);
	if (SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &highContrast, 0) == TRUE && (highContrast.dwFlags & HCF_HIGHCONTRASTON))
	{
		SendEditor(SCI_SETLEXER, SCLEX_NULL);
		return;
	}

	//SetAStyle(SCE_DIFF_DEFAULT, RGB(0, 0, 0));
	SetAStyle(SCE_DIFF_COMMAND,
				CRegStdDWORD(L"Software\\TortoiseGit\\UDiffForeCommandColor", UDIFF_COLORFORECOMMAND),
				CRegStdDWORD(L"Software\\TortoiseGit\\UDiffBackCommandColor", UDIFF_COLORBACKCOMMAND));
	SetAStyle(SCE_DIFF_POSITION,
				CRegStdDWORD(L"Software\\TortoiseGit\\UDiffForePositionColor", UDIFF_COLORFOREPOSITION),
				CRegStdDWORD(L"Software\\TortoiseGit\\UDiffBackPositionColor", UDIFF_COLORBACKPOSITION));
	SetAStyle(SCE_DIFF_HEADER,
				CRegStdDWORD(L"Software\\TortoiseGit\\UDiffForeHeaderColor", UDIFF_COLORFOREHEADER),
				CRegStdDWORD(L"Software\\TortoiseGit\\UDiffBackHeaderColor", UDIFF_COLORBACKHEADER));
	SetAStyle(SCE_DIFF_COMMENT,
				CRegStdDWORD(L"Software\\TortoiseGit\\UDiffForeCommentColor", UDIFF_COLORFORECOMMENT),
				CRegStdDWORD(L"Software\\TortoiseGit\\UDiffBackCommentColor", UDIFF_COLORBACKCOMMENT));
	SendEditor(SCI_STYLESETBOLD, SCE_DIFF_COMMENT, TRUE);

	for (int style : { SCE_DIFF_ADDED, SCE_DIFF_PATCH_ADD, SCE_DIFF_PATCH_DELETE })
	{
		SetAStyle(style,
			CRegStdDWORD(L"Software\\TortoiseGit\\UDiffForeAddedColor", UDIFF_COLORFOREADDED),
			CRegStdDWORD(L"Software\\TortoiseGit\\UDiffBackAddedColor", UDIFF_COLORBACKADDED));
	}
	for (int style : { SCE_DIFF_DELETED, SCE_DIFF_REMOVED_PATCH_ADD, SCE_DIFF_REMOVED_PATCH_DELETE })
	{
		SetAStyle(style,
			CRegStdDWORD(L"Software\\TortoiseGit\\UDiffForeRemovedColor", UDIFF_COLORFOREREMOVED),
			CRegStdDWORD(L"Software\\TortoiseGit\\UDiffBackRemovedColor", UDIFF_COLORBACKREMOVED));
	}

	SendEditor(SCI_SETLEXER, SCLEX_DIFF);
	SendEditor(SCI_SETKEYWORDS, 0, reinterpret_cast<LPARAM>("revision"));

	if (recolorize)
		SendEditor(SCI_COLOURISE, 0, -1);
}
Ejemplo n.º 3
0
STDMETHODIMP CShellExt::GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, VARIANT *pvarData)
{
	PreserveChdir preserveChdir;
	if (!g_ShellCache.IsPathAllowed((TCHAR *)pscd->wszFile))
	{
		return S_FALSE;
	}
	LoadLangDll();
	ShellCache::CacheType cachetype = g_ShellCache.GetCacheType();
	if (pscid->fmtid == CLSID_Tortoisegit_UPTODATE)
	{
		stdstring szInfo;
		const TCHAR * path = (TCHAR *)pscd->wszFile;

		// reserve for the path + trailing \0

		TCHAR buf[MAX_STATUS_STRING_LENGTH+1];
		SecureZeroMemory(buf, MAX_STATUS_STRING_LENGTH);
		switch (pscid->pid)
		{
			case 0:	// Git Status
				GetColumnStatus(path, pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
				GitStatus::GetStatusString(g_hResInst, filestatus, buf, _countof(buf), (WORD)CRegStdDWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)));
				szInfo = buf;
				break;
			case 1:	// Git Revision
#if 0
				GetColumnStatus(path, pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
				if (columnrev >= 0)
				{
					V_VT(pvarData) = VT_I4;
					V_I4(pvarData) = columnrev;
				}
#endif
				return S_OK;
				break;
			case 2:	// Git Url
				GetColumnStatus(path, pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
				szInfo = itemurl;
				break;
			case 3:	// Git Short Url
				GetColumnStatus(path, pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
				szInfo = itemshorturl;
				break;
			case 5:	// Git eol-style
#if 0
				if (cachetype == ShellCache::none)
					return S_FALSE;
				if (g_ShellCache.IsPathAllowed(path))
				{
					SVNProperties props = SVNProperties(CTSVNPath(path), false);
					for (int i=0; i<props.GetCount(); i++)
					{
						if (props.GetItemName(i).compare(_T("svn:eol-style"))==0)
						{
							szInfo = MultibyteToWide((char *)props.GetItemValue(i).c_str());
						}
					}
				}
#endif
				break;
			default:
				return S_FALSE;
		}
		const WCHAR * wsInfo = szInfo.c_str();
		V_VT(pvarData) = VT_BSTR;
		V_BSTR(pvarData) = SysAllocString(wsInfo);
		return S_OK;
	}
	if (pscid->fmtid == FMTID_SummaryInformation)
	{
		stdstring szInfo;
		const TCHAR * path = pscd->wszFile;

		if (cachetype == ShellCache::none)
			return S_FALSE;
		switch (pscid->pid)
		{
		case PIDSI_AUTHOR:			// Author and Git Author
			GetColumnStatus(path, pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
			szInfo = columnauthor;
			break;
		default:
			return S_FALSE;
		}
		wide_string wsInfo = szInfo;
		V_VT(pvarData) = VT_BSTR;
		V_BSTR(pvarData) = SysAllocString(wsInfo.c_str());
		return S_OK;
	}

	return S_FALSE;
}
Ejemplo n.º 4
0
STDMETHODIMP CDeskBand::QueryContextMenu(HMENU hMenu,
                                         UINT indexMenu,
                                         UINT idCmdFirst,
                                         UINT /*idCmdLast*/,
                                         UINT uFlags)
{
    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;

    if ((m_ContextDirectory.empty()) && (m_ContextItems.empty()))
        return S_OK;


    if (m_ContextDirectory.empty())
    {
        // folder is empty, but maybe files are selected
        if (m_ContextItems.empty())
            return S_OK;    // nothing selected - we don't have a menu to show
        // check whether a selected entry is an UID - those are namespace extensions
        // which we can't handle
        for (std::map<tstring, ULONG>::const_iterator it = m_ContextItems.begin(); it != m_ContextItems.end(); ++it)
        {
            if (_tcsncmp(it->first.c_str(), _T("::{"), 3)==0)
                return S_OK;
        }
    }
    else
    {
        // ignore namespace extensions
        if (_tcsncmp(m_ContextDirectory.c_str(), _T("::{"), 3)==0)
            return S_OK;
    }

    if (DWORD(CRegStdDWORD(_T("Software\\StefansTools\\StExBar\\ContextMenu"), TRUE)) == FALSE)
        return S_OK;

    //check if we already added our menu entry for a folder.
    //we check that by iterating through all menu entries and check if
    //the dwItemData member points to our global ID string. That string is set
    //by our shell extension when the folder menu is inserted.
    TCHAR menubuf[MAX_PATH];
    int count = GetMenuItemCount(hMenu);
    for (int i=0; i<count; ++i)
    {
        MENUITEMINFO miif;
        SecureZeroMemory(&miif, sizeof(MENUITEMINFO));
        miif.cbSize = sizeof(MENUITEMINFO);
        miif.fMask = MIIM_DATA;
        miif.dwTypeData = menubuf;
        miif.cch = _countof(menubuf);
        GetMenuItemInfo(hMenu, i, TRUE, &miif);
        if (miif.dwItemData == (ULONG_PTR)g_MenuIDString)
            return S_OK;
    }

    UINT idCmd = idCmdFirst;

    //create the sub menu
    HMENU subMenu = CreateMenu();
    int indexSubMenu = 0;


    m_commands.LoadFromFile();

    int index = 0;
    for (int j = 0; j < m_commands.GetCount(); ++j)
    {
        MENUITEMINFO menuiteminfo = {0};

        Command cmd = m_commands.GetCommand(j);
        m_hotkeys[cmd.key] = j;
        if ((cmd.commandline.compare(INTERNALCOMMANDHIDDEN)==0)&&(cmd.name.compare(_T("Options")) == 0))
        {
            cmd.commandline = INTERNALCOMMAND;  // make sure the options button is never hidden.
            m_commands.SetCommand(j, cmd);
        }
        if ((cmd.name.compare(_T("StexBar Internal Edit Box")) == 0)||
            (cmd.commandline.compare(INTERNALCOMMANDHIDDEN) == 0)||
            (cmd.name.compare(_T("New Folder")) == 0))
        {
            continue;
        }
        bool bEnabled = cmd.enabled_viewpath ||
                        (cmd.enabled_fileselected && !m_ContextItems.empty()) ||
                        (cmd.enabled_folderselected && (!m_ContextItems.empty() || !m_ContextDirectory.empty())) ||
                        (cmd.enabled_noselection && (m_ContextItems.empty())) ||
                        (cmd.enabled_selectedcount && (cmd.enabled_selectedcount == (int)!m_ContextItems.empty()));

        HICON hIcon = LoadCommandIcon(cmd);
        if (hIcon)
        {
            menuiteminfo.hbmpItem = IsWindowsVistaOrGreater() ? IconToBitmapPARGB32(hIcon) : HBMMENU_CALLBACK;
            DestroyIcon(hIcon);
        }
        else
            menuiteminfo.hbmpItem = NULL;
        if (!cmd.separator)
            m_tooltips[j] = cmd.name.c_str();

        myIDMap[idCmd - idCmdFirst] = j;
        myIDMap[idCmd] = j;

        menuiteminfo.cbSize = sizeof(menuiteminfo);
        menuiteminfo.fMask = cmd.separator ? MIIM_FTYPE : MIIM_FTYPE | MIIM_ID | MIIM_BITMAP | MIIM_STRING | MIIM_STATE;
        menuiteminfo.fType = cmd.separator ? MFT_SEPARATOR : MFT_STRING;
        menuiteminfo.fState = bEnabled ? MFS_ENABLED : MFS_DISABLED;
        TCHAR menutextbuf[100];
        _tcscpy_s(menutextbuf, _countof(menutextbuf), m_commands.GetCommandPtr(j)->name.c_str());
        menuiteminfo.dwTypeData = menutextbuf;
        menuiteminfo.wID = idCmd++;
        InsertMenuItem(subMenu, indexSubMenu++, TRUE, &menuiteminfo);
        index++;
    }

    //add sub menu to main context menu
    //don't use InsertMenu because this will lead to multiple menu entries in the explorer file menu.
    //see http://support.microsoft.com/default.aspx?scid=kb;en-us;214477 for details of that.
    MENUITEMINFO menuiteminfo = {0};
    SecureZeroMemory(&menuiteminfo, sizeof(menuiteminfo));
    menuiteminfo.cbSize = sizeof(menuiteminfo);
    menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_STRING;
    menuiteminfo.fType = MFT_STRING;
    menuiteminfo.dwTypeData = _T("StEx");

    menuiteminfo.hSubMenu = subMenu;
    menuiteminfo.wID = idCmd++;
    InsertMenuItem(hMenu, indexMenu++, TRUE, &menuiteminfo);

    //return number of menu items added
    return ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(idCmd - idCmdFirst)));
}
Ejemplo n.º 5
0
LRESULT CMainWindow::DoCommand(int id)
{
	switch (id)
	{
	case ID_FILE_OPEN:
		loadOrSaveFile(true);
		break;
	case ID_FILE_SAVEAS:
		loadOrSaveFile(false);
		break;
	case ID_FILE_SAVE:
		loadOrSaveFile(false, m_filename);
		break;
	case ID_FILE_EXIT:
		::PostQuitMessage(0);
		return 0;
	case IDM_SHOWFINDBAR:
		{
			m_bShowFindBar = true;
			::ShowWindow(m_FindBar, SW_SHOW);
			RECT rect;
			GetClientRect(*this, &rect);
			::SetWindowPos(m_hWndEdit, HWND_TOP,
				rect.left, rect.top,
				rect.right - rect.left, rect.bottom - rect.top - int(30 * CDPIAware::Instance().ScaleFactorY()),
				SWP_SHOWWINDOW);
			::SetWindowPos(m_FindBar, HWND_TOP,
				rect.left, rect.bottom - int(30 * CDPIAware::Instance().ScaleFactorY()),
				rect.right - rect.left, int(30 * CDPIAware::Instance().ScaleFactorY()),
				SWP_SHOWWINDOW);
			::SetFocus(m_FindBar);
			SendEditor(SCI_SETSELECTIONSTART, 0);
			SendEditor(SCI_SETSELECTIONEND, 0);
			SendEditor(SCI_SEARCHANCHOR);
		}
		break;
	case IDM_FINDNEXT:
		SendEditor(SCI_CHARRIGHT);
		SendEditor(SCI_SEARCHANCHOR);
		if (SendEditor(SCI_SEARCHNEXT, m_bMatchCase ? SCFIND_MATCHCASE : 0, reinterpret_cast<LPARAM>(CUnicodeUtils::StdGetUTF8(m_findtext).c_str())) == -1)
		{
			FLASHWINFO fwi;
			fwi.cbSize = sizeof(FLASHWINFO);
			fwi.uCount = 3;
			fwi.dwTimeout = 100;
			fwi.dwFlags = FLASHW_ALL;
			fwi.hwnd = m_hwnd;
			FlashWindowEx(&fwi);
		}
		SendEditor(SCI_SCROLLCARET);
		break;
	case IDM_FINDPREV:
		SendEditor(SCI_SEARCHANCHOR);
		if (SendEditor(SCI_SEARCHPREV, m_bMatchCase ? SCFIND_MATCHCASE : 0, reinterpret_cast<LPARAM>(CUnicodeUtils::StdGetUTF8(m_findtext).c_str())) == -1)
		{
			FLASHWINFO fwi;
			fwi.cbSize = sizeof(FLASHWINFO);
			fwi.uCount = 3;
			fwi.dwTimeout = 100;
			fwi.dwFlags = FLASHW_ALL;
			fwi.hwnd = m_hwnd;
			FlashWindowEx(&fwi);
		}
		SendEditor(SCI_SCROLLCARET);
		break;
	case IDM_FINDEXIT:
		if (IsWindowVisible(m_FindBar))
		{
			RECT rect;
			GetClientRect(*this, &rect);
			m_bShowFindBar = false;
			::ShowWindow(m_FindBar, SW_HIDE);
			::SetWindowPos(m_hWndEdit, HWND_TOP,
				rect.left, rect.top,
				rect.right-rect.left, rect.bottom-rect.top,
				SWP_SHOWWINDOW);
		}
		else
			PostQuitMessage(0);
		break;
	case ID_FILE_SETTINGS:
		{
			tstring gitCmd = L" /command:settings /page:udiff";
			RunCommand(gitCmd);
		}
		break;
	case ID_FILE_APPLYPATCH:
		{
			std::wstring command = L" /diff:\"";
			command += m_filename;
			command += L'"';
			std::wstring tortoiseMergePath = GetAppDirectory() + L"TortoiseGitMerge.exe";
			CCreateProcessHelper::CreateProcessDetached(tortoiseMergePath.c_str(), command.c_str());
		}
		break;
	case ID_FILE_PAGESETUP:
		{
			TCHAR localeInfo[3] = { 0 };
			GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, 3);
			// Metric system. '1' is US System
			int defaultMargin = localeInfo[0] == '0' ? 2540 : 1000;

			PAGESETUPDLG pdlg = {0};
			pdlg.lStructSize = sizeof(PAGESETUPDLG);
			pdlg.hwndOwner = *this;
			pdlg.hInstance = nullptr;
			pdlg.Flags = PSD_DEFAULTMINMARGINS|PSD_MARGINS|PSD_DISABLEPAPER|PSD_DISABLEORIENTATION;
			if (localeInfo[0] == '0')
				pdlg.Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;

			CRegStdDWORD m_regMargLeft   = CRegStdDWORD(L"Software\\TortoiseGit\\UDiffpagesetupmarginleft", defaultMargin);
			CRegStdDWORD m_regMargTop    = CRegStdDWORD(L"Software\\TortoiseGit\\UDiffpagesetupmargintop", defaultMargin);
			CRegStdDWORD m_regMargRight  = CRegStdDWORD(L"Software\\TortoiseGit\\UDiffpagesetupmarginright", defaultMargin);
			CRegStdDWORD m_regMargBottom = CRegStdDWORD(L"Software\\TortoiseGit\\UDiffpagesetupmarginbottom", defaultMargin);

			pdlg.rtMargin.left   = static_cast<long>(m_regMargLeft);
			pdlg.rtMargin.top    = static_cast<long>(m_regMargTop);
			pdlg.rtMargin.right  = static_cast<long>(m_regMargRight);
			pdlg.rtMargin.bottom = static_cast<long>(m_regMargBottom);

			if (!PageSetupDlg(&pdlg))
				return false;

			m_regMargLeft   = pdlg.rtMargin.left;
			m_regMargTop    = pdlg.rtMargin.top;
			m_regMargRight  = pdlg.rtMargin.right;
			m_regMargBottom = pdlg.rtMargin.bottom;
		}
		break;
	case ID_FILE_PRINT:
		{
			PRINTDLGEX pdlg = {0};
			pdlg.lStructSize = sizeof(PRINTDLGEX);
			pdlg.hwndOwner = *this;
			pdlg.hInstance = nullptr;
			pdlg.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_ALLPAGES | PD_RETURNDC | PD_NOCURRENTPAGE | PD_NOPAGENUMS;
			pdlg.nMinPage = 1;
			pdlg.nMaxPage = 0xffffU; // We do not know how many pages in the document
			pdlg.nCopies = 1;
			pdlg.hDC = 0;
			pdlg.nStartPage = START_PAGE_GENERAL;

			// See if a range has been selected
			auto startPos = static_cast<Sci_Position>(SendEditor(SCI_GETSELECTIONSTART));
			auto endPos = static_cast<Sci_Position>(SendEditor(SCI_GETSELECTIONEND));

			if (startPos == endPos)
				pdlg.Flags |= PD_NOSELECTION;
			else
				pdlg.Flags |= PD_SELECTION;

			HRESULT hResult = PrintDlgEx(&pdlg);
			if ((hResult != S_OK) || (pdlg.dwResultAction != PD_RESULT_PRINT))
				return 0;

			// reset all indicators
			auto endpos = static_cast<int>(SendEditor(SCI_GETLENGTH));
			for (int i = INDIC_CONTAINER; i <= INDIC_MAX; ++i)
			{
				SendEditor(SCI_SETINDICATORCURRENT, i);
				SendEditor(SCI_INDICATORCLEARRANGE, 0, endpos);
			}
			// store and reset UI settings
			auto viewws = static_cast<int>(SendEditor(SCI_GETVIEWWS));
			SendEditor(SCI_SETVIEWWS, 0);
			auto edgemode = static_cast<int>(SendEditor(SCI_GETEDGEMODE));
			SendEditor(SCI_SETEDGEMODE, EDGE_NONE);
			SendEditor(SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_END);

			HDC hdc = pdlg.hDC;

			RECT rectMargins, rectPhysMargins;
			POINT ptPage;
			POINT ptDpi;

			// Get printer resolution
			ptDpi.x = GetDeviceCaps(hdc, LOGPIXELSX);    // dpi in X direction
			ptDpi.y = GetDeviceCaps(hdc, LOGPIXELSY);    // dpi in Y direction

			// Start by getting the physical page size (in device units).
			ptPage.x = GetDeviceCaps(hdc, PHYSICALWIDTH);   // device units
			ptPage.y = GetDeviceCaps(hdc, PHYSICALHEIGHT);  // device units

			// Get the dimensions of the unprintable
			// part of the page (in device units).
			rectPhysMargins.left = GetDeviceCaps(hdc, PHYSICALOFFSETX);
			rectPhysMargins.top = GetDeviceCaps(hdc, PHYSICALOFFSETY);

			// To get the right and lower unprintable area,
			// we take the entire width and height of the paper and
			// subtract everything else.
			rectPhysMargins.right = ptPage.x                        // total paper width
				- GetDeviceCaps(hdc, HORZRES)                       // printable width
				- rectPhysMargins.left;                             // left unprintable margin

			rectPhysMargins.bottom = ptPage.y                       // total paper height
				- GetDeviceCaps(hdc, VERTRES)                       // printable height
				- rectPhysMargins.top;                              // right unprintable margin

			TCHAR localeInfo[3] = { 0 };
			GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, localeInfo, 3);
			// Metric system. '1' is US System
			int defaultMargin = localeInfo[0] == '0' ? 2540 : 1000;
			RECT pagesetupMargin;
			CRegStdDWORD m_regMargLeft   = CRegStdDWORD(L"Software\\TortoiseGit\\UDiffpagesetupmarginleft", defaultMargin);
			CRegStdDWORD m_regMargTop    = CRegStdDWORD(L"Software\\TortoiseGit\\UDiffpagesetupmargintop", defaultMargin);
			CRegStdDWORD m_regMargRight  = CRegStdDWORD(L"Software\\TortoiseGit\\UDiffpagesetupmarginright", defaultMargin);
			CRegStdDWORD m_regMargBottom = CRegStdDWORD(L"Software\\TortoiseGit\\UDiffpagesetupmarginbottom", defaultMargin);

			pagesetupMargin.left   = static_cast<long>(m_regMargLeft);
			pagesetupMargin.top    = static_cast<long>(m_regMargTop);
			pagesetupMargin.right  = static_cast<long>(m_regMargRight);
			pagesetupMargin.bottom = static_cast<long>(m_regMargBottom);

			if (pagesetupMargin.left != 0 || pagesetupMargin.right != 0 ||
				pagesetupMargin.top != 0 || pagesetupMargin.bottom != 0)
			{
				RECT rectSetup;

				// Convert the hundredths of millimeters (HiMetric) or
				// thousandths of inches (HiEnglish) margin values
				// from the Page Setup dialog to device units.
				// (There are 2540 hundredths of a mm in an inch.)
				if (localeInfo[0] == '0')
				{
					// Metric system. '1' is US System
					rectSetup.left      = MulDiv (pagesetupMargin.left, ptDpi.x, 2540);
					rectSetup.top       = MulDiv (pagesetupMargin.top, ptDpi.y, 2540);
					rectSetup.right     = MulDiv(pagesetupMargin.right, ptDpi.x, 2540);
					rectSetup.bottom    = MulDiv(pagesetupMargin.bottom, ptDpi.y, 2540);
				}
				else
				{
					rectSetup.left      = MulDiv(pagesetupMargin.left, ptDpi.x, 1000);
					rectSetup.top       = MulDiv(pagesetupMargin.top, ptDpi.y, 1000);
					rectSetup.right     = MulDiv(pagesetupMargin.right, ptDpi.x, 1000);
					rectSetup.bottom    = MulDiv(pagesetupMargin.bottom, ptDpi.y, 1000);
				}

				// Don't reduce margins below the minimum printable area
				rectMargins.left    = max(rectPhysMargins.left, rectSetup.left);
				rectMargins.top     = max(rectPhysMargins.top, rectSetup.top);
				rectMargins.right   = max(rectPhysMargins.right, rectSetup.right);
				rectMargins.bottom  = max(rectPhysMargins.bottom, rectSetup.bottom);
			}
			else
			{
				rectMargins.left    = rectPhysMargins.left;
				rectMargins.top     = rectPhysMargins.top;
				rectMargins.right   = rectPhysMargins.right;
				rectMargins.bottom  = rectPhysMargins.bottom;
			}

			// rectMargins now contains the values used to shrink the printable
			// area of the page.

			// Convert device coordinates into logical coordinates
			DPtoLP(hdc, reinterpret_cast<LPPOINT>(&rectMargins), 2);
			DPtoLP(hdc, reinterpret_cast<LPPOINT>(&rectPhysMargins), 2);

			// Convert page size to logical units and we're done!
			DPtoLP(hdc, reinterpret_cast<LPPOINT>(&ptPage), 1);


			DOCINFO di = {sizeof(DOCINFO), 0, 0, 0, 0};
			di.lpszDocName = m_filename.c_str();
			di.lpszOutput = 0;
			di.lpszDatatype = 0;
			di.fwType = 0;
			if (::StartDoc(hdc, &di) < 0)
			{
				::DeleteDC(hdc);
				return 0;
			}

			size_t lengthDoc = static_cast<int>(SendEditor(SCI_GETLENGTH));
			size_t lengthDocMax = lengthDoc;
			size_t lengthPrinted = 0;

			// Requested to print selection
			if (pdlg.Flags & PD_SELECTION)
			{
				if (startPos > endPos)
				{
					lengthPrinted = endPos;
					lengthDoc = startPos;
				}
				else
				{
					lengthPrinted = startPos;
					lengthDoc = endPos;
				}

				if (lengthDoc > lengthDocMax)
					lengthDoc = lengthDocMax;
			}

			// We must subtract the physical margins from the printable area
			Sci_RangeToFormat frPrint;
			frPrint.hdc             = hdc;
			frPrint.hdcTarget       = hdc;
			frPrint.rc.left         = rectMargins.left - rectPhysMargins.left;
			frPrint.rc.top          = rectMargins.top - rectPhysMargins.top;
			frPrint.rc.right        = ptPage.x - rectMargins.right - rectPhysMargins.left;
			frPrint.rc.bottom       = ptPage.y - rectMargins.bottom - rectPhysMargins.top;
			frPrint.rcPage.left     = 0;
			frPrint.rcPage.top      = 0;
			frPrint.rcPage.right    = ptPage.x - rectPhysMargins.left - rectPhysMargins.right - 1;
			frPrint.rcPage.bottom   = ptPage.y - rectPhysMargins.top - rectPhysMargins.bottom - 1;

			// Print each page
			while (lengthPrinted < lengthDoc)
			{
				::StartPage(hdc);

				frPrint.chrg.cpMin = static_cast<long>(lengthPrinted);
				frPrint.chrg.cpMax = static_cast<long>(lengthDoc);

				lengthPrinted = SendEditor(SCI_FORMATRANGE, true, reinterpret_cast<LPARAM>(&frPrint));

				::EndPage(hdc);
			}

			SendEditor(SCI_FORMATRANGE, FALSE, 0);

			::EndDoc(hdc);
			::DeleteDC(hdc);

			if (pdlg.hDevMode)
				GlobalFree(pdlg.hDevMode);
			if (pdlg.hDevNames)
				GlobalFree(pdlg.hDevNames);
			if (pdlg.lpPageRanges)
				GlobalFree(pdlg.lpPageRanges);

			// reset the UI
			SendEditor(SCI_SETVIEWWS, viewws);
			SendEditor(SCI_SETEDGEMODE, edgemode);
			SendEditor(SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_NONE);
		}
		break;
	default:
		break;
	};
	return 1;
}
Ejemplo n.º 6
0
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*cmdShow*/)
{
	SetDllDirectory(L"");
	HANDLE hReloadProtection = ::CreateMutex(NULL, FALSE, GetCacheMutexName());

	if (hReloadProtection == 0 || GetLastError() == ERROR_ALREADY_EXISTS)
	{
		// An instance of TGitCache is already running
		ATLTRACE("TGitCache ignoring restart\n");
		return 0;
	}

//	apr_initialize();
//	svn_dso_initialize2();
	g_GitAdminDir.Init();
	CGitStatusCache::Create();
	CGitStatusCache::Instance().Init();

	SecureZeroMemory(szCurrentCrawledPath, sizeof(szCurrentCrawledPath));
	
	DWORD dwThreadId; 
	HANDLE hPipeThread; 
	HANDLE hCommandWaitThread;
	MSG msg;
	TCHAR szWindowClass[] = {TGIT_CACHE_WINDOW_NAME};

	// create a hidden window to receive window messages.
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX); 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= 0;
	wcex.hCursor		= 0;
	wcex.hbrBackground	= 0;
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= 0;
	RegisterClassEx(&wcex);
	hWnd = CreateWindow(TGIT_CACHE_WINDOW_NAME, TGIT_CACHE_WINDOW_NAME, WS_CAPTION, 0, 0, 800, 300, NULL, 0, hInstance, 0);
	hTrayWnd = hWnd;
	if (hWnd == NULL)
	{
		return 0;
	}
	if (CRegStdDWORD(_T("Software\\TortoiseGit\\CacheTrayIcon"), FALSE)==TRUE)
	{
		SecureZeroMemory(&niData,sizeof(NOTIFYICONDATA));

		DWORD dwVersion = GetDllVersion(_T("Shell32.dll"));

		if (dwVersion >= PACKVERSION(6,0))
			niData.cbSize = sizeof(NOTIFYICONDATA);
		else if (dwVersion >= PACKVERSION(5,0))
			niData.cbSize = NOTIFYICONDATA_V2_SIZE;
		else 
			niData.cbSize = NOTIFYICONDATA_V1_SIZE;

		niData.uID = TRAY_ID;		// own tray icon ID
		niData.hWnd	 = hWnd;
		niData.uFlags = NIF_ICON|NIF_MESSAGE;

		// load the icon
		niData.hIcon =
			(HICON)LoadImage(hInstance,
			MAKEINTRESOURCE(IDI_TGITCACHE),
			IMAGE_ICON,
			GetSystemMetrics(SM_CXSMICON),
			GetSystemMetrics(SM_CYSMICON),
			LR_DEFAULTCOLOR);

		// set the message to send
		// note: the message value should be in the
		// range of WM_APP through 0xBFFF
		niData.uCallbackMessage = TRAY_CALLBACK;
		Shell_NotifyIcon(NIM_ADD,&niData);
		// free icon handle
		if(niData.hIcon && DestroyIcon(niData.hIcon))
			niData.hIcon = NULL;
	}
	
	// Create a thread which waits for incoming pipe connections 
	hPipeThread = CreateThread( 
		NULL,              // no security attribute 
		0,                 // default stack size 
		PipeThread, 
		(LPVOID) &bRun,    // thread parameter 
		0,                 // not suspended 
		&dwThreadId);      // returns thread ID 

	if (hPipeThread == NULL) 
	{
		//OutputDebugStringA("TSVNCache: Could not create pipe thread\n");
		//DebugOutputLastError();
		return 0;
	}
	else CloseHandle(hPipeThread); 

	// Create a thread which waits for incoming pipe connections 
	hCommandWaitThread = CreateThread( 
		NULL,              // no security attribute 
		0,                 // default stack size 
		CommandWaitThread, 
		(LPVOID) &bRun,    // thread parameter 
		0,                 // not suspended 
		&dwThreadId);      // returns thread ID 

	if (hCommandWaitThread == NULL) 
	{
		//OutputDebugStringA("TSVNCache: Could not create command wait thread\n");
		//DebugOutputLastError();
		return 0;
	}
	else CloseHandle(hCommandWaitThread); 


	// loop to handle window messages.
	BOOL bLoopRet;
	while (bRun)
	{
		bLoopRet = GetMessage(&msg, NULL, 0, 0);
		if ((bLoopRet != -1)&&(bLoopRet != 0))
		{
			DispatchMessage(&msg);
		}
	}

	bRun = false;

	Shell_NotifyIcon(NIM_DELETE,&niData);
	CGitStatusCache::Destroy();
	g_GitAdminDir.Close();
//	apr_terminate();

	return 0;
}
Ejemplo n.º 7
0
void SetUUIDOverlayIcon( HWND hWnd )
{
    if (!CRegStdDWORD(L"Software\\TortoiseGit\\GroupTaskbarIconsPerRepo", 3))
        return;

    if (!CRegStdDWORD(L"Software\\TortoiseGit\\GroupTaskbarIconsPerRepoOverlay", TRUE))
        return;

    std::wstring uuid;
    std::wstring sicon;
    bool bRemoveicon = false;
#ifdef __AFXWIN_H__
    uuid = g_sGroupingUUID;
    sicon = g_sGroupingIcon;
    bRemoveicon = g_bGroupingRemoveIcon;
#else
    CCmdLineParser parser(GetCommandLine());
    if (parser.HasVal(L"groupuuid"))
        uuid = parser.GetVal(L"groupuuid");
#endif
    if (uuid.empty())
        return;

    CComPtr<ITaskbarList3> pTaskbarInterface;
    if (FAILED(pTaskbarInterface.CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER)))
        return;

    int foundUUIDIndex = 0;
    do
    {
        wchar_t buf[MAX_PATH] = { 0 };
        swprintf_s(buf, L"%s%d", L"Software\\TortoiseGit\\LastUsedUUIDsForGrouping\\", foundUUIDIndex);
        CRegStdString r = CRegStdString(buf);
        std::wstring sr = r;
        if (sr.empty())
        {
            r = uuid + (sicon.empty() ? L"" : (L";" + sicon));
            break;
        }
        size_t sep = sr.find(L';');
        std::wstring olduuid = sep != std::wstring::npos ? sr.substr(0, sep) : sr;
        if (olduuid.compare(uuid) == 0)
        {
            if (bRemoveicon)
                r = uuid; // reset icon path in registry
            else if (!sicon.empty())
                r = uuid + (sicon.empty() ? L"" : (L";" + sicon));
            else
                sicon = sep != std::wstring::npos ? sr.substr(sep + 1) : L"";
            break;
        }
        foundUUIDIndex++;
    } while (foundUUIDIndex < 20);
    if (foundUUIDIndex >= 20)
    {
        CRegStdString r = CRegStdString(L"Software\\TortoiseGit\\LastUsedUUIDsForGrouping\\1");
        r.removeKey();
    }

    int iconWidth = GetSystemMetrics(SM_CXSMICON);
    int iconHeight = GetSystemMetrics(SM_CYSMICON);

    HICON icon = nullptr;
    if (!sicon.empty())
    {
        if (sicon.size() >= 4 && !_wcsicmp(sicon.substr(sicon.size() - 4).c_str(), L".ico"))
            icon = (HICON)::LoadImage(nullptr, sicon.c_str(), IMAGE_ICON, iconWidth, iconHeight, LR_LOADFROMFILE | LR_SHARED);
        else
        {
            ULONG_PTR gdiplusToken = 0;
            Gdiplus::GdiplusStartupInput gdiplusStartupInput;
            GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
            if (gdiplusToken)
            {
                Gdiplus::Bitmap* pBitmap = new Gdiplus::Bitmap(sicon.c_str(), FALSE);
                if (pBitmap->GetLastStatus() == Gdiplus::Status::Ok)
                    pBitmap->GetHICON(&icon);
                delete pBitmap;
                Gdiplus::GdiplusShutdown(gdiplusToken);
            }
        }
    }

    if (!icon)
    {
        DWORD colors[6] = { 0x80FF0000, 0x80FFFF00, 0x8000FF00, 0x800000FF, 0x80000000, 0x8000FFFF };

        // AND mask - monochrome - determines which pixels get drawn
        BYTE AND[32];
        for (int i = 0; i<32; i++)
        {
            AND[i] = 0xFF;
        }

        // XOR mask - 32bpp ARGB - determines the pixel values
        DWORD XOR[256];
        for (int i = 0; i<256; i++)
        {
            XOR[i] = colors[foundUUIDIndex % 6];
        }

        icon = ::CreateIcon(nullptr, iconWidth, iconHeight, 1, 32, AND, (BYTE*)XOR);
    }
    pTaskbarInterface->SetOverlayIcon(hWnd, icon, uuid.c_str());
    DestroyIcon(icon);
}
Ejemplo n.º 8
0
int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmdShow);

    // uncomment the following lines for low-memory tests.
    // note: process needs to run elevated for this to work.
    //
    //auto job = CreateJobObject(NULL, NULL);
    //JOBOBJECT_EXTENDED_LIMIT_INFORMATION joblimit = { 0 };
    //joblimit.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_WORKINGSET;
    //joblimit.JobMemoryLimit = 30 * 1024 * 1024;
    //joblimit.ProcessMemoryLimit = 30 * 1024 * 1024;
    //joblimit.PeakProcessMemoryUsed = 30 * 1024 * 1024;
    //joblimit.BasicLimitInformation.MaximumWorkingSetSize = 30 * 1024 * 1024;
    //joblimit.BasicLimitInformation.MinimumWorkingSetSize = 30 * 1024;
    //SetInformationJobObject(job, JobObjectExtendedLimitInformation, &joblimit, sizeof(joblimit));
    //AssignProcessToJobObject(job, GetCurrentProcess());

    SetDllDirectory(L"");
    // if multiple items are selected in explorer and grepWin is started for all of them,
    // explorer starts multiple grepWin instances at once. In case there's already a grepWin instance
    // running, sleep for a while to give that instance time to fully initialize
    HANDLE hReloadProtection = ::CreateMutex(NULL, FALSE, L"{6473AA76-0EAE-4C96-8C99-AFDFEFFE42B5}");
    bool alreadyRunning = false;
    if ((!hReloadProtection) || (GetLastError() == ERROR_ALREADY_EXISTS))
    {
        // An instance of grepWin is already running
        alreadyRunning = true;
    }

    g_hInst = hInstance;
    ::OleInitialize(NULL);
    ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    // we need some of the common controls
    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC = ICC_LINK_CLASS|ICC_LISTVIEW_CLASSES|ICC_PAGESCROLLER_CLASS
        |ICC_PROGRESS_CLASS|ICC_STANDARD_CLASSES|ICC_TAB_CLASSES|ICC_TREEVIEW_CLASSES
        |ICC_UPDOWN_CLASS|ICC_USEREX_CLASSES|ICC_WIN95_CLASSES;
    InitCommonControlsEx(&icex);

    HMODULE hRichEdt = LoadLibrary(_T("Riched20.dll"));

    CCmdLineParser parser(lpCmdLine);

    if (parser.HasKey(L"register"))
    {
        RegisterContextMenu(true);
        return FALSE;
    }
    if ((parser.HasKey(L"unregister")) || (parser.HasKey(L"deregister")))
    {
        RegisterContextMenu(false);
        return FALSE;
    }

    bool bQuit = false;
    HWND hWnd = NULL;
    int timeout = 20;
    do
    {
        EnumWindows(windowenumerator, (LPARAM)&hWnd);
        if (alreadyRunning && (hWnd == NULL))
            Sleep(100);
        timeout--;
    } while ((hWnd == NULL) && alreadyRunning && timeout);

    auto modulename = CPathUtils::GetFileName(CPathUtils::GetModulePath(0));
    bPortable = ((_tcsstr(modulename.c_str(), _T("portable"))) || (parser.HasKey(_T("portable"))));

    std::wstring iniPath = CPathUtils::GetModuleDir(0);
    iniPath += L"\\grepwin.ini";
    if (parser.HasVal(L"inipath"))
        iniPath = parser.GetVal(L"inipath");

    if (bPortable)
        g_iniFile.LoadFile(iniPath.c_str());


    if (hWnd)
    {
        bool bOnlyOne = !!DWORD(CRegStdDWORD(_T("Software\\grepWin\\onlyone"), 0));
        if (bPortable)
            bOnlyOne = !!_wtoi(g_iniFile.GetValue(L"global", L"onlyone", L"0"));
        UINT GREPWIN_STARTUPMSG = RegisterWindowMessage(_T("grepWin_StartupMessage"));
        if (SendMessage(hWnd, GREPWIN_STARTUPMSG, 0, 0))                // send the new path
        {
            std::wstring spath = parser.GetVal(_T("searchpath"));
            SearchReplace(spath, L"/", L"\\");
            spath = SanitizeSearchPaths(spath);
            COPYDATASTRUCT CopyData = {0};
            CopyData.lpData = (LPVOID)spath.c_str();
            CopyData.cbData = (DWORD)spath.size()*sizeof(wchar_t);
            SendMessage(hWnd, WM_COPYDATA, 0, (LPARAM)&CopyData);
            SetForegroundWindow(hWnd);                                  //set the window to front
            bQuit = true;
        }
        else if (bOnlyOne)
        {
            std::wstring spath = parser.HasVal(L"searchpath") ? parser.GetVal(_T("searchpath")) : L"";
            SearchReplace(spath, L"/", L"\\");
            spath = SanitizeSearchPaths(spath);
            COPYDATASTRUCT CopyData = { 0 };
            CopyData.lpData = (LPVOID)spath.c_str();
            CopyData.cbData = (DWORD)spath.size()*sizeof(wchar_t);
            SendMessage(hWnd, WM_COPYDATA, 1, (LPARAM)&CopyData);
            SetForegroundWindow(hWnd);                                  //set the window to front
            bQuit = true;
        }
    }

    int ret = 0;
    if (!bQuit)
    {
        CLanguage::Instance().LoadFile(bPortable ? g_iniFile.GetValue(L"global", L"languagefile", L"") : std::wstring(CRegStdString(L"Software\\grepWin\\languagefile")));
        if (parser.HasKey(_T("about"))||parser.HasKey(_T("?"))||parser.HasKey(_T("help")))
        {
            CAboutDlg aboutDlg(NULL);
            ret= (int)aboutDlg.DoModal(hInstance, IDD_ABOUT, NULL, NULL);
        }
        else
        {
            CSearchDlg searchDlg(NULL);
            if (parser.HasVal(_T("searchpath")))
            {
                std::wstring spath = parser.GetVal(L"searchpath");
                spath = SanitizeSearchPaths(spath);
                searchDlg.SetSearchPath(spath);
            }
            if (parser.HasVal(_T("searchfor")))
                searchDlg.SetSearchString(parser.GetVal(_T("searchfor")));
            if (parser.HasVal(_T("filemaskregex")))
                searchDlg.SetFileMask(parser.GetVal(_T("filemaskregex")), true);
            if (parser.HasVal(_T("filemask")))
                searchDlg.SetFileMask(parser.GetVal(_T("filemask")), false);
            if (parser.HasVal(_T("filemaskexclude")))
                searchDlg.SetExcludeFileMask(parser.GetVal(_T("filemaskexclude")));
            if (parser.HasVal(_T("replacewith")))
                searchDlg.SetReplaceWith(parser.GetVal(_T("replacewith")));

            if (parser.HasVal(_T("i")))
                searchDlg.SetCaseSensitive(_tcsicmp(parser.GetVal(_T("i")), _T("yes"))!=0);
            if (parser.HasVal(_T("n")))
                searchDlg.SetMatchesNewline(_tcsicmp(parser.GetVal(_T("n")), _T("yes"))==0);
            if (parser.HasVal(_T("k")))
                searchDlg.SetCreateBackups(_tcsicmp(parser.GetVal(_T("k")), _T("yes"))==0);
            if (parser.HasVal(_T("utf8")))
                searchDlg.SetUTF8(_tcsicmp(parser.GetVal(_T("utf8")), _T("yes"))==0);
            if (parser.HasVal(_T("size")))
            {
                int cmp = 0;
                if (parser.HasVal(_T("sizecmp")))
                    cmp = parser.GetLongVal(_T("sizecmp"));
                searchDlg.SetSize(parser.GetLongVal(_T("size")), cmp);
            }
            if (parser.HasVal(_T("s")))
                searchDlg.SetIncludeSystem(_tcsicmp(parser.GetVal(_T("s")), _T("yes"))==0);
            if (parser.HasVal(_T("h")))
                searchDlg.SetIncludeHidden(_tcsicmp(parser.GetVal(_T("h")), _T("yes"))==0);
            if (parser.HasVal(_T("u")))
                searchDlg.SetIncludeSubfolders(_tcsicmp(parser.GetVal(_T("u")), _T("yes"))==0);
            if (parser.HasVal(_T("b")))
                searchDlg.SetIncludeBinary(_tcsicmp(parser.GetVal(_T("b")), _T("yes"))==0);
            if (parser.HasVal(_T("regex")))
                searchDlg.SetUseRegex(_tcsicmp(parser.GetVal(_T("regex")), _T("yes")) == 0);
            else if(parser.HasVal(_T("searchfor")))
                searchDlg.SetUseRegex(true);

            if (parser.HasKey(L"execute") || parser.HasKey(L"executesearch"))
                searchDlg.SetExecute(ExecuteAction::Search);
            if (parser.HasKey(L"executereplace"))
                searchDlg.SetExecute(ExecuteAction::Replace);
            if (parser.HasKey(L"closedialog"))
                searchDlg.SetEndDialog();

            ret = (int)searchDlg.DoModal(hInstance, IDD_SEARCHDLG, NULL, IDR_SEARCHDLG);
        }
        if (bPortable)
        {
            FILE * pFile = NULL;
            _tfopen_s(&pFile, iniPath.c_str(), _T("wb"));
            g_iniFile.SaveFile(pFile);
            fclose(pFile);
        }
    }

    ::CoUninitialize();
    ::OleUninitialize();
    FreeLibrary(hRichEdt);
    CloseHandle(hReloadProtection);
    return ret;
}
Ejemplo n.º 9
0
void SetUUIDOverlayIcon( HWND hWnd )
{
    if (CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepo"), 3))
    {
        if (CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepoOverlay"), TRUE))
        {
            std::wstring uuid;
#ifdef _MFC_VER
            uuid = g_sGroupingUUID;
#else
            CCmdLineParser parser(GetCommandLine());
            if (parser.HasVal(L"groupuuid"))
                uuid = parser.GetVal(L"groupuuid");
#endif
            if (!uuid.empty())
            {
                ITaskbarList3 * pTaskbarInterface = NULL;
                HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, reinterpret_cast<void**> (&(pTaskbarInterface)));

                if (SUCCEEDED(hr))
                {
                    int foundUUIDIndex = 0;
                    do
                    {
                        wchar_t buf[MAX_PATH];
                        swprintf_s(buf, _countof(buf), L"%s%d", L"Software\\TortoiseGit\\LastUsedUUIDsForGrouping\\", foundUUIDIndex);
                        CRegStdString r = CRegStdString(buf);
                        std::wstring sr = r;
                        if (sr.empty() || (sr.compare(uuid)==0))
                        {
                            r = uuid;
                            break;
                        }
                        foundUUIDIndex++;
                    } while (foundUUIDIndex < 20);
                    if (foundUUIDIndex >= 20)
                    {
                        CRegStdString r = CRegStdString(L"Software\\TortoiseGit\\LastUsedUUIDsForGrouping\\1");
                        r.removeKey();
                    }

                    DWORD colors[6] = {0x80FF0000, 0x80FFFF00, 0x8000FF00, 0x800000FF, 0x80000000, 0x8000FFFF};

                    // AND mask - monochrome - determines which pixels get drawn
                    BYTE AND[32];
                    for( int i=0; i<32; i++ )
                    {
                        AND[i] = 0xFF;
                    }

                    // XOR mask - 32bpp ARGB - determines the pixel values
                    DWORD XOR[256];
                    for( int i=0; i<256; i++ )
                    {
                        XOR[i] = colors[foundUUIDIndex % 6];
                    }

                    HICON icon = ::CreateIcon(NULL,16,16,1,32,AND,(BYTE*)XOR);
                    pTaskbarInterface->SetOverlayIcon(hWnd, icon, uuid.c_str());
                    pTaskbarInterface->Release();
                    DestroyIcon(icon);
                }
            }
        }
    }
}
Ejemplo n.º 10
0
LRESULT CALLBACK CMainWindow::WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
    {
        m_hwnd = hwnd;
        Initialize();
    }
    break;
    case WM_COMMAND:
    {
        return DoCommand(LOWORD(wParam));
    }
    break;
    case WM_MOUSEWHEEL:
    {
        if (GET_KEYSTATE_WPARAM(wParam) == MK_SHIFT)
        {
            // scroll sideways
            SendEditor(SCI_LINESCROLL, -GET_WHEEL_DELTA_WPARAM(wParam)/40, 0);
        }
        else
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    break;
    case WM_SIZE:
    {
        RECT rect;
        GetClientRect(*this, &rect);
        if (m_bShowFindBar)
        {
            ::SetWindowPos(m_hWndEdit, HWND_TOP,
                           rect.left, rect.top,
                           rect.right-rect.left, rect.bottom-rect.top-30,
                           SWP_SHOWWINDOW);
            ::SetWindowPos(m_FindBar, HWND_TOP,
                           rect.left, rect.bottom-30,
                           rect.right-rect.left, 30,
                           SWP_SHOWWINDOW);
        }
        else
        {
            ::SetWindowPos(m_hWndEdit, HWND_TOP,
                           rect.left, rect.top,
                           rect.right-rect.left, rect.bottom-rect.top,
                           SWP_SHOWWINDOW);
            ::ShowWindow(m_FindBar, SW_HIDE);
        }
    }
    break;
    case WM_GETMINMAXINFO:
    {
        MINMAXINFO * mmi = (MINMAXINFO*)lParam;
        mmi->ptMinTrackSize.x = 100;
        mmi->ptMinTrackSize.y = 100;
        return 0;
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_CLOSE:
    {
        CRegStdDWORD w = CRegStdDWORD(_T("Software\\TortoiseGit\\UDiffViewerWidth"), (DWORD)CW_USEDEFAULT);
        CRegStdDWORD h = CRegStdDWORD(_T("Software\\TortoiseGit\\UDiffViewerHeight"), (DWORD)CW_USEDEFAULT);
        CRegStdDWORD p = CRegStdDWORD(_T("Software\\TortoiseGit\\UDiffViewerPos"), 0);

        RECT rect;
        ::GetWindowRect(*this, &rect);
        w = rect.right-rect.left;
        h = rect.bottom-rect.top;
        p = MAKELONG(rect.left, rect.top);
    }
    ::DestroyWindow(m_hwnd);
    break;
    case WM_SETFOCUS:
        SetFocus(m_hWndEdit);
        break;
    case COMMITMONITOR_FINDMSGNEXT:
    {
        SendEditor(SCI_CHARRIGHT);
        SendEditor(SCI_SEARCHANCHOR);
        m_bMatchCase = !!wParam;
        m_findtext = (LPCTSTR)lParam;
        SendEditor(SCI_SEARCHNEXT, m_bMatchCase ? SCFIND_MATCHCASE : 0, (LPARAM)CUnicodeUtils::StdGetUTF8(m_findtext).c_str());
        SendEditor(SCI_SCROLLCARET);
    }
    break;
    case COMMITMONITOR_FINDMSGPREV:
    {
        SendEditor(SCI_SEARCHANCHOR);
        m_bMatchCase = !!wParam;
        m_findtext = (LPCTSTR)lParam;
        SendEditor(SCI_SEARCHPREV, m_bMatchCase ? SCFIND_MATCHCASE : 0, (LPARAM)CUnicodeUtils::StdGetUTF8(m_findtext).c_str());
        SendEditor(SCI_SCROLLCARET);
    }
    break;
    case COMMITMONITOR_FINDEXIT:
    {
        RECT rect;
        GetClientRect(*this, &rect);
        m_bShowFindBar = false;
        ::ShowWindow(m_FindBar, SW_HIDE);
        ::SetWindowPos(m_hWndEdit, HWND_TOP,
                       rect.left, rect.top,
                       rect.right-rect.left, rect.bottom-rect.top,
                       SWP_SHOWWINDOW);
    }
    break;
    case COMMITMONITOR_FINDRESET:
        SendEditor(SCI_SETSELECTIONSTART, 0);
        SendEditor(SCI_SETSELECTIONEND, 0);
        SendEditor(SCI_SEARCHANCHOR);
        break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }

    return 0;
};
Ejemplo n.º 11
0
BOOL CSetOverlayIcons::OnInitDialog()
{
	ISettingsPropPage::OnInitDialog();

	m_cIconList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_SUBITEMIMAGES);
	// get the path to our icon sets
	TCHAR buf[MAX_PATH] = {0};
	SHGetSpecialFolderPath(m_hWnd, buf, CSIDL_PROGRAM_FILES_COMMON, true);
	m_sIconPath = buf;
	m_sIconPath += _T("\\TortoiseOverlays\\Icons");
	// list all the icon sets
	CDirFileEnum filefinder(m_sIconPath);
	bool isDir = false;
	CString item;
	while (filefinder.NextFile(item, &isDir))
	{
		if (!isDir)
			continue;
		m_cIconSet.AddString(CPathUtils::GetFileNameFromPath(item));
	}
	CheckRadioButton(IDC_LISTRADIO, IDC_SYMBOLRADIO, IDC_LISTRADIO);
	CString sModifiedIcon = m_regModified;
	if (sModifiedIcon.IsEmpty())
	{
		// no custom icon set, use the default
		sModifiedIcon = m_sIconPath + _T("\\XPStyle\\ModifiedIcon.ico");
	}
	if (sModifiedIcon.Left(m_sIconPath.GetLength()).CompareNoCase(m_sIconPath)!=0)
	{
		// an icon set outside our own installation? We don't support that,
		// so fall back to the default!
		sModifiedIcon = m_sIconPath + _T("\\XPStyle\\ModifiedIcon.ico");
	}
	// the name of the icon set is the folder of the icon location
	m_sOriginalIconSet = sModifiedIcon.Mid(m_sIconPath.GetLength()+1);
	m_sOriginalIconSet = m_sOriginalIconSet.Left(m_sOriginalIconSet.ReverseFind('\\'));
	// now we have the name of the icon set. Set the combobox to show
	// that as selected
	CString ComboItem;
	for (int i=0; i<m_cIconSet.GetCount(); ++i)
	{
		m_cIconSet.GetLBText(i, ComboItem);
		if (ComboItem.CompareNoCase(m_sOriginalIconSet)==0)
			m_cIconSet.SetCurSel(i);
	}

	WORD langID = (WORD)(DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\LanguageID"), GetUserDefaultLangID());
	TCHAR statustext[MAX_STATUS_STRING_LENGTH] = { 0 };
	GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_normal, statustext, _countof(statustext), langID);
	m_sNormal = statustext;
	GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_modified, statustext, _countof(statustext), langID);
	m_sModified = statustext;
	GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_conflicted, statustext, _countof(statustext), langID);
	m_sConflicted = statustext;
	GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_deleted, statustext, _countof(statustext), langID);
	m_sDeleted = statustext;
	GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_added, statustext, _countof(statustext), langID);
	m_sAdded = statustext;
	GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_ignored, statustext, _countof(statustext), langID);
	m_sIgnored = statustext;
	GitStatus::GetStatusString(AfxGetResourceHandle(), git_wc_status_unversioned, statustext, _countof(statustext), langID);
	m_sUnversioned = statustext;

	m_sReadOnly.LoadString(IDS_SETTINGS_READONLYNAME);
	m_sLocked.LoadString(IDS_SETTINGS_LOCKEDNAME);

	SetWindowTheme(m_hWnd, L"Explorer", NULL);

	ShowIconSet(true);

	return TRUE;
}
Ejemplo n.º 12
0
bool CMainWindow::Initialize()
{
    CRegStdDWORD pos(_T("Software\\TortoiseGit\\UDiffViewerPos"), 0);
    CRegStdDWORD width(_T("Software\\TortoiseGit\\UDiffViewerWidth"), (DWORD)640);
    CRegStdDWORD height(_T("Software\\TortoiseGit\\UDiffViewerHeight"), (DWORD)480);
    if (DWORD(pos) && DWORD(width) && DWORD(height))
    {
        RECT rc;
        rc.left = LOWORD(DWORD(pos));
        rc.top = HIWORD(DWORD(pos));
        rc.right = rc.left + DWORD(width);
        rc.bottom = rc.top + DWORD(height);
        HMONITOR hMon = MonitorFromRect(&rc, MONITOR_DEFAULTTONULL);
        if (hMon)
        {
            // only restore the window position if the monitor is valid
            MoveWindow(*this, LOWORD(DWORD(pos)), HIWORD(DWORD(pos)),
                       DWORD(width), DWORD(height), FALSE);
        }
    }

    m_hWndEdit = ::CreateWindow(
                     _T("Scintilla"),
                     _T("Source"),
                     WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN,
                     CW_USEDEFAULT, CW_USEDEFAULT,
                     CW_USEDEFAULT, CW_USEDEFAULT,
                     *this,
                     0,
                     hResource,
                     0);
    if (m_hWndEdit == NULL)
        return false;

    RECT rect;
    GetClientRect(*this, &rect);
    ::SetWindowPos(m_hWndEdit, HWND_TOP,
                   rect.left, rect.top,
                   rect.right-rect.left, rect.bottom-rect.top,
                   SWP_SHOWWINDOW);

    m_directFunction = SendMessage(m_hWndEdit, SCI_GETDIRECTFUNCTION, 0, 0);
    m_directPointer = SendMessage(m_hWndEdit, SCI_GETDIRECTPOINTER, 0, 0);

    // Set up the global default style. These attributes are used wherever no explicit choices are made.
    SetAStyle(STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOWTEXT), ::GetSysColor(COLOR_WINDOW),
              // Reusing TortoiseBlame's setting which already have an user friendly
              // pane in TortoiseSVN's Settings dialog, while there is no such
              // pane for TortoiseUDiff.
              CRegStdDWORD(_T("Software\\TortoiseGit\\BlameFontSize"), 10),
              WideToMultibyte(CRegStdString(_T("Software\\TortoiseGit\\BlameFontName"), _T("Courier New"))).c_str());
    SendEditor(SCI_SETTABWIDTH, 4);
    SendEditor(SCI_SETREADONLY, TRUE);
    LRESULT pix = SendEditor(SCI_TEXTWIDTH, STYLE_LINENUMBER, (LPARAM)"_99999");
    SendEditor(SCI_SETMARGINWIDTHN, 0, pix);
    SendEditor(SCI_SETMARGINWIDTHN, 1);
    SendEditor(SCI_SETMARGINWIDTHN, 2);
    //Set the default windows colors for edit controls
    SendEditor(SCI_STYLESETFORE, STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOWTEXT));
    SendEditor(SCI_STYLESETBACK, STYLE_DEFAULT, ::GetSysColor(COLOR_WINDOW));
    SendEditor(SCI_SETSELFORE, TRUE, ::GetSysColor(COLOR_HIGHLIGHTTEXT));
    SendEditor(SCI_SETSELBACK, TRUE, ::GetSysColor(COLOR_HIGHLIGHT));
    SendEditor(SCI_SETCARETFORE, ::GetSysColor(COLOR_WINDOWTEXT));

    return true;
}
// 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.
//
#include "StdAfx.h"
#include ".\statuscacheentry.h"
#include "GitStatus.h"
#include "CacheInterface.h"
#include "registry.h"

#define CACHEVERION 7

DWORD cachetimeout = (DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\Cachetimeout"), CACHETIMEOUT);

CStatusCacheEntry::CStatusCacheEntry()
	: m_bSet(false)
	, m_kind(git_node_unknown)
	, m_highestPriorityLocalStatus(git_wc_status_none)
	, m_bAssumeValid(false)
	, m_bSkipWorktree(false)
{
	SetAsUnversioned();
}

CStatusCacheEntry::CStatusCacheEntry(const git_wc_status_kind status)
	: m_bSet(true)
	, m_kind(git_node_unknown)
	, m_highestPriorityLocalStatus(status)
Ejemplo n.º 14
0
git_revnum_t GitStatus::GetStatus(const CTGitPath& path, bool update /* = false */, bool noignore /* = false */, bool /*noexternals*/ /* = false */)
{
	// NOTE: unlike the SVN version this one does not cache the enumerated files, because in practice no code in all of
	//       Tortoise uses this, all places that call GetStatus create a temp GitStatus object which gets destroyed right
	//       after the call again

//	apr_hash_t *				statushash;
//	apr_hash_t *				exthash;
//	apr_array_header_t *		statusarray;
//	const sort_item*			item;

//	git_error_clear(m_err);
//	statushash = apr_hash_make(m_pool);
//	exthash = apr_hash_make(m_pool);
	git_revnum_t youngest = GIT_INVALID_REVNUM;
//	git_opt_revision_t rev;
//	rev.kind = git_opt_revision_unspecified;

	CString sProjectRoot;
	if ( !path.HasAdminDir(&sProjectRoot) )
		return youngest;

	struct hashbaton_t hashbaton;
//	hashbaton.hash = statushash;
//	hashbaton.exthash = exthash;
	hashbaton.pThis = this;

	bool isfull = ((DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\CacheType"),
				GetSystemMetrics(SM_REMOTESESSION) ? ShellCache::dll : ShellCache::exe) == ShellCache::dllFull);

	{
		LPCTSTR lpszSubPath = NULL;
		CString sSubPath;
		CString s = path.GetWinPathString();
		if (s.GetLength() > sProjectRoot.GetLength())
		{
			sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength());
			lpszSubPath = sSubPath;
			// skip initial slash if necessary
			if (*lpszSubPath == _T('\\'))
				lpszSubPath++;
		}

		m_status.prop_status = m_status.text_status = git_wc_status_none;

		if(path.IsDirectory())
		{
			m_err = GetDirStatus(sProjectRoot,CString(lpszSubPath),&m_status.text_status , isfull, false,!noignore, NULL, NULL);

		}
		else
		{
			m_err = GetFileStatus(sProjectRoot,CString(lpszSubPath),&m_status.text_status ,isfull, false,!noignore, NULL,NULL);
		}
	}

	// Error present if function is not under version control
	if (m_err) /*|| (apr_hash_count(statushash) == 0)*/
	{
		status = NULL;
		return GIT_INVALID_REVNUM;
	}

	// Convert the unordered hash to an ordered, sorted array
	/*statusarray = sort_hash (statushash,
							  sort_compare_items_as_paths,
							  m_pool);*/

	// only the first entry is needed (no recurse)
//	item = &APR_ARRAY_IDX (statusarray, 0, const sort_item);

//	status = (git_wc_status2_t *) item->value;
	status = &m_status;

	if (update)
	{
		// done to match TSVN functionality of this function (not sure if any code uses the reutrn val)
		// if TGit does not need this, then change the return type of function
		youngest = g_Git.GetHash(_T("HEAD"));
	}

	return youngest;
}
Ejemplo n.º 15
0
void CFolderCrawler::WorkerThread()
{
	HANDLE hWaitHandles[2];
	hWaitHandles[0] = m_hTerminationEvent;
	hWaitHandles[1] = m_hWakeEvent;
	CTGitPath workingPath;
	ULONGLONG currentTicks = 0;

	for(;;)
	{
		bool bRecursive = !!(DWORD)CRegStdDWORD(L"Software\\TortoiseGit\\RecursiveOverlay", TRUE);

		SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);

		DWORD waitResult = WaitForMultipleObjects(_countof(hWaitHandles), hWaitHandles, FALSE, INFINITE);

		// exit event/working loop if the first event (m_hTerminationEvent)
		// has been signaled or if one of the events has been abandoned
		// (i.e. ~CFolderCrawler() is being executed)
		if(m_bRun == false || waitResult == WAIT_OBJECT_0 || waitResult == WAIT_ABANDONED_0 || waitResult == WAIT_ABANDONED_0+1)
		{
			// Termination event
			break;
		}

		SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);

		// If we get here, we've been woken up by something being added to the queue.
		// However, it's important that we don't do our crawling while
		// the shell is still asking for items
		bool bFirstRunAfterWakeup = true;
		for(;;)
		{
			if (!m_bRun)
				break;
			// Any locks today?
			if (CGitStatusCache::Instance().m_bClearMemory)
			{
				CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
				CGitStatusCache::Instance().ClearCache();
				CGitStatusCache::Instance().m_bClearMemory = false;
			}
			if(m_lCrawlInhibitSet > 0)
			{
				// We're in crawl hold-off
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Crawl hold-off\n");
				Sleep(50);
				continue;
			}
			if (bFirstRunAfterWakeup)
			{
				Sleep(20);
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Crawl bFirstRunAfterWakeup\n");
				bFirstRunAfterWakeup = false;
				continue;
			}
			if ((m_blockReleasesAt < GetTickCount64()) && (!m_blockedPath.IsEmpty()))
			{
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Crawl stop blocking path %s\n", m_blockedPath.GetWinPath());
				m_blockedPath.Reset();
			}
			CGitStatusCache::Instance().RemoveTimedoutBlocks();

			while (!m_pathsToRelease.empty())
			{
				AutoLocker lock(m_critSec);
				CTGitPath path = m_pathsToRelease.Pop();
				GitStatus::ReleasePath(path.GetWinPathString());
			}

			if (m_foldersToUpdate.empty() && m_pathsToUpdate.empty())
			{
				// Nothing left to do
				break;
			}
			currentTicks = GetTickCount64();
			if (!m_pathsToUpdate.empty())
			{
				{
					AutoLocker lock(m_critSec);

					m_bPathsAddedSinceLastCrawl = false;

					workingPath = m_pathsToUpdate.Pop();
					if ((!m_blockedPath.IsEmpty()) && (m_blockedPath.IsAncestorOf(workingPath)))
					{
						// move the path to the end of the list
						m_pathsToUpdate.Push(workingPath);
						if (m_pathsToUpdate.size() < 3)
							Sleep(50);
						continue;
					}
				}

				// don't crawl paths that are excluded
				if (!CGitStatusCache::Instance().IsPathAllowed(workingPath))
					continue;
				// check if the changed path is inside an .git folder
				CString projectroot;
				if ((workingPath.HasAdminDir(&projectroot)&&workingPath.IsDirectory()) || workingPath.IsAdminDir())
				{
					// we don't crawl for paths changed in a tmp folder inside an .git folder.
					// Because we also get notifications for those even if we just ask for the status!
					// And changes there don't affect the file status at all, so it's safe
					// to ignore notifications on those paths.
					if (workingPath.IsAdminDir())
					{
						// TODO: add git specific filters here. is there really any change besides index file in .git
						//       that is relevant for overlays?
						/*CString lowerpath = workingPath.GetWinPathString();
						lowerpath.MakeLower();
						if (lowerpath.Find(L"\\tmp\\") > 0)
							continue;
						if (CStringUtils::EndsWith(lowerpath, L"\\tmp"))
							continue;
						if (lowerpath.Find(L"\\log") > 0)
							continue;*/
						// Here's a little problem:
						// the lock file is also created for fetching the status
						// and not just when committing.
						// If we could find out why the lock file was changed
						// we could decide to crawl the folder again or not.
						// But for now, we have to crawl the parent folder
						// no matter what.

						//if (lowerpath.Find(L"\\lock") > 0)
						//	continue;
						// only go back to wc root if we are in .git-dir
						do
						{
							workingPath = workingPath.GetContainingDirectory();
						} while(workingPath.IsAdminDir());
					}
					else if (!workingPath.Exists())
					{
						CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
						CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
						continue;
					}

					if (!CGitStatusCache::Instance().IsPathGood(workingPath))
					{
						AutoLocker lock(m_critSec);
						// move the path, the root of the repository, to the end of the list
						if (projectroot.IsEmpty())
							m_pathsToUpdate.Push(workingPath);
						else
							m_pathsToUpdate.Push(CTGitPath(projectroot));
						if (m_pathsToUpdate.size() < 3)
							Sleep(50);
						continue;
					}

					CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Invalidating and refreshing folder: %s\n", workingPath.GetWinPath());
					{
						AutoLocker print(critSec);
						_sntprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _TRUNCATE, L"Invalidating and refreshing folder: %s", workingPath.GetWinPath());
						++nCurrentCrawledpathIndex;
						if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS)
							nCurrentCrawledpathIndex = 0;
					}
					InvalidateRect(hWndHidden, nullptr, FALSE);
					{
						CAutoReadLock readLock(CGitStatusCache::Instance().GetGuard());
						// Invalidate the cache of this folder, to make sure its status is fetched again.
						CCachedDirectory * pCachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath);
						if (pCachedDir)
						{
							git_wc_status_kind status = pCachedDir->GetCurrentFullStatus();
							pCachedDir->Invalidate();
							if (workingPath.Exists())
							{
								pCachedDir->RefreshStatus(bRecursive);
								// if the previous status wasn't normal and now it is, then
								// send a notification too.
								// We do this here because GetCurrentFullStatus() doesn't send
								// notifications for 'normal' status - if it would, we'd get tons
								// of notifications when crawling a working copy not yet in the cache.
								if ((status != git_wc_status_normal) && (pCachedDir->GetCurrentFullStatus() != status))
								{
									CGitStatusCache::Instance().UpdateShell(workingPath);
									CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": shell update in crawler for %s\n", workingPath.GetWinPath());
								}
							}
							else
							{
								CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
								CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
							}
						}
					}
					//In case that svn_client_stat() modified a file and we got
					//a notification about that in the directory watcher,
					//remove that here again - this is to prevent an endless loop
					AutoLocker lock(m_critSec);
					m_pathsToUpdate.erase(workingPath);
				}
				else if (workingPath.HasAdminDir())
				{
					if (!workingPath.Exists())
					{
						CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
						CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
						if (!workingPath.GetContainingDirectory().Exists())
							continue;
						else
							workingPath = workingPath.GetContainingDirectory();
					}
					CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Updating path: %s\n", workingPath.GetWinPath());
					{
						AutoLocker print(critSec);
						_sntprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _TRUNCATE, L"Updating path: %s", workingPath.GetWinPath());
						++nCurrentCrawledpathIndex;
						if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS)
							nCurrentCrawledpathIndex = 0;
					}
					InvalidateRect(hWndHidden, nullptr, FALSE);
					{
						CAutoReadLock readLock(CGitStatusCache::Instance().GetGuard());
						// Invalidate the cache of folders manually. The cache of files is invalidated
						// automatically if the status is asked for it and the file times don't match
						// anymore, so we don't need to manually invalidate those.
						CCachedDirectory* cachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath.GetDirectory());
						if (cachedDir && workingPath.IsDirectory())
							cachedDir->Invalidate();
						if (cachedDir && cachedDir->GetStatusForMember(workingPath, bRecursive).GetEffectiveStatus() > git_wc_status_unversioned)
							CGitStatusCache::Instance().UpdateShell(workingPath);
					}
					AutoLocker lock(m_critSec);
					m_pathsToUpdate.erase(workingPath);
				}
				else
				{
					if (!workingPath.Exists())
					{
						CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
						CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
					}
				}
			}
			if (!m_foldersToUpdate.empty())
			{
				{
					AutoLocker lock(m_critSec);
					m_bItemsAddedSinceLastCrawl = false;

					// create a new CTGitPath object to make sure the cached flags are requested again.
					// without this, a missing file/folder is still treated as missing even if it is available
					// now when crawling.
					workingPath = CTGitPath(m_foldersToUpdate.Pop().GetWinPath());

					if ((!m_blockedPath.IsEmpty())&&(m_blockedPath.IsAncestorOf(workingPath)))
					{
						// move the path to the end of the list
						m_foldersToUpdate.Push(workingPath);
						if (m_foldersToUpdate.size() < 3)
							Sleep(50);
						continue;
					}
				}
				if ((!m_blockedPath.IsEmpty())&&(m_blockedPath.IsAncestorOf(workingPath)))
					continue;
				if (!CGitStatusCache::Instance().IsPathAllowed(workingPath))
					continue;
				if (!CGitStatusCache::Instance().IsPathGood(workingPath))
					continue;

				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Crawling folder: %s\n", workingPath.GetWinPath());
				{
					AutoLocker print(critSec);
					_sntprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _TRUNCATE, L"Crawling folder: %s", workingPath.GetWinPath());
					++nCurrentCrawledpathIndex;
					if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS)
						nCurrentCrawledpathIndex = 0;
				}
				InvalidateRect(hWndHidden, nullptr, FALSE);
				{
					CAutoReadLock readLock(CGitStatusCache::Instance().GetGuard());
					// Now, we need to visit this folder, to make sure that we know its 'most important' status
					CCachedDirectory * cachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath.GetDirectory());
					// check if the path is monitored by the watcher. If it isn't, then we have to invalidate the cache
					// for that path and add it to the watcher.
					if (!CGitStatusCache::Instance().IsPathWatched(workingPath))
					{
						if (workingPath.HasAdminDir())
						{
							CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Add watch path %s\n", workingPath.GetWinPath());
							CGitStatusCache::Instance().AddPathToWatch(workingPath);
						}
						if (cachedDir)
							cachedDir->Invalidate();
						else
						{
							CAutoWriteLock writeLock(CGitStatusCache::Instance().GetGuard());
							CGitStatusCache::Instance().RemoveCacheForPath(workingPath);
							// now cacheDir is invalid because it got deleted in the RemoveCacheForPath() call above.
							cachedDir = nullptr;
						}
					}
					if (cachedDir)
						cachedDir->RefreshStatus(bRecursive);
				}

				// While refreshing the status, we could get another crawl request for the same folder.
				// This can happen if the crawled folder has a lower status than one of the child folders
				// (recursively). To avoid double crawlings, remove such a crawl request here
				AutoLocker lock(m_critSec);
				if (m_bItemsAddedSinceLastCrawl)
				{
					m_foldersToUpdate.erase(workingPath);
				}
			}
		}
	}
	_endthread();
}
Ejemplo n.º 16
0
void CTortoiseProcApp::CheckUpgrade()
{
	CRegString regVersion = CRegString(_T("Software\\TortoiseGit\\CurrentVersion"));
	CString sVersion = regVersion;
	if (sVersion.Compare(_T(STRPRODUCTVER))==0)
		return;
	// we're starting the first time with a new version!

	LONG lVersion = 0;
	int pos = sVersion.Find(',');
	if (pos > 0)
	{
		lVersion = (_ttol(sVersion.Left(pos))<<24);
		lVersion |= (_ttol(sVersion.Mid(pos+1))<<16);
		pos = sVersion.Find(',', pos+1);
		lVersion |= (_ttol(sVersion.Mid(pos+1))<<8);
	}

	CRegDWORD regval = CRegDWORD(_T("Software\\TortoiseGit\\DontConvertBase"), 999);
	if ((DWORD)regval != 999)
	{
		// there's a leftover registry setting we have to convert and then delete it
		CRegDWORD newregval = CRegDWORD(_T("Software\\TortoiseGit\\ConvertBase"));
		newregval = !regval;
		regval.removeValue();
	}
#if 0
	if (lVersion <= 0x01010300)
	{
		CSoundUtils::RegisterTSVNSounds();
		// remove all saved dialog positions
		CRegString(_T("Software\\TortoiseGit\\TortoiseProc\\ResizableState\\")).removeKey();
		CRegDWORD(_T("Software\\TortoiseGit\\RecursiveOverlay")).removeValue();
		// remove the external cache key
		CRegDWORD(_T("Software\\TortoiseGit\\ExternalCache")).removeValue();
	}
#endif
	if (lVersion <= 0x01020200)
	{
		// upgrade to > 1.2.3 means the doc diff scripts changed from vbs to js
		// so remove the diff/merge scripts if they're the defaults
		CRegString diffreg = CRegString(_T("Software\\TortoiseGit\\DiffTools\\.doc"));
		CString sDiff = diffreg;
		CString sCL = _T("wscript.exe \"") + CPathUtils::GetAppParentDirectory()+_T("Diff-Scripts\\diff-doc.vbs\"");
		if (sDiff.Left(sCL.GetLength()).CompareNoCase(sCL)==0)
			diffreg = _T("");
		CRegString mergereg = CRegString(_T("Software\\TortoiseGit\\MergeTools\\.doc"));
		sDiff = mergereg;
		sCL = _T("wscript.exe \"") + CPathUtils::GetAppParentDirectory()+_T("Diff-Scripts\\merge-doc.vbs\"");
		if (sDiff.Left(sCL.GetLength()).CompareNoCase(sCL)==0)
			mergereg = _T("");
	}
	if (lVersion <= 0x01040000)
	{
		CRegStdDWORD(_T("Software\\TortoiseGit\\OwnerdrawnMenus")).removeValue();
	}

	// set the custom diff scripts for every user
	CString scriptsdir = CPathUtils::GetAppParentDirectory();
	scriptsdir += _T("Diff-Scripts");
	CSimpleFileFind files(scriptsdir);
	while (files.FindNextFileNoDirectories())
	{
		CString file = files.GetFilePath();
		CString filename = files.GetFileName();
		CString ext = file.Mid(file.ReverseFind('-')+1);
		ext = _T(".")+ext.Left(ext.ReverseFind('.'));
		CString kind;
		if (file.Right(3).CompareNoCase(_T("vbs"))==0)
		{
			kind = _T(" //E:vbscript");
		}
		if (file.Right(2).CompareNoCase(_T("js"))==0)
		{
			kind = _T(" //E:javascript");
		}

		if (filename.Left(5).CompareNoCase(_T("diff-"))==0)
		{
			CRegString diffreg = CRegString(_T("Software\\TortoiseGit\\DiffTools\\")+ext);
			CString diffregstring = diffreg;
			if ((diffregstring.IsEmpty()) || (diffregstring.Find(filename)>=0))
				diffreg = _T("wscript.exe \"") + file + _T("\" %base %mine") + kind;
		}
		if (filename.Left(6).CompareNoCase(_T("merge-"))==0)
		{
			CRegString diffreg = CRegString(_T("Software\\TortoiseGit\\MergeTools\\")+ext);
			CString diffregstring = diffreg;
			if ((diffregstring.IsEmpty()) || (diffregstring.Find(filename)>=0))
				diffreg = _T("wscript.exe \"") + file + _T("\" %merged %theirs %mine %base") + kind;
		}
	}

	// Initialize "Software\\TortoiseGit\\DiffProps" once with the same value as "Software\\TortoiseGit\\Diff"
	CRegString regDiffPropsPath = CRegString(_T("Software\\TortoiseGit\\DiffProps"),_T("non-existant"));
	CString strDiffPropsPath = regDiffPropsPath;
	if ( strDiffPropsPath==_T("non-existant") )
	{
		CString strDiffPath = CRegString(_T("Software\\TortoiseGit\\Diff"));
		regDiffPropsPath = strDiffPath;
	}

	// set the current version so we don't come here again until the next update!
	regVersion = _T(STRPRODUCTVER);
}
Ejemplo n.º 17
0
void CGitStatusCache::Create()
{
	ATLASSERT(m_pInstance == NULL);
	m_pInstance = new CGitStatusCache;

	m_pInstance->watcher.SetFolderCrawler(&m_pInstance->m_folderCrawler);

	if (!CRegStdDWORD(_T("Software\\TortoiseGit\\CacheSave"), TRUE))
		return;

#define LOADVALUEFROMFILE(x) if (fread(&x, sizeof(x), 1, pFile)!=1) goto exit;
#define LOADVALUEFROMFILE2(x) if (fread(&x, sizeof(x), 1, pFile)!=1) goto error;
	unsigned int value = (unsigned int)-1;
	FILE * pFile = NULL;
	// find the location of the cache
	CString path = CPathUtils::GetLocalAppDataDirectory();
	CString path2;
	if (!path.IsEmpty())
	{
		path += STATUSCACHEFILENAME;
		// in case the cache file is corrupt, we could crash while
		// reading it! To prevent crashing every time once that happens,
		// we make a copy of the cache file and use that copy to read from.
		// if that copy is corrupt, the original file won't exist anymore
		// and the second time we start up and try to read the file,
		// it's not there anymore and we start from scratch without a crash.
		path2 = path;
		path2 += _T("2");
		DeleteFile(path2);
		CopyFile(path, path2, FALSE);
		DeleteFile(path);
		pFile = _tfsopen(path2, _T("rb"), _SH_DENYNO);
		if (pFile)
		{
			try
			{
				LOADVALUEFROMFILE(value);
				if (value != CACHEDISKVERSION)
				{
					goto error;
				}
				int mapsize = 0;
				LOADVALUEFROMFILE(mapsize);
				for (int i=0; i<mapsize; ++i)
				{
					LOADVALUEFROMFILE2(value);
					if (value > MAX_PATH)
						goto error;
					if (value)
					{
						CString sKey;
						if (fread(sKey.GetBuffer(value+1), sizeof(TCHAR), value, pFile)!=value)
						{
							sKey.ReleaseBuffer(0);
							goto error;
						}
						sKey.ReleaseBuffer(value);
						std::unique_ptr<CCachedDirectory> cacheddir (new CCachedDirectory());
						if (!cacheddir.get() || !cacheddir->LoadFromDisk(pFile))
						{
							cacheddir.reset();
							goto error;
						}
						CTGitPath KeyPath = CTGitPath(sKey);
						if (m_pInstance->IsPathAllowed(KeyPath))
						{
							// only add the path to the watch list if it is versioned
							if ((cacheddir->GetCurrentFullStatus() != git_wc_status_unversioned)&&(cacheddir->GetCurrentFullStatus() != git_wc_status_none))
								m_pInstance->watcher.AddPath(KeyPath, false);

							m_pInstance->m_directoryCache[KeyPath] = cacheddir.release();

							// do *not* add the paths for crawling!
							// because crawled paths will trigger a shell
							// notification, which makes the desktop flash constantly
							// until the whole first time crawling is over
							// m_pInstance->AddFolderForCrawling(KeyPath);
						}
					}
				}
			}
			catch (CAtlException)
			{
				goto error;
			}
		}
	}
exit:
	if (pFile)
		fclose(pFile);
	DeleteFile(path2);
	m_pInstance->watcher.ClearInfoMap();
	CTraceToOutputDebugString::Instance()(__FUNCTION__ ": cache loaded from disk successfully!\n");
	return;
error:
	if (pFile)
		fclose(pFile);
	DeleteFile(path2);
	m_pInstance->watcher.ClearInfoMap();
	Destroy();
	m_pInstance = new CGitStatusCache;
	CTraceToOutputDebugString::Instance()(__FUNCTION__ ": cache not loaded from disk\n");
}
Ejemplo n.º 18
0
void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect, CMenu *popmenu)
{
	POSITION pos = GetFirstSelectedItemPosition();
	int indexNext = GetNextSelectedItem(pos);
	if (indexNext < 0)
		return;

	GitRevLoglist* pSelLogEntry = reinterpret_cast<GitRevLoglist*>(m_arShownList.GetAt(indexNext));

	theApp.DoWaitCursor(1);
	switch (cmd&0xFFFF)
		{
			case ID_COMMIT:
			{
				CTGitPathList pathlist;
				CTGitPathList selectedlist;
				pathlist.AddPath(this->m_Path);
				bool bSelectFilesForCommit = !!DWORD(CRegStdDWORD(_T("Software\\TortoiseGit\\SelectFilesForCommit"), TRUE));
				CString str;
				CAppUtils::Commit(CString(),false,str,
								  pathlist,selectedlist,bSelectFilesForCommit);
				//this->Refresh();
				this->GetParent()->PostMessage(WM_COMMAND,ID_LOGDLG_REFRESH,0);
			}
			break;
			case ID_MERGE_ABORT:
			{
				if (CAppUtils::MergeAbort())
					this->GetParent()->PostMessage(WM_COMMAND,ID_LOGDLG_REFRESH, 0);
			}
			break;
			case ID_GNUDIFF1: // compare with WC, unified
			{
				GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));
				bool bMerge = false, bCombine = false;
				CString hash2;
				if(!r1->m_CommitHash.IsEmpty())
				{
					CString merge;
					cmd >>= 16;
					if( (cmd&0xFFFF) == 0xFFFF)
						bMerge = true;
					else if((cmd&0xFFFF) == 0xFFFE)
						bCombine = true;
					else if ((cmd & 0xFFFF) == 0xFFFD)
					{
						CString tempfile = GetTempFile();
						CString cmd = _T("git.exe diff-tree --cc ") + r1->m_CommitHash.ToString();
						CString lastErr;
						if (g_Git.RunLogFile(cmd, tempfile, &lastErr))
						{
							MessageBox(lastErr, _T("TortoiseGit"), MB_ICONERROR);
							break;
						}

						try
						{
							CStdioFile file(tempfile, CFile::typeText | CFile::modeRead | CFile::shareDenyWrite);
							CString strLine;
							bool isHash = file.ReadString(strLine) && r1->m_CommitHash.ToString() == strLine;
							bool more = isHash && file.ReadString(strLine) && !strLine.IsEmpty();
							if (!more)
							{
								CMessageBox::Show(nullptr, IDS_NOCHANGEAFTERMERGE, IDS_APPNAME, MB_OK);
								break;
							}
						}
						catch (CFileException* e)
						{
							e->Delete();
						}

						CAppUtils::StartUnifiedDiffViewer(tempfile, _T("dd"));
						break;
					}
					else
					{
						if(cmd > r1->m_ParentHash.size())
						{
							CString str;
							str.Format(IDS_PROC_NOPARENT, cmd);
							MessageBox(str, _T("TortoiseGit"), MB_OK | MB_ICONERROR);
							return;
						}
						else
						{
							if(cmd>0)
								hash2 = r1->m_ParentHash[cmd-1].ToString();
						}
					}
					CAppUtils::StartShowUnifiedDiff(nullptr, CTGitPath(), hash2, CTGitPath(), r1->m_CommitHash.ToString(), false, false, false, bMerge, bCombine);
				}
				else
					CAppUtils::StartShowUnifiedDiff(nullptr, CTGitPath(), _T("HEAD"), CTGitPath(), GitRev::GetWorkingCopy(), false, false, false, bMerge, bCombine);
			}
Ejemplo n.º 19
0
void CTortoiseProcApp::CheckUpgrade()
{
	CRegString regVersion = CRegString(_T("Software\\TortoiseGit\\CurrentVersion"));
	CString sVersion = regVersion;
	if (sVersion.Compare(_T(STRPRODUCTVER))==0)
		return;
	// we're starting the first time with a new version!

	LONG lVersion = 0;
	int pos = sVersion.Find('.');
	if (pos > 0)
	{
		lVersion = (_ttol(sVersion.Left(pos))<<24);
		lVersion |= (_ttol(sVersion.Mid(pos+1))<<16);
		pos = sVersion.Find('.', pos+1);
		lVersion |= (_ttol(sVersion.Mid(pos+1))<<8);
	}
	else
	{
		pos = sVersion.Find(',');
		if (pos > 0)
		{
			lVersion = (_ttol(sVersion.Left(pos))<<24);
			lVersion |= (_ttol(sVersion.Mid(pos+1))<<16);
			pos = sVersion.Find(',', pos+1);
			lVersion |= (_ttol(sVersion.Mid(pos+1))<<8);
		}
	}

	if (lVersion <= 0x01080202)
	{
		CSoundUtils::RegisterTGitSounds();
		// upgrade to 1.8.3: force recreation of all diff scripts.
		CAppUtils::SetupDiffScripts(true, CString());
	}

	if (lVersion <= 0x01080100)
	{
		if (CRegStdDWORD(_T("Software\\TortoiseGit\\LogTopoOrder"), TRUE) == FALSE)
			CRegStdDWORD(_T("Software\\TortoiseGit\\LogOrderBy")) = 0;

		// smoothly migrate broken msysgit path settings
		CString oldmsysGitSetting = CRegString(REG_MSYSGIT_PATH);
		oldmsysGitSetting.TrimRight(_T("\\"));
		CString right = oldmsysGitSetting.Right(4);
		if (oldmsysGitSetting.GetLength() > 4 && oldmsysGitSetting.Right(4) == _T("\\cmd"))
		{
			CString newPath = oldmsysGitSetting.Mid(0, oldmsysGitSetting.GetLength() - 3) + _T("bin");
			if (PathFileExists(newPath + _T("\\git.exe")))
			{
				CRegString(REG_MSYSGIT_PATH) = newPath;
				g_Git.m_bInitialized = FALSE;
				g_Git.CheckMsysGitDir();
			}
		}
	}

	if (lVersion <= 0x01040000)
	{
		CRegStdDWORD(_T("Software\\TortoiseGit\\OwnerdrawnMenus")).removeValue();
	}

	if (lVersion <= 0x01070600)
	{
		CoInitialize(NULL);
		EnsureGitLibrary();
		CoUninitialize();
		CRegStdDWORD(_T("Software\\TortoiseGit\\ConvertBase")).removeValue();
		CRegStdDWORD(_T("Software\\TortoiseGit\\DiffProps")).removeValue();
		if (CRegStdDWORD(_T("Software\\TortoiseGit\\CheckNewer"), TRUE) == FALSE)
			CRegStdDWORD(_T("Software\\TortoiseGit\\VersionCheck")) = FALSE;
	}

	if (lVersion <= 0x01070E00)
	{
		CRegStdDWORD(_T("Software\\TortoiseGit\\CheckNewer")).removeValue();
	}
	CAppUtils::SetupDiffScripts(false, CString());

	// set the current version so we don't come here again until the next update!
	regVersion = _T(STRPRODUCTVER);
}
Ejemplo n.º 20
0
int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE /*hPrevInstance*/,
                       LPTSTR    lpCmdLine,
                       int       /*nCmdShow*/)
{
    SetDllDirectory(L"");
    SetTaskIDPerUUID();
    CRegStdDWORD loc = CRegStdDWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);
    long langId = loc;
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    CLangDll langDLL;
    hResource = langDLL.Init(_T("TortoiseIDiff"), langId);
    if (hResource == NULL)
        hResource = hInstance;

    git_libgit2_init();

    CCmdLineParser parser(lpCmdLine);

    if (parser.HasKey(_T("?")) || parser.HasKey(_T("help")))
    {
        TCHAR buf[1024] = { 0 };
        LoadString(hResource, IDS_COMMANDLINEHELP, buf, _countof(buf));
        MessageBox(NULL, buf, _T("TortoiseIDiff"), MB_ICONINFORMATION);
        langDLL.Close();
        return 0;
    }


    MSG msg;
    hInst = hInstance;

    INITCOMMONCONTROLSEX used = {
        sizeof(INITCOMMONCONTROLSEX),
        ICC_STANDARD_CLASSES | ICC_BAR_CLASSES | ICC_WIN95_CLASSES
    };
    InitCommonControlsEx(&used);

    // load the cursors we need
    curHand = (HCURSOR)LoadImage(hInst, MAKEINTRESOURCE(IDC_PANCUR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);
    curHandDown = (HCURSOR)LoadImage(hInst, MAKEINTRESOURCE(IDC_PANDOWNCUR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);

    std::unique_ptr<CMainWindow> mainWindow(new CMainWindow(hResource));
    mainWindow->SetRegistryPath(_T("Software\\TortoiseGit\\TortoiseIDiffWindowPos"));
    std::wstring leftfile = parser.HasVal(_T("left")) ? parser.GetVal(_T("left")) : _T("");
    std::wstring rightfile = parser.HasVal(_T("right")) ? parser.GetVal(_T("right")) : _T("");
    if ((leftfile.empty()) && (lpCmdLine[0] != 0))
    {
        int nArgs;
        LPWSTR * szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
        if (szArglist)
        {
            if (nArgs == 3)
            {
                // Four parameters:
                // [0]: Program name
                // [1]: left file
                // [2]: right file
                if (PathFileExists(szArglist[1]) && PathFileExists(szArglist[2]))
                {
                    leftfile = szArglist[1];
                    rightfile = szArglist[2];
                }
            }
        }

        // Free memory allocated for CommandLineToArgvW arguments.
        LocalFree(szArglist);
    }
    mainWindow->SetLeft(leftfile.c_str(), parser.HasVal(_T("lefttitle")) ? parser.GetVal(_T("lefttitle")) : _T(""));
    mainWindow->SetRight(rightfile.c_str(), parser.HasVal(_T("righttitle")) ? parser.GetVal(_T("righttitle")) : _T(""));
    if (parser.HasVal(L"base"))
        mainWindow->SetSelectionImage(FileTypeBase, parser.GetVal(L"base"), parser.HasVal(L"basetitle") ? parser.GetVal(L"basetitle") : L"");
    if (parser.HasVal(L"mine"))
        mainWindow->SetSelectionImage(FileTypeMine, parser.GetVal(L"mine"), parser.HasVal(L"minetitle") ? parser.GetVal(L"minetitle") : L"");
    if (parser.HasVal(L"theirs"))
        mainWindow->SetSelectionImage(FileTypeTheirs, parser.GetVal(L"theirs"), parser.HasVal(L"theirstitle") ? parser.GetVal(L"theirstitle") : L"");
    if (parser.HasVal(L"result"))
        mainWindow->SetSelectionResult(parser.GetVal(L"result"));
    mainWindow->resolveMsgWnd = parser.HasVal(L"resolvemsghwnd") ? (HWND)parser.GetLongLongVal(L"resolvemsghwnd") : 0;
    mainWindow->resolveMsgWParam = parser.HasVal(L"resolvemsgwparam") ? (WPARAM)parser.GetLongLongVal(L"resolvemsgwparam") : 0;
    mainWindow->resolveMsgLParam = parser.HasVal(L"resolvemsglparam") ? (LPARAM)parser.GetLongLongVal(L"resolvemsglparam") : 0;
    if (mainWindow->RegisterAndCreateWindow())
    {
        HACCEL hAccelTable = LoadAccelerators(hResource, MAKEINTRESOURCE(IDR_TORTOISEIDIFF));
        if (!parser.HasVal(L"left") && parser.HasVal(L"base") && !parser.HasVal(L"mine") && !parser.HasVal(L"theirs"))
        {
            PostMessage(*mainWindow, WM_COMMAND, ID_FILE_OPEN, 0);
        }
        if (parser.HasKey(_T("overlay")))
        {
            PostMessage(*mainWindow, WM_COMMAND, ID_VIEW_OVERLAPIMAGES, 0);
        }
        if (parser.HasKey(_T("fit")))
        {
            PostMessage(*mainWindow, WM_COMMAND, ID_VIEW_FITIMAGEHEIGHTS, 0);
            PostMessage(*mainWindow, WM_COMMAND, ID_VIEW_FITIMAGEWIDTHS, 0);
        }
        if (parser.HasKey(_T("fitwidth")))
        {
            PostMessage(*mainWindow, WM_COMMAND, ID_VIEW_FITIMAGEWIDTHS, 0);
        }
        if (parser.HasKey(_T("fitheight")))
        {
            PostMessage(*mainWindow, WM_COMMAND, ID_VIEW_FITIMAGEHEIGHTS, 0);
        }
        if (parser.HasKey(_T("showinfo")))
        {
            PostMessage(*mainWindow, WM_COMMAND, ID_VIEW_IMAGEINFO, 0);
        }
        // Main message loop:
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (!TranslateAccelerator(*mainWindow, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        return (int) msg.wParam;
    }
    langDLL.Close();
    DestroyCursor(curHand);
    DestroyCursor(curHandDown);
    CoUninitialize();
    git_libgit2_shutdown();
    return 1;
}
Ejemplo n.º 21
0
BOOL CTortoiseProcApp::InitInstance()
{
	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": InitInstance\n"));
	CheckUpgrade();
	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
	CMFCButton::EnableWindowsTheming();
	CHistoryCombo::m_nGitIconIndex = SYS_IMAGE_LIST().AddIcon((HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_GITCONFIG), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));

	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
	Gdiplus::GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);

	//set the resource dll for the required language
	CRegDWORD loc = CRegDWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);
	long langId = loc;
	{
		CString langStr;
		langStr.Format(_T("%ld"), langId);
		CCrashReport::Instance().AddUserInfoToReport(L"LanguageID", langStr);
	}
	CString langDll;
	CStringA langpath = CStringA(CPathUtils::GetAppParentDirectory());
	langpath += "Languages";
	do
	{
		langDll.Format(_T("%sLanguages\\TortoiseProc%ld.dll"), (LPCTSTR)CPathUtils::GetAppParentDirectory(), langId);

		CString sVer = _T(STRPRODUCTVER);
		CString sFileVer = CPathUtils::GetVersionFromFile(langDll);
		if (sFileVer == sVer)
		{
			HINSTANCE hInst = LoadLibrary(langDll);
			if (hInst != NULL)
			{
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Load Language DLL %s\n"), langDll);
				AfxSetResourceHandle(hInst);
				break;
			}
		}
		{
			DWORD lid = SUBLANGID(langId);
			lid--;
			if (lid > 0)
			{
				langId = MAKELANGID(PRIMARYLANGID(langId), lid);
			}
			else
				langId = 0;
		}
	} while (langId != 0);
	TCHAR buf[6] = { 0 };
	_tcscpy_s(buf, _T("en"));
	langId = loc;
	// MFC uses a help file with the same name as the application by default,
	// which means we have to change that default to our language specific help files
	CString sHelppath = CPathUtils::GetAppDirectory() + _T("TortoiseGit_en.chm");
	free((void*)m_pszHelpFilePath);
	m_pszHelpFilePath=_tcsdup(sHelppath);
	sHelppath = CPathUtils::GetAppParentDirectory() + _T("Languages\\TortoiseGit_en.chm");
	do
	{
		CString sLang = _T("_");
		if (GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO639LANGNAME, buf, _countof(buf)))
		{
			sLang += buf;
			sHelppath.Replace(_T("_en"), sLang);
			if (PathFileExists(sHelppath))
			{
				free((void*)m_pszHelpFilePath);
				m_pszHelpFilePath=_tcsdup(sHelppath);
				break;
			}
		}
		sHelppath.Replace(sLang, _T("_en"));
		if (GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO3166CTRYNAME, buf, _countof(buf)))
		{
			sLang += _T("_");
			sLang += buf;
			sHelppath.Replace(_T("_en"), sLang);
			if (PathFileExists(sHelppath))
			{
				free((void*)m_pszHelpFilePath);
				m_pszHelpFilePath=_tcsdup(sHelppath);
				break;
			}
		}
		sHelppath.Replace(sLang, _T("_en"));

		DWORD lid = SUBLANGID(langId);
		lid--;
		if (lid > 0)
		{
			langId = MAKELANGID(PRIMARYLANGID(langId), lid);
		}
		else
			langId = 0;
	} while (langId);
	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Set Help Filename %s\n"), m_pszHelpFilePath);
	setlocale(LC_ALL, "");

	if (!g_Git.CheckMsysGitDir())
	{
		UINT ret = CMessageBox::Show(NULL, IDS_PROC_NOMSYSGIT, IDS_APPNAME, 3, IDI_HAND, IDS_PROC_SETMSYSGITPATH, IDS_PROC_GOTOMSYSGITWEBSITE, IDS_ABORTBUTTON);
		if(ret == 2)
		{
			ShellExecute(NULL, NULL, _T("http://msysgit.github.io/"), NULL, NULL, SW_SHOW);
		}
		else if(ret == 1)
		{
			// open settings dialog
			CSinglePropSheetDlg(CString(MAKEINTRESOURCE(IDS_PROC_SETTINGS_TITLE)), new CSetMainPage(), this->GetMainWnd()).DoModal();
		}
		return FALSE;
	}
	if (CAppUtils::GetMsysgitVersion() < 0x01070a00)
	{
		int ret = CMessageBox::ShowCheck(NULL, IDS_PROC_OLDMSYSGIT, IDS_APPNAME, 1, IDI_EXCLAMATION, IDS_PROC_GOTOMSYSGITWEBSITE, IDS_ABORTBUTTON, IDS_IGNOREBUTTON, _T("OldMsysgitVersionWarning"), IDS_PROC_NOTSHOWAGAINIGNORE);
		if (ret == 1)
		{
			CMessageBox::RemoveRegistryKey(_T("OldMsysgitVersionWarning")); // only store answer if it is "Ignore"
			ShellExecute(NULL, NULL, _T("http://msysgit.github.io/"), NULL, NULL, SW_SHOW);
			return FALSE;
		}
		else if (ret == 2)
		{
			CMessageBox::RemoveRegistryKey(_T("OldMsysgitVersionWarning")); // only store answer if it is "Ignore"
			return FALSE;
		}
	}

	{
		CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Registering Crash Report ...\n"));
		CCrashReport::Instance().AddUserInfoToReport(L"msysGitDir", CGit::ms_LastMsysGitDir);
		CString versionString;
		versionString.Format(_T("%d"), CGit::ms_LastMsysGitVersion);
		CCrashReport::Instance().AddUserInfoToReport(L"msysGitVersion", versionString);
	}

	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Initializing UI components ...\n"));
	// InitCommonControls() is required on Windows XP if an application
	// manifest specifies use of ComCtl32.dll version 6 or later to enable
	// visual styles.  Otherwise, any window creation will fail.

	INITCOMMONCONTROLSEX used = {
		sizeof(INITCOMMONCONTROLSEX),
			ICC_ANIMATE_CLASS | ICC_BAR_CLASSES | ICC_COOL_CLASSES | ICC_DATE_CLASSES |
			ICC_HOTKEY_CLASS | ICC_INTERNET_CLASSES | ICC_LISTVIEW_CLASSES |
			ICC_NATIVEFNTCTL_CLASS | ICC_PAGESCROLLER_CLASS | ICC_PROGRESS_CLASS |
			ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS |
			ICC_USEREX_CLASSES | ICC_WIN95_CLASSES
	};
	InitCommonControlsEx(&used);
	AfxOleInit();
	AfxEnableControlContainer();
	AfxInitRichEdit5();
	CWinAppEx::InitInstance();
	SetRegistryKey(_T("TortoiseGit"));
	AfxGetApp()->m_pszProfileName = _tcsdup(_T("TortoiseProc")); // w/o this ResizableLib will store data under TortoiseGitProc which is not compatible with older versions

	CCmdLineParser parser(AfxGetApp()->m_lpCmdLine);

	hWndExplorer = NULL;
	CString sVal = parser.GetVal(_T("hwnd"));
	if (!sVal.IsEmpty())
		hWndExplorer = (HWND)_wcstoui64(sVal, nullptr, 16);

	while (GetParent(hWndExplorer)!=NULL)
		hWndExplorer = GetParent(hWndExplorer);
	if (!IsWindow(hWndExplorer))
	{
		hWndExplorer = NULL;
	}

	// if HKCU\Software\TortoiseGit\Debug is not 0, show our command line
	// in a message box
	if (CRegDWORD(_T("Software\\TortoiseGit\\Debug"), FALSE)==TRUE)
		AfxMessageBox(AfxGetApp()->m_lpCmdLine, MB_OK | MB_ICONINFORMATION);

	if (parser.HasKey(_T("urlhandler")))
	{
		CString url = parser.GetVal(_T("urlhandler"));
		if (url.Find(_T("tgit://clone/")) == 0)
		{
			url = url.Mid(13); // 21 = "tgit://clone/".GetLength()
		}
		else if (url.Find(_T("github-windows://openRepo/")) == 0)
		{
			url = url.Mid(26); // 26 = "github-windows://openRepo/".GetLength()
			int questioMark = url.Find('?');
			if (questioMark > 0)
				url = url.Left(questioMark);
		}
		else if (url.Find(_T("smartgit://cloneRepo/")) == 0)
		{
			url = url.Mid(21); // 21 = "smartgit://cloneRepo/".GetLength()
		}
		else
		{
			CMessageBox::Show(NULL, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
			return FALSE;
		}
		CString newCmd;
		newCmd.Format(_T("/command:clone /url:\"%s\" /hasurlhandler"), url);
		parser = CCmdLineParser(newCmd);
	}

	if ( parser.HasKey(_T("path")) && parser.HasKey(_T("pathfile")))
	{
		CMessageBox::Show(NULL, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
		return FALSE;
	}

	CTGitPath cmdLinePath;
	CTGitPathList pathList;
	if (g_sGroupingUUID.IsEmpty())
		g_sGroupingUUID = parser.GetVal(L"groupuuid");
	if ( parser.HasKey(_T("pathfile")) )
	{

		CString sPathfileArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("pathfile")));

		cmdLinePath.SetFromUnknown(sPathfileArgument);
		if (pathList.LoadFromFile(cmdLinePath)==false)
			return FALSE;		// no path specified!
		if ( parser.HasKey(_T("deletepathfile")) )
		{
			// We can delete the temporary path file, now that we've loaded it
			::DeleteFile(cmdLinePath.GetWinPath());
		}
		// This was a path to a temporary file - it's got no meaning now, and
		// anybody who uses it again is in for a problem...
		cmdLinePath.Reset();

	}
	else
	{

		CString sPathArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("path")));
		if (parser.HasKey(_T("expaths")))
		{
			// an /expaths param means we're started via the buttons in our Win7 library
			// and that means the value of /expaths is the current directory, and
			// the selected paths are then added as additional parameters but without a key, only a value

			// because of the "strange treatment of quotation marks and backslashes by CommandLineToArgvW"
			// we have to escape the backslashes first. Since we're only dealing with paths here, that's
			// a save bet.
			// Without this, a command line like:
			// /command:commit /expaths:"D:\" "D:\Utils"
			// would fail because the "D:\" is treated as the backslash being the escape char for the quotation
			// mark and we'd end up with:
			// argv[1] = /command:commit
			// argv[2] = /expaths:D:" D:\Utils
			// See here for more details: http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
			CString cmdLine = GetCommandLineW();
			cmdLine.Replace(L"\\", L"\\\\");
			int nArgs = 0;
			LPWSTR *szArglist = CommandLineToArgvW(cmdLine, &nArgs);
			if (szArglist)
			{
				// argument 0 is the process path, so start with 1
				for (int i = 1; i < nArgs; ++i)
				{
					if (szArglist[i][0] != '/')
					{
						if (!sPathArgument.IsEmpty())
							sPathArgument += '*';
						sPathArgument += szArglist[i];
					}
				}
				sPathArgument.Replace(L"\\\\", L"\\");
			}
			LocalFree(szArglist);
		}
		if (sPathArgument.IsEmpty() && parser.HasKey(L"path"))
		{
			CMessageBox::Show(hWndExplorer, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
			return FALSE;
		}
		int asterisk = sPathArgument.Find('*');
		cmdLinePath.SetFromUnknown(asterisk >= 0 ? sPathArgument.Left(asterisk) : sPathArgument);
		pathList.LoadFromAsteriskSeparatedString(sPathArgument);
	}

	if (pathList.IsEmpty()) {
		pathList.AddPath(CTGitPath::CTGitPath(g_Git.m_CurrentDir));
	}

	// Set CWD to temporary dir, and restore it later
	{
		DWORD len = GetCurrentDirectory(0, NULL);
		if (len)
		{
			std::unique_ptr<TCHAR[]> originalCurrentDirectory(new TCHAR[len]);
			if (GetCurrentDirectory(len, originalCurrentDirectory.get()))
			{
				sOrigCWD = originalCurrentDirectory.get();
				sOrigCWD = CPathUtils::GetLongPathname(sOrigCWD);
			}
		}
		TCHAR pathbuf[MAX_PATH] = {0};
		GetTortoiseGitTempPath(MAX_PATH, pathbuf);
		SetCurrentDirectory(pathbuf);
	}

	CheckForNewerVersion();

	CAutoGeneralHandle TGitMutex = ::CreateMutex(NULL, FALSE, _T("TortoiseGitProc.exe"));
	if (!g_Git.SetCurrentDir(cmdLinePath.GetWinPathString(), parser.HasKey(_T("submodule")) == TRUE))
	{
		for (int i = 0; i < pathList.GetCount(); ++i)
			if(g_Git.SetCurrentDir(pathList[i].GetWinPath()))
				break;
	}

	if(!g_Git.m_CurrentDir.IsEmpty())
	{
		sOrigCWD = g_Git.m_CurrentDir;
		SetCurrentDirectory(g_Git.m_CurrentDir);
	}

	if (g_sGroupingUUID.IsEmpty())
	{
		CRegStdDWORD groupSetting = CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepo"), 3);
		switch (DWORD(groupSetting))
		{
		case 1:
		case 2:
			// implemented differently to TortoiseSVN atm
			break;
		case 3:
		case 4:
			{
				CString wcroot;
				if (g_GitAdminDir.HasAdminDir(g_Git.m_CurrentDir, true, &wcroot))
				{
					git_oid oid;
					CStringA wcRootA(wcroot + CPathUtils::GetAppDirectory());
					if (!git_odb_hash(&oid, wcRootA, wcRootA.GetLength(), GIT_OBJ_BLOB))
					{
						CStringA hash;
						git_oid_tostr(hash.GetBufferSetLength(GIT_OID_HEXSZ + 1), GIT_OID_HEXSZ + 1, &oid);
						hash.ReleaseBuffer();
						g_sGroupingUUID = hash;
					}
					ProjectProperties pp;
					pp.ReadProps();
					CString icon = pp.sIcon;
					icon.Replace('/', '\\');
					if (icon.IsEmpty())
						g_bGroupingRemoveIcon = true;
					g_sGroupingIcon = icon;
				}
			}
		}
	}

	CString sAppID = GetTaskIDPerUUID(g_sGroupingUUID).c_str();
	InitializeJumpList(sAppID);
	EnsureGitLibrary(false);

	{
		CString err;
		try
		{
			// requires CWD to be set
			CGit::m_LogEncode = CAppUtils::GetLogOutputEncode();

			// make sure all config files are read in order to check that none contains an error
			g_Git.GetConfigValue(_T("doesnot.exist"));
		}
		catch (char* msg)
		{
			err = CString(msg);
		}

		if (!err.IsEmpty())
		{
			UINT choice = CMessageBox::Show(hWndExplorer, err, _T("TortoiseGit"), 1, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_PROC_EDITLOCALGITCONFIG)), CString(MAKEINTRESOURCE(IDS_PROC_EDITGLOBALGITCONFIG)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON)));
			if (choice == 1)
			{
				// open the config file with alternative editor
				CAppUtils::LaunchAlternativeEditor(g_Git.GetGitLocalConfig());
			}
			else if (choice == 2)
			{
				// open the global config file with alternative editor
				CAppUtils::LaunchAlternativeEditor(g_Git.GetGitGlobalConfig());
			}
			return FALSE;
		}
	}

	// execute the requested command
	CommandServer server;
	Command * cmd = server.GetCommand(parser.GetVal(_T("command")));
	if (cmd)
	{
		cmd->SetExplorerHwnd(hWndExplorer);

		cmd->SetParser(parser);
		cmd->SetPaths(pathList, cmdLinePath);

		retSuccess = cmd->Execute();
		delete cmd;
	}

	// Look for temporary files left around by TortoiseSVN and
	// remove them. But only delete 'old' files because some
	// apps might still be needing the recent ones.
	{
		DWORD len = GetTortoiseGitTempPath(0, NULL);
		std::unique_ptr<TCHAR[]> path(new TCHAR[len + 100]);
		len = GetTortoiseGitTempPath (len + 100, path.get());
		if (len != 0)
		{
			CDirFileEnum finder(path.get());
			FILETIME systime_;
			::GetSystemTimeAsFileTime(&systime_);
			__int64 systime = (((_int64)systime_.dwHighDateTime)<<32) | ((__int64)systime_.dwLowDateTime);
			bool isDir;
			CString filepath;
			while (finder.NextFile(filepath, &isDir))
			{
				HANDLE hFile = ::CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, isDir ? FILE_FLAG_BACKUP_SEMANTICS : NULL, NULL);
				if (hFile != INVALID_HANDLE_VALUE)
				{
					FILETIME createtime_;
					if (::GetFileTime(hFile, &createtime_, NULL, NULL))
					{
						::CloseHandle(hFile);
						__int64 createtime = (((_int64)createtime_.dwHighDateTime)<<32) | ((__int64)createtime_.dwLowDateTime);
						if ((createtime + 864000000000) < systime)		//only delete files older than a day
						{
							::SetFileAttributes(filepath, FILE_ATTRIBUTE_NORMAL);
							if (isDir)
								::RemoveDirectory(filepath);
							else
								::DeleteFile(filepath);
						}
					}
					else
						::CloseHandle(hFile);
				}
			}
		}
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	// application, rather than start the application's message pump.
	return FALSE;
}
Ejemplo n.º 22
0
ShellCache::ShellCache()
{
    cachetype = CRegStdDWORD(L"Software\\TortoiseSVN\\CacheType", GetSystemMetrics(SM_REMOTESESSION) ? dll : exe);
    showrecursive = CRegStdDWORD(L"Software\\TortoiseSVN\\RecursiveOverlay", TRUE);
    folderoverlay = CRegStdDWORD(L"Software\\TortoiseSVN\\FolderOverlay", TRUE);
    driveremote = CRegStdDWORD(L"Software\\TortoiseSVN\\DriveMaskRemote");
    drivefixed = CRegStdDWORD(L"Software\\TortoiseSVN\\DriveMaskFixed", TRUE);
    drivecdrom = CRegStdDWORD(L"Software\\TortoiseSVN\\DriveMaskCDROM");
    driveremove = CRegStdDWORD(L"Software\\TortoiseSVN\\DriveMaskRemovable");
    drivefloppy = CRegStdDWORD(L"Software\\TortoiseSVN\\DriveMaskFloppy");
    driveram = CRegStdDWORD(L"Software\\TortoiseSVN\\DriveMaskRAM");
    driveunknown = CRegStdDWORD(L"Software\\TortoiseSVN\\DriveMaskUnknown");
    shellmenuaccelerators = CRegStdDWORD(L"Software\\TortoiseSVN\\ShellMenuAccelerators", TRUE);
    unversionedasmodified = CRegStdDWORD(L"Software\\TortoiseSVN\\UnversionedAsModified", FALSE);
    ignoreoncommitignored = CRegStdDWORD(L"Software\\TortoiseSVN\\IgnoreOnCommitIgnored", TRUE);
    hidemenusforunversioneditems = CRegStdDWORD(L"Software\\TortoiseSVN\\HideMenusForUnversionedItems", FALSE);
    getlocktop = CRegStdDWORD(L"Software\\TortoiseSVN\\GetLockTop", TRUE);
    excludedasnormal = CRegStdDWORD(L"Software\\TortoiseSVN\\ShowExcludedFoldersAsNormal", FALSE);
    alwaysextended = CRegStdDWORD(L"Software\\TortoiseSVN\\AlwaysExtendedMenu", FALSE);
    cachetypeticker = GetTickCount64();
    recursiveticker = cachetypeticker;
    folderoverlayticker = cachetypeticker;
    driveticker = cachetypeticker;
    drivetypeticker = 0;
    langticker = cachetypeticker;
    columnrevformatticker = cachetypeticker;
    pathfilterticker = 0;
    shellmenuacceleratorsticker = cachetypeticker;
    unversionedasmodifiedticker = cachetypeticker;
    ignoreoncommitignoredticker = cachetypeticker;
    columnseverywhereticker = cachetypeticker;
    getlocktopticker = cachetypeticker;
    excludedasnormalticker = cachetypeticker;
    alwaysextendedticker = cachetypeticker;
    hidemenusforunversioneditemsticker = cachetypeticker;
    layoutticker = cachetypeticker;
    menumaskticker = cachetypeticker;
    blockstatusticker = cachetypeticker;
    excontextticker = 0;
    menulayoutlow = CRegStdDWORD(L"Software\\TortoiseSVN\\ContextMenuEntries", MENUCHECKOUT | MENUUPDATE | MENUCOMMIT);
    menulayouthigh = CRegStdDWORD(L"Software\\TortoiseSVN\\ContextMenuEntrieshigh", 0);
    menumasklow_lm = CRegStdDWORD(L"Software\\TortoiseSVN\\ContextMenuEntriesMaskLow", 0, FALSE, HKEY_LOCAL_MACHINE);
    menumaskhigh_lm = CRegStdDWORD(L"Software\\TortoiseSVN\\ContextMenuEntriesMaskHigh", 0, FALSE, HKEY_LOCAL_MACHINE);
    menumasklow_cu = CRegStdDWORD(L"Software\\TortoiseSVN\\ContextMenuEntriesMaskLow", 0);
    menumaskhigh_cu = CRegStdDWORD(L"Software\\TortoiseSVN\\ContextMenuEntriesMaskHigh", 0);
    langid = CRegStdDWORD(L"Software\\TortoiseSVN\\LanguageID", 1033);
    blockstatus = CRegStdDWORD(L"Software\\TortoiseSVN\\BlockStatus", 0);
    columnseverywhere = CRegStdDWORD(L"Software\\TortoiseSVN\\ColumnsEveryWhere", FALSE);
    std::fill_n(drivetypecache, 27, (UINT)-1);
    if (DWORD(drivefloppy) == 0)
    {
        // A: and B: are floppy disks
        drivetypecache[0] = DRIVE_REMOVABLE;
        drivetypecache[1] = DRIVE_REMOVABLE;
    }
    TCHAR szBuffer[5] = { 0 };
    columnrevformatticker = GetTickCount64();
    SecureZeroMemory(&columnrevformat, sizeof(NUMBERFMT));
    GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &szDecSep[0], _countof(szDecSep));
    GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, &szThousandsSep[0], _countof(szThousandsSep));
    columnrevformat.lpDecimalSep = szDecSep;
    columnrevformat.lpThousandSep = szThousandsSep;
    GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, &szBuffer[0], _countof(szBuffer));
    columnrevformat.Grouping = _wtoi(szBuffer);
    GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER, &szBuffer[0], _countof(szBuffer));
    columnrevformat.NegativeOrder = _wtoi(szBuffer);
    nocontextpaths = CRegStdString(L"Software\\TortoiseSVN\\NoContextPaths", L"");
    drivetypepathcache[0] = 0;
    m_critSec.Init();
}