Beispiel #1
0
void web_page::set_base_url( const litehtml::tchar_t* base_url )
{
#ifndef LITEHTML_UTF8
	if(base_url)
	{
		if(PathIsRelative(base_url) && !PathIsURL(base_url))
		{
			make_url(base_url, m_url.c_str(), m_base_path);
		} else
		{
			m_base_path = base_url;
		}
	} else
	{
		m_base_path = m_url;
	}
#else
	LPWSTR bu = cairo_font::utf8_to_wchar(base_url);

	if(bu)
	{
		if(PathIsRelative(bu) && !PathIsURL(bu))
		{
			make_url(bu, m_url.c_str(), m_base_path);
		} else
		{
			m_base_path = bu;
		}
	} else
	{
		m_base_path = m_url;
	}
#endif
}
Beispiel #2
0
CString CPathUtils::GetLongPathname(const CString& path)
{
	if (path.IsEmpty())
		return path;
	TCHAR pathbufcanonicalized[MAX_PATH]; // MAX_PATH ok.
	DWORD ret = 0;
	CString sRet;
	if (!PathIsURL(path) && PathIsRelative(path))
	{
		ret = GetFullPathName(path, 0, NULL, NULL);
		if (ret)
		{
			std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 1]);
			if ((ret = GetFullPathName(path, ret, pathbuf.get(), NULL)) != 0)
				sRet = CString(pathbuf.get(), ret);
		}
	}
	else if (PathCanonicalize(pathbufcanonicalized, path))
	{
		ret = ::GetLongPathName(pathbufcanonicalized, NULL, 0);
		std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 2]);
		ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret + 1);
		sRet = CString(pathbuf.get(), ret);
	}
	else
	{
		ret = ::GetLongPathName(path, NULL, 0);
		std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 2]);
		ret = ::GetLongPathName(path, pathbuf.get(), ret + 1);
		sRet = CString(pathbuf.get(), ret);
	}
	if (ret == 0)
		return path;
	return sRet;
}
Beispiel #3
0
bstr_t CCommonUtils::CreateRelativeURL(bstr_t baseURL, bstr_t relURL)
{
    WCHAR ret[INTERNET_MAX_URL_LENGTH];
    DWORD dwLen = INTERNET_MAX_URL_LENGTH;
    HRESULT hr = E_FAIL;

    if(PathIsURL(baseURL))
    {
        hr = UrlCombine(baseURL, relURL, ret, &dwLen, 0);
        if(FAILED(hr))
        {
            throw _com_error(hr);
        }
    }
    else
    {
        hr = StringCchCopyW(ret, sizeof(ret)/sizeof(WCHAR), relURL);
        if(FAILED(hr))
        {
            throw _com_error(hr);
        }
    }

    return ret;
}
DWORD FDownloadDispatcher::LoadDownload(FDownloadInfo& pUrlInfo)
{
    BOOL bLoadVideo = TRUE;

    FString StoreFolder = g_AppSettings.GetLastSelectedFolder();
    BOOL bCtrl  = ( GetKeyState(VK_CONTROL) & 0x8000) != 0;
    BOOL bShift = ( GetKeyState(VK_SHIFT) & 0x8000) != 0;

    FIniConfig aConf;
    FString StrDownloadType;
    if (GetFileSize(pUrlInfo.m_DownloadFile) < 8192 &&
            aConf.Load(pUrlInfo.m_DownloadFile))
    {
        if (aConf.SectionExists("Subscribe")) //Subscribe to FEED
        {
            FString FeedUrl = aConf.GetValue("Subscribe", "FeedURL");
            FString FeedName = aConf.GetValue("Subscribe", "FeedName");
            if (PathIsURL(FeedUrl))
            {
                g_MainFrame->m_Container->SwitchActiveView(VIEW_FEEDS);
                g_MainFrame->AddFeedDialog(FeedUrl, FeedName);
                g_MainFrame->m_Container->SwitchActiveView(VIEW_FEEDS);
                return 1;
            }

        }
        else
            StrDownloadType = aConf.GetValue("Clip 0", "DownloadType");
    }

    if (StoreFolder.GetLength() == 0 || !PathIsDirectory(StoreFolder) || bCtrl || bShift)
    {
        if (StrDownloadType != "stream")
        {
            FDlgSaveVideo aSaveVideo;
            FDlgSaveVideo::SaveDlgOpenParams Params(&g_AppSettings);

            int nRes = aSaveVideo.Open(g_MainFrame, Params);
            if (nRes  == IDOK)
            {
                StoreFolder = aSaveVideo.m_StrStorage;
                g_AppSettings.SaveSettings();
            }
            else
                bLoadVideo = FALSE;
        }
        else
            StoreFolder = g_AppSettings.m_IndexPath;
    }
    vidtype videoID = 0;
    if (bLoadVideo)
    {
        videoID = g_Objects._DownloadManager.ConvertAndLoad(&pUrlInfo, StoreFolder);
        if (g_MainFrame.IsObjectAndWindow())
            g_MainFrame->PostMessage(WM_DOWNLOAD_LOADED, (WPARAM)videoID, 0);
    }

    return videoID;
}
Beispiel #5
0
void web_page::load( LPCWSTR url )
{
	m_url		= url;
	m_base_path	= m_url;
	if(PathIsURL(url))
	{
		m_http.download_file( url, new web_file(this, web_file_document) );
	} else
	{
		on_document_loaded(url, L"UTF-8", NULL);
	}
}
Beispiel #6
0
CString CStringUtils::WordWrap(const CString& longstring, int limit /* = 80 */, bool bCompactPaths /* = true */)
{
	CString retString;
	if (longstring.GetLength() < limit)
		return longstring;	// no wrapping needed.
	CString temp = longstring;
	while (temp.GetLength() > limit)
	{
		int pos=0;
		int oldpos=0;
		while ((pos>=0)&&(temp.Find(' ', pos)<limit)&&(temp.Find(' ', pos)>0))
		{
			oldpos = pos;
			pos = temp.Find(' ', pos+1);
		}
		if (oldpos==0)
			oldpos = temp.Find(' ');
		if (pos<0)
		{
			retString += temp;
			temp.Empty();
		}
		else
		{
			CString longline = oldpos >= 0 ? temp.Left(oldpos+1) : temp;
			if ((bCompactPaths)&&(longline.GetLength() < MAX_PATH))
			{
				if (((!PathIsFileSpec(longline))&&longline.Find(':')<3)||(PathIsURL(longline)))
				{
					TCHAR buf[MAX_PATH];
					PathCompactPathEx(buf, longline, limit+1, 0);
					longline = buf;
				}				
			}

			retString += longline;
			if (oldpos >= 0)
				temp = temp.Mid(oldpos+1);
			else
				temp.Empty();
		}
		retString += _T("\n");
		pos = oldpos;
	}
	retString += temp;
	retString.Trim();
	return retString;
}
bool RenameCommand::Execute()
{
	bool bRet = true;
	CString filename = cmdLinePath.GetFileOrDirectoryName();
	CString basePath = cmdLinePath.GetContainingDirectory().GetGitPathString();

	// show the rename dialog until the user either cancels or enters a new
	// name (one that's different to the original name
	CString sNewName;
	do
	{
		CRenameDlg dlg;
		dlg.m_name = filename;
		if (dlg.DoModal() != IDOK)
			return FALSE;
		sNewName = dlg.m_name;
	} while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));

	if(!basePath.IsEmpty())
		sNewName=basePath+"/"+sNewName;

	CString force;
	// if the filenames only differ in case, we have to pass "-f"
	if (sNewName.CompareNoCase(cmdLinePath.GetGitPathString()) == 0)
		force = _T("-f ");

	CString cmd;
	CString output;
	cmd.Format(_T("git.exe mv %s-- \"%s\" \"%s\""),
					force,
					cmdLinePath.GetGitPathString(),
					sNewName);

	if (g_Git.Run(cmd, &output, CP_UTF8))
	{
		CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK);
		bRet = false;
	}

	CTGitPath newpath;
	newpath.SetFromGit(sNewName);

	CShellUpdater::Instance().AddPathForUpdate(newpath);
	CShellUpdater::Instance().Flush();
	return bRet;
}
Beispiel #8
0
BOOL FSubManager::DownloadSubtitle(SubDownInfo* pInfo) 
{
    FString FStrUrl; 
    FStrUrl.Format("%s?videoID=%u&lang=%s", pInfo->SubURL, pInfo->videoID, pInfo->SubLang); 
	
	if (!PathIsURL(FStrUrl))
	{
		return FALSE; 
	}

	FDownloadInfo* pUrlInfo = new FDownloadInfo; 

	pUrlInfo->m_DownloadUrl = FStrUrl; 
	pUrlInfo->m_DownloadFile = pInfo->SubPath; 
	pUrlInfo->m_ContentType = "text/html, text/plain";
	pUrlInfo->m_pv = (void*)pInfo; 

    return g_Objects._HttpDownloader->DownloadURL(pUrlInfo, &m_DownloadNotify);
}
DHANDLE FAsyncDownload::DownloadURL(FDownloadInfo* pInfo,  IClipDownloadNotify* pvObj)
{
	if (!pInfo)
		return 0; 

	if (!PathIsURL(pInfo->m_DownloadUrl))
	{
		_DBGAlert("**FAsyncDownload: Path is not a URL: %s\n", pInfo->m_DownloadUrl); 
		return 0; 
	}

	DHANDLE hHandle = (DWORD)InterlockedIncrement((LONG*)&m_HandleID);

	FAsyncDownData* pData = new FAsyncDownData; 
	pData->m_pUrlInfo = pInfo; 
	pData->m_pNotify = pvObj; 
	pData->m_pUrlInfo->m_Handle = hHandle; 
	AddDownload(pData);
    return hHandle; 
}
Beispiel #10
0
char *
DCirfile::PathRight(void)
{
	if (SecFound)
		return SecFile->PathRight();
	if (CurrRight == NULL)
		return NULL;

	char *chp = strncpy(NewName(RightLen + 1), CurrRight, RightLen);
	chp[RightLen] = '\0';

	char *currdir = _getcwd(NewName(1024), 1024);
	char *inidir = this->getBasePath();
	int currdrive = _getdrive();
	int inidrive = 0;

	if (stricmp(currdir, inidir)
	 && !PathIsURL(chp)
	 && PathIsRelative(chp)) { // fix rel path
		if (*(inidir + 1) == ':')
			inidrive = (toupper(*inidir) - 'A') + 1;
		if (inidrive
		 && (currdrive != inidrive))
			_chdrive(inidrive);
		_chdir(inidir);
		char *nref = NewName(MAX_PATH);
		if (_fullpath(nref, chp, MAX_PATH)) {
			DeleteName(chp);
			chp = NewName(nref);
		}
		DeleteName(nref);
		if (inidrive
		 && (currdrive != inidrive))
			_chdrive(currdrive);
		_chdir(currdir);
	}
	DeleteName(currdir);

	return chp;
}
CString CPathUtils::GetLongPathname(const CString& path)
{
	if (path.IsEmpty())
		return path;
	TCHAR pathbufcanonicalized[MAX_PATH] = {0}; // MAX_PATH ok.
	DWORD ret = 0;
	CString sRet;
	if (!PathIsURL(path) && PathIsRelative(path))
	{
		ret = GetFullPathName(path, 0, nullptr, nullptr);
		if (ret)
		{
			auto pathbuf = std::make_unique<TCHAR[]>(ret + 1);
			if ((ret = GetFullPathName(path, ret, pathbuf.get(), nullptr)) != 0)
				sRet = CString(pathbuf.get(), ret);
		}
	}
	else if (PathCanonicalize(pathbufcanonicalized, path))
	{
		ret = ::GetLongPathName(pathbufcanonicalized, nullptr, 0);
		if (ret == 0)
			return path;
		auto pathbuf = std::make_unique<TCHAR[]>(ret + 2);
		ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret + 1);
		sRet = CString(pathbuf.get(), ret);
	}
	else
	{
		ret = ::GetLongPathName(path, nullptr, 0);
		if (ret == 0)
			return path;
		auto pathbuf = std::make_unique<TCHAR[]>(ret + 2);
		ret = ::GetLongPathName(path, pathbuf.get(), ret + 1);
		sRet = CString(pathbuf.get(), ret);
	}
	if (ret == 0)
		return path;
	return sRet;
}
Beispiel #12
0
cairo_container::image_ptr web_page::get_image(LPCWSTR url, bool redraw_on_ready)
{
	cairo_container::image_ptr img;
	if(PathIsURL(url))
	{
		if(redraw_on_ready)
		{
			m_http.download_file( url, new web_file(this, web_file_image_redraw) );
		} else
		{
			m_http.download_file( url, new web_file(this, web_file_image_rerender) );
		}
	} else
	{
		img = cairo_container::image_ptr(new CTxDIB);
		if(!img->load(url))
		{
			img = nullptr;
		}
	}
	return img;
}
Beispiel #13
0
BOOL web_page::download_and_wait( LPCWSTR url )
{
	if(PathIsURL(url))
	{
		m_waited_file = L"";
		m_hWaitDownload = CreateEvent(NULL, TRUE, FALSE, NULL);
		if(m_http.download_file( url, new web_file(this, web_file_waited) ))
		{
			WaitForSingleObject(m_hWaitDownload, INFINITE);
			CloseHandle(m_hWaitDownload);
			if(m_waited_file.empty())
			{
				return FALSE;
			}
			return TRUE;
		}
	} else
	{
		m_waited_file = url;
		return TRUE;
	}
	return FALSE;
}
Beispiel #14
0
CString CStringUtils::WordWrap(const CString& longstring, int limit, bool bCompactPaths, bool bForceWrap, int tabSize)
{
	int nLength = longstring.GetLength();
	CString retString;

	if (limit < 0)
		limit = 0;

	int nLineStart = 0;
	int nLineEnd = 0;
	int tabOffset = 0;
	for (int i = 0; i < nLength; ++i)
	{
		if (i-nLineStart+tabOffset >= limit)
		{
			if (nLineEnd == nLineStart)
			{
				if (bForceWrap)
					nLineEnd = i;
				else
				{
					while ((i < nLength) && (longstring[i] != ' ') && (longstring[i] != '\t'))
						++i;
					nLineEnd = i;
				}
			}
			if (bCompactPaths)
			{
				CString longline = longstring.Mid(nLineStart, nLineEnd-nLineStart).Left(MAX_PATH-1);
				if ((bCompactPaths)&&(longline.GetLength() < MAX_PATH))
				{
					if (((!PathIsFileSpec(longline))&&longline.Find(':')<3)||(PathIsURL(longline)))
					{
						TCHAR buf[MAX_PATH] = {0};
						PathCompactPathEx(buf, longline, limit+1, 0);
						longline = buf;
					}
				}
				retString += longline;
			}
			else
				retString += longstring.Mid(nLineStart, nLineEnd-nLineStart);
			retString += L"\n";
			tabOffset = 0;
			nLineStart = nLineEnd;
		}
		if (longstring[i] == ' ')
			nLineEnd = i;
		if (longstring[i] == '\t')
		{
			tabOffset += (tabSize - i % tabSize);
			nLineEnd = i;
		}
	}
	if (bCompactPaths)
	{
		CString longline = longstring.Mid(nLineStart).Left(MAX_PATH-1);
		if ((bCompactPaths)&&(longline.GetLength() < MAX_PATH))
		{
			if (((!PathIsFileSpec(longline))&&longline.Find(':')<3)||(PathIsURL(longline)))
			{
				TCHAR buf[MAX_PATH] = {0};
				PathCompactPathEx(buf, longline, limit+1, 0);
				longline = buf;
			}
		}
		retString += longline;
	}
	else
		retString += longstring.Mid(nLineStart);

	return retString;
}
Beispiel #15
0
STDMETHODIMP CXMLDOMDocument::load(VARIANT xmlSource, VARIANT_BOOL  *isSuccessful)
{
	ATLTRACE(_T("CXMLDOMDocument::load\n"));

	if (NULL == isSuccessful)
		return E_POINTER;

	*isSuccessful = VARIANT_FALSE;

	if (V_VT(&xmlSource) != VT_BSTR					&&
		V_VT(&xmlSource) != VT_DISPATCH				&&
		V_VT(&xmlSource) != (VT_ARRAY | VT_VARIANT)	&&
		V_VT(&xmlSource) != (VT_ARRAY | VT_UI1)		&&
		V_VT(&xmlSource) != VT_UNKNOWN)
		return E_INVALIDARG;

	// do not start another thread if there is another active
	if (NULL != m_hParseThread) {
		DWORD exitCode = 0;
		BOOL rc = ::GetExitCodeThread(m_hParseThread, &exitCode);
		if (!rc || STILL_ACTIVE == exitCode)
			return S_OK;
		
		::CloseHandle(m_hParseThread);
		m_hParseThread = NULL;
	}

	HRESULT hr = S_OK;
	m_bAbort = false;
	
	m_FileName = _T("");
	m_xml = _T("");
	m_TmpDocument = 0;
	m_bThreadValidate = m_bValidate;
	
	if (V_VT(&xmlSource) == VT_BSTR) {
		m_FileName = V_BSTR(&xmlSource);
		if (0 == m_FileName.length())
			return E_INVALIDARG;

		// see if the file is relative path
		if (!PathIsURL(m_FileName) && PathIsRelative(m_FileName)) {
			// try appending baseurl if exists
			_bstr_t baseURL;
			if (S_OK == GetBaseURL(baseURL)) {
				TCHAR szCurFile[MAX_PATH];
				_tcscpy(szCurFile, m_FileName);
				// change any backslashes to slashes
				LPTSTR loc = _tcschr(szCurFile,_T('\\'));
				while (loc != NULL) {
					*loc = _T('/');
					loc = _tcschr(szCurFile,_T('\\'));
				}
				m_FileName = baseURL + _T("/") + szCurFile;
			}
			else {
				TCHAR szCurDir[MAX_PATH];
				GetCurrentDirectory(MAX_PATH,szCurDir);
				m_FileName=_bstr_t(szCurDir) + _T("\\") + m_FileName;
			}
		}
	}
	else
	if (V_VT(&xmlSource) == VT_UNKNOWN) {
		CComQIPtr<IStream,&IID_IStream> pS(V_UNKNOWN(&xmlSource));
		if (!pS)
			return E_INVALIDARG;

		CComBSTR b;
		hr = b.ReadFromStream(pS);
		if (S_OK != hr)
			return hr;

		m_xml = b;
		if (0 == m_xml.length())
			return E_INVALIDARG;
	}
	else
	if (V_VT(&xmlSource) == VT_DISPATCH) {
		CComQIPtr<IXMLDOMDocument,&IID_IXMLDOMDocument> pDoc(V_DISPATCH(&xmlSource));
		if (!pDoc)
			return E_INVALIDARG;
		
		BSTR b = NULL;
		hr = pDoc->get_xml(&b);
		if (S_OK != hr)
			return hr;

		m_xml = b;
		::SysFreeString(b);

		if (0 == m_xml.length())
			return E_INVALIDARG;
	}
	else
	if (V_VT(&xmlSource) == (VT_ARRAY | VT_VARIANT)) {
		SAFEARRAY *pArray = reinterpret_cast<SAFEARRAY *> (xmlSource.byref);
		if (NULL == pArray)
			return E_INVALIDARG;

		long lLBoundVar = 0;
		long lUBoundVar = 0;
	
		UINT dims = ::SafeArrayGetDim(pArray);
		if (dims == 0)
			return E_INVALIDARG;
	
		hr = ::SafeArrayGetLBound(pArray, dims, &lLBoundVar);
		if (S_OK != hr)
			return hr;

		hr = ::SafeArrayGetUBound(pArray, dims, &lUBoundVar);
		if (S_OK != hr)
			return hr;

		if (lUBoundVar >= lLBoundVar) {
			VARIANT *pIndex = NULL;
			hr = ::SafeArrayAccessData(pArray, reinterpret_cast<void **> (&pIndex));
			if (S_OK != hr)
				return hr;

			int length = lUBoundVar-lLBoundVar+2;
			BYTE *body = new BYTE[length];
			for (long i = 0; i <= lUBoundVar-lLBoundVar; ++i) {	
				VARIANT var = pIndex[i];
				if (V_VT(&var) != VT_UI1) {
					hr = E_INVALIDARG;
					break;
				}
				body[i] = V_UI1(&var);
			}
			body[length-1] = 0;
					
			::SafeArrayUnaccessData(pArray);
			if (S_OK != hr) {
				delete [] body;
				return hr;
			}
			m_xml = reinterpret_cast<char*> (body);
			delete [] body;
			if (0 == m_xml.length())
				return E_INVALIDARG;
		}
	}	
	else
	if (V_VT(&xmlSource) == (VT_ARRAY | VT_UI1)) {
		SAFEARRAY *pArray = reinterpret_cast<SAFEARRAY *> (xmlSource.byref);
		if (NULL == pArray)
			return E_INVALIDARG;

		long lLBoundVar = 0;
		long lUBoundVar = 0;
	
		UINT dims = ::SafeArrayGetDim(pArray);
		if (dims == 0)
			return E_INVALIDARG;
	
		hr = ::SafeArrayGetLBound(pArray, dims, &lLBoundVar);
		if (S_OK != hr)
			return hr;

		hr = ::SafeArrayGetUBound(pArray, dims, &lUBoundVar);
		if (S_OK != hr)
			return hr;

		if (lUBoundVar >= lLBoundVar) {
			BYTE *pIndex = NULL;
			hr = ::SafeArrayAccessData(pArray, reinterpret_cast<void **> (&pIndex));
			if (S_OK != hr)
				return hr;

			int length = lUBoundVar-lLBoundVar+2;
			BYTE *body = new BYTE[length];
			for (long i = 0; i <= lUBoundVar-lLBoundVar; ++i)	
				body[i] = pIndex[i];
			
			body[length-1] = 0;
			::SafeArrayUnaccessData(pArray);
			m_xml = reinterpret_cast<char*> (body);
			delete [] body;
			if (0 == m_xml.length())
				return E_INVALIDARG;
		}
	}	

	UINT nthreadID = 0;
	m_hParseThread = reinterpret_cast<HANDLE> (_beginthreadex(NULL,
												 0,
											     CXMLDOMDocument::ParseThread,
												 (void *) this,
												 0,
												 &nthreadID));
	if (NULL == m_hParseThread)
		return S_OK;
	
	if (m_bAsync) {
		*isSuccessful = VARIANT_TRUE;
		return S_OK;
	}

	bool bWait = true;
	while (bWait) {
		DWORD dwEvt = MsgWaitForMultipleObjects(1,&m_hParseThread,FALSE,INFINITE,QS_ALLINPUT);
		switch(dwEvt) {
			case WAIT_OBJECT_0:
				bWait = false;
				break;
			case WAIT_OBJECT_0 + 1:
			{
				MSG msg;
				while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
					if (WM_CLOSE == msg.message || WM_QUIT == msg.message) {
						 bWait = false;
						 m_bAbort = true;
						 break;
					}
					else {
						PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
						TranslateMessage(&msg);
						DispatchMessage(&msg);
					}
				}
				break;
			}
			default:
				m_bAbort = true;
				bWait = false;
				break;
		}
	}

	if (m_bAbort)
		return S_OK;

	if (m_bParseError)
		return hr;

    if(m_Document)
        delete m_Document;
	m_Document = m_TmpDocument;
	m_TmpDocument = 0;
	
	m_url = m_FileName;
	*isSuccessful = VARIANT_TRUE;
	
	return hr;
}
Beispiel #16
0
void web_page::make_url( LPCWSTR url, LPCWSTR basepath, std::wstring& out )
{
	if(PathIsRelative(url) && !PathIsURL(url))
	{
		if(basepath && basepath[0])
		{
			DWORD dl = lstrlen(url) + lstrlen(basepath) + 1;
			LPWSTR abs_url = new WCHAR[dl];
			HRESULT res = UrlCombine(basepath, url, abs_url, &dl, 0);
			if (res == E_POINTER)
			{
				delete abs_url;
				abs_url = new WCHAR[dl + 1];
				if (UrlCombine(basepath, url, abs_url, &dl, 0) == S_OK)
				{
					out = abs_url;
				}
			}
			else if (res == S_OK)
			{
				out = abs_url;
			}
			delete abs_url;
		}
		else
		{
			DWORD dl = lstrlen(url) + (DWORD) m_base_path.length() + 1;
			LPWSTR abs_url = new WCHAR[dl];
			HRESULT res = UrlCombine(m_base_path.c_str(), url, abs_url, &dl, 0);
			if (res == E_POINTER)
			{
				delete abs_url;
				abs_url = new WCHAR[dl + 1];
				if (UrlCombine(m_base_path.c_str(), url, abs_url, &dl, 0) == S_OK)
				{
					out = abs_url;
				}
			}
			else if (res == S_OK)
			{
				out = abs_url;
			}
			delete abs_url;
		}
	} else
	{
		if(PathIsURL(url))
		{
			out = url;
		} else
		{
			DWORD dl = lstrlen(url) + 1;
			LPWSTR abs_url = new WCHAR[dl];
			HRESULT res = UrlCreateFromPath(url, abs_url, &dl, 0);
			if (res == E_POINTER)
			{
				delete abs_url;
				abs_url = new WCHAR[dl + 1];
				if (UrlCreateFromPath(url, abs_url, &dl, 0) == S_OK)
				{
					out = abs_url;
				}
			}
			else if (res == S_OK)
			{
				out = abs_url;
			}
			delete abs_url;
		}
	}
	if(out.substr(0, 8) == L"file:///")
	{
		out.erase(5, 1);
	}
	if(out.substr(0, 7) == L"file://")
	{
		out.erase(0, 7);
	}
}
Beispiel #17
0
void CFileDiffDlg::DoDiff(int selIndex, bool blame)
{
	CFileDiffDlg::FileDiff fd = m_arFilteredList[selIndex];

	CTSVNPath url1 = CTSVNPath(m_path1.GetSVNPathString() + _T("/") + fd.path.GetSVNPathString());
	CTSVNPath url2 = m_bDoPegDiff ? url1 : CTSVNPath(m_path2.GetSVNPathString() + _T("/") + fd.path.GetSVNPathString());

	if (fd.kind == svn_client_diff_summarize_kind_deleted)
	{
		if (!PathIsURL(url1))
			url1 = CTSVNPath(GetURLFromPath(m_path1) + _T("/") + fd.path.GetSVNPathString());
		if (!PathIsURL(url2))
			url2 = m_bDoPegDiff ? url1 : CTSVNPath(GetURLFromPath(m_path2) + _T("/") + fd.path.GetSVNPathString());
	}

	if (fd.propchanged)
	{
		DiffProps(selIndex);
	}
	if (fd.node == svn_node_dir)
		return;

	CTSVNPath tempfile = CTempFiles::Instance().GetTempFilePath(false, m_path1, m_rev1);
	CString sTemp;
	CProgressDlg progDlg;
	progDlg.SetTitle(IDS_PROGRESSWAIT);
	progDlg.SetAnimation(IDR_DOWNLOAD);
	progDlg.ShowModeless(this);
	progDlg.FormatPathLine(1, IDS_PROGRESSGETFILE, (LPCTSTR)m_path1.GetUIPathString());
	progDlg.FormatNonPathLine(2, IDS_PROGRESSREVISIONTEXT, (LPCTSTR)m_rev1.ToString());

	if ((fd.kind != svn_client_diff_summarize_kind_added)&&(!blame)&&(!Cat(url1, m_bDoPegDiff ? m_peg : m_rev1, m_rev1, tempfile)))
	{
		if ((!m_bDoPegDiff)||(!Cat(url1, m_rev1, m_rev1, tempfile)))
		{
			CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
			return;
		}
	}
	else if ((fd.kind != svn_client_diff_summarize_kind_added)&&(blame)&&(!m_blamer.BlameToFile(url1, 1, m_rev1, m_bDoPegDiff ? m_peg : m_rev1, tempfile, _T(""), TRUE, TRUE)))
	{
		if ((!m_bDoPegDiff)||(!m_blamer.BlameToFile(url1, 1, m_rev1, m_rev1, tempfile, _T(""), TRUE, TRUE)))
		{
			CMessageBox::Show(this->m_hWnd, m_blamer.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
			return;
		}
	}
	SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);
	progDlg.SetProgress(1, 2);
	progDlg.FormatPathLine(1, IDS_PROGRESSGETFILE, (LPCTSTR)url2.GetUIPathString());
	progDlg.FormatNonPathLine(2, IDS_PROGRESSREVISIONTEXT, (LPCTSTR)m_rev2.ToString());
	CTSVNPath tempfile2 = CTempFiles::Instance().GetTempFilePath(false, url2, m_rev2);
	if ((fd.kind != svn_client_diff_summarize_kind_deleted)&&(!blame)&&(!Cat(url2, m_bDoPegDiff ? m_peg : m_rev2, m_rev2, tempfile2)))
	{
		if ((!m_bDoPegDiff)||(!Cat(url2, m_rev2, m_rev2, tempfile2)))
		{
			CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
			return;
		}
	}
	else if ((fd.kind != svn_client_diff_summarize_kind_deleted)&&(blame)&&(!m_blamer.BlameToFile(url2, 1, m_bDoPegDiff ? m_peg : m_rev2, m_rev2, tempfile2, _T(""), TRUE, TRUE)))
	{
		if ((!m_bDoPegDiff)||(!m_blamer.BlameToFile(url2, 1, m_rev2, m_rev2, tempfile2, _T(""), TRUE, TRUE)))
		{
			CMessageBox::Show(this->m_hWnd, m_blamer.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
			return;
		}
	}
	SetFileAttributes(tempfile2.GetWinPath(), FILE_ATTRIBUTE_READONLY);
	progDlg.SetProgress(2,2);
	progDlg.Stop();

	CString rev1name, rev2name;
	if (m_bDoPegDiff)
	{
		rev1name.Format(_T("%s Revision %ld"), (LPCTSTR)fd.path.GetSVNPathString(), (LONG)m_rev1);
		rev2name.Format(_T("%s Revision %ld"), (LPCTSTR)fd.path.GetSVNPathString(), (LONG)m_rev2);
	}
	else
	{
		rev1name = m_path1.GetSVNPathString() + _T("/") + fd.path.GetSVNPathString();
		rev2name = m_path2.GetSVNPathString() + _T("/") + fd.path.GetSVNPathString();
	}
	CAppUtils::DiffFlags flags;
	flags.AlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));
	flags.Blame(blame);
	CAppUtils::StartExtDiff(
		tempfile, tempfile2, rev1name, rev2name, flags, 0);
}
Beispiel #18
0
CString CPathUtils::GetLongPathname(const CString& path)
{
    if (path.IsEmpty())
        return path;
    TCHAR pathbufcanonicalized[MAX_PATH]; // MAX_PATH ok.
    DWORD ret = 0;
    CString sRet = path;
    if (!PathIsURL(path) && PathIsRelative(path))
    {
        ret = GetFullPathName(path, 0, NULL, NULL);
        if (ret)
        {
            std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+1]);
            if ((ret = GetFullPathName(path, ret, pathbuf.get(), NULL))!=0)
            {
                sRet = CString(pathbuf.get(), ret);
            }
        }
    }
    else if (PathCanonicalize(pathbufcanonicalized, path))
    {
        ret = ::GetLongPathName(pathbufcanonicalized, NULL, 0);
        if (ret == 0)
            return path;
        std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+2]);
        ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret+1);
        // GetFullPathName() sometimes returns the full path with the wrong
        // case. This is not a problem on Windows since its filesystem is
        // case-insensitive. But for SVN that's a problem if the wrong case
        // is inside a working copy: the svn wc database is case sensitive.
        // To fix the casing of the path, we use a trick:
        // convert the path to its short form, then back to its long form.
        // That will fix the wrong casing of the path.
        int shortret = ::GetShortPathName(pathbuf.get(), NULL, 0);
        if (shortret)
        {
            std::unique_ptr<TCHAR[]> shortpath(new TCHAR[shortret+2]);
            if (::GetShortPathName(pathbuf.get(), shortpath.get(), shortret+1))
            {
                int ret2 = ::GetLongPathName(shortpath.get(), pathbuf.get(), ret+1);
                if (ret2)
                    sRet = CString(pathbuf.get(), ret2);
            }
        }
    }
    else
    {
        ret = ::GetLongPathName(path, NULL, 0);
        if (ret == 0)
            return path;
        std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+2]);
        ret = ::GetLongPathName(path, pathbuf.get(), ret+1);
        sRet = CString(pathbuf.get(), ret);
        // fix the wrong casing of the path. See above for details.
        int shortret = ::GetShortPathName(pathbuf.get(), NULL, 0);
        if (shortret)
        {
            std::unique_ptr<TCHAR[]> shortpath(new TCHAR[shortret+2]);
            if (::GetShortPathName(pathbuf.get(), shortpath.get(), shortret+1))
            {
                int ret2 = ::GetLongPathName(shortpath.get(), pathbuf.get(), ret+1);
                if (ret2)
                    sRet = CString(pathbuf.get(), ret2);
            }
        }
    }
    if (ret == 0)
        return path;
    return sRet;
}
Beispiel #19
0
bool RenameCommand::Execute()
{
	bool bRet = false;
	CString filename = cmdLinePath.GetFileOrDirectoryName();
	CString basePath = cmdLinePath.GetContainingDirectory().GetGitPathString();
	//::SetCurrentDirectory(basePath);

	// show the rename dialog until the user either cancels or enters a new
	// name (one that's different to the original name
	CString sNewName;
	do
	{
		CRenameDlg dlg;
		dlg.m_name = filename;
		if (dlg.DoModal() != IDOK)
			return FALSE;
		sNewName = dlg.m_name;
	} while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));

	if(!basePath.IsEmpty())
		sNewName=basePath+"/"+sNewName;

	CString cmd;
	CString output;
	cmd.Format(_T("git.exe mv -- \"%s\" \"%s\""),
					cmdLinePath.GetGitPathString(),
					sNewName);

	if(g_Git.Run(cmd,&output,CP_ACP))
	{
		CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK);
	}

	CTGitPath newpath;
	newpath.SetFromGit(sNewName);

	CShellUpdater::Instance().AddPathForUpdate(newpath);
