OSDN Git Service

Change Log Code structure Unfinished
[tortoisegit/TortoiseGitJp.git] / src / TortoiseShell / SVNPropertyPage.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2008 - TortoiseGit\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "stdafx.h"\r
20 \r
21 #include "ShellExt.h"\r
22 #include "svnpropertypage.h"\r
23 #include "UnicodeUtils.h"\r
24 #include "PathUtils.h"\r
25 #include "GitStatus.h"\r
26 \r
27 #define MAX_STRING_LENGTH               4096                    //should be big enough\r
28 \r
29 // Nonmember function prototypes\r
30 BOOL CALLBACK PageProc (HWND, UINT, WPARAM, LPARAM);\r
31 UINT CALLBACK PropPageCallbackProc ( HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp );\r
32 \r
33 /////////////////////////////////////////////////////////////////////////////\r
34 // Dialog procedures and other callback functions\r
35 \r
36 BOOL CALLBACK PageProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)\r
37 {\r
38     CGitPropertyPage * sheetpage;\r
39 \r
40     if (uMessage == WM_INITDIALOG)\r
41     {\r
42         sheetpage = (CGitPropertyPage*) ((LPPROPSHEETPAGE) lParam)->lParam;\r
43         SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) sheetpage);\r
44         sheetpage->SetHwnd(hwnd);\r
45     }\r
46     else\r
47     {\r
48         sheetpage = (CGitPropertyPage*) GetWindowLongPtr (hwnd, GWLP_USERDATA);\r
49     }\r
50 \r
51     if (sheetpage != 0L)\r
52         return sheetpage->PageProc(hwnd, uMessage, wParam, lParam);\r
53     else\r
54         return FALSE;\r
55 }\r
56 \r
57 UINT CALLBACK PropPageCallbackProc ( HWND /*hwnd*/, UINT uMsg, LPPROPSHEETPAGE ppsp )\r
58 {\r
59     // Delete the page before closing.\r
60     if (PSPCB_RELEASE == uMsg)\r
61     {\r
62         CGitPropertyPage* sheetpage = (CGitPropertyPage*) ppsp->lParam;\r
63         if (sheetpage != NULL)\r
64             delete sheetpage;\r
65     }\r
66     return 1;\r
67 }\r
68 \r
69 // *********************** CGitPropertyPage *************************\r
70 \r
71 CGitPropertyPage::CGitPropertyPage(const std::vector<stdstring> &newFilenames)\r
72         :filenames(newFilenames)\r
73 {\r
74 }\r
75 \r
76 CGitPropertyPage::~CGitPropertyPage(void)\r
77 {\r
78 }\r
79 \r
80 void CGitPropertyPage::SetHwnd(HWND newHwnd)\r
81 {\r
82     m_hwnd = newHwnd;\r
83 }\r
84 \r
85 BOOL CGitPropertyPage::PageProc (HWND /*hwnd*/, UINT uMessage, WPARAM wParam, LPARAM lParam)\r
86 {\r
87         switch (uMessage)\r
88         {\r
89         case WM_INITDIALOG:\r
90                 {\r
91                         InitWorkfileView();\r
92                         return TRUE;\r
93                 }\r
94         case WM_NOTIFY:\r
95                 {\r
96                         LPNMHDR point = (LPNMHDR)lParam;\r
97                         int code = point->code;\r
98                         //\r
99                         // Respond to notifications.\r
100                         //    \r
101                         if (code == PSN_APPLY)\r
102                         {\r
103                         }\r
104                         SetWindowLongPtr (m_hwnd, DWLP_MSGRESULT, FALSE);\r
105                         return TRUE;        \r
106 \r
107                         }\r
108                 case WM_DESTROY:\r
109                         return TRUE;\r
110 \r
111                 case WM_COMMAND:\r
112                         switch (HIWORD(wParam))\r
113                         {\r
114                                 case BN_CLICKED:\r
115                                         if (LOWORD(wParam) == IDC_SHOWLOG)\r
116                                         {\r
117                                                 STARTUPINFO startup;\r
118                                                 PROCESS_INFORMATION process;\r
119                                                 memset(&startup, 0, sizeof(startup));\r
120                                                 startup.cb = sizeof(startup);\r
121                                                 memset(&process, 0, sizeof(process));\r
122                                                 CRegStdString tortoiseProcPath(_T("Software\\TortoiseGit\\ProcPath"), _T("TortoiseProc.exe"), false, HKEY_LOCAL_MACHINE);\r
123                                                 stdstring svnCmd = _T(" /command:");\r
124                                                 svnCmd += _T("log /path:\"");\r
125                                                 svnCmd += filenames.front().c_str();\r
126                                                 svnCmd += _T("\"");\r
127                                                 if (CreateProcess(((stdstring)tortoiseProcPath).c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))\r
128                                                 {\r
129                                                         CloseHandle(process.hThread);\r
130                                                         CloseHandle(process.hProcess);\r
131                                                 }\r
132                                         }\r
133                                         if (LOWORD(wParam) == IDC_EDITPROPERTIES)\r
134                                         {\r
135                                                 DWORD pathlength = GetTempPath(0, NULL);\r
136                                                 TCHAR * path = new TCHAR[pathlength+1];\r
137                                                 TCHAR * tempFile = new TCHAR[pathlength + 100];\r
138                                                 GetTempPath (pathlength+1, path);\r
139                                                 GetTempFileName (path, _T("svn"), 0, tempFile);\r
140                                                 stdstring retFilePath = stdstring(tempFile);\r
141 \r
142                                                 HANDLE file = ::CreateFile (tempFile,\r
143                                                         GENERIC_WRITE, \r
144                                                         FILE_SHARE_READ, \r
145                                                         0, \r
146                                                         CREATE_ALWAYS, \r
147                                                         FILE_ATTRIBUTE_TEMPORARY,\r
148                                                         0);\r
149 \r
150                                                 delete [] path;\r
151                                                 delete [] tempFile;\r
152                                                 if (file != INVALID_HANDLE_VALUE)\r
153                                                 {\r
154                                                         DWORD written = 0;\r
155                                                         for (std::vector<stdstring>::iterator I = filenames.begin(); I != filenames.end(); ++I)\r
156                                                         {\r
157                                                                 ::WriteFile (file, I->c_str(), I->size()*sizeof(TCHAR), &written, 0);\r
158                                                                 ::WriteFile (file, _T("\n"), 2, &written, 0);\r
159                                                         }\r
160                                                         ::CloseHandle(file);\r
161 \r
162                                                         STARTUPINFO startup;\r
163                                                         PROCESS_INFORMATION process;\r
164                                                         memset(&startup, 0, sizeof(startup));\r
165                                                         startup.cb = sizeof(startup);\r
166                                                         memset(&process, 0, sizeof(process));\r
167                                                         CRegStdString tortoiseProcPath(_T("Software\\TortoiseGit\\ProcPath"), _T("TortoiseProc.exe"), false, HKEY_LOCAL_MACHINE);\r
168                                                         stdstring svnCmd = _T(" /command:");\r
169                                                         svnCmd += _T("properties /pathfile:\"");\r
170                                                         svnCmd += retFilePath.c_str();\r
171                                                         svnCmd += _T("\"");\r
172                                                         svnCmd += _T(" /deletepathfile");\r
173                                                         if (CreateProcess(((stdstring)tortoiseProcPath).c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))\r
174                                                         {\r
175                                                                 CloseHandle(process.hThread);\r
176                                                                 CloseHandle(process.hProcess);\r
177                                                         }\r
178                                                 }\r
179                                         }\r
180                                         break;\r
181                         } // switch (HIWORD(wParam)) \r
182         } // switch (uMessage) \r
183         return FALSE;\r
184 }\r
185 void CGitPropertyPage::Time64ToTimeString(__time64_t time, TCHAR * buf, size_t buflen)\r
186 {\r
187         struct tm newtime;\r
188         SYSTEMTIME systime;\r
189         TCHAR timebuf[MAX_STRING_LENGTH];\r
190         TCHAR datebuf[MAX_STRING_LENGTH];\r
191 \r
192         LCID locale = (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT));\r
193         locale = MAKELCID(locale, SORT_DEFAULT);\r
194 \r
195         *buf = '\0';\r
196         if (time)\r
197         {\r
198                 _localtime64_s(&newtime, &time);\r
199 \r
200                 systime.wDay = (WORD)newtime.tm_mday;\r
201                 systime.wDayOfWeek = (WORD)newtime.tm_wday;\r
202                 systime.wHour = (WORD)newtime.tm_hour;\r
203                 systime.wMilliseconds = 0;\r
204                 systime.wMinute = (WORD)newtime.tm_min;\r
205                 systime.wMonth = (WORD)newtime.tm_mon+1;\r
206                 systime.wSecond = (WORD)newtime.tm_sec;\r
207                 systime.wYear = (WORD)newtime.tm_year+1900;\r
208                 if (CRegStdWORD(_T("Software\\TortoiseGit\\LogDateFormat")) == 1)\r
209                         GetDateFormat(locale, DATE_SHORTDATE, &systime, NULL, datebuf, MAX_STRING_LENGTH);\r
210                 else\r
211                         GetDateFormat(locale, DATE_LONGDATE, &systime, NULL, datebuf, MAX_STRING_LENGTH);\r
212                 GetTimeFormat(locale, 0, &systime, NULL, timebuf, MAX_STRING_LENGTH);\r
213                 *buf = '\0';\r
214                 _tcsncat_s(buf, buflen, timebuf, MAX_STRING_LENGTH-1);\r
215                 _tcsncat_s(buf, buflen, _T(", "), MAX_STRING_LENGTH-1);\r
216                 _tcsncat_s(buf, buflen, datebuf, MAX_STRING_LENGTH-1);\r
217         }\r
218 }\r
219 \r
220 void CGitPropertyPage::InitWorkfileView()\r
221 {\r
222         CString username;\r
223         //can't git.exe when create process\r
224         g_Git.Run(_T("tgit config user.name"),&username,CP_ACP);\r
225         CString useremail;\r
226         g_Git.Run(_T("tgit config user.email"),&useremail,CP_ACP);\r
227         CString autocrlf;\r
228         g_Git.Run(_T("tgit config core.autocrlf"),&autocrlf,CP_ACP);\r
229         CString safecrlf;\r
230         g_Git.Run(_T("tgit config core.safecrlf"),&safecrlf,CP_ACP);\r
231 \r
232         CString branch;\r
233         CString headhash;\r
234         CString remotebranch;\r
235 \r
236         g_Git.Run(_T("tgit symbolic-ref HEAD"),&branch,CP_ACP);\r
237         CString cmd,log;\r
238 \r
239         if(!branch.IsEmpty())\r
240         {\r
241                 if( branch.Find(_T("refs/heads/"),0) >=0 )\r
242                 {\r
243                         CString remote;\r
244                         branch=branch.Mid(11);\r
245                         int start=0;\r
246                         branch=branch.Tokenize(_T("\n"),start);\r
247                         start=0;\r
248                         branch=branch.Tokenize(_T("\r"),start);\r
249                         cmd.Format(_T("tgit config branch.%s.merge"),branch);\r
250                         g_Git.Run(cmd,&remotebranch,CP_ACP);\r
251                         cmd.Format(_T("tgit config branch.%s.remote"),branch);\r
252                         g_Git.Run(cmd,&remote,CP_ACP);\r
253                         if((!remote.IsEmpty()) && (!remotebranch.IsEmpty()))\r
254                         {\r
255                                 remotebranch=remotebranch.Mid(11);\r
256                                 remotebranch=remote+_T("/")+remotebranch;\r
257                         }\r
258                 }\r
259         }\r
260 \r
261 \r
262         BYTE_VECTOR logout;\r
263 \r
264         \r
265         cmd=_T("tgit log -z --topo-order -n1 --parents --pretty=format:\"");\r
266         \r
267         g_Git.BuildOutputFormat(log,true);\r
268 \r
269         cmd += log;\r
270         cmd += CString(_T("\"  "));\r
271 \r
272         g_Git.Run(cmd,&logout);\r
273         GitRev rev;\r
274         rev.ParserFromLog(logout);\r
275 \r
276         SetDlgItemText(m_hwnd,IDC_CONFIG_USERNAME,username);\r
277         SetDlgItemText(m_hwnd,IDC_CONFIG_USEREMAIL,useremail);\r
278         SetDlgItemText(m_hwnd,IDC_CONFIG_AUTOCRLF,autocrlf);\r
279         SetDlgItemText(m_hwnd,IDC_CONFIG_SAFECRLF,safecrlf);\r
280 \r
281         SetDlgItemText(m_hwnd,IDC_SHELL_CURRENT_BRANCH,branch);\r
282         SetDlgItemText(m_hwnd,IDC_SHELL_REMOTE_BRANCH,remotebranch);\r
283 \r
284         SetDlgItemText(m_hwnd,IDC_HEAD_HASH,rev.m_CommitHash.ToString());\r
285         SetDlgItemText(m_hwnd,IDC_HEAD_SUBJECT,rev.m_Subject);\r
286         SetDlgItemText(m_hwnd,IDC_HEAD_AUTHOR,rev.m_AuthorName);\r
287         SetDlgItemText(m_hwnd,IDC_HEAD_DATE,rev.m_AuthorDate.Format(_T("%Y-%m-%d %H:%M:%S")));\r
288 \r
289         if (filenames.size() == 1)\r
290         {\r
291                 CTGitPath path(filenames.front().c_str());\r
292                 CTGitPath relatepath;\r
293                 CString strpath=path.GetWinPathString();\r
294                 CString ProjectTopDir;\r
295 \r
296                 if(!path.HasAdminDir(&ProjectTopDir))\r
297                         return;\r
298                 \r
299                 if(ProjectTopDir[ProjectTopDir.GetLength()-1] == _T('\\'))\r
300                 {\r
301                         relatepath.SetFromWin( strpath.Right(strpath.GetLength()-ProjectTopDir.GetLength()));\r
302                 }else\r
303                 {\r
304                         relatepath.SetFromWin( strpath.Right(strpath.GetLength()-ProjectTopDir.GetLength()-1));\r
305                 }\r
306 \r
307                 cmd+=_T("-- \"");\r
308                 cmd+=relatepath.GetGitPathString();     \r
309                 cmd+=_T("\"");\r
310 \r
311                 logout.clear();\r
312                 g_Git.Run(cmd,&logout);\r
313                 rev.Clear();\r
314                 rev.ParserFromLog(logout);\r
315 \r
316                 SetDlgItemText(m_hwnd,IDC_LAST_HASH,rev.m_CommitHash.ToString());\r
317                 SetDlgItemText(m_hwnd,IDC_LAST_SUBJECT,rev.m_Subject);\r
318                 SetDlgItemText(m_hwnd,IDC_LAST_AUTHOR,rev.m_AuthorName);\r
319                 SetDlgItemText(m_hwnd,IDC_LAST_DATE,rev.m_AuthorDate.Format(_T("%Y-%m-%d %H:%M:%S")));\r
320 \r
321         }else\r
322         {\r
323 \r
324         }\r
325 \r
326 #if 0\r
327         GitStatus svn = GitStatus();\r
328         TCHAR tbuf[MAX_STRING_LENGTH];\r
329         if (filenames.size() == 1)\r
330         {\r
331                 if (svn.GetStatus(CTGitPath(filenames.front().c_str()))>(-2))\r
332                 {\r
333                         TCHAR buf[MAX_STRING_LENGTH];\r
334                         __time64_t      time;\r
335                         if (svn.status->entry != NULL)\r
336                         {\r
337                                 LoadLangDll();\r
338                                 if (svn.status->text_status == svn_wc_status_added)\r
339                                 {\r
340                                         // disable the "show log" button for added files\r
341                                         HWND showloghwnd = GetDlgItem(m_hwnd, IDC_SHOWLOG);\r
342                                         if (GetFocus() == showloghwnd)\r
343                                                 ::SendMessage(m_hwnd, WM_NEXTDLGCTL, 0, FALSE);\r
344                                         ::EnableWindow(showloghwnd, FALSE);\r
345                                 }\r
346                                 else\r
347                                 {\r
348                                         _stprintf_s(buf, MAX_STRING_LENGTH, _T("%d"), svn.status->entry->revision);\r
349                                         SetDlgItemText(m_hwnd, IDC_REVISION, buf);\r
350                                 }\r
351                                 if (svn.status->entry->url)\r
352                                 {\r
353                                         size_t len = strlen(svn.status->entry->url);\r
354                                         char * unescapedurl = new char[len+1];\r
355                                         strcpy_s(unescapedurl, len+1, svn.status->entry->url);\r
356                                         CPathUtils::Unescape(unescapedurl);\r
357                                         SetDlgItemText(m_hwnd, IDC_REPOURL, UTF8ToWide(unescapedurl).c_str());\r
358                                         if (strcmp(unescapedurl, svn.status->entry->url))\r
359                                         {\r
360                                                 ShowWindow(GetDlgItem(m_hwnd, IDC_ESCAPEDURLLABEL), SW_SHOW);\r
361                                                 ShowWindow(GetDlgItem(m_hwnd, IDC_REPOURLUNESCAPED), SW_SHOW);\r
362                                                 SetDlgItemText(m_hwnd, IDC_REPOURLUNESCAPED, UTF8ToWide(svn.status->entry->url).c_str());\r
363                                         }\r
364                                         else\r
365                                         {\r
366                                                 ShowWindow(GetDlgItem(m_hwnd, IDC_ESCAPEDURLLABEL), SW_HIDE);\r
367                                                 ShowWindow(GetDlgItem(m_hwnd, IDC_REPOURLUNESCAPED), SW_HIDE);\r
368                                         }\r
369                                         delete [] unescapedurl;\r
370                                 }\r
371                                 else\r
372                                 {\r
373                                         ShowWindow(GetDlgItem(m_hwnd, IDC_ESCAPEDURLLABEL), SW_HIDE);\r
374                                         ShowWindow(GetDlgItem(m_hwnd, IDC_REPOURLUNESCAPED), SW_HIDE);\r
375                                 }\r
376                                 if (svn.status->text_status != svn_wc_status_added)\r
377                                 {\r
378                                         _stprintf_s(buf, MAX_STRING_LENGTH, _T("%d"), svn.status->entry->cmt_rev);\r
379                                         SetDlgItemText(m_hwnd, IDC_CREVISION, buf);\r
380                                         time = (__time64_t)svn.status->entry->cmt_date/1000000L;\r
381                                         Time64ToTimeString(time, buf, MAX_STRING_LENGTH);\r
382                                         SetDlgItemText(m_hwnd, IDC_CDATE, buf);\r
383                                 }\r
384                                 if (svn.status->entry->cmt_author)\r
385                                         SetDlgItemText(m_hwnd, IDC_AUTHOR, UTF8ToWide(svn.status->entry->cmt_author).c_str());\r
386                                 GitStatus::GetStatusString(g_hResInst, svn.status->text_status, buf, sizeof(buf)/sizeof(TCHAR), (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)));\r
387                                 SetDlgItemText(m_hwnd, IDC_TEXTSTATUS, buf);\r
388                                 GitStatus::GetStatusString(g_hResInst, svn.status->prop_status, buf, sizeof(buf)/sizeof(TCHAR), (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)));\r
389                                 SetDlgItemText(m_hwnd, IDC_PROPSTATUS, buf);\r
390                                 time = (__time64_t)svn.status->entry->text_time/1000000L;\r
391                                 Time64ToTimeString(time, buf, MAX_STRING_LENGTH);\r
392                                 SetDlgItemText(m_hwnd, IDC_TEXTDATE, buf);\r
393                                 time = (__time64_t)svn.status->entry->prop_time/1000000L;\r
394                                 Time64ToTimeString(time, buf, MAX_STRING_LENGTH);\r
395                                 SetDlgItemText(m_hwnd, IDC_PROPDATE, buf);\r
396 \r
397                                 if (svn.status->entry->lock_owner)\r
398                                         SetDlgItemText(m_hwnd, IDC_LOCKOWNER, UTF8ToWide(svn.status->entry->lock_owner).c_str());\r
399                                 time = (__time64_t)svn.status->entry->lock_creation_date/1000000L;\r
400                                 Time64ToTimeString(time, buf, MAX_STRING_LENGTH);\r
401                                 SetDlgItemText(m_hwnd, IDC_LOCKDATE, buf);\r
402         \r
403                                 if (svn.status->entry->uuid)\r
404                                         SetDlgItemText(m_hwnd, IDC_REPOUUID, UTF8ToWide(svn.status->entry->uuid).c_str());\r
405                                 if (svn.status->entry->changelist)\r
406                                         SetDlgItemText(m_hwnd, IDC_CHANGELIST, UTF8ToWide(svn.status->entry->changelist).c_str());\r
407                                 GitStatus::GetDepthString(g_hResInst, svn.status->entry->depth, buf, sizeof(buf)/sizeof(TCHAR), (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)));\r
408                                 SetDlgItemText(m_hwnd, IDC_DEPTHEDIT, buf);\r
409 \r
410                                 if (svn.status->entry->checksum)\r
411                                         SetDlgItemText(m_hwnd, IDC_CHECKSUM, UTF8ToWide(svn.status->entry->checksum).c_str());\r
412 \r
413                                 if (svn.status->locked)\r
414                                         MAKESTRING(IDS_YES);\r
415                                 else\r
416                                         MAKESTRING(IDS_NO);\r
417                                 SetDlgItemText(m_hwnd, IDC_LOCKED, stringtablebuffer);\r
418 \r
419                                 if (svn.status->copied)\r
420                                         MAKESTRING(IDS_YES);\r
421                                 else\r
422                                         MAKESTRING(IDS_NO);\r
423                                 SetDlgItemText(m_hwnd, IDC_COPIED, stringtablebuffer);\r
424 \r
425                                 if (svn.status->switched)\r
426                                         MAKESTRING(IDS_YES);\r
427                                 else\r
428                                         MAKESTRING(IDS_NO);\r
429                                 SetDlgItemText(m_hwnd, IDC_SWITCHED, stringtablebuffer);\r
430                         } // if (svn.status->entry != NULL)\r
431                 } // if (svn.GetStatus(CTGitPath(filenames.front().c_str()))>(-2))\r
432         } // if (filenames.size() == 1) \r
433         else if (filenames.size() != 0)\r
434         {\r
435                 //deactivate the show log button\r
436                 HWND logwnd = GetDlgItem(m_hwnd, IDC_SHOWLOG);\r
437                 if (GetFocus() == logwnd)\r
438                         ::SendMessage(m_hwnd, WM_NEXTDLGCTL, 0, FALSE);\r
439                 ::EnableWindow(logwnd, FALSE);\r
440                 //get the handle of the list view\r
441                 if (svn.GetStatus(CTGitPath(filenames.front().c_str()))>(-2))\r
442                 {\r
443                         if (svn.status->entry != NULL)\r
444                         {\r
445                                 LoadLangDll();\r
446                                 if (svn.status->entry->url)\r
447                                 {\r
448                                         CPathUtils::Unescape((char*)svn.status->entry->url);\r
449                                         _tcsncpy_s(tbuf, MAX_STRING_LENGTH, UTF8ToWide(svn.status->entry->url).c_str(), 4095);\r
450                                         TCHAR * ptr = _tcsrchr(tbuf, '/');\r
451                                         if (ptr != 0)\r
452                                         {\r
453                                                 *ptr = 0;\r
454                                         }\r
455                                         SetDlgItemText(m_hwnd, IDC_REPOURL, tbuf);\r
456                                 }\r
457                                 SetDlgItemText(m_hwnd, IDC_LOCKED, _T(""));\r
458                                 SetDlgItemText(m_hwnd, IDC_COPIED, _T(""));\r
459                                 SetDlgItemText(m_hwnd, IDC_SWITCHED, _T(""));\r
460 \r
461                                 SetDlgItemText(m_hwnd, IDC_DEPTHEDIT, _T(""));\r
462                                 SetDlgItemText(m_hwnd, IDC_CHECKSUM, _T(""));\r
463                                 SetDlgItemText(m_hwnd, IDC_REPOUUID, _T(""));\r
464 \r
465                                 ShowWindow(GetDlgItem(m_hwnd, IDC_ESCAPEDURLLABEL), SW_HIDE);\r
466                                 ShowWindow(GetDlgItem(m_hwnd, IDC_REPOURLUNESCAPED), SW_HIDE);\r
467                         }\r
468                 }\r
469         }\r
470 #endif\r
471 }\r
472 \r
473 \r
474 // CShellExt member functions (needed for IShellPropSheetExt)\r
475 STDMETHODIMP CShellExt::AddPages (LPFNADDPROPSHEETPAGE lpfnAddPage,\r
476                                   LPARAM lParam)\r
477 {\r
478 \r
479         CString ProjectTopDir;\r
480 \r
481         for (std::vector<stdstring>::iterator I = files_.begin(); I != files_.end(); ++I)\r
482         {\r
483                 /*\r
484                 GitStatus svn = GitStatus();\r
485                 if (svn.GetStatus(CTGitPath(I->c_str())) == (-2))\r
486                         return NOERROR;                 // file/directory not under version control\r
487 \r
488                 if (svn.status->entry == NULL)\r
489                         return NOERROR;\r
490                 */\r
491                 if( CTGitPath(I->c_str()).HasAdminDir(&ProjectTopDir))\r
492                         break;\r
493                 else\r
494                         return NOERROR;\r
495         }\r
496 \r
497         if (files_.size() == 0)\r
498                 return NOERROR;\r
499 \r
500         LoadLangDll();\r
501     PROPSHEETPAGE psp;\r
502         SecureZeroMemory(&psp, sizeof(PROPSHEETPAGE));\r
503         HPROPSHEETPAGE hPage;\r
504         CGitPropertyPage *sheetpage = new CGitPropertyPage(files_);\r
505 \r
506     psp.dwSize = sizeof (psp);\r
507     psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_USEICONID | PSP_USECALLBACK;    \r
508         psp.hInstance = g_hResInst;\r
509         psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE);\r
510     psp.pszIcon = MAKEINTRESOURCE(IDI_APPSMALL);\r
511     psp.pszTitle = _T("Git");\r
512     psp.pfnDlgProc = (DLGPROC) PageProc;\r
513     psp.lParam = (LPARAM) sheetpage;\r
514     psp.pfnCallback = PropPageCallbackProc;\r
515     psp.pcRefParent = &g_cRefThisDll;\r
516 \r
517     hPage = CreatePropertySheetPage (&psp);\r
518 \r
519         if (hPage != NULL)\r
520         {\r
521         if (!lpfnAddPage (hPage, lParam))\r
522         {\r
523             delete sheetpage;\r
524             DestroyPropertySheetPage (hPage);\r
525         }\r
526         }\r
527 \r
528     return NOERROR;\r
529 }\r
530 \r
531 \r
532 \r
533 STDMETHODIMP CShellExt::ReplacePage (UINT /*uPageID*/, LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/, LPARAM /*lParam*/)\r
534 {\r
535     return E_FAIL;\r
536 }\r
537 \r