Sync translations with Transifex
[TortoiseGit.git] / src / TortoiseGitBlame / TortoiseGitBlameDoc.cpp
blob9e485a68c62c18c21608d0d63a32a714583ceec7
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2014 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 // TortoiseGitBlameDoc.cpp : implementation of the CTortoiseGitBlameDoc class
24 #include "stdafx.h"
25 #include "TortoiseGitBlame.h"
27 #include "TortoiseGitBlameDoc.h"
28 #include "GitAdminDir.h"
29 #include "MessageBox.h"
30 #include "Git.h"
31 #include "MainFrm.h"
32 #include "TGitPath.h"
33 #include "TortoiseGitBlameView.h"
34 #include "CmdLineParser.h"
35 #include "CommonAppUtils.h"
36 #include "BlameDetectMovedOrCopiedLines.h"
38 #ifdef _DEBUG
39 #define new DEBUG_NEW
40 #endif
43 // CTortoiseGitBlameDoc
45 IMPLEMENT_DYNCREATE(CTortoiseGitBlameDoc, CDocument)
47 BEGIN_MESSAGE_MAP(CTortoiseGitBlameDoc, CDocument)
48 END_MESSAGE_MAP()
51 // CTortoiseGitBlameDoc construction/destruction
53 CTortoiseGitBlameDoc::CTortoiseGitBlameDoc()
55 m_bFirstStartup = true;
56 m_IsGitFile = FALSE;
57 m_lLine = 1;
60 CTortoiseGitBlameDoc::~CTortoiseGitBlameDoc()
64 BOOL CTortoiseGitBlameDoc::OnNewDocument()
66 return TRUE;
68 BOOL CTortoiseGitBlameDoc::OnOpenDocument(LPCTSTR lpszPathName)
70 CCmdLineParser parser(AfxGetApp()->m_lpCmdLine);
71 if (m_bFirstStartup)
73 m_Rev=parser.GetVal(_T("rev"));
74 m_lLine = (int)parser.GetLongVal(_T("line"));
75 m_bFirstStartup = false;
77 else
79 m_Rev.Empty();
80 m_lLine = 1;
83 return OnOpenDocument(lpszPathName,m_Rev);
86 BOOL CTortoiseGitBlameDoc::OnOpenDocument(LPCTSTR lpszPathName,CString Rev)
88 if(Rev.IsEmpty())
89 Rev = _T("HEAD");
91 // enable blame for files which do not exist in current working tree
92 if (!PathFileExists(lpszPathName) && Rev != _T("HEAD"))
94 if (!CDocument::OnOpenDocument(GetTempFile()))
95 return FALSE;
97 else
99 if (!CDocument::OnOpenDocument(lpszPathName))
100 return FALSE;
103 m_CurrentFileName = lpszPathName;
105 m_Rev=Rev;
107 // (SDI documents will reuse this document)
108 if(!g_Git.CheckMsysGitDir())
110 CCommonAppUtils::RunTortoiseGitProc(_T(" /command:settings"));
111 return FALSE;
113 GitAdminDir admindir;
114 CString topdir;
115 if(!admindir.HasAdminDir(m_CurrentFileName, &topdir))
117 CString temp;
118 temp.Format(IDS_CANNOTBLAMENOGIT, CString(m_CurrentFileName));
119 CMessageBox::Show(NULL, temp, _T("TortoiseGitBlame"), MB_OK);
120 return FALSE;
122 else
124 GitAdminDir lastAdminDir;
125 CString oldTopDir;
126 if (topdir != g_Git.m_CurrentDir && CTGitPath(g_Git.m_CurrentDir).HasAdminDir(&oldTopDir) && oldTopDir != topdir)
128 CString sMsg;
129 sMsg.Format(IDS_ERR_DIFFENERTPREPO, oldTopDir, topdir);
130 MessageBox(NULL, sMsg, _T("TortoiseGitBlame"), MB_OK | MB_ICONERROR);
131 return FALSE;
134 m_IsGitFile=TRUE;
135 sOrigCWD = g_Git.m_CurrentDir = topdir;
137 CString PathName = m_CurrentFileName;
138 if(topdir[topdir.GetLength()-1] == _T('\\') ||
139 topdir[topdir.GetLength()-1] == _T('/'))
140 PathName=PathName.Right(PathName.GetLength()-g_Git.m_CurrentDir.GetLength());
141 else
142 PathName=PathName.Right(PathName.GetLength()-g_Git.m_CurrentDir.GetLength()-1);
144 CTGitPath path;
145 path.SetFromWin(PathName);
147 if(!g_Git.m_CurrentDir.IsEmpty())
148 SetCurrentDirectory(g_Git.m_CurrentDir);
152 // make sure all config files are read in order to check that none contains an error
153 g_Git.GetConfigValue(_T("doesnot.exist"));
155 catch (char * libgiterr)
157 MessageBox(NULL, CString(libgiterr), _T("TortoiseGitBlame"), MB_ICONERROR);
158 return FALSE;
161 CString cmd, option;
162 int dwDetectMovedOrCopiedLines = theApp.GetInt(_T("DetectMovedOrCopiedLines"), BLAME_DETECT_MOVED_OR_COPIED_LINES_DISABLED);
163 int dwDetectMovedOrCopiedLinesNumCharactersWithinFile = theApp.GetInt(_T("DetectMovedOrCopiedLinesNumCharactersWithinFile"), BLAME_DETECT_MOVED_OR_COPIED_LINES_NUM_CHARACTERS_WITHIN_FILE_DEFAULT);
164 int dwDetectMovedOrCopiedLinesNumCharactersFromFiles = theApp.GetInt(_T("DetectMovedOrCopiedLinesNumCharactersFromFiles"), BLAME_DETECT_MOVED_OR_COPIED_LINES_NUM_CHARACTERS_FROM_FILES_DEFAULT);
165 switch(dwDetectMovedOrCopiedLines)
167 default:
168 case BLAME_DETECT_MOVED_OR_COPIED_LINES_DISABLED:
169 option.Empty();
170 break;
171 case BLAME_DETECT_MOVED_OR_COPIED_LINES_WITHIN_FILE:
172 option.Format(_T("-M%d"), dwDetectMovedOrCopiedLinesNumCharactersWithinFile);
173 break;
174 case BLAME_DETECT_MOVED_OR_COPIED_LINES_FROM_MODIFIED_FILES:
175 option.Format(_T("-C%d"), dwDetectMovedOrCopiedLinesNumCharactersFromFiles);
176 break;
177 case BLAME_DETECT_MOVED_OR_COPIED_LINES_FROM_EXISTING_FILES_AT_FILE_CREATION:
178 option.Format(_T("-C -C%d"), dwDetectMovedOrCopiedLinesNumCharactersFromFiles);
179 break;
180 case BLAME_DETECT_MOVED_OR_COPIED_LINES_FROM_EXISTING_FILES:
181 option.Format(_T("-C -C -C%d"), dwDetectMovedOrCopiedLinesNumCharactersFromFiles);
182 break;
185 if (theApp.GetInt(_T("IgnoreWhitespace"), 0) == 1)
186 option += _T(" -w");
188 cmd.Format(_T("git.exe blame -p %s %s -- \"%s\""), option, Rev, path.GetGitPathString());
189 m_BlameData.clear();
190 BYTE_VECTOR err;
191 if(g_Git.Run(cmd, &m_BlameData, &err))
193 CString str;
194 if (!m_BlameData.empty())
195 g_Git.StringAppend(&str, &m_BlameData[0], CP_UTF8);
196 if (!err.empty())
197 g_Git.StringAppend(&str, &err[0], CP_UTF8);
198 MessageBox(NULL, CString(MAKEINTRESOURCE(IDS_BLAMEERROR)) + _T("\n\n") + str, _T("TortoiseGitBlame"), MB_OK);
200 return FALSE;
203 #ifdef USE_TEMPFILENAME
204 if(!m_TempFileName.IsEmpty())
206 ::DeleteFile(m_TempFileName);
207 m_TempFileName.Empty();
210 m_TempFileName=GetTempFile();
212 cmd.Format(_T("git.exe cat-file blob %s:\"%s\""),Rev,path.GetGitPathString());
214 if(g_Git.RunLogFile(cmd, m_TempFileName))
216 CString str;
217 str.Format(IDS_CHECKOUTFAILED, path.GetGitPathString());
218 MessageBox(NULL, CString(MAKEINTRESOURCE(IDS_BLAMEERROR)) + _T("\n\n") + str, _T("TortoiseGitBlame"), MB_OK);
219 return FALSE;
221 #endif
222 m_GitPath = path;
224 CTortoiseGitBlameView *pView=DYNAMIC_DOWNCAST(CTortoiseGitBlameView,GetMainFrame()->GetActiveView());
225 if(pView == NULL)
227 CWnd* pWnd = GetMainFrame()->GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
228 if (pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CTortoiseGitBlameView)))
230 pView = (CTortoiseGitBlameView*)pWnd;
232 else
234 return FALSE;
237 pView->ParseBlame();
239 BOOL bShowCompleteLog = (theApp.GetInt(_T("ShowCompleteLog"), 1) == 1);
240 if (bShowCompleteLog && BlameIsLimitedToOneFilename(dwDetectMovedOrCopiedLines))
242 if (GetMainFrame()->m_wndOutput.LoadHistory(path.GetGitPathString(), m_Rev, (theApp.GetInt(_T("FollowRenames"), 0) == 1)))
243 return FALSE;
245 else
247 std::set<CGitHash> hashes;
248 pView->m_data.GetHashes(hashes);
249 if (GetMainFrame()->m_wndOutput.LoadHistory(hashes))
250 return FALSE;
253 pView->MapLineToLogIndex();
254 pView->UpdateInfo();
255 if (m_lLine > 0)
256 pView->GotoLine(m_lLine);
258 SetPathName(m_CurrentFileName, FALSE);
261 return TRUE;
264 void CTortoiseGitBlameDoc::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU)
266 CDocument::SetPathName(lpszPathName, bAddToMRU && (m_Rev == _T("HEAD")));
268 this->SetTitle(CString(lpszPathName) + _T(":") + m_Rev);
271 // CTortoiseGitBlameDoc diagnostics
273 #ifdef _DEBUG
274 void CTortoiseGitBlameDoc::AssertValid() const
276 CDocument::AssertValid();
279 void CTortoiseGitBlameDoc::Dump(CDumpContext& dc) const
281 CDocument::Dump(dc);
283 #endif //_DEBUG
286 // CTortoiseGitBlameDoc commands