Add Miss file
[TortoiseGit.git] / src / TortoiseShell / SVNPropertyPage.cpp
blobcc878442eab694766d2152cbee39e03681404c52
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - 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.
19 #include "stdafx.h"
21 #include "ShellExt.h"
22 #include "svnpropertypage.h"
23 #include "UnicodeUtils.h"
24 #include "PathUtils.h"
25 #include "GitStatus.h"
27 #define MAX_STRING_LENGTH 4096 //should be big enough
29 // Nonmember function prototypes
30 BOOL CALLBACK PageProc (HWND, UINT, WPARAM, LPARAM);
31 UINT CALLBACK PropPageCallbackProc ( HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp );
33 /////////////////////////////////////////////////////////////////////////////
34 // Dialog procedures and other callback functions
36 BOOL CALLBACK PageProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
38 CGitPropertyPage * sheetpage;
40 if (uMessage == WM_INITDIALOG)
42 sheetpage = (CGitPropertyPage*) ((LPPROPSHEETPAGE) lParam)->lParam;
43 SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) sheetpage);
44 sheetpage->SetHwnd(hwnd);
46 else
48 sheetpage = (CGitPropertyPage*) GetWindowLongPtr (hwnd, GWLP_USERDATA);
51 if (sheetpage != 0L)
52 return sheetpage->PageProc(hwnd, uMessage, wParam, lParam);
53 else
54 return FALSE;
57 UINT CALLBACK PropPageCallbackProc ( HWND /*hwnd*/, UINT uMsg, LPPROPSHEETPAGE ppsp )
59 // Delete the page before closing.
60 if (PSPCB_RELEASE == uMsg)
62 CGitPropertyPage* sheetpage = (CGitPropertyPage*) ppsp->lParam;
63 if (sheetpage != NULL)
64 delete sheetpage;
66 return 1;
69 // *********************** CGitPropertyPage *************************
71 CGitPropertyPage::CGitPropertyPage(const std::vector<stdstring> &newFilenames)
72 :filenames(newFilenames)
76 CGitPropertyPage::~CGitPropertyPage(void)
80 void CGitPropertyPage::SetHwnd(HWND newHwnd)
82 m_hwnd = newHwnd;
85 BOOL CGitPropertyPage::PageProc (HWND /*hwnd*/, UINT uMessage, WPARAM wParam, LPARAM lParam)
87 switch (uMessage)
89 case WM_INITDIALOG:
91 InitWorkfileView();
92 return TRUE;
94 case WM_NOTIFY:
96 LPNMHDR point = (LPNMHDR)lParam;
97 int code = point->code;
99 // Respond to notifications.
101 if (code == PSN_APPLY)
104 SetWindowLongPtr (m_hwnd, DWLP_MSGRESULT, FALSE);
105 return TRUE;
108 case WM_DESTROY:
109 return TRUE;
111 case WM_COMMAND:
112 switch (HIWORD(wParam))
114 case BN_CLICKED:
115 if (LOWORD(wParam) == IDC_SHOWLOG)
117 STARTUPINFO startup;
118 PROCESS_INFORMATION process;
119 memset(&startup, 0, sizeof(startup));
120 startup.cb = sizeof(startup);
121 memset(&process, 0, sizeof(process));
122 CRegStdString tortoiseProcPath(_T("Software\\TortoiseGit\\ProcPath"), _T("TortoiseProc.exe"), false, HKEY_LOCAL_MACHINE);
123 stdstring svnCmd = _T(" /command:");
124 svnCmd += _T("log /path:\"");
125 svnCmd += filenames.front().c_str();
126 svnCmd += _T("\"");
127 if (CreateProcess(((stdstring)tortoiseProcPath).c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))
129 CloseHandle(process.hThread);
130 CloseHandle(process.hProcess);
133 if (LOWORD(wParam) == IDC_EDITPROPERTIES)
135 DWORD pathlength = GetTempPath(0, NULL);
136 TCHAR * path = new TCHAR[pathlength+1];
137 TCHAR * tempFile = new TCHAR[pathlength + 100];
138 GetTempPath (pathlength+1, path);
139 GetTempFileName (path, _T("svn"), 0, tempFile);
140 stdstring retFilePath = stdstring(tempFile);
142 HANDLE file = ::CreateFile (tempFile,
143 GENERIC_WRITE,
144 FILE_SHARE_READ,
146 CREATE_ALWAYS,
147 FILE_ATTRIBUTE_TEMPORARY,
150 delete [] path;
151 delete [] tempFile;
152 if (file != INVALID_HANDLE_VALUE)
154 DWORD written = 0;
155 for (std::vector<stdstring>::iterator I = filenames.begin(); I != filenames.end(); ++I)
157 ::WriteFile (file, I->c_str(), I->size()*sizeof(TCHAR), &written, 0);
158 ::WriteFile (file, _T("\n"), 2, &written, 0);
160 ::CloseHandle(file);
162 STARTUPINFO startup;
163 PROCESS_INFORMATION process;
164 memset(&startup, 0, sizeof(startup));
165 startup.cb = sizeof(startup);
166 memset(&process, 0, sizeof(process));
167 CRegStdString tortoiseProcPath(_T("Software\\TortoiseGit\\ProcPath"), _T("TortoiseProc.exe"), false, HKEY_LOCAL_MACHINE);
168 stdstring svnCmd = _T(" /command:");
169 svnCmd += _T("properties /pathfile:\"");
170 svnCmd += retFilePath.c_str();
171 svnCmd += _T("\"");
172 svnCmd += _T(" /deletepathfile");
173 if (CreateProcess(((stdstring)tortoiseProcPath).c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))
175 CloseHandle(process.hThread);
176 CloseHandle(process.hProcess);
180 break;
181 } // switch (HIWORD(wParam))
182 } // switch (uMessage)
183 return FALSE;
185 void CGitPropertyPage::Time64ToTimeString(__time64_t time, TCHAR * buf, size_t buflen)
187 struct tm newtime;
188 SYSTEMTIME systime;
189 TCHAR timebuf[MAX_STRING_LENGTH];
190 TCHAR datebuf[MAX_STRING_LENGTH];
192 LCID locale = (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT));
193 locale = MAKELCID(locale, SORT_DEFAULT);
195 *buf = '\0';
196 if (time)
198 _localtime64_s(&newtime, &time);
200 systime.wDay = (WORD)newtime.tm_mday;
201 systime.wDayOfWeek = (WORD)newtime.tm_wday;
202 systime.wHour = (WORD)newtime.tm_hour;
203 systime.wMilliseconds = 0;
204 systime.wMinute = (WORD)newtime.tm_min;
205 systime.wMonth = (WORD)newtime.tm_mon+1;
206 systime.wSecond = (WORD)newtime.tm_sec;
207 systime.wYear = (WORD)newtime.tm_year+1900;
208 if (CRegStdWORD(_T("Software\\TortoiseGit\\LogDateFormat")) == 1)
209 GetDateFormat(locale, DATE_SHORTDATE, &systime, NULL, datebuf, MAX_STRING_LENGTH);
210 else
211 GetDateFormat(locale, DATE_LONGDATE, &systime, NULL, datebuf, MAX_STRING_LENGTH);
212 GetTimeFormat(locale, 0, &systime, NULL, timebuf, MAX_STRING_LENGTH);
213 *buf = '\0';
214 _tcsncat_s(buf, buflen, timebuf, MAX_STRING_LENGTH-1);
215 _tcsncat_s(buf, buflen, _T(", "), MAX_STRING_LENGTH-1);
216 _tcsncat_s(buf, buflen, datebuf, MAX_STRING_LENGTH-1);
220 void CGitPropertyPage::InitWorkfileView()
222 GitStatus svn = GitStatus();
223 TCHAR tbuf[MAX_STRING_LENGTH];
224 if (filenames.size() == 1)
226 if (svn.GetStatus(CTGitPath(filenames.front().c_str()))>(-2))
228 TCHAR buf[MAX_STRING_LENGTH];
229 __time64_t time;
230 if (svn.status->entry != NULL)
232 LoadLangDll();
233 if (svn.status->text_status == svn_wc_status_added)
235 // disable the "show log" button for added files
236 HWND showloghwnd = GetDlgItem(m_hwnd, IDC_SHOWLOG);
237 if (GetFocus() == showloghwnd)
238 ::SendMessage(m_hwnd, WM_NEXTDLGCTL, 0, FALSE);
239 ::EnableWindow(showloghwnd, FALSE);
241 else
243 _stprintf_s(buf, MAX_STRING_LENGTH, _T("%d"), svn.status->entry->revision);
244 SetDlgItemText(m_hwnd, IDC_REVISION, buf);
246 if (svn.status->entry->url)
248 size_t len = strlen(svn.status->entry->url);
249 char * unescapedurl = new char[len+1];
250 strcpy_s(unescapedurl, len+1, svn.status->entry->url);
251 CPathUtils::Unescape(unescapedurl);
252 SetDlgItemText(m_hwnd, IDC_REPOURL, UTF8ToWide(unescapedurl).c_str());
253 if (strcmp(unescapedurl, svn.status->entry->url))
255 ShowWindow(GetDlgItem(m_hwnd, IDC_ESCAPEDURLLABEL), SW_SHOW);
256 ShowWindow(GetDlgItem(m_hwnd, IDC_REPOURLUNESCAPED), SW_SHOW);
257 SetDlgItemText(m_hwnd, IDC_REPOURLUNESCAPED, UTF8ToWide(svn.status->entry->url).c_str());
259 else
261 ShowWindow(GetDlgItem(m_hwnd, IDC_ESCAPEDURLLABEL), SW_HIDE);
262 ShowWindow(GetDlgItem(m_hwnd, IDC_REPOURLUNESCAPED), SW_HIDE);
264 delete [] unescapedurl;
266 else
268 ShowWindow(GetDlgItem(m_hwnd, IDC_ESCAPEDURLLABEL), SW_HIDE);
269 ShowWindow(GetDlgItem(m_hwnd, IDC_REPOURLUNESCAPED), SW_HIDE);
271 if (svn.status->text_status != svn_wc_status_added)
273 _stprintf_s(buf, MAX_STRING_LENGTH, _T("%d"), svn.status->entry->cmt_rev);
274 SetDlgItemText(m_hwnd, IDC_CREVISION, buf);
275 time = (__time64_t)svn.status->entry->cmt_date/1000000L;
276 Time64ToTimeString(time, buf, MAX_STRING_LENGTH);
277 SetDlgItemText(m_hwnd, IDC_CDATE, buf);
279 if (svn.status->entry->cmt_author)
280 SetDlgItemText(m_hwnd, IDC_AUTHOR, UTF8ToWide(svn.status->entry->cmt_author).c_str());
281 GitStatus::GetStatusString(g_hResInst, svn.status->text_status, buf, sizeof(buf)/sizeof(TCHAR), (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)));
282 SetDlgItemText(m_hwnd, IDC_TEXTSTATUS, buf);
283 GitStatus::GetStatusString(g_hResInst, svn.status->prop_status, buf, sizeof(buf)/sizeof(TCHAR), (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)));
284 SetDlgItemText(m_hwnd, IDC_PROPSTATUS, buf);
285 time = (__time64_t)svn.status->entry->text_time/1000000L;
286 Time64ToTimeString(time, buf, MAX_STRING_LENGTH);
287 SetDlgItemText(m_hwnd, IDC_TEXTDATE, buf);
288 time = (__time64_t)svn.status->entry->prop_time/1000000L;
289 Time64ToTimeString(time, buf, MAX_STRING_LENGTH);
290 SetDlgItemText(m_hwnd, IDC_PROPDATE, buf);
292 if (svn.status->entry->lock_owner)
293 SetDlgItemText(m_hwnd, IDC_LOCKOWNER, UTF8ToWide(svn.status->entry->lock_owner).c_str());
294 time = (__time64_t)svn.status->entry->lock_creation_date/1000000L;
295 Time64ToTimeString(time, buf, MAX_STRING_LENGTH);
296 SetDlgItemText(m_hwnd, IDC_LOCKDATE, buf);
298 if (svn.status->entry->uuid)
299 SetDlgItemText(m_hwnd, IDC_REPOUUID, UTF8ToWide(svn.status->entry->uuid).c_str());
300 if (svn.status->entry->changelist)
301 SetDlgItemText(m_hwnd, IDC_CHANGELIST, UTF8ToWide(svn.status->entry->changelist).c_str());
302 GitStatus::GetDepthString(g_hResInst, svn.status->entry->depth, buf, sizeof(buf)/sizeof(TCHAR), (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)));
303 SetDlgItemText(m_hwnd, IDC_DEPTHEDIT, buf);
305 if (svn.status->entry->checksum)
306 SetDlgItemText(m_hwnd, IDC_CHECKSUM, UTF8ToWide(svn.status->entry->checksum).c_str());
308 if (svn.status->locked)
309 MAKESTRING(IDS_YES);
310 else
311 MAKESTRING(IDS_NO);
312 SetDlgItemText(m_hwnd, IDC_LOCKED, stringtablebuffer);
314 if (svn.status->copied)
315 MAKESTRING(IDS_YES);
316 else
317 MAKESTRING(IDS_NO);
318 SetDlgItemText(m_hwnd, IDC_COPIED, stringtablebuffer);
320 if (svn.status->switched)
321 MAKESTRING(IDS_YES);
322 else
323 MAKESTRING(IDS_NO);
324 SetDlgItemText(m_hwnd, IDC_SWITCHED, stringtablebuffer);
325 } // if (svn.status->entry != NULL)
326 } // if (svn.GetStatus(CTGitPath(filenames.front().c_str()))>(-2))
327 } // if (filenames.size() == 1)
328 else if (filenames.size() != 0)
330 //deactivate the show log button
331 HWND logwnd = GetDlgItem(m_hwnd, IDC_SHOWLOG);
332 if (GetFocus() == logwnd)
333 ::SendMessage(m_hwnd, WM_NEXTDLGCTL, 0, FALSE);
334 ::EnableWindow(logwnd, FALSE);
335 //get the handle of the list view
336 if (svn.GetStatus(CTGitPath(filenames.front().c_str()))>(-2))
338 if (svn.status->entry != NULL)
340 LoadLangDll();
341 if (svn.status->entry->url)
343 CPathUtils::Unescape((char*)svn.status->entry->url);
344 _tcsncpy_s(tbuf, MAX_STRING_LENGTH, UTF8ToWide(svn.status->entry->url).c_str(), 4095);
345 TCHAR * ptr = _tcsrchr(tbuf, '/');
346 if (ptr != 0)
348 *ptr = 0;
350 SetDlgItemText(m_hwnd, IDC_REPOURL, tbuf);
352 SetDlgItemText(m_hwnd, IDC_LOCKED, _T(""));
353 SetDlgItemText(m_hwnd, IDC_COPIED, _T(""));
354 SetDlgItemText(m_hwnd, IDC_SWITCHED, _T(""));
356 SetDlgItemText(m_hwnd, IDC_DEPTHEDIT, _T(""));
357 SetDlgItemText(m_hwnd, IDC_CHECKSUM, _T(""));
358 SetDlgItemText(m_hwnd, IDC_REPOUUID, _T(""));
360 ShowWindow(GetDlgItem(m_hwnd, IDC_ESCAPEDURLLABEL), SW_HIDE);
361 ShowWindow(GetDlgItem(m_hwnd, IDC_REPOURLUNESCAPED), SW_HIDE);