OSDN Git Service

Add union code encode at commit support i18n.commitencoding
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / AppUtils.cpp
index b616560..74acedb 100644 (file)
 #include "CreateBranchTagDlg.h"\r
 #include "GitSwitchDlg.h"\r
 #include "ResetDlg.h"\r
+#include "DeleteConflictDlg.h"\r
+#include "ChangedDlg.h"\r
+#include "SendMailDlg.h"\r
+#include "SVNProgressDlg.h"\r
 \r
 CAppUtils::CAppUtils(void)\r
 {\r
@@ -50,6 +54,29 @@ CAppUtils::~CAppUtils(void)
 {\r
 }\r
 \r
+int     CAppUtils::StashApply(CString ref)\r
+{\r
+       CString cmd,out;\r
+       cmd=_T("git.exe stash apply ");\r
+       cmd+=ref;\r
+       \r
+       if(g_Git.Run(cmd,&out,CP_ACP))\r
+       {\r
+               CMessageBox::Show(NULL,CString(_T("<ct=0x0000FF>Stash Apply Fail!!!</ct>\n"))+out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
+\r
+       }else\r
+       {\r
+               if(CMessageBox::Show(NULL,CString(_T("<ct=0xff0000>Stash Apply Success</ct>\nDo you want to show change?"))\r
+                       ,_T("TortoiseGit"),MB_YESNO|MB_ICONINFORMATION) == IDYES)\r
+               {\r
+                       CChangedDlg dlg;\r
+                       dlg.m_pathList.AddPath(CTGitPath());\r
+                       dlg.DoModal();                  \r
+               }\r
+               return 0;\r
+       }\r
+       return -1;\r
+}\r
 bool CAppUtils::GetMimeType(const CTGitPath& file, CString& mimetype)\r
 {\r
 #if 0\r
@@ -589,7 +616,46 @@ bool CAppUtils::LaunchApplication(const CString& sCommandLine, UINT idErrMessage
        CloseHandle(process.hProcess);\r
        return true;\r
 }\r
+bool CAppUtils::LaunchPAgent(CString *keyfile,CString * pRemote)\r
+{\r
+       CString key,remote;\r
+       CString cmd,out;\r
+       if( pRemote == NULL)\r
+       {\r
+               remote=_T("origin");\r
+       }else\r
+       {\r
+               remote=*pRemote;\r
+       }\r
+       if(keyfile == NULL)\r
+       {\r
+               cmd.Format(_T("git.exe config remote.%s.puttykeyfile"),remote);\r
+               g_Git.Run(cmd,&key,CP_ACP);\r
+               int start=0;\r
+               key = key.Tokenize(_T("\n"),start);\r
+       }\r
+       else\r
+               key=*keyfile;\r
+\r
+       if(key.IsEmpty())\r
+               return false;\r
+\r
+       CString proc=CPathUtils::GetAppDirectory();\r
+    proc += _T("pageant.exe \"");\r
+       proc += key;\r
+       proc += _T("\"");\r
 \r
+    return LaunchApplication(proc, IDS_ERR_PAGEANT, false);\r
+}\r
+bool CAppUtils::LaunchRemoteSetting()\r
+{\r
+    CString proc=CPathUtils::GetAppDirectory();\r
+    proc += _T("TortoiseProc.exe /command:settings");\r
+    proc += _T(" /path:\"");\r
+    proc += g_Git.m_CurrentDir;\r
+    proc += _T("\" /page:remote");\r
+    return LaunchApplication(proc, IDS_ERR_EXTDIFFSTART, false);\r
+}\r
 /**\r
 * Launch the external blame viewer\r
 */\r
@@ -957,11 +1023,18 @@ bool CAppUtils::StartShowUnifiedDiff(HWND hWnd, const CTGitPath& url1, const git
        CString cmd;\r
        if(rev1 == GitRev::GetWorkingCopy())\r
        {\r
-               cmd.Format(_T("git.exe diff --stat -p %s"),rev2);\r
+               cmd.Format(_T("git.exe diff --stat -p %s "),rev2);\r
        }else\r
        {       \r
                cmd.Format(_T("git.exe diff-tree -r -p --stat %s %s"),rev1,rev2);\r
        }\r
+\r
+       if( !url1.IsEmpty() )\r
+       {\r
+               cmd+=_T(" \"");\r
+               cmd+=url1.GetGitPathString();\r
+               cmd+=_T("\" ");\r
+       }\r
        g_Git.RunLogFile(cmd,tempfile);\r
        CAppUtils::StartUnifiedDiffViewer(tempfile,rev1.Left(6)+_T(":")+rev2.Left(6));\r
 \r
@@ -1077,10 +1150,10 @@ bool CAppUtils::CreateBranchTag(bool IsTag,CString *CommitHash)
                CString force;\r
                CString track;\r
                if(dlg.m_bTrack)\r
-                       track=_T("--track");\r
+                       track=_T(" --track ");\r
 \r
                if(dlg.m_bForce)\r
-                       force=_T("-f");\r
+                       force=_T(" -f ");\r
 \r
                if(IsTag)\r
                {\r
@@ -1156,35 +1229,60 @@ bool CAppUtils::Switch(CString *CommitHash)
        return FALSE;\r
 }\r
 \r
-bool CAppUtils::IgnoreFile(CTGitPath &path,bool IsMask)\r
+bool CAppUtils::IgnoreFile(CTGitPathList &path,bool IsMask)\r
 {\r
        CString ignorefile;\r
-       ignorefile=g_Git.m_CurrentDir;\r
-       ignorefile+=path.GetDirectory().GetWinPathString()+_T("\\.gitignore");\r
+       ignorefile=g_Git.m_CurrentDir+_T("\\");\r
+\r
+       if(IsMask)\r
+       {\r
+               ignorefile+=path.GetCommonRoot().GetDirectory().GetWinPathString()+_T("\\.gitignore");\r
+\r
+       }else\r
+       {\r
+               ignorefile+=_T("\\.gitignore");\r
+       }\r
 \r
        CStdioFile file;\r
-       if(!file.Open(ignorefile,CFile::modeCreate|CFile::modeWrite))\r
+       if(!file.Open(ignorefile,CFile::modeCreate|CFile::modeReadWrite|CFile::modeNoTruncate))\r
        {\r
                CMessageBox::Show(NULL,ignorefile+_T(" Open Failure"),_T("TortoiseGit"),MB_OK);\r
                return FALSE;\r
        }\r
 \r
        CString ignorelist;\r
-       file.ReadString(ignorelist);\r
-\r
-       if(IsMask)\r
+       CString mask;\r
+       try\r
        {\r
-               ignorelist+=_T("\n*.")+path.GetFileExtension();\r
-       }else\r
+               //file.ReadString(ignorelist);\r
+               file.SeekToEnd();\r
+               for(int i=0;i<path.GetCount();i++)\r
+               {\r
+                       if(IsMask)\r
+                       {\r
+                               mask=_T("*")+path[i].GetFileExtension();\r
+                               if(ignorelist.Find(mask)<0)\r
+                                       ignorelist+=_T("\n")+mask;\r
+                               \r
+                       }else\r
+                       {\r
+                               ignorelist+=_T("\n/")+path[i].GetGitPathString();\r
+                       }\r
+               }\r
+               file.WriteString(ignorelist);\r
+\r
+               file.Close();\r
+\r
+       }catch(...)\r
        {\r
-               ignorelist+=_T("\n")+path.GetBaseFilename();\r
+               file.Close();\r
+               return FALSE;\r
        }\r
-       file.WriteString(ignorelist);\r
-\r
-       file.Close();\r
+       \r
        return TRUE;\r
 }\r
 \r
+\r
 bool CAppUtils::GitReset(CString *CommitHash,int type)\r
 {\r
        CResetDlg dlg;\r
@@ -1219,6 +1317,30 @@ bool CAppUtils::GitReset(CString *CommitHash,int type)
        return FALSE;\r
 }\r
 \r
+void CAppUtils::DescribeFile(bool mode, bool base,CString &descript)\r
+{\r
+       if(mode == FALSE)\r
+       {\r
+               descript=_T("Deleted");\r
+               return;\r
+       }\r
+       if(base)\r
+       {\r
+               descript=_T("Modified");\r
+               return;\r
+       }\r
+       descript=_T("Created");\r
+       return;\r
+}\r
+\r
+CString CAppUtils::GetMergeTempFile(CString type,CTGitPath &merge)\r
+{\r
+       CString file;\r
+       file=g_Git.m_CurrentDir+_T("\\")+merge.GetDirectory().GetWinPathString()+_T("\\")+merge.GetFilename()+_T(".")+type+merge.GetFileExtension();\r
+\r
+       return file;\r
+}\r
+\r
 bool CAppUtils::ConflictEdit(CTGitPath &path,bool bAlternativeTool)\r
 {\r
        bool bRet = false;\r
@@ -1260,42 +1382,87 @@ bool CAppUtils::ConflictEdit(CTGitPath &path,bool bAlternativeTool)
        CTGitPath mine;\r
        CTGitPath base;\r
 \r
-       CString format;\r
-       format=g_Git.m_CurrentDir+_T("\\")+directory.GetWinPathString()+merge.GetFilename()+CString(_T(".%s."))+temp+merge.GetFileExtension();\r
+       \r
+       mine.SetFromGit(GetMergeTempFile(_T("LOCAL"),merge));\r
+       theirs.SetFromGit(GetMergeTempFile(_T("REMOTE"),merge));\r
+       base.SetFromGit(GetMergeTempFile(_T("BASE"),merge));\r
 \r
-       CString file;\r
-       file.Format(format,_T("LOCAL"));\r
-       mine.SetFromGit(file);\r
-       file.Format(format,_T("REMOTE"));\r
-       theirs.SetFromGit(file);\r
-       file.Format(format,_T("BASE"));\r
-       base.SetFromGit(file);\r
+       CString format;\r
 \r
-       \r
        format=_T("git.exe cat-file blob \":%d:%s\"");\r
+       CFile tempfile;\r
+       //create a empty file, incase stage is not three\r
+       tempfile.Open(mine.GetWinPathString(),CFile::modeCreate|CFile::modeReadWrite);\r
+       tempfile.Close();\r
+       tempfile.Open(theirs.GetWinPathString(),CFile::modeCreate|CFile::modeReadWrite);\r
+       tempfile.Close();\r
+       tempfile.Open(base.GetWinPathString(),CFile::modeCreate|CFile::modeReadWrite);\r
+       tempfile.Close();\r
+\r
+       bool b_base=false, b_local=false, b_remote=false;\r
+\r
        for(int i=0;i<list.GetCount();i++)\r
        {\r
                CString cmd;\r
                CString outfile;\r
                cmd.Format(format,list[i].m_Stage,list[i].GetGitPathString());\r
-\r
+               \r
                if( list[i].m_Stage == 1)\r
                {\r
+                       b_base = true;\r
                        outfile=base.GetWinPathString();\r
                }\r
                if( list[i].m_Stage == 2 )\r
                {\r
+                       b_local = true;\r
                        outfile=mine.GetWinPathString();\r
                }\r
                if( list[i].m_Stage == 3 )\r
                {\r
+                       b_remote = true;\r
                        outfile=theirs.GetWinPathString();\r
-               }\r
+               }       \r
                g_Git.RunLogFile(cmd,outfile);\r
        }\r
 \r
-       merge.SetFromWin(g_Git.m_CurrentDir+_T("\\")+merge.GetWinPathString());\r
-       bRet = !!CAppUtils::StartExtMerge(base, theirs, mine, merge,_T("BASE"),_T("REMOTE"),_T("LOCAL"));\r
+       if(b_local && b_remote )\r
+       {\r
+               merge.SetFromWin(g_Git.m_CurrentDir+_T("\\")+merge.GetWinPathString());\r
+               bRet = !!CAppUtils::StartExtMerge(base, theirs, mine, merge,_T("BASE"),_T("REMOTE"),_T("LOCAL"));\r
+       \r
+       }else\r
+       {\r
+               CFile::Remove(mine.GetWinPathString());\r
+               CFile::Remove(theirs.GetWinPathString());\r
+               CFile::Remove(base.GetWinPathString());\r
+\r
+               CDeleteConflictDlg dlg;\r
+               DescribeFile(b_local, b_base,dlg.m_LocalStatus);\r
+               DescribeFile(b_remote,b_base,dlg.m_RemoteStatus);\r
+               dlg.m_bShowModifiedButton=b_base;\r
+               dlg.m_File=merge.GetGitPathString();\r
+               if(dlg.DoModal() == IDOK)\r
+               {\r
+                       CString cmd,out;\r
+                       if(dlg.m_bIsDelete)\r
+                       {\r
+                               cmd.Format(_T("git.exe rm \"%s\""),merge.GetGitPathString());\r
+                       }else\r
+                               cmd.Format(_T("git.exe add \"%s\""),merge.GetGitPathString());\r
+\r
+                       if(g_Git.Run(cmd,&out,CP_ACP))\r
+                       {\r
+                               CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
+                               return FALSE;\r
+                       }\r
+                       return TRUE;\r
+               }\r
+               else \r
+                       return FALSE;\r
+\r
+               \r
+\r
+       }\r
 \r
 #if 0\r
 \r
@@ -1700,3 +1867,153 @@ CString CAppUtils::ExpandRelativeTime( int count, UINT format_1, UINT format_n )
        return answer;\r
 }\r
 \r
+bool CAppUtils::IsSSHPutty()\r
+{\r
+    CString sshclient=CRegString(_T("Software\\TortoiseGit\\SSH"));\r
+    sshclient=sshclient.MakeLower();\r
+    if(sshclient.Find(_T("plink.exe"),0)>=0)\r
+    {\r
+        return true;\r
+    }\r
+    return false;\r
+}\r
+\r
+CString CAppUtils::GetClipboardLink()\r
+{\r
+       if (!OpenClipboard(NULL))\r
+               return CString();\r
+\r
+       CString sClipboardText;\r
+       HGLOBAL hglb = GetClipboardData(CF_TEXT);\r
+       if (hglb)\r
+       {\r
+               LPCSTR lpstr = (LPCSTR)GlobalLock(hglb);\r
+               sClipboardText = CString(lpstr);\r
+               GlobalUnlock(hglb); \r
+       }\r
+       hglb = GetClipboardData(CF_UNICODETEXT);\r
+       if (hglb)\r
+       {\r
+               LPCTSTR lpstr = (LPCTSTR)GlobalLock(hglb);\r
+               sClipboardText = lpstr;\r
+               GlobalUnlock(hglb); \r
+       }\r
+       CloseClipboard();\r
+\r
+       if(!sClipboardText.IsEmpty())\r
+       {\r
+               if(sClipboardText[0] == _T('\"') && sClipboardText[sClipboardText.GetLength()-1] == _T('\"'))\r
+                       sClipboardText=sClipboardText.Mid(1,sClipboardText.GetLength()-2);\r
+\r
+               if(sClipboardText.Find( _T("http://")) == 0)\r
+                       return sClipboardText;\r
+               \r
+               if(sClipboardText.Find( _T("https://")) == 0)\r
+                       return sClipboardText;\r
+\r
+               if(sClipboardText.Find( _T("git://")) == 0)\r
+                       return sClipboardText;\r
+\r
+               if(sClipboardText.Find( _T("ssh://")) == 0)\r
+                       return sClipboardText;\r
+\r
+               if(sClipboardText.GetLength()>=2)\r
+                       if( sClipboardText[1] == _T(':') )\r
+                               if( (sClipboardText[0] >= 'A' &&  sClipboardText[0] <= 'Z') \r
+                                       || (sClipboardText[0] >= 'a' &&  sClipboardText[0] <= 'z') )\r
+                                       return sClipboardText;\r
+       }\r
+\r
+       return CString(_T(""));\r
+}\r
+\r
+CString CAppUtils::ChooseRepository(CString *path)\r
+{\r
+       CBrowseFolder browseFolder;\r
+       browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;\r
+       CString strCloneDirectory;\r
+       if(path)\r
+               strCloneDirectory=*path;\r
+\r
+       CString title;\r
+       title.LoadString(IDS_CHOOSE_REPOSITORY);\r
+\r
+       browseFolder.SetInfo(title);\r
+\r
+       if (browseFolder.Show(NULL, strCloneDirectory) == CBrowseFolder::OK) \r
+       {\r
+               return strCloneDirectory;\r
+               \r
+       }else\r
+       {\r
+               return CString();\r
+       }\r
+       \r
+}\r
+\r
+bool CAppUtils::SendPatchMail(CTGitPathList &list,bool autoclose)\r
+{\r
+       CSendMailDlg dlg;\r
+\r
+       dlg.m_PathList  = list;\r
+       \r
+       if(dlg.DoModal()==IDOK)\r
+       {\r
+               if(dlg.m_PathList.GetCount() == 0)\r
+                       return FALSE;\r
+       \r
+               CGitProgressDlg progDlg;\r
+               \r
+               theApp.m_pMainWnd = &progDlg;\r
+               progDlg.SetCommand(CGitProgressDlg::GitProgress_SendMail);\r
+                               \r
+               progDlg.SetAutoClose(autoclose);\r
+\r
+               progDlg.SetPathList(dlg.m_PathList);\r
+                               //ProjectProperties props;\r
+                               //props.ReadPropsPathList(dlg.m_pathList);\r
+                               //progDlg.SetProjectProperties(props);\r
+               progDlg.SetItemCount(dlg.m_PathList.GetCount());\r
+\r
+               DWORD flags =0;\r
+               if(dlg.m_bAttachment)\r
+                       flags |= SENDMAIL_ATTACHMENT;\r
+               if(dlg.m_bCombine)\r
+                       flags |= SENDMAIL_COMBINED;\r
+\r
+               progDlg.SetSendMailOption(dlg.m_To,dlg.m_CC,dlg.m_Subject,flags);\r
+               \r
+               progDlg.DoModal();              \r
+\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+int CAppUtils::SaveCommitUnicodeFile(CString &filename, CString &message)\r
+{\r
+       CFile file(filename,CFile::modeReadWrite|CFile::modeCreate );\r
+       CString cmd,output;\r
+       int cp=CP_UTF8;\r
+\r
+       cmd=_T("git.exe config i18n.commitencoding");\r
+       if(g_Git.Run(cmd,&output,CP_ACP))\r
+               cp=CP_UTF8;\r
+       \r
+       int start=0;\r
+       output=output.Tokenize(_T("\n"),start);\r
+       cp=CUnicodeUtils::GetCPCode(output);    \r
+\r
+       int len=message.GetLength();\r
+\r
+       char * buf;\r
+       buf = new char[len*4 + 4];\r
+       SecureZeroMemory(buf, (len*4 + 4));\r
+\r
+       int lengthIncTerminator = WideCharToMultiByte(cp, 0, message, -1, buf, len*4, NULL, NULL);\r
+\r
+       file.Write(buf,lengthIncTerminator-1);\r
+       file.Close();\r
+       delete buf;\r
+       return 0;\r
+}
\ No newline at end of file