#if 0
	TRACE(_T("rename file %s to %s\n"), (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName);
	CTSVNPath destinationPath(basePath);
	if (PathIsRelative(sNewName) && !PathIsURL(sNewName))
		destinationPath.AppendPathString(sNewName);
	else
		destinationPath.SetFromWin(sNewName);
	// check if a rename just with case is requested: that's not possible on windows file systems
	// and we have to show an error.
	if (cmdLinePath.GetWinPathString().CompareNoCase(destinationPath.GetWinPathString())==0)
	{
		//rename to the same file!
		CString sHelpPath = theApp.m_pszHelpFilePath;
		sHelpPath += _T("::/tsvn-dug-rename.html#tsvn-dug-renameincase");
		CMessageBox::Show(hwndExplorer, IDS_PROC_CASERENAME, IDS_APPNAME, MB_OK|MB_HELP, sHelpPath);
	}
	else
	{
		CString sMsg;
		if (SVN::PathIsURL(cmdLinePath))
		{
			// rename an URL.
			// Ask for a commit message, then rename directly in
			// the repository
			CInputLogDlg input;
			CString sUUID;
			SVN svn;
			svn.GetRepositoryRootAndUUID(cmdLinePath, sUUID);
			input.SetUUID(sUUID);
			CString sHint;
			sHint.Format(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString());
			input.SetActionText(sHint);
			if (input.DoModal() == IDOK)
			{
				sMsg = input.GetLogMessage();
			}
			else
			{
				return FALSE;
			}
		}
		if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1))
		{
			// renaming a directory can take a while: use the
			// progress dialog to show the progress of the renaming
			// operation.
			CSVNProgressDlg progDlg;
			progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename);
			if (parser.HasVal(_T("closeonend")))
				progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend")));
			progDlg.SetPathList(pathList);
			progDlg.SetUrl(destinationPath.GetWinPathString());
			progDlg.SetCommitMessage(sMsg);
			progDlg.SetRevision(SVNRev::REV_WC);
			progDlg.DoModal();
			bRet = !progDlg.DidErrorsOccur();
		}
		else
		{
			SVN svn;
			CString sFilemask = cmdLinePath.GetFilename();
			if (sFilemask.ReverseFind('.')>=0)
			{
				sFilemask = sFilemask.Left(sFilemask.ReverseFind('.'));
			}
			else
				sFilemask.Empty();
			CString sNewMask = sNewName;
			if (sNewMask.ReverseFind('.'>=0))
			{
				sNewMask = sNewMask.Left(sNewMask.ReverseFind('.'));
			}
			else
				sNewMask.Empty();

			if (((!sFilemask.IsEmpty()) && (parser.HasKey(_T("noquestion")))) ||
				(cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0))
			{
				if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
				{
					TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
					CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
				}
				else
					bRet = true;
			}
			else
			{
				// when refactoring, multiple files have to be renamed
				// at once because those files belong together.
				// e.g. file.aspx, file.aspx.cs, file.aspx.resx
				CTSVNPathList renlist;
				CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+_T(".*"));
				while (filefind.FindNextFileNoDots())
				{
					if (!filefind.IsDirectory())
						renlist.AddPath(CTSVNPath(filefind.GetFilePath()));
				}
				if (renlist.GetCount()<=1)
				{
					// we couldn't find any other matching files
					// just do the default...
					if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
					{
						TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
						CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
					}
					else
					{
						bRet = true;
						CShellUpdater::Instance().AddPathForUpdate(destinationPath);
					}
				}
				else
				{
					std::map<CString, CString> renmap;
					CString sTemp;
					CString sRenList;
					for (int i=0; i<renlist.GetCount(); ++i)
					{
						CString sFilename = renlist[i].GetFilename();
						CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength());
						sTemp.Format(_T("\n%s -> %s"), (LPCTSTR)sFilename, (LPCTSTR)sNewFilename);
						if (!renlist[i].IsEquivalentTo(cmdLinePath))
							sRenList += sTemp;
						renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+_T("\\")+sNewFilename;
					}
					CString sRenameMultipleQuestion;
					sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList);
					UINT idret = CMessageBox::Show(hwndExplorer, sRenameMultipleQuestion, _T("TortoiseGit"), MB_ICONQUESTION|MB_YESNOCANCEL);
					if (idret == IDYES)
					{
						CProgressDlg progress;
						progress.SetTitle(IDS_PROC_MOVING);
						progress.SetAnimation(IDR_MOVEANI);
						progress.SetTime(true);
						progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
						DWORD count = 1;
						for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it)
						{
							progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first);
							progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second);
							progress.SetProgress(count, renmap.size());
							if (!svn.Move(CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), TRUE, sMsg))
							{
								if (svn.Err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
								{
									bRet = !!MoveFile(it->first, it->second);
								}
								else
								{
									TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
									CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
									bRet = false;
								}
							}
							else
							{
								bRet = true;
								CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second));
							}
						}
						progress.Stop();
					}
					else if (idret == IDNO)
					{
						// no, user wants to just rename the file he selected
						if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))
						{
							TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
							CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
						}
						else
						{
							bRet = true;
							CShellUpdater::Instance().AddPathForUpdate(destinationPath);
						}
					}
					else if (idret == IDCANCEL)
					{
						// nothing
					}
				}
			}
		}
	}
