Use CAutoGeneralHandle
[TortoiseGit.git] / src / TortoiseProc / CheckForUpdatesDlg.cpp
blobb04c005c4c6aa3ef391b0f729337c34f966ccd68
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - TortoiseSVN
4 // Copyright (C) 2008-2011 - 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.
20 #include "stdafx.h"
21 #include "TortoiseProc.h"
22 #include "LoglistCommonResource.h"
23 #include "..\version.h"
24 #include "MessageBox.h"
25 #include ".\checkforupdatesdlg.h"
26 #include "Registry.h"
27 #include "AppUtils.h"
28 #include "TempFile.h"
31 IMPLEMENT_DYNAMIC(CCheckForUpdatesDlg, CStandAloneDialog)
32 CCheckForUpdatesDlg::CCheckForUpdatesDlg(CWnd* pParent /*=NULL*/)
33 : CStandAloneDialog(CCheckForUpdatesDlg::IDD, pParent)
34 , m_bShowInfo(FALSE)
35 , m_bVisible(FALSE)
37 m_sUpdateDownloadLink = _T("http://code.google.com/p/tortoisegit/downloads");
38 m_sUpdateChangeLogLink = _T("http://code.google.com/p/tortoisegit/wiki/ReleaseNotes");
41 CCheckForUpdatesDlg::~CCheckForUpdatesDlg()
45 void CCheckForUpdatesDlg::DoDataExchange(CDataExchange* pDX)
47 CStandAloneDialog::DoDataExchange(pDX);
48 DDX_Control(pDX, IDC_LINK, m_link);
49 DDX_Control(pDX, IDC_LINK_CHANGE_LOG, m_ChangeLogLink);
53 BEGIN_MESSAGE_MAP(CCheckForUpdatesDlg, CStandAloneDialog)
54 ON_STN_CLICKED(IDC_CHECKRESULT, OnStnClickedCheckresult)
55 ON_WM_TIMER()
56 ON_WM_WINDOWPOSCHANGING()
57 ON_WM_SETCURSOR()
58 END_MESSAGE_MAP()
60 BOOL CCheckForUpdatesDlg::OnInitDialog()
62 CStandAloneDialog::OnInitDialog();
63 CAppUtils::MarkWindowAsUnpinnable(m_hWnd);
65 CString temp;
66 temp.Format(IDS_CHECKNEWER_YOURVERSION, TGIT_VERMAJOR, TGIT_VERMINOR, TGIT_VERMICRO, TGIT_VERBUILD);
67 SetDlgItemText(IDC_YOURVERSION, temp);
69 DialogEnableWindow(IDOK, FALSE);
71 if (AfxBeginThread(CheckThreadEntry, this)==NULL)
73 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);
76 SetTimer(100, 1000, NULL);
77 return TRUE;
80 void CCheckForUpdatesDlg::OnOK()
82 if (m_bThreadRunning)
83 return;
84 CStandAloneDialog::OnOK();
87 void CCheckForUpdatesDlg::OnCancel()
89 if (m_bThreadRunning)
90 return;
91 CStandAloneDialog::OnCancel();
94 UINT CCheckForUpdatesDlg::CheckThreadEntry(LPVOID pVoid)
96 return ((CCheckForUpdatesDlg*)pVoid)->CheckThread();
99 UINT CCheckForUpdatesDlg::CheckThread()
101 m_bThreadRunning = TRUE;
103 CString temp;
104 CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();
106 CRegString checkurluser = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""));
107 CRegString checkurlmachine = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""), FALSE, HKEY_LOCAL_MACHINE);
108 CString sCheckURL = checkurluser;
109 if (sCheckURL.IsEmpty())
111 sCheckURL = checkurlmachine;
112 if (sCheckURL.IsEmpty())
113 sCheckURL = _T("http://code.google.com/p/tortoisegit/downloads/list?q=label%3AFeatured");
115 CoInitialize(NULL);
116 HRESULT res = URLDownloadToFile(NULL, sCheckURL, tempfile, 0, NULL);
117 if (res == S_OK)
121 CStdioFile file(tempfile, CFile::modeRead | CFile::shareDenyWrite);
122 CString ver;
123 unsigned int major,minor,micro,build;
124 major=minor=micro=build=0;
125 unsigned __int64 version=0;
127 if(file.GetLength()>100)
129 while(file.ReadString(ver))
131 ver.Trim().MakeLower();
132 int start;
133 while( (start=ver.Find(_T("tortoisegit-"))) > 0 )
135 ver = ver.Mid(start+CString(_T("tortoisegit-")).GetLength());
136 unsigned int x1,x2,x3,x4;
137 x1=_ttoi(ver)&0xFFFF;
138 ver = ver.Mid(ver.Find('.')+1);
139 x2=_ttoi(ver)&0xFFFF;
140 ver = ver.Mid(ver.Find('.')+1);
141 x3=_ttoi(ver)&0xFFFF;
142 ver = ver.Mid(ver.Find('.')+1);
143 x4=_ttoi(ver)&0xFFFF;
145 unsigned __int64 newversion;
146 newversion = x1;
147 newversion <<= 16;
148 newversion += x2;
149 newversion <<= 16;
150 newversion += x3;
151 newversion <<=16;
152 newversion += x4;
154 if(newversion>version)
156 major=x1;
157 minor=x2;
158 micro=x3;
159 build=x4;
160 version = newversion;
166 else if (file.ReadString(ver))
168 CString vertemp = ver;
169 major = _ttoi(vertemp);
170 vertemp = vertemp.Mid(vertemp.Find('.')+1);
171 minor = _ttoi(vertemp);
172 vertemp = vertemp.Mid(vertemp.Find('.')+1);
173 micro = _ttoi(vertemp);
174 vertemp = vertemp.Mid(vertemp.Find('.')+1);
175 build = _ttoi(vertemp);
176 version = major;
177 version <<= 16;
178 version += minor;
179 version <<= 16;
180 version += micro;
181 version <<= 16;
182 version += build;
186 BOOL bNewer = FALSE;
187 if (major > TGIT_VERMAJOR)
188 bNewer = TRUE;
189 else if ((minor > TGIT_VERMINOR)&&(major == TGIT_VERMAJOR))
190 bNewer = TRUE;
191 else if ((micro > TGIT_VERMICRO)&&(minor == TGIT_VERMINOR)&&(major == TGIT_VERMAJOR))
192 bNewer = TRUE;
193 else if ((build > TGIT_VERBUILD)&&(micro == TGIT_VERMICRO)&&(minor == TGIT_VERMINOR)&&(major == TGIT_VERMAJOR))
194 bNewer = TRUE;
196 if (version != 0)
198 ver.Format(_T("%d.%d.%d.%d"),major,minor,micro,build);
199 temp.Format(IDS_CHECKNEWER_CURRENTVERSION, (LPCTSTR)ver);
200 SetDlgItemText(IDC_CURRENTVERSION, temp);
201 temp.Format(_T("%d.%d.%d.%d"), TGIT_VERMAJOR, TGIT_VERMINOR, TGIT_VERMICRO, TGIT_VERBUILD);
204 if (version == 0)
206 temp.LoadString(IDS_CHECKNEWER_NETERROR);
207 SetDlgItemText(IDC_CHECKRESULT, temp);
209 else if (bNewer)
211 if(file.ReadString(temp) && !temp.IsEmpty())
212 { // Read the next line, it could contain a message for the user
213 CString tempLink;
214 if(file.ReadString(tempLink) && !tempLink.IsEmpty())
215 { // Read another line to find out the download link-URL, if any
216 m_sUpdateDownloadLink = tempLink;
220 else
222 temp.LoadString(IDS_CHECKNEWER_NEWERVERSIONAVAILABLE);
224 SetDlgItemText(IDC_CHECKRESULT, temp);
225 m_bShowInfo = TRUE;
227 else
229 temp.LoadString(IDS_CHECKNEWER_YOURUPTODATE);
230 SetDlgItemText(IDC_CHECKRESULT, temp);
234 catch (CException * e)
236 e->Delete();
237 temp.LoadString(IDS_CHECKNEWER_NETERROR);
238 SetDlgItemText(IDC_CHECKRESULT, temp);
241 else
243 // Try to cache web page;
245 temp.LoadString(IDS_CHECKNEWER_NETERROR);
246 SetDlgItemText(IDC_CHECKRESULT, temp);
248 if (!m_sUpdateDownloadLink.IsEmpty())
250 m_link.ShowWindow(SW_SHOW);
251 m_link.SetURL(m_sUpdateDownloadLink);
253 if (!m_sUpdateDownloadLink.IsEmpty())
255 m_ChangeLogLink.ShowWindow(SW_SHOW);
256 m_ChangeLogLink.SetURL(m_sUpdateChangeLogLink);
259 DeleteFile(tempfile);
260 m_bThreadRunning = FALSE;
261 DialogEnableWindow(IDOK, TRUE);
262 return 0;
265 void CCheckForUpdatesDlg::OnStnClickedCheckresult()
267 // user clicked on the label, start the browser with our web page
268 HINSTANCE result = ShellExecute(NULL, _T("opennew"), m_sUpdateDownloadLink, NULL,NULL, SW_SHOWNORMAL);
269 if ((UINT)result <= HINSTANCE_ERROR)
271 result = ShellExecute(NULL, _T("open"), m_sUpdateDownloadLink, NULL,NULL, SW_SHOWNORMAL);
275 void CCheckForUpdatesDlg::OnTimer(UINT_PTR nIDEvent)
277 if (nIDEvent == 100)
279 if (m_bThreadRunning == FALSE)
281 if (m_bShowInfo)
283 m_bVisible = TRUE;
284 ShowWindow(SW_SHOWNORMAL);
286 else
288 EndDialog(0);
292 CStandAloneDialog::OnTimer(nIDEvent);
295 void CCheckForUpdatesDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
297 CStandAloneDialog::OnWindowPosChanging(lpwndpos);
298 if (m_bVisible == FALSE)
299 lpwndpos->flags &= ~SWP_SHOWWINDOW;
302 BOOL CCheckForUpdatesDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
304 if ((!m_sUpdateDownloadLink.IsEmpty())&&(pWnd)&&(pWnd == GetDlgItem(IDC_CHECKRESULT)))
306 HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND));
307 SetCursor(hCur);
308 return TRUE;
311 HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
312 SetCursor(hCur);
313 return CStandAloneDialogTmpl<CDialog>::OnSetCursor(pWnd, nHitTest, message);