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 }
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; }
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; }
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); } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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); }
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; }
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; }
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; }
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; }