#endif
	CShellUpdater::Instance().Flush();
	return bRet;
}
Beispiel #20
0
std::wstring CPathUtils::GetLongPathname(const std::wstring& path)
{
    if (path.empty())
        return path;
    TCHAR pathbufcanonicalized[MAX_PATH]; // MAX_PATH ok.
    DWORD ret = 0;
    std::wstring sRet = path;
    if (!PathIsURL(path.c_str()) && PathIsRelative(path.c_str()))
    {
        ret = GetFullPathName(path.c_str(), 0, nullptr, nullptr);
        if (ret)
        {
            auto pathbuf = std::make_unique<TCHAR[]>(ret+1);
            if ((ret = GetFullPathName(path.c_str(), ret, pathbuf.get(), nullptr))!=0)
            {
                sRet = std::wstring(pathbuf.get(), ret);
            }
        }
    }
    else if (PathCanonicalize(pathbufcanonicalized, path.c_str()))
    {
        ret = ::GetLongPathName(pathbufcanonicalized, nullptr, 0);
        // TODO REIVEW: Why + 2 and not + 1? A few other instances of this exist too.
        auto pathbuf = std::make_unique<TCHAR[]>(ret+2);
        ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret+1);
        // GetFullPathName() sometimes returns the full path with the wrong
        // case. This is not a problem on Windows since its filesystem is
        // case-insensitive. But for SVN that's a problem if the wrong case
        // is inside a working copy: the svn wc database is case sensitive.
        // To fix the casing of the path, we use a trick:
        // convert the path to its short form, then back to its long form.
        // That will fix the wrong casing of the path.
        int shortret = ::GetShortPathName(pathbuf.get(), nullptr, 0);
        if (shortret)
        {
            auto shortpath = std::make_unique<TCHAR[]>(shortret+2);
            if (::GetShortPathName(pathbuf.get(), shortpath.get(), shortret+1))
            {
                int ret2 = ::GetLongPathName(shortpath.get(), pathbuf.get(), ret+1);
                if (ret2)
                    sRet = std::wstring(pathbuf.get(), ret2);
            }
        }
    }
    else
    {
        ret = ::GetLongPathName(path.c_str(), nullptr, 0);
        auto pathbuf = std::make_unique<TCHAR[]>(ret+2);
        ret = ::GetLongPathName(path.c_str(), pathbuf.get(), ret+1);
        sRet = std::wstring(pathbuf.get(), ret);
        // fix the wrong casing of the path. See above for details.
        int shortret = ::GetShortPathName(pathbuf.get(), nullptr, 0);
        if (shortret)
        {
            auto shortpath = std::make_unique<TCHAR[]>(shortret+2);
            if (::GetShortPathName(pathbuf.get(), shortpath.get(), shortret+1))
            {
                int ret2 = ::GetLongPathName(shortpath.get(), pathbuf.get(), ret+1);
                if (ret2)
                    sRet = std::wstring(pathbuf.get(), ret2);
            }
        }
    }
    if (ret == 0)
        return path;
    return sRet;
}
Beispiel #21
0
bool RenameCommand::Execute()
{
    bool bRet = false;
    CString filename = cmdLinePath.GetFileOrDirectoryName();
    CString basePath = cmdLinePath.GetContainingDirectory().GetWinPathString();
    ::SetCurrentDirectory(basePath);

    // show the rename dialog until the user either cancels or enters a new
    // name (one that's different to the original name
    CString sNewName;
    do
    {
        CRenameDlg dlg;
        dlg.m_name = filename;
        if (!SVN::PathIsURL(cmdLinePath))
            dlg.SetFileSystemAutoComplete();
        if (dlg.DoModal() != IDOK)
            return FALSE;
        sNewName = dlg.m_name;
    } while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));

    CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": rename file %s to %s\n", (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName);
    CTSVNPath destinationPath(basePath);
    if (PathIsRelative(sNewName) && !PathIsURL(sNewName))
        destinationPath.AppendPathString(sNewName);
    else
        destinationPath.SetFromWin(sNewName);
    CString sMsg;
    if (SVN::PathIsURL(cmdLinePath))
    {
        // rename an URL.
        // Ask for a commit message, then rename directly in
        // the repository
        CInputLogDlg input;
        CString sUUID;
        SVN svn;
        svn.GetRepositoryRootAndUUID(cmdLinePath, true, sUUID);
        input.SetUUID(sUUID);
        CString sHint;
        sHint.FormatMessage(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString());
        input.SetActionText(sHint);
        if (input.DoModal() == IDOK)
        {
            sMsg = input.GetLogMessage();
        }
        else
        {
            return FALSE;
        }
    }
    if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1))
    {
        // renaming a directory can take a while: use the
        // progress dialog to show the progress of the renaming
        // operation.
        CSVNProgressDlg progDlg;
        progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename);
        progDlg.SetAutoClose (parser);
        progDlg.SetPathList(pathList);
        progDlg.SetUrl(destinationPath.GetWinPathString());
        progDlg.SetCommitMessage(sMsg);
        progDlg.DoModal();
        bRet = !progDlg.DidErrorsOccur();
    }
    else
    {
        CString sFilemask = cmdLinePath.GetFilename();
        int slashpos = 0;
        // find out up to which char sFilemask and sNewName are identical
        int minlen = min(sFilemask.GetLength(), sNewName.GetLength());
        for (; slashpos < minlen; ++slashpos)
        {
            if (sFilemask[slashpos] != sNewName[slashpos])
                break;
        }

        if (sFilemask.ReverseFind('.') >= slashpos)
        {
            while (sFilemask.ReverseFind('.') >= slashpos)
                sFilemask = sFilemask.Left(sFilemask.ReverseFind('.'));
        }
        else
            sFilemask.Empty();
        CString sNewMask = sNewName;
        if (sNewMask.ReverseFind('.') >= slashpos)
        {
            while (sNewMask.ReverseFind('.') >= slashpos)
                sNewMask = sNewMask.Left(sNewMask.ReverseFind('.'));
        }
        else
            sNewMask.Empty();

        CString sRightPartNew = sNewName.Mid(sNewMask.GetLength());
        CString sRightPartOld = cmdLinePath.GetFilename().Mid(sFilemask.GetLength());

        // if the file extension changed, or the old and new right parts are not the
        // same then we can not correctly guess the new names of similar files, so
        // just do the plain rename of the selected file and don't offer to rename similar ones.
        if (((!sFilemask.IsEmpty()) && (parser.HasKey(L"noquestion"))) ||
            (cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0) ||
            (sRightPartOld.CompareNoCase(sRightPartNew)))
        {
            if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg))
                bRet = true;
        }
        else
        {
            // when refactoring, multiple files have to be renamed
            // at once because those files belong together.
            // e.g. file.aspx, file.aspx.cs, file.aspx.resx
            CTSVNPathList renlist;
            CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+L".*");
            while (filefind.FindNextFileNoDots())
            {
                if (!filefind.IsDirectory())
                    renlist.AddPath(CTSVNPath(filefind.GetFilePath()));
            }
            if ((renlist.GetCount() <= 1) ||
                (renlist.GetCount() > 10))  // arbitrary value of ten
            {
                // Either no matching files to rename, or way too many of them:
                // just do the default...
                if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg))
                {
                    bRet = true;
                    CShellUpdater::Instance().AddPathForUpdate(destinationPath);
                }
            }
            else
            {
                std::map<CString, CString> renmap;
                CString sTemp;
                CString sRenList;
                for (int i=0; i<renlist.GetCount(); ++i)
                {
                    CString sFilename = renlist[i].GetFilename();
                    CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength());
                    sTemp.Format(L"\n%s -> %s", (LPCTSTR)sFilename, (LPCTSTR)sNewFilename);
                    if (!renlist[i].IsEquivalentTo(cmdLinePath))
                        sRenList += sTemp;
                    renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+L"\\"+sNewFilename;
                }
                CString sRenameMultipleQuestion;
                sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList);
                UINT idret = ::MessageBox(GetExplorerHWND(), sRenameMultipleQuestion, L"TortoiseSVN", MB_ICONQUESTION|MB_YESNOCANCEL);
                if (idret == IDYES)
                {
                    CProgressDlg progress;
                    progress.SetTitle(IDS_PROC_MOVING);
                    progress.SetTime(true);
                    progress.ShowModeless(CWnd::FromHandle(GetExplorerHWND()));
                    DWORD count = 1;
                    for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it)
                    {
                        progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first);
                        progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second);
                        progress.SetProgress64(count, renmap.size());
                        if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), sMsg))
                        {
                            bRet = true;
                            CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second));
                        }
                    }
                    progress.Stop();
                }
                else if (idret == IDNO)
                {
                    // no, user wants to just rename the file he selected
                    if (RenameWithReplace(GetExplorerHWND(), CTSVNPathList(cmdLinePath), destinationPath, sMsg))
                    {
                        bRet = true;
                        CShellUpdater::Instance().AddPathForUpdate(destinationPath);
                    }
                }
                else if (idret == IDCANCEL)
                {
                    // nothing
                }
            }
        }
    }
    return bRet;
}
	bool is_url() const { return PathIsURL(this->buf)==TRUE; }