1 /*
2   KeePass Password Safe - The Open-Source Password Manager
3   Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de>
4 
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9 
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.
14 
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
17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19 
20 using System;
21 using System.Collections.Generic;
22 using System.ComponentModel;
23 using System.Diagnostics;
24 using System.Drawing;
25 using System.Text;
26 using System.Windows.Forms;
27 
28 using KeePass.App;
29 using KeePass.Native;
30 using KeePass.Resources;
31 using KeePass.UI;
32 using KeePass.Util;
33 
34 using KeePassLib;
35 using KeePassLib.Utility;
36 
37 namespace KeePass.Forms
38 {
39 	public partial class UpdateCheckForm : Form, IGwmWindow
40 	{
41 		private List<UpdateComponentInfo> m_lInfo = null;
42 		private ImageList m_ilIcons = null;
43 
44 		public bool CanCloseWithoutDataLoss { get { return true; } }
45 
InitEx(List<UpdateComponentInfo> lInfo, bool bModal)46 		public void InitEx(List<UpdateComponentInfo> lInfo, bool bModal)
47 		{
48 			m_lInfo = lInfo;
49 
50 			if(!bModal) this.ShowInTaskbar = true;
51 		}
52 
UpdateCheckForm()53 		public UpdateCheckForm()
54 		{
55 			InitializeComponent();
56 			GlobalWindowManager.InitializeForm(this);
57 		}
58 
OnFormLoad(object sender, EventArgs e)59 		private void OnFormLoad(object sender, EventArgs e)
60 		{
61 			if(m_lInfo == null) throw new InvalidOperationException();
62 
63 			GlobalWindowManager.AddWindow(this, this);
64 
65 			BannerFactory.CreateBannerEx(this, m_bannerImage,
66 				Properties.Resources.B48x48_WWW, KPRes.UpdateCheck,
67 				KPRes.UpdateCheckResults);
68 			this.Icon = AppIcons.Default;
69 			this.Text = KPRes.UpdateCheck + " - " + PwDefs.ShortProductName;
70 
71 			UIUtil.SetExplorerTheme(m_lvInfo, true);
72 
73 			m_lvInfo.Columns.Add(KPRes.Component);
74 			m_lvInfo.Columns.Add(KPRes.Status);
75 			m_lvInfo.Columns.Add(KPRes.Installed);
76 			m_lvInfo.Columns.Add(KPRes.Available);
77 
78 			List<Image> lImages = new List<Image>();
79 			lImages.Add(Properties.Resources.B16x16_Help);
80 			lImages.Add(Properties.Resources.B16x16_Apply);
81 			lImages.Add(Properties.Resources.B16x16_Redo);
82 			lImages.Add(Properties.Resources.B16x16_History);
83 			lImages.Add(Properties.Resources.B16x16_Error);
84 			m_ilIcons = UIUtil.BuildImageListUnscaled(lImages,
85 				DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16));
86 
87 			m_lvInfo.SmallImageList = m_ilIcons;
88 
89 			string strCat = string.Empty;
90 			ListViewGroup lvg = null;
91 			const uint uMinComp = 2;
92 
93 			foreach(UpdateComponentInfo uc in m_lInfo)
94 			{
95 				if(uc.Category != strCat)
96 				{
97 					lvg = new ListViewGroup(uc.Category);
98 					m_lvInfo.Groups.Add(lvg);
99 					strCat = uc.Category;
100 				}
101 
102 				ListViewItem lvi = new ListViewItem(uc.Name);
103 
104 				string strStatus = KPRes.Unknown + ".";
105 				if(uc.Status == UpdateComponentStatus.UpToDate)
106 				{
107 					strStatus = KPRes.UpToDate + ".";
108 					lvi.ImageIndex = 1;
109 				}
110 				else if(uc.Status == UpdateComponentStatus.NewVerAvailable)
111 				{
112 					strStatus = KPRes.NewVersionAvailable + "!";
113 					lvi.ImageIndex = 2;
114 				}
115 				else if(uc.Status == UpdateComponentStatus.PreRelease)
116 				{
117 					strStatus = KPRes.PreReleaseVersion + ".";
118 					lvi.ImageIndex = 3;
119 				}
120 				else if(uc.Status == UpdateComponentStatus.DownloadFailed)
121 				{
122 					strStatus = KPRes.UpdateCheckFailedNoDl;
123 					lvi.ImageIndex = 4;
124 				}
125 				else lvi.ImageIndex = 0;
126 
127 				lvi.SubItems.Add(strStatus);
128 				lvi.SubItems.Add(StrUtil.VersionToString(uc.VerInstalled, uMinComp));
129 
130 				if((uc.Status == UpdateComponentStatus.UpToDate) ||
131 					(uc.Status == UpdateComponentStatus.NewVerAvailable) ||
132 					(uc.Status == UpdateComponentStatus.PreRelease))
133 					lvi.SubItems.Add(StrUtil.VersionToString(uc.VerAvailable, uMinComp));
134 				else lvi.SubItems.Add("?");
135 
136 				if(lvg != null) lvi.Group = lvg;
137 				m_lvInfo.Items.Add(lvi);
138 			}
139 
140 			UIUtil.ResizeColumns(m_lvInfo, new int[] { 2, 2, 1, 1 }, true);
141 		}
142 
CleanUpEx()143 		private void CleanUpEx()
144 		{
145 			if(m_ilIcons != null)
146 			{
147 				m_lvInfo.SmallImageList = null; // Detach event handlers
148 				m_ilIcons.Dispose();
149 				m_ilIcons = null;
150 			}
151 		}
152 
OnFormClosed(object sender, FormClosedEventArgs e)153 		private void OnFormClosed(object sender, FormClosedEventArgs e)
154 		{
155 			CleanUpEx();
156 			GlobalWindowManager.RemoveWindow(this);
157 		}
158 
OnLinkWeb(object sender, LinkLabelLinkClickedEventArgs e)159 		private void OnLinkWeb(object sender, LinkLabelLinkClickedEventArgs e)
160 		{
161 			OpenUrl(PwDefs.HomepageUrl);
162 		}
163 
OnLinkPlugins(object sender, LinkLabelLinkClickedEventArgs e)164 		private void OnLinkPlugins(object sender, LinkLabelLinkClickedEventArgs e)
165 		{
166 			OpenUrl(PwDefs.PluginsUrl);
167 		}
168 
OpenUrl(string strUrl)169 		private void OpenUrl(string strUrl)
170 		{
171 			/* if(!KeePassLib.Native.NativeLib.IsUnix())
172 			{
173 				// Process.Start has a considerable delay when opening URLs
174 				// here (different thread, etc.), therefore try the native
175 				// ShellExecute first (which doesn't have any delay)
176 				try
177 				{
178 					IntPtr h = NativeMethods.ShellExecute(this.Handle,
179 						null, strUrl, null, null, NativeMethods.SW_SHOW);
180 					long l = h.ToInt64();
181 					if((l < 0) || (l > 32)) return;
182 					else { Debug.Assert(false); }
183 				}
184 				catch(Exception) { Debug.Assert(false); }
185 			}
186 
187 			try { NativeLib.StartProcess(strUrl); }
188 			catch(Exception) { Debug.Assert(false); } */
189 
190 			WinUtil.OpenUrl(strUrl, null); // Thread-safe
191 		}
192 
OnInfoItemActivate(object sender, EventArgs e)193 		private void OnInfoItemActivate(object sender, EventArgs e)
194 		{
195 			ListView.SelectedListViewItemCollection lvsic = m_lvInfo.SelectedItems;
196 			if((lvsic == null) || (lvsic.Count != 1)) { Debug.Assert(false); return; }
197 			ListViewItem lvi = lvsic[0];
198 			if((lvi == null) || (lvi.Group == null)) { Debug.Assert(false); return; }
199 
200 			string strGroup = (lvi.Group.Header ?? string.Empty);
201 			if(strGroup == PwDefs.ShortProductName)
202 				OpenUrl(PwDefs.HomepageUrl);
203 			else if(strGroup == KPRes.Plugins)
204 				OpenUrl(PwDefs.PluginsUrl);
205 			else { Debug.Assert(false); }
206 		}
207 	}
208 }
209