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.IO;
26 using System.Text;
27 using System.Windows.Forms;
28 
29 using KeePass.App;
30 using KeePass.Plugins;
31 using KeePass.Resources;
32 using KeePass.UI;
33 using KeePass.Util;
34 
35 using KeePassLib;
36 using KeePassLib.Utility;
37 
38 namespace KeePass.Forms
39 {
40 	public partial class PluginsForm : Form, IGwmWindow
41 	{
42 		private PluginManager m_mgr = null;
43 		private bool m_bBlockListUpdate = false;
44 		private ImageList m_ilIcons = new ImageList();
45 
46 		public bool CanCloseWithoutDataLoss { get { return true; } }
47 
InitEx(PluginManager mgr)48 		internal void InitEx(PluginManager mgr)
49 		{
50 			Debug.Assert(mgr != null);
51 			m_mgr = mgr;
52 		}
53 
PluginsForm()54 		public PluginsForm()
55 		{
56 			InitializeComponent();
57 			GlobalWindowManager.InitializeForm(this);
58 		}
59 
OnFormLoad(object sender, EventArgs e)60 		private void OnFormLoad(object sender, EventArgs e)
61 		{
62 			if(m_mgr == null) { Debug.Assert(false); throw new InvalidOperationException(); }
63 
64 			GlobalWindowManager.AddWindow(this, this);
65 
66 			BannerFactory.CreateBannerEx(this, m_bannerImage,
67 				Properties.Resources.B48x48_BlockDevice, KPRes.Plugins,
68 				KPRes.PluginsDesc);
69 			this.Icon = AppIcons.Default;
70 
71 			Debug.Assert(!m_lblCacheSize.AutoSize); // For RTL support
72 			m_lblCacheSize.Text += " " + StrUtil.FormatDataSize(
73 				PlgxCache.GetUsedCacheSize()) + ".";
74 
75 			m_cbCacheDeleteOld.Checked = Program.Config.Application.Start.PluginCacheDeleteOld;
76 
77 			if(string.IsNullOrEmpty(PluginManager.UserDirectory))
78 			{
79 				Debug.Assert(false);
80 				m_btnOpenFolder.Enabled = false;
81 			}
82 
83 			m_lvPlugins.Columns.Add(KPRes.Plugin);
84 			m_lvPlugins.Columns.Add(KPRes.Version);
85 			m_lvPlugins.Columns.Add(KPRes.Author);
86 			m_lvPlugins.Columns.Add(KPRes.Description);
87 			m_lvPlugins.Columns.Add(KPRes.File);
88 			UIUtil.ResizeColumns(m_lvPlugins, new int[] {
89 				4, 2, 3, 0, 2 }, true);
90 
91 			m_ilIcons.ImageSize = new Size(DpiUtil.ScaleIntX(16),
92 				DpiUtil.ScaleIntY(16));
93 			m_ilIcons.ColorDepth = ColorDepth.Depth32Bit;
94 			m_lvPlugins.SmallImageList = m_ilIcons;
95 
96 			UpdatePluginsList();
97 			if(m_lvPlugins.Items.Count > 0)
98 				m_lvPlugins.Items[0].Selected = true;
99 
100 			UpdatePluginDescription();
101 		}
102 
CleanUpEx()103 		private void CleanUpEx()
104 		{
105 			if(m_ilIcons != null)
106 			{
107 				m_lvPlugins.SmallImageList = null; // Detach event handlers
108 				m_ilIcons.Dispose();
109 				m_ilIcons = null;
110 			}
111 		}
112 
UpdatePluginsList()113 		private void UpdatePluginsList()
114 		{
115 			if(m_bBlockListUpdate) return;
116 			m_bBlockListUpdate = true;
117 
118 			m_lvPlugins.Items.Clear();
119 			m_ilIcons.Images.Clear();
120 
121 			m_ilIcons.Images.Add(Properties.Resources.B16x16_BlockDevice);
122 
123 			List<PluginInfo> lInfos = new List<PluginInfo>(m_mgr);
124 			lInfos.Sort(PluginsForm.ComparePluginInfos);
125 
126 			foreach(PluginInfo pi in lInfos)
127 			{
128 				ListViewItem lvi = m_lvPlugins.Items.Add(pi.Name);
129 
130 				lvi.SubItems.Add(pi.FileVersion);
131 				lvi.SubItems.Add(pi.Author);
132 				lvi.SubItems.Add(pi.Description);
133 				lvi.SubItems.Add(pi.DisplayFilePath);
134 
135 				Plugin p = pi.Interface;
136 				Debug.Assert(p != null);
137 
138 				int nImageIndex = 0;
139 				Image img = ((p != null) ? p.SmallIcon : null);
140 				if(img != null)
141 				{
142 					nImageIndex = m_ilIcons.Images.Count;
143 					m_ilIcons.Images.Add(img);
144 				}
145 				lvi.ImageIndex = nImageIndex;
146 			}
147 
148 			m_bBlockListUpdate = false;
149 			UpdatePluginDescription();
150 		}
151 
ComparePluginInfos(PluginInfo x, PluginInfo y)152 		private static int ComparePluginInfos(PluginInfo x, PluginInfo y)
153 		{
154 			return string.Compare(x.Name, y.Name, StrUtil.CaseIgnoreCmp);
155 		}
156 
UpdatePluginDescription()157 		private void UpdatePluginDescription()
158 		{
159 			Debug.Assert(!m_lblSelectedPluginDesc.AutoSize); // For RTL support
160 
161 			ListView.SelectedListViewItemCollection lvsic = m_lvPlugins.SelectedItems;
162 			if(lvsic.Count == 0)
163 			{
164 				m_grpPluginDesc.Text = string.Empty;
165 				m_lblSelectedPluginDesc.Text = string.Empty;
166 				return;
167 			}
168 
169 			ListViewItem lvi = lvsic[0];
170 			m_grpPluginDesc.Text = lvi.SubItems[0].Text;
171 			m_lblSelectedPluginDesc.Text = lvi.SubItems[3].Text;
172 		}
173 
OnBtnClose(object sender, EventArgs e)174 		private void OnBtnClose(object sender, EventArgs e)
175 		{
176 		}
177 
OnPluginListSelectedIndexChanged(object sender, EventArgs e)178 		private void OnPluginListSelectedIndexChanged(object sender, EventArgs e)
179 		{
180 			UpdatePluginDescription();
181 		}
182 
OnFormClosed(object sender, FormClosedEventArgs e)183 		private void OnFormClosed(object sender, FormClosedEventArgs e)
184 		{
185 			CleanUpEx();
186 			GlobalWindowManager.RemoveWindow(this);
187 		}
188 
OnBtnClearCache(object sender, EventArgs e)189 		private void OnBtnClearCache(object sender, EventArgs e)
190 		{
191 			Program.Config.Application.Start.PluginCacheClearOnce = true;
192 
193 			MessageService.ShowInfo(KPRes.PluginCacheClearInfo);
194 		}
195 
OnFormClosing(object sender, FormClosingEventArgs e)196 		private void OnFormClosing(object sender, FormClosingEventArgs e)
197 		{
198 			Program.Config.Application.Start.PluginCacheDeleteOld =
199 				m_cbCacheDeleteOld.Checked;
200 		}
201 
OnBtnGetMore(object sender, EventArgs e)202 		private void OnBtnGetMore(object sender, EventArgs e)
203 		{
204 			WinUtil.OpenUrl(PwDefs.PluginsUrl, null);
205 		}
206 
OnBtnOpenFolder(object sender, EventArgs e)207 		private void OnBtnOpenFolder(object sender, EventArgs e)
208 		{
209 			try
210 			{
211 				string str = PluginManager.UserDirectory;
212 				if(string.IsNullOrEmpty(str)) { Debug.Assert(false); return; }
213 
214 				if(!Directory.Exists(str)) Directory.CreateDirectory(str);
215 
216 				WinUtil.OpenUrlDirectly(str);
217 			}
218 			catch(Exception ex) { MessageService.ShowWarning(ex); }
219 		}
220 	}
221 }
222