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.Resources; 30 using KeePass.UI; 31 32 using KeePassLib; 33 using KeePassLib.Collections; 34 using KeePassLib.Delegates; 35 36 namespace KeePass.Forms 37 { 38 public partial class DatabaseOperationsForm : Form, IGwmWindow 39 { 40 private PwDatabase m_pwDatabase = null; 41 private bool m_bModified = false; 42 43 private StringDictionaryEx m_sdCustomData = null; 44 45 public bool CanCloseWithoutDataLoss { get { return true; } } 46 public bool HasModifiedDatabase { get { return m_bModified; } } 47 InitEx(PwDatabase pwDatabase)48 public void InitEx(PwDatabase pwDatabase) 49 { 50 m_pwDatabase = pwDatabase; 51 } 52 DatabaseOperationsForm()53 public DatabaseOperationsForm() 54 { 55 InitializeComponent(); 56 GlobalWindowManager.InitializeForm(this); 57 } 58 OnFormLoad(object sender, EventArgs e)59 private void OnFormLoad(object sender, EventArgs e) 60 { 61 Debug.Assert(m_pwDatabase != null); if(m_pwDatabase == null) throw new InvalidOperationException(); 62 63 GlobalWindowManager.AddWindow(this, this); 64 65 BannerFactory.CreateBannerEx(this, m_bannerImage, 66 Properties.Resources.B48x48_Package_Settings, KPRes.DatabaseMaintenance, 67 KPRes.DatabaseMaintenanceDesc); 68 this.Icon = AppIcons.Default; 69 this.Text = KPRes.DatabaseMaintenance; 70 71 m_numHistoryDays.Value = m_pwDatabase.MaintenanceHistoryDays; 72 73 m_sdCustomData = m_pwDatabase.CustomData.CloneDeep(); 74 UIUtil.StrDictListInit(m_lvCustomData); 75 UIUtil.StrDictListUpdate(m_lvCustomData, m_sdCustomData, false); 76 77 m_pbStatus.Visible = false; 78 EnableControlsEx(); 79 } 80 OnBtnClose(object sender, EventArgs e)81 private void OnBtnClose(object sender, EventArgs e) 82 { 83 m_pwDatabase.MaintenanceHistoryDays = (uint)m_numHistoryDays.Value; 84 85 if(m_sdCustomData.Count != m_pwDatabase.CustomData.Count) 86 { 87 m_pwDatabase.CustomData = m_sdCustomData; 88 m_bModified = true; 89 } 90 else { Debug.Assert(m_sdCustomData.Equals(m_pwDatabase.CustomData)); } 91 } 92 EnableControlsEx()93 private void EnableControlsEx() 94 { 95 m_btnCDDel.Enabled = (m_lvCustomData.SelectedIndices.Count > 0); 96 } 97 EnableStatusMsgEx(bool bEnable)98 private void EnableStatusMsgEx(bool bEnable) 99 { 100 if(bEnable) 101 { 102 m_btnClose.Enabled = m_btnHistoryEntriesDelete.Enabled = 103 m_btnRemoveDelObjInfo.Enabled = false; 104 if(!m_pbStatus.Visible) m_pbStatus.Visible = true; 105 106 m_pbStatus.Value = 0; 107 } 108 else 109 { 110 m_btnClose.Enabled = m_btnHistoryEntriesDelete.Enabled = 111 m_btnRemoveDelObjInfo.Enabled = true; 112 113 m_pbStatus.Value = m_pbStatus.Maximum; 114 } 115 } 116 OnBtnDelete(object sender, EventArgs e)117 private void OnBtnDelete(object sender, EventArgs e) 118 { 119 EnableStatusMsgEx(true); 120 121 DateTime dtNow = DateTime.UtcNow; 122 TimeSpan tsSpan = new TimeSpan((int)m_numHistoryDays.Value, 0, 0, 0); 123 124 uint uNumGroups, uNumEntries; 125 m_pwDatabase.RootGroup.GetCounts(true, out uNumGroups, out uNumEntries); 126 127 uint uCurEntryNumber = 1; 128 EntryHandler eh = delegate(PwEntry pe) 129 { 130 for(uint u = 0; u < pe.History.UCount; ++u) 131 { 132 PwEntry peHist = pe.History.GetAt(u); 133 134 if((dtNow - peHist.LastModificationTime) >= tsSpan) 135 { 136 pe.History.Remove(peHist); 137 --u; 138 139 m_bModified = true; 140 } 141 } 142 143 m_pbStatus.Value = (int)((uCurEntryNumber * 100) / uNumEntries); 144 ++uCurEntryNumber; 145 return true; 146 }; 147 148 m_pwDatabase.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh); 149 150 EnableStatusMsgEx(false); // Database is set modified by parent 151 } 152 OnFormClosed(object sender, FormClosedEventArgs e)153 private void OnFormClosed(object sender, FormClosedEventArgs e) 154 { 155 GlobalWindowManager.RemoveWindow(this); 156 } 157 OnBtnRemoveDelObjInfo(object sender, EventArgs e)158 private void OnBtnRemoveDelObjInfo(object sender, EventArgs e) 159 { 160 EnableStatusMsgEx(true); 161 162 if(m_pwDatabase.DeletedObjects.UCount > 0) 163 { 164 m_pwDatabase.DeletedObjects.Clear(); 165 m_bModified = true; 166 } 167 168 EnableStatusMsgEx(false); // Database is set modified by parent 169 } 170 OnCustomDataSelectedIndexChanged(object sender, EventArgs e)171 private void OnCustomDataSelectedIndexChanged(object sender, EventArgs e) 172 { 173 EnableControlsEx(); 174 } 175 OnBtnCDDel(object sender, EventArgs e)176 private void OnBtnCDDel(object sender, EventArgs e) 177 { 178 UIUtil.StrDictListDeleteSel(m_lvCustomData, m_sdCustomData, false); 179 UIUtil.SetFocus(m_lvCustomData, this); 180 EnableControlsEx(); 181 } 182 } 183 } 184