1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - TortoiseSVN
4 // Copyright (C) 2008-2012 - TortoiseGit
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "PreserveChdir.h"
24 //#include "SVNProperties.h"
25 #include "UnicodeUtils.h"
26 #include "GitStatus.h"
27 #include "PathUtils.h"
28 #include "..\TGitCache\CacheInterface.h"
31 const static int ColumnFlags
= SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
;
33 // Defines that revision numbers occupy at most MAX_REV_STRING_LEN characters.
34 // There are Perforce repositories out there that have several 100,000 revs.
35 // So, don't be too restrictive by limiting this to 6 digits + 1 separator,
38 // Because shorter strings will be extended to have exactly MAX_REV_STRING_LEN
39 // characters, large numbers will produce large strings. These, in turn, will
40 // affect column auto sizing. This setting is a reasonable compromise.
42 // IColumnProvider members
43 STDMETHODIMP
CShellExt::GetColumnInfo(DWORD dwIndex
, SHCOLUMNINFO
*psci
)
45 PreserveChdir preserveChdir
;
46 if (dwIndex
> 0) // TODO: keep for now to be able to hide unimplemented columns
49 ShellCache::CacheType cachetype
= g_ShellCache
.GetCacheType();
50 if (cachetype
== ShellCache::none
)
57 GetColumnInfo(dwIndex
, psci
, 15, IDS_COLTITLESTATUS
, IDS_COLDESCSTATUS
);
59 case 1: // Git Revision
60 GetColumnInfo(dwIndex
, psci
, 40, IDS_COLTITLEREV
, IDS_COLDESCREV
);
63 GetColumnInfo(dwIndex
, psci
, 30, IDS_COLTITLEURL
, IDS_COLDESCURL
);
65 case 3: // Git Short Url
66 GetColumnInfo(dwIndex
, psci
, 30, IDS_COLTITLESHORTURL
, IDS_COLDESCSHORTURL
);
68 case 4: // Author and Git Author
69 psci
->scid
.fmtid
= FMTID_SummaryInformation
; // predefined FMTID
70 psci
->scid
.pid
= PIDSI_AUTHOR
; // Predefined - author
71 psci
->vt
= VT_LPSTR
; // We'll return the data as a string
72 psci
->fmt
= LVCFMT_LEFT
; // Text will be left-aligned in the column
73 psci
->csFlags
= SHCOLSTATE_TYPE_STR
; // Data should be sorted as strings
74 psci
->cChars
= 32; // Default col width in chars
75 MAKESTRING(IDS_COLTITLEAUTHOR
);
76 lstrcpynW(psci
->wszTitle
, stringtablebuffer
, MAX_COLUMN_NAME_LEN
);
77 MAKESTRING(IDS_COLDESCAUTHOR
);
78 lstrcpynW(psci
->wszDescription
, stringtablebuffer
, MAX_COLUMN_DESC_LEN
);
87 void CShellExt::GetColumnInfo(DWORD dwIndex
, SHCOLUMNINFO
*psci
, UINT characterCount
, UINT title
, UINT description
)
89 psci
->scid
.fmtid
= CLSID_Tortoisegit_UPTODATE
;
90 psci
->scid
.pid
= dwIndex
;
92 psci
->fmt
= LVCFMT_LEFT
;
93 psci
->cChars
= characterCount
;
94 psci
->csFlags
= ColumnFlags
;
97 lstrcpynW(psci
->wszTitle
, stringtablebuffer
, MAX_COLUMN_NAME_LEN
);
98 MAKESTRING(description
);
99 lstrcpynW(psci
->wszDescription
, stringtablebuffer
, MAX_COLUMN_DESC_LEN
);
102 STDMETHODIMP
CShellExt::GetItemData(LPCSHCOLUMNID pscid
, LPCSHCOLUMNDATA pscd
, VARIANT
*pvarData
)
104 PreserveChdir preserveChdir
;
105 if (!g_ShellCache
.IsPathAllowed((TCHAR
*)pscd
->wszFile
))
110 ShellCache::CacheType cachetype
= g_ShellCache
.GetCacheType();
111 if (pscid
->fmtid
== CLSID_Tortoisegit_UPTODATE
)
114 const TCHAR
* path
= (TCHAR
*)pscd
->wszFile
;
116 // reserve for the path + trailing \0
118 TCHAR buf
[MAX_STATUS_STRING_LENGTH
+1];
119 SecureZeroMemory(buf
, MAX_STATUS_STRING_LENGTH
);
122 case 0: // Git Status
123 GetColumnStatus(path
, pscd
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
);
124 GitStatus::GetStatusString(g_hResInst
, filestatus
, buf
, _countof(buf
), (WORD
)CRegStdDWORD(_T("Software\\TortoiseGit\\LanguageID"), MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
)));
127 case 1: // Git Revision
129 GetColumnStatus(path
, pscd
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
);
132 V_VT(pvarData
) = VT_I4
;
133 V_I4(pvarData
) = columnrev
;
139 GetColumnStatus(path
, pscd
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
);
142 case 3: // Git Short Url
143 GetColumnStatus(path
, pscd
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
);
144 szInfo
= itemshorturl
;
149 const WCHAR
* wsInfo
= szInfo
.c_str();
150 V_VT(pvarData
) = VT_BSTR
;
151 V_BSTR(pvarData
) = SysAllocString(wsInfo
);
154 if (pscid
->fmtid
== FMTID_SummaryInformation
)
157 const TCHAR
* path
= pscd
->wszFile
;
159 if (cachetype
== ShellCache::none
)
163 case PIDSI_AUTHOR
: // Author and Git Author
164 GetColumnStatus(path
, pscd
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
);
165 szInfo
= columnauthor
;
170 wide_string wsInfo
= szInfo
;
171 V_VT(pvarData
) = VT_BSTR
;
172 V_BSTR(pvarData
) = SysAllocString(wsInfo
.c_str());
179 STDMETHODIMP
CShellExt::Initialize(LPCSHCOLUMNINIT psci
)
181 // psci->wszFolder (WCHAR) holds the path to the folder to be displayed
182 // Should check to see if its a "SVN" folder and if not return E_FAIL
184 PreserveChdir preserveChdir
;
185 if (g_ShellCache
.IsColumnsEveryWhere())
187 std::wstring path
= psci
->wszFolder
;
190 if (! g_ShellCache
.HasGITAdminDir(path
.c_str(), TRUE
))
193 columnfilepath
= _T("");
197 void CShellExt::GetColumnStatus(const TCHAR
* path
, BOOL bIsDir
)
199 PreserveChdir preserveChdir
;
200 if (_tcscmp(path
, columnfilepath
.c_str())==0)
203 columnfilepath
= path
;
204 const FileStatusCacheEntry
* status
= NULL
;
205 TGITCacheResponse itemStatus
;
206 ShellCache::CacheType t
= ShellCache::exe
;
207 AutoLocker
lock(g_csGlobalCOMGuard
);
208 t
= g_ShellCache
.GetCacheType();
212 case ShellCache::exe
:
214 SecureZeroMemory(&itemStatus
, sizeof(itemStatus
));
215 if(m_remoteCacheLink
.GetStatusFromRemoteCache(CTGitPath(path
), &itemStatus
, true))
217 filestatus
= GitStatus::GetMoreImportant(itemStatus
.m_status
.text_status
, itemStatus
.m_status
.prop_status
);
221 filestatus
= git_wc_status_none
;
222 columnauthor
.clear();
223 columnrev
= GIT_INVALID_REVNUM
;
225 itemshorturl
.clear();
230 case ShellCache::dll
:
231 case ShellCache::dllFull
:
233 status
= m_CachedStatus
.GetFullStatus(CTGitPath(path
), bIsDir
, TRUE
);
234 filestatus
= status
->status
;
238 case ShellCache::none
:
240 if (g_ShellCache
.HasGITAdminDir(path
, bIsDir
))
241 filestatus
= git_wc_status_normal
;
243 filestatus
= git_wc_status_none
;
244 columnauthor
.clear();
245 columnrev
= GIT_INVALID_REVNUM
;
247 itemshorturl
.clear();
253 if (t
== ShellCache::exe
)
255 columnrev
= itemStatus
.m_entry
.cmt_rev
;
261 columnrev
= status
->rev
;