1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2007-2008 - TortoiseSVN
\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
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
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
20 #include "TortoiseProc.h"
\r
21 #include "SettingsLogCaches.h"
\r
22 #include "MessageBox.h"
\r
24 #include "SVNError.h"
\r
25 #include "LogCachePool.h"
\r
26 #include "LogCacheStatistics.h"
\r
27 #include "LogCacheStatisticsDlg.h"
\r
28 #include "ProgressDlg.h"
\r
29 #include "SVNLogQuery.h"
\r
30 #include "CacheLogQuery.h"
\r
31 #include "CSVWriter.h"
\r
32 #include "XPTheme.h"
\r
34 using namespace LogCache;
\r
36 IMPLEMENT_DYNAMIC(CSettingsLogCaches, ISettingsPropPage)
\r
38 #define WM_REFRESH_REPOSITORYLIST (WM_APP + 110)
\r
40 CSettingsLogCaches::CSettingsLogCaches()
\r
41 : ISettingsPropPage(CSettingsLogCaches::IDD)
\r
46 CSettingsLogCaches::~CSettingsLogCaches()
\r
50 // update cache list
\r
52 BOOL CSettingsLogCaches::OnSetActive()
\r
54 FillRepositoryList();
\r
56 return ISettingsPropPage::OnSetActive();
\r
59 void CSettingsLogCaches::DoDataExchange(CDataExchange* pDX)
\r
61 ISettingsPropPage::DoDataExchange(pDX);
\r
63 DDX_Control(pDX, IDC_REPOSITORYLIST, m_cRepositoryList);
\r
67 BEGIN_MESSAGE_MAP(CSettingsLogCaches, ISettingsPropPage)
\r
68 ON_BN_CLICKED(IDC_CACHEDETAILS, OnBnClickedDetails)
\r
69 ON_BN_CLICKED(IDC_CACHEUPDATE, OnBnClickedUpdate)
\r
70 ON_BN_CLICKED(IDC_CACHEEXPORT, OnBnClickedExport)
\r
71 ON_BN_CLICKED(IDC_CACHEDELETE, OnBnClickedDelete)
\r
73 ON_MESSAGE(WM_REFRESH_REPOSITORYLIST, OnRefeshRepositoryList)
\r
74 ON_NOTIFY(NM_DBLCLK, IDC_REPOSITORYLIST, &CSettingsLogCaches::OnNMDblclkRepositorylist)
\r
75 ON_NOTIFY(LVN_ITEMCHANGED, IDC_REPOSITORYLIST, &CSettingsLogCaches::OnLvnItemchangedRepositorylist)
\r
78 BOOL CSettingsLogCaches::OnInitDialog()
\r
80 ISettingsPropPage::OnInitDialog();
\r
82 // repository list (including header text update when language changed)
\r
84 m_cRepositoryList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP);
\r
86 m_cRepositoryList.DeleteAllItems();
\r
87 int c = m_cRepositoryList.GetHeaderCtrl()->GetItemCount()-1;
\r
89 m_cRepositoryList.DeleteColumn(c--);
\r
92 temp.LoadString(IDS_SETTINGS_REPOSITORY_URL);
\r
93 m_cRepositoryList.InsertColumn (0, temp, LVCFMT_LEFT, 289);
\r
94 temp.LoadString(IDS_SETTINGS_REPOSITORY_SIZE);
\r
95 m_cRepositoryList.InsertColumn (1, temp, LVCFMT_RIGHT, 95);
\r
98 theme.SetWindowTheme(m_cRepositoryList.GetSafeHwnd(), L"Explorer", NULL);
\r
100 FillRepositoryList();
\r
104 m_tooltips.Create(this);
\r
106 m_tooltips.AddTool(IDC_REPOSITORYLIST, IDS_SETTINGS_LOGCACHE_CACHELIST);
\r
108 m_tooltips.AddTool(IDC_CACHEDETAILS, IDS_SETTINGS_LOGCACHE_DETAILS);
\r
109 m_tooltips.AddTool(IDC_CACHEUPDATE, IDS_SETTINGS_LOGCACHE_UPDATE);
\r
110 m_tooltips.AddTool(IDC_CACHEEXPORT, IDS_SETTINGS_LOGCACHE_EXPORT);
\r
111 m_tooltips.AddTool(IDC_CACHEDELETE, IDS_SETTINGS_LOGCACHE_DELETE);
\r
116 BOOL CSettingsLogCaches::PreTranslateMessage(MSG* pMsg)
\r
118 m_tooltips.RelayEvent(pMsg);
\r
119 return ISettingsPropPage::PreTranslateMessage(pMsg);
\r
122 void CSettingsLogCaches::OnBnClickedDetails()
\r
124 TRepo repo = GetSelectedRepo();
\r
125 if (!repo.first.IsEmpty())
\r
127 CLogCacheStatistics staticstics
\r
128 (*SVN().GetLogCachePool(), repo.second, repo.first);
\r
130 CLogCacheStatisticsDlg dialog (staticstics.GetData(), this);
\r
135 void CSettingsLogCaches::OnBnClickedUpdate()
\r
137 AfxBeginThread (WorkerThread, this);
\r
140 void CSettingsLogCaches::OnBnClickedExport()
\r
142 TRepo repo = GetSelectedRepo();
\r
143 if (!repo.first.IsEmpty())
\r
145 CFileDialog dialog (FALSE);
\r
146 if (dialog.DoModal() == IDOK)
\r
149 CCachedLogInfo* cache
\r
150 = svn.GetLogCachePool()->GetCache (repo.second, repo.first);
\r
152 writer.Write (*cache, (LPCTSTR)dialog.GetFileName());
\r
157 void CSettingsLogCaches::OnBnClickedDelete()
\r
159 int nSelCount = m_cRepositoryList.GetSelectedCount();
\r
161 sQuestion.Format(IDS_SETTINGS_CACHEDELETEQUESTION, nSelCount);
\r
162 if (CMessageBox::Show(m_hWnd, sQuestion, _T("TortoiseSVN"), MB_YESNO | MB_ICONQUESTION) == IDYES)
\r
164 POSITION pos = m_cRepositoryList.GetFirstSelectedItemPosition();
\r
167 int index = m_cRepositoryList.GetNextSelectedItem(pos);
\r
168 IT iter = repos.begin();
\r
169 std::advance (iter, index);
\r
170 SVN().GetLogCachePool()->DropCache (iter->second, iter->first);
\r
172 FillRepositoryList();
\r
176 LRESULT CSettingsLogCaches::OnRefeshRepositoryList (WPARAM, LPARAM)
\r
178 FillRepositoryList();
\r
182 CSettingsLogCaches::TRepo CSettingsLogCaches::GetSelectedRepo()
\r
184 int index = m_cRepositoryList.GetSelectionMark();
\r
186 return CSettingsLogCaches::TRepo();
\r
188 IT iter = repos.begin();
\r
189 std::advance (iter, index);
\r
194 void CSettingsLogCaches::FillRepositoryList()
\r
196 int count = m_cRepositoryList.GetItemCount();
\r
198 m_cRepositoryList.DeleteItem (--count);
\r
201 CLogCachePool* caches = svn.GetLogCachePool();
\r
202 repos = caches->GetRepositoryURLs();
\r
204 for (IT iter = repos.begin(), end = repos.end(); iter != end; ++iter, ++count)
\r
206 CString url = iter->first;
\r
208 m_cRepositoryList.InsertItem (count, url);
\r
209 size_t fileSize = caches->FileSize (iter->second, url) / 1024;
\r
212 sizeText.Format(TEXT("%d"), fileSize);
\r
213 m_cRepositoryList.SetItemText (count, 1, sizeText);
\r
217 // implement ILogReceiver
\r
219 void CSettingsLogCaches::ReceiveLog ( LogChangedPathArray*
\r
221 , const StandardRevProps*
\r
222 , UserRevPropArray*
\r
225 // update internal data
\r
227 if ((headRevision < (svn_revnum_t)rev) || (headRevision == NO_REVISION))
\r
228 headRevision = rev;
\r
230 // update progress bar and check for user pressing "Cancel"
\r
232 static DWORD lastProgressCall = 0;
\r
233 if (lastProgressCall < GetTickCount() - 500)
\r
235 lastProgressCall = GetTickCount();
\r
238 temp.LoadString(IDS_REVGRAPH_PROGGETREVS);
\r
239 progress->SetLine(1, temp);
\r
240 temp.Format(IDS_REVGRAPH_PROGCURRENTREV, rev);
\r
241 progress->SetLine(2, temp);
\r
243 progress->SetProgress (headRevision - rev, headRevision);
\r
244 if (progress->HasUserCancelled())
\r
245 throw SVNError (SVN_ERR_CANCELLED, "");
\r
249 UINT CSettingsLogCaches::WorkerThread(LPVOID pVoid)
\r
251 CoInitialize (NULL);
\r
253 CSettingsLogCaches* dialog = (CSettingsLogCaches*)pVoid;
\r
255 dialog->progress = new CProgressDlg();
\r
256 dialog->progress->SetTitle(IDS_SETTINGS_LOGCACHE_UPDATETITLE);
\r
257 dialog->progress->SetCancelMsg(IDS_REVGRAPH_PROGCANCEL);
\r
258 dialog->progress->SetTime();
\r
259 dialog->progress->ShowModal (dialog->m_hWnd);
\r
261 // we have to get the log from the repository root
\r
264 CLogCachePool* caches = svn.GetLogCachePool();
\r
265 CRepositoryInfo& info = caches->GetRepositoryInfo();
\r
267 TRepo repo = dialog->GetSelectedRepo();
\r
269 urlpath.SetFromSVN (repo.first);
\r
271 dialog->headRevision = info.GetHeadRevision (repo.second, urlpath);
\r
272 dialog->progress->SetProgress (0, dialog->headRevision);
\r
274 apr_pool_t *pool = svn_pool_create(NULL);
\r
278 CSVNLogQuery svnQuery (svn.m_pctx, pool);
\r
279 CCacheLogQuery query (caches, &svnQuery);
\r
281 query.Log ( CTSVNPathList (urlpath)
\r
282 , dialog->headRevision
\r
283 , dialog->headRevision
\r
286 , false // strictNodeHistory
\r
288 , true // includeChanges
\r
289 , false // includeMerges
\r
290 , true // includeStandardRevProps
\r
291 , true // includeUserRevProps
\r
292 , TRevPropNames());
\r
299 svn_pool_destroy (pool);
\r
301 if (dialog->progress)
\r
303 dialog->progress->Stop();
\r
304 delete dialog->progress;
\r
305 dialog->progress = NULL;
\r
310 dialog->PostMessage (WM_REFRESH_REPOSITORYLIST);
\r
315 void CSettingsLogCaches::OnNMDblclkRepositorylist(NMHDR * /*pNMHDR*/, LRESULT *pResult)
\r
317 OnBnClickedDetails();
\r
321 void CSettingsLogCaches::OnLvnItemchangedRepositorylist(NMHDR * /*pNMHDR*/, LRESULT *pResult)
\r
323 UINT count = m_cRepositoryList.GetSelectedCount();
\r
324 GetDlgItem(IDC_CACHEDETAILS)->EnableWindow(count == 1);
\r
325 GetDlgItem(IDC_CACHEUPDATE)->EnableWindow(count == 1);
\r
326 GetDlgItem(IDC_CACHEEXPORT)->EnableWindow(count == 1);
\r
327 GetDlgItem(IDC_CACHEDELETE)->EnableWindow(count >= 1);
\r