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.Ecas;
30 using KeePass.Resources;
31 using KeePass.UI;
32 
33 using KeePassLib;
34 using KeePassLib.Utility;
35 
36 namespace KeePass.Forms
37 {
38 	public partial class EcasTriggerForm : Form
39 	{
40 		private EcasTrigger m_triggerInOut = null;
41 		private EcasTrigger m_trigger = null;
42 
43 		private bool m_bEditing = false;
44 		private ImageList m_ilIcons = null;
45 
InitEx(EcasTrigger trigger, bool bEditing, ImageList ilIcons)46 		public void InitEx(EcasTrigger trigger, bool bEditing, ImageList ilIcons)
47 		{
48 			m_triggerInOut = trigger;
49 			m_trigger = trigger.CloneDeep();
50 
51 			m_bEditing = bEditing;
52 			m_ilIcons = ilIcons;
53 		}
54 
EcasTriggerForm()55 		public EcasTriggerForm()
56 		{
57 			InitializeComponent();
58 			GlobalWindowManager.InitializeForm(this);
59 		}
60 
OnFormLoad(object sender, EventArgs e)61 		private void OnFormLoad(object sender, EventArgs e)
62 		{
63 			GlobalWindowManager.AddWindow(this);
64 
65 			string strTitle = (m_bEditing ? KPRes.TriggerEdit : KPRes.TriggerAdd);
66 			string strDesc = (m_bEditing ? KPRes.TriggerEditDesc : KPRes.TriggerAddDesc);
67 			BannerFactory.CreateBannerEx(this, m_bannerImage,
68 				Properties.Resources.B48x48_Run, strTitle, strDesc);
69 			this.Text = strTitle;
70 			this.Icon = AppIcons.Default;
71 
72 			m_lvEvents.SmallImageList = m_ilIcons;
73 			m_lvConditions.SmallImageList = m_ilIcons;
74 			m_lvActions.SmallImageList = m_ilIcons;
75 
76 			Debug.Assert((m_lvEvents.Width == m_lvConditions.Width) &&
77 				(m_lvEvents.Width == m_lvActions.Width));
78 			int nColWidth = ((m_lvEvents.ClientSize.Width - UIUtil.GetVScrollBarWidth()) / 2);
79 			m_lvEvents.Columns.Add(KPRes.Event, nColWidth);
80 			m_lvEvents.Columns.Add(string.Empty, nColWidth);
81 			m_lvConditions.Columns.Add(KPRes.Condition, nColWidth);
82 			m_lvConditions.Columns.Add(string.Empty, nColWidth);
83 			m_lvActions.Columns.Add(KPRes.Action, nColWidth);
84 			m_lvActions.Columns.Add(string.Empty, nColWidth);
85 
86 			m_tbName.Text = m_trigger.Name;
87 			UIUtil.SetMultilineText(m_tbComments, m_trigger.Comments);
88 			m_cbEnabled.Checked = m_trigger.Enabled;
89 			m_cbInitiallyOn.Checked = m_trigger.InitiallyOn;
90 			m_cbTurnOffAfterAction.Checked = m_trigger.TurnOffAfterAction;
91 
92 			UIUtil.AccSetName(m_btnEventMoveUp, KPRes.MoveUp);
93 			UIUtil.AccSetName(m_btnEventMoveDown, KPRes.MoveDown);
94 			UIUtil.AccSetName(m_btnConditionMoveUp, KPRes.MoveUp);
95 			UIUtil.AccSetName(m_btnConditionMoveDown, KPRes.MoveDown);
96 			UIUtil.AccSetName(m_btnActionMoveUp, KPRes.MoveUp);
97 			UIUtil.AccSetName(m_btnActionMoveDown, KPRes.MoveDown);
98 
99 			UpdateListsEx(false);
100 			EnableControlsEx();
101 			UIUtil.SetFocus(m_tbName, this);
102 		}
103 
CleanUpEx()104 		private void CleanUpEx()
105 		{
106 			// Detach event handlers
107 			m_lvEvents.SmallImageList = null;
108 			m_lvConditions.SmallImageList = null;
109 			m_lvActions.SmallImageList = null;
110 		}
111 
OnFormClosed(object sender, FormClosedEventArgs e)112 		private void OnFormClosed(object sender, FormClosedEventArgs e)
113 		{
114 			CleanUpEx();
115 			GlobalWindowManager.RemoveWindow(this);
116 		}
117 
OnBtnOK(object sender, EventArgs e)118 		private void OnBtnOK(object sender, EventArgs e)
119 		{
120 			m_triggerInOut.Name = m_tbName.Text;
121 			m_triggerInOut.Comments = m_tbComments.Text;
122 			m_triggerInOut.Enabled = m_cbEnabled.Checked;
123 			m_triggerInOut.InitiallyOn = m_cbInitiallyOn.Checked;
124 			m_triggerInOut.TurnOffAfterAction = m_cbTurnOffAfterAction.Checked;
125 
126 			m_triggerInOut.EventCollection = m_trigger.EventCollection;
127 			m_triggerInOut.ConditionCollection = m_trigger.ConditionCollection;
128 			m_triggerInOut.ActionCollection = m_trigger.ActionCollection;
129 		}
130 
OnBtnCancel(object sender, EventArgs e)131 		private void OnBtnCancel(object sender, EventArgs e)
132 		{
133 		}
134 
OnBtnPrev(object sender, EventArgs e)135 		private void OnBtnPrev(object sender, EventArgs e)
136 		{
137 			if(m_tabMain.SelectedIndex > 0)
138 				m_tabMain.SelectedIndex = (m_tabMain.SelectedIndex - 1);
139 		}
140 
OnBtnNext(object sender, EventArgs e)141 		private void OnBtnNext(object sender, EventArgs e)
142 		{
143 			if(m_tabMain.SelectedIndex < (m_tabMain.TabCount - 1))
144 				m_tabMain.SelectedIndex = (m_tabMain.SelectedIndex + 1);
145 		}
146 
EnableControlsEx()147 		private void EnableControlsEx()
148 		{
149 			int nTab = m_tabMain.SelectedIndex;
150 			m_btnPrev.Enabled = (nTab > 0);
151 			m_btnNext.Enabled = (nTab < (m_tabMain.TabCount - 1));
152 
153 			int nEventsSel = m_lvEvents.SelectedIndices.Count;
154 			m_btnEventEdit.Enabled = (nEventsSel == 1);
155 			m_btnEventDelete.Enabled = m_btnEventMoveUp.Enabled =
156 				m_btnEventMoveDown.Enabled = (nEventsSel > 0);
157 
158 			int nConditionsSel = m_lvConditions.SelectedIndices.Count;
159 			m_btnConditionEdit.Enabled = (nConditionsSel == 1);
160 			m_btnConditionDelete.Enabled = m_btnConditionMoveUp.Enabled =
161 				m_btnConditionMoveDown.Enabled = (nConditionsSel > 0);
162 
163 			int nActionsSel = m_lvActions.SelectedIndices.Count;
164 			m_btnActionEdit.Enabled = (nActionsSel == 1);
165 			m_btnActionDelete.Enabled = m_btnActionMoveUp.Enabled =
166 				m_btnActionMoveDown.Enabled = (nActionsSel > 0);
167 		}
168 
UpdateListsEx(bool bRestoreSelected)169 		private void UpdateListsEx(bool bRestoreSelected)
170 		{
171 			UpdateEventListEx(bRestoreSelected);
172 			UpdateConditionListEx(bRestoreSelected);
173 			UpdateActionListEx(bRestoreSelected);
174 		}
175 
UpdateEventListEx(bool bRestoreSelected)176 		private void UpdateEventListEx(bool bRestoreSelected)
177 		{
178 			object[] vSelected = (bRestoreSelected ?
179 				UIUtil.GetSelectedItemTags(m_lvEvents) : null);
180 			UIScrollInfo s = UIUtil.GetScrollInfo(m_lvEvents, true);
181 			List<EcasEvent> lToRemove = new List<EcasEvent>();
182 
183 			m_lvEvents.BeginUpdate();
184 			m_lvEvents.Items.Clear();
185 			foreach(EcasEvent e in m_trigger.EventCollection)
186 			{
187 				EcasEventType t = Program.EcasPool.FindEvent(e.Type);
188 				if(t == null) { Debug.Assert(false); lToRemove.Add(e); continue; }
189 
190 				ListViewItem lvi = m_lvEvents.Items.Add(t.Name);
191 				lvi.SubItems.Add(EcasUtil.ParametersToString(e, t.Parameters));
192 				lvi.Tag = e;
193 				lvi.ImageIndex = (int)t.Icon;
194 			}
195 
196 			foreach(EcasEvent e in lToRemove)
197 				m_trigger.EventCollection.Remove(e);
198 			if(vSelected != null) UIUtil.SelectItems(m_lvEvents, vSelected);
199 
200 			UIUtil.Scroll(m_lvEvents, s, true);
201 			m_lvEvents.EndUpdate();
202 		}
203 
UpdateConditionListEx(bool bRestoreSelected)204 		private void UpdateConditionListEx(bool bRestoreSelected)
205 		{
206 			object[] vSelected = (bRestoreSelected ?
207 				UIUtil.GetSelectedItemTags(m_lvConditions) : null);
208 			UIScrollInfo s = UIUtil.GetScrollInfo(m_lvConditions, true);
209 			List<EcasCondition> lToRemove = new List<EcasCondition>();
210 
211 			m_lvConditions.BeginUpdate();
212 			m_lvConditions.Items.Clear();
213 			foreach(EcasCondition c in m_trigger.ConditionCollection)
214 			{
215 				EcasConditionType t = Program.EcasPool.FindCondition(c.Type);
216 				if(t == null) { Debug.Assert(false); lToRemove.Add(c); continue; }
217 
218 				ListViewItem lvi = m_lvConditions.Items.Add(t.Name);
219 				lvi.SubItems.Add(EcasUtil.ParametersToString(c, t.Parameters));
220 				lvi.Tag = c;
221 				lvi.ImageIndex = (int)t.Icon;
222 			}
223 
224 			foreach(EcasCondition c in lToRemove)
225 				m_trigger.ConditionCollection.Remove(c);
226 			if(vSelected != null) UIUtil.SelectItems(m_lvConditions, vSelected);
227 
228 			UIUtil.Scroll(m_lvConditions, s, true);
229 			m_lvConditions.EndUpdate();
230 		}
231 
UpdateActionListEx(bool bRestoreSelected)232 		private void UpdateActionListEx(bool bRestoreSelected)
233 		{
234 			object[] vSelected = (bRestoreSelected ?
235 				UIUtil.GetSelectedItemTags(m_lvActions) : null);
236 			UIScrollInfo s = UIUtil.GetScrollInfo(m_lvActions, true);
237 			List<EcasAction> lToRemove = new List<EcasAction>();
238 
239 			m_lvActions.BeginUpdate();
240 			m_lvActions.Items.Clear();
241 			foreach(EcasAction a in m_trigger.ActionCollection)
242 			{
243 				EcasActionType t = Program.EcasPool.FindAction(a.Type);
244 				if(t == null) { Debug.Assert(false); lToRemove.Add(a); continue; }
245 
246 				ListViewItem lvi = m_lvActions.Items.Add(t.Name);
247 				lvi.SubItems.Add(EcasUtil.ParametersToString(a, t.Parameters));
248 				lvi.Tag = a;
249 				lvi.ImageIndex = (int)t.Icon;
250 			}
251 
252 			foreach(EcasAction a in lToRemove)
253 				m_trigger.ActionCollection.Remove(a);
254 			if(vSelected != null) UIUtil.SelectItems(m_lvActions, vSelected);
255 
256 			UIUtil.Scroll(m_lvActions, s, true);
257 			m_lvActions.EndUpdate();
258 		}
259 
OnEventsSelectedIndexChanged(object sender, EventArgs e)260 		private void OnEventsSelectedIndexChanged(object sender, EventArgs e)
261 		{
262 			EnableControlsEx();
263 		}
264 
OnConditionsSelectedIndexChanged(object sender, EventArgs e)265 		private void OnConditionsSelectedIndexChanged(object sender, EventArgs e)
266 		{
267 			EnableControlsEx();
268 		}
269 
OnActionsSelectedIndexChanged(object sender, EventArgs e)270 		private void OnActionsSelectedIndexChanged(object sender, EventArgs e)
271 		{
272 			EnableControlsEx();
273 		}
274 
OnEventAdd(object sender, EventArgs e)275 		private void OnEventAdd(object sender, EventArgs e)
276 		{
277 			EcasEvent eNew = new EcasEvent();
278 			eNew.Type = EcasEventIDs.AppLoadPost;
279 
280 			EcasEventForm dlg = new EcasEventForm();
281 			dlg.InitEx(eNew);
282 			if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK)
283 			{
284 				m_trigger.EventCollection.Add(eNew);
285 				UpdateEventListEx(false);
286 			}
287 		}
288 
OnEventEdit(object sender, EventArgs e)289 		private void OnEventEdit(object sender, EventArgs e)
290 		{
291 			ListView.SelectedListViewItemCollection lvsic = m_lvEvents.SelectedItems;
292 			if((lvsic == null) || (lvsic.Count == 0)) return;
293 
294 			EcasEventForm dlg = new EcasEventForm();
295 			dlg.InitEx(lvsic[0].Tag as EcasEvent);
296 			if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK)
297 				UpdateEventListEx(true);
298 		}
299 
OnEventDelete(object sender, EventArgs e)300 		private void OnEventDelete(object sender, EventArgs e)
301 		{
302 			UIUtil.DeleteSelectedItems(m_lvEvents, m_trigger.EventCollection);
303 		}
304 
OnConditionAdd(object sender, EventArgs e)305 		private void OnConditionAdd(object sender, EventArgs e)
306 		{
307 			EcasCondition eNew = new EcasCondition();
308 			EcasConditionForm dlg = new EcasConditionForm();
309 			dlg.InitEx(eNew);
310 			if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK)
311 			{
312 				m_trigger.ConditionCollection.Add(eNew);
313 				UpdateConditionListEx(false);
314 			}
315 		}
316 
OnConditionEdit(object sender, EventArgs e)317 		private void OnConditionEdit(object sender, EventArgs e)
318 		{
319 			ListView.SelectedListViewItemCollection lvsic = m_lvConditions.SelectedItems;
320 			if((lvsic == null) || (lvsic.Count == 0)) return;
321 
322 			EcasConditionForm dlg = new EcasConditionForm();
323 			dlg.InitEx(lvsic[0].Tag as EcasCondition);
324 			if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK)
325 				UpdateConditionListEx(true);
326 		}
327 
OnConditionDelete(object sender, EventArgs e)328 		private void OnConditionDelete(object sender, EventArgs e)
329 		{
330 			UIUtil.DeleteSelectedItems(m_lvConditions, m_trigger.ConditionCollection);
331 		}
332 
OnActionAdd(object sender, EventArgs e)333 		private void OnActionAdd(object sender, EventArgs e)
334 		{
335 			EcasAction eNew = new EcasAction();
336 			EcasActionForm dlg = new EcasActionForm();
337 			dlg.InitEx(eNew);
338 			if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK)
339 			{
340 				m_trigger.ActionCollection.Add(eNew);
341 				UpdateActionListEx(false);
342 			}
343 		}
344 
OnActionEdit(object sender, EventArgs e)345 		private void OnActionEdit(object sender, EventArgs e)
346 		{
347 			ListView.SelectedListViewItemCollection lvsic = m_lvActions.SelectedItems;
348 			if((lvsic == null) || (lvsic.Count == 0)) return;
349 
350 			EcasActionForm dlg = new EcasActionForm();
351 			dlg.InitEx(lvsic[0].Tag as EcasAction);
352 			if(UIUtil.ShowDialogAndDestroy(dlg) == DialogResult.OK)
353 				UpdateActionListEx(true);
354 		}
355 
OnActionDelete(object sender, EventArgs e)356 		private void OnActionDelete(object sender, EventArgs e)
357 		{
358 			UIUtil.DeleteSelectedItems(m_lvActions, m_trigger.ActionCollection);
359 		}
360 
OnBtnEventMoveUp(object sender, EventArgs e)361 		private void OnBtnEventMoveUp(object sender, EventArgs e)
362 		{
363 			UIUtil.MoveSelectedItemsInternalOne(m_lvEvents,
364 				m_trigger.EventCollection, true);
365 			UpdateEventListEx(true);
366 		}
367 
OnBtnEventMoveDown(object sender, EventArgs e)368 		private void OnBtnEventMoveDown(object sender, EventArgs e)
369 		{
370 			UIUtil.MoveSelectedItemsInternalOne(m_lvEvents,
371 				m_trigger.EventCollection, false);
372 			UpdateEventListEx(true);
373 		}
374 
OnBtnConditionMoveUp(object sender, EventArgs e)375 		private void OnBtnConditionMoveUp(object sender, EventArgs e)
376 		{
377 			UIUtil.MoveSelectedItemsInternalOne(m_lvConditions,
378 				m_trigger.ConditionCollection, true);
379 			UpdateConditionListEx(true);
380 		}
381 
OnBtnConditionMoveDown(object sender, EventArgs e)382 		private void OnBtnConditionMoveDown(object sender, EventArgs e)
383 		{
384 			UIUtil.MoveSelectedItemsInternalOne(m_lvConditions,
385 				m_trigger.ConditionCollection, false);
386 			UpdateConditionListEx(true);
387 		}
388 
OnBtnActionMoveUp(object sender, EventArgs e)389 		private void OnBtnActionMoveUp(object sender, EventArgs e)
390 		{
391 			UIUtil.MoveSelectedItemsInternalOne(m_lvActions,
392 				m_trigger.ActionCollection, true);
393 			UpdateActionListEx(true);
394 		}
395 
OnBtnActionMoveDown(object sender, EventArgs e)396 		private void OnBtnActionMoveDown(object sender, EventArgs e)
397 		{
398 			UIUtil.MoveSelectedItemsInternalOne(m_lvActions,
399 				m_trigger.ActionCollection, false);
400 			UpdateActionListEx(true);
401 		}
402 
OnBtnHelp(object sender, EventArgs e)403 		private void OnBtnHelp(object sender, EventArgs e)
404 		{
405 			AppHelp.ShowHelp(AppDefs.HelpTopics.Triggers, null);
406 		}
407 
OnEventsItemActivate(object sender, EventArgs e)408 		private void OnEventsItemActivate(object sender, EventArgs e)
409 		{
410 			OnEventEdit(sender, e);
411 		}
412 
OnConditionsItemActivate(object sender, EventArgs e)413 		private void OnConditionsItemActivate(object sender, EventArgs e)
414 		{
415 			OnConditionEdit(sender, e);
416 		}
417 
OnActionsItemActivate(object sender, EventArgs e)418 		private void OnActionsItemActivate(object sender, EventArgs e)
419 		{
420 			OnActionEdit(sender, e);
421 		}
422 
OnTabMainSelectedIndexChanged(object sender, EventArgs e)423 		private void OnTabMainSelectedIndexChanged(object sender, EventArgs e)
424 		{
425 			EnableControlsEx();
426 		}
427 	}
428 }
429