private void txtNotes_Leave(object sender, EventArgs e) { if (txtNotes.Tag != null) // Textbox has been marked as changed { PwDatabase pwStorage = m_host.Database; PwEntry pe = m_host.MainWindow.GetSelectedEntry(true); PwEntry peInit = (PwEntry)txtNotes.Tag; PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreLastMod | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreLastBackup); if (pe.EqualsEntry(peInit, cmpOpt, MemProtCmpMode.None)) { // Text contents has not been changed, undo last backup from history pe.LastModificationTime = peInit.LastModificationTime; pe.History.Remove(pe.History.GetAt(pe.History.UCount - 1)); // Undo backup } else { // Text has been changed - enable save icon Util.UpdateSaveState(); m_host.MainWindow.EnsureVisibleEntry(pe.Uuid); } txtNotes.Tag = null; } txtNotes.TextChanged -= txtNotes_TextChanged; }
public bool HasBackupOfData(PwEntry peData, bool bIgnoreLastMod, bool bIgnoreLastAccess) { if (peData == null) { Debug.Assert(false); return(false); } PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreParentGroup | PwCompareOptions.IgnoreHistory | PwCompareOptions.NullEmptyEquivStd); if (bIgnoreLastMod) { cmpOpt |= PwCompareOptions.IgnoreLastMod; } if (bIgnoreLastAccess) { cmpOpt |= PwCompareOptions.IgnoreLastAccess; } foreach (PwEntry pe in m_listHistory) { if (pe.EqualsEntry(peData, cmpOpt, MemProtCmpMode.None)) { return(true); } } return(false); }
private static PwCompareOptions BuildCmpOpt(bool bIgnoreParentGroup, bool bIgnoreLastMod, bool bIgnoreLastAccess, bool bIgnoreHistory, bool bIgnoreThisLastBackup) { PwCompareOptions pwOpt = PwCompareOptions.None; if (bIgnoreParentGroup) { pwOpt |= PwCompareOptions.IgnoreParentGroup; } if (bIgnoreLastMod) { pwOpt |= PwCompareOptions.IgnoreLastMod; } if (bIgnoreLastAccess) { pwOpt |= PwCompareOptions.IgnoreLastAccess; } if (bIgnoreHistory) { pwOpt |= PwCompareOptions.IgnoreHistory; } if (bIgnoreThisLastBackup) { pwOpt |= PwCompareOptions.IgnoreLastBackup; } return(pwOpt); }
private bool SaveEntryStatus(ListViewItem Item, PwIcon icon, string text) { PwListItem pli = (((ListViewItem)Item).Tag as PwListItem); if (pli == null) { Debug.Assert(false); return(false); } PwEntry pe = pli.Entry; pe = m_host.Database.RootGroup.FindEntry(pe.Uuid, true); var protString = pe.Strings.Get(PwDefs.PasswordField); if (protString != null && !protString.IsEmpty) { return(false); } PwEntry peInit = pe.CloneDeep(); pe.CreateBackup(null); pe.Touch(true, false); // Touch *after* backup pe.IconId = icon; Item.ImageIndex = (int)icon; pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, text)); Item.SubItems[getSubitemOfField(KeePass.App.Configuration.AceColumnType.UserName)].Text = text; PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreLastMod | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreLastBackup); if (pe.EqualsEntry(peInit, cmpOpt, MemProtCmpMode.None)) { pe.LastModificationTime = peInit.LastModificationTime; pe.History.Remove(pe.History.GetAt(pe.History.UCount - 1)); // Undo backup return(false); } else { return(true); } }
/// <summary> /// The function compares two PwEntries in every scope except the Uuid /// </summary> /// <param name="entry">the first entry</param> /// <param name="otherEntry">the second entry</param> /// <param name="bIgnoreKeeShareFields">Should the KeeShare-specific fields be ignored?</param> /// <returns>True if both entries are equal in all field, accordingly to the parametersettings</returns> public static bool IsSimilarTo(this PwEntry entry, PwEntry otherEntry, bool bIgnoreKeeShareFields) { //if both are null they are equal if (entry == null && otherEntry == null) { return(true); } //if only one of them is null we could not clone it => they are not equal if (entry == null || otherEntry == null) { return(false); } // only clone both entries if we need to PwEntry myCopy = entry.CloneDeep(); PwEntry otherCopy = otherEntry; if (bIgnoreKeeShareFields) { myCopy.Strings.Remove(KeeShare.UuidLinkField); otherCopy = otherEntry.CloneDeep(); otherCopy.Strings.Remove(KeeShare.UuidLinkField); } //we have to make the Uuids and creation times equal, because PwEntry.EqualsEntry compares these too //and returns false if they are not equal!! myCopy.SetUuid(otherCopy.Uuid, false); myCopy.CreationTime = otherCopy.CreationTime; PwCompareOptions opts = PwCompareOptions.IgnoreHistory | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreLastBackup | PwCompareOptions.IgnoreLastMod | PwCompareOptions.IgnoreParentGroup | PwCompareOptions.IgnoreTimes; return(myCopy.EqualsEntry(otherCopy, opts, MemProtCmpMode.Full)); }
public bool EqualsDictionary(ProtectedStringDictionary dict, PwCompareOptions pwOpt, MemProtCmpMode mpCompare) { if (dict == null) { Debug.Assert(false); return(false); } bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) != PwCompareOptions.None); if (!bNeEqStd) { if (m_vStrings.Count != dict.m_vStrings.Count) { return(false); } } foreach (KeyValuePair <string, ProtectedString> kvp in m_vStrings) { bool bStdField = PwDefs.IsStandardField(kvp.Key); ProtectedString ps = dict.Get(kvp.Key); if (bNeEqStd && (ps == null) && bStdField) { ps = ProtectedString.Empty; } if (ps == null) { return(false); } if (mpCompare == MemProtCmpMode.Full) { if (ps.IsProtected != kvp.Value.IsProtected) { return(false); } } else if (mpCompare == MemProtCmpMode.CustomOnly) { if (!bStdField && (ps.IsProtected != kvp.Value.IsProtected)) { return(false); } } if (!ps.Equals(kvp.Value, false)) { return(false); } } if (bNeEqStd) { foreach (KeyValuePair <string, ProtectedString> kvp in dict.m_vStrings) { ProtectedString ps = Get(kvp.Key); if (ps != null) { continue; // Compared previously } if (!PwDefs.IsStandardField(kvp.Key)) { return(false); } if (!kvp.Value.IsEmpty) { return(false); } } } return(true); }
private static void PrepareModDbForMerge(PwDatabase pd, PwDatabase pdOrg) { PwGroup pgRootOrg = pdOrg.RootGroup; PwGroup pgRootNew = pd.RootGroup; if (pgRootNew == null) { Debug.Assert(false); return; } PwCompareOptions pwCmp = (PwCompareOptions.IgnoreParentGroup | PwCompareOptions.NullEmptyEquivStd); DateTime dtNow = DateTime.UtcNow; GroupHandler ghOrg = delegate(PwGroup pg) { PwGroup pgNew = pgRootNew.FindGroup(pg.Uuid, true); if (pgNew == null) { AddDeletedObject(pd, pg.Uuid); return(true); } if (!pgNew.EqualsGroup(pg, (pwCmp | PwCompareOptions.PropertiesOnly), MemProtCmpMode.Full)) { pgNew.Touch(true, false); } PwGroup pgParentA = pg.ParentGroup; PwGroup pgParentB = pgNew.ParentGroup; if ((pgParentA != null) && (pgParentB != null)) { if (!pgParentA.Uuid.Equals(pgParentB.Uuid)) { pgNew.LocationChanged = dtNow; } } else if ((pgParentA == null) && (pgParentB == null)) { } else { pgNew.LocationChanged = dtNow; } return(true); }; EntryHandler ehOrg = delegate(PwEntry pe) { PwEntry peNew = pgRootNew.FindEntry(pe.Uuid, true); if (peNew == null) { AddDeletedObject(pd, pe.Uuid); return(true); } if (!peNew.EqualsEntry(pe, pwCmp, MemProtCmpMode.Full)) { peNew.Touch(true, false); bool bRestoreHistory = false; if (peNew.History.UCount != pe.History.UCount) { bRestoreHistory = true; } else { for (uint u = 0; u < pe.History.UCount; ++u) { if (!peNew.History.GetAt(u).EqualsEntry( pe.History.GetAt(u), pwCmp, MemProtCmpMode.CustomOnly)) { bRestoreHistory = true; break; } } } if (bRestoreHistory) { peNew.History = pe.History.CloneDeep(); foreach (PwEntry peHistNew in peNew.History) { peHistNew.ParentGroup = peNew.ParentGroup; } } } PwGroup pgParentA = pe.ParentGroup; PwGroup pgParentB = peNew.ParentGroup; if ((pgParentA != null) && (pgParentB != null)) { if (!pgParentA.Uuid.Equals(pgParentB.Uuid)) { peNew.LocationChanged = dtNow; } } else if ((pgParentA == null) && (pgParentB == null)) { } else { peNew.LocationChanged = dtNow; } return(true); }; pgRootOrg.TraverseTree(TraversalMethod.PreOrder, ghOrg, ehOrg); }
public bool EqualsEntry(PwEntry pe, PwCompareOptions pwOpt, MemProtCmpMode mpCmpStr) { if (pe == null) { Debug.Assert(false); return(false); } bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) != PwCompareOptions.None); bool bIgnoreLastAccess = ((pwOpt & PwCompareOptions.IgnoreLastAccess) != PwCompareOptions.None); bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) != PwCompareOptions.None); if (!m_uuid.Equals(pe.m_uuid)) { return(false); } if ((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None) { if (m_pParentGroup != pe.m_pParentGroup) { return(false); } if (!bIgnoreLastMod && (m_tParentGroupLastMod != pe.m_tParentGroupLastMod)) { return(false); } } if (!m_listStrings.EqualsDictionary(pe.m_listStrings, pwOpt, mpCmpStr)) { return(false); } if (!m_listBinaries.EqualsDictionary(pe.m_listBinaries)) { return(false); } if (!m_listAutoType.Equals(pe.m_listAutoType)) { return(false); } if ((pwOpt & PwCompareOptions.IgnoreHistory) == PwCompareOptions.None) { bool bIgnoreLastBackup = ((pwOpt & PwCompareOptions.IgnoreLastBackup) != PwCompareOptions.None); if (!bIgnoreLastBackup && (m_listHistory.UCount != pe.m_listHistory.UCount)) { return(false); } if (bIgnoreLastBackup && (m_listHistory.UCount == 0)) { Debug.Assert(false); return(false); } if (bIgnoreLastBackup && ((m_listHistory.UCount - 1) != pe.m_listHistory.UCount)) { return(false); } PwCompareOptions cmpSub = PwCompareOptions.IgnoreParentGroup; if (bNeEqStd) { cmpSub |= PwCompareOptions.NullEmptyEquivStd; } if (bIgnoreLastMod) { cmpSub |= PwCompareOptions.IgnoreLastMod; } if (bIgnoreLastAccess) { cmpSub |= PwCompareOptions.IgnoreLastAccess; } for (uint uHist = 0; uHist < pe.m_listHistory.UCount; ++uHist) { if (!m_listHistory.GetAt(uHist).EqualsEntry(pe.m_listHistory.GetAt( uHist), cmpSub, MemProtCmpMode.None)) { return(false); } } } if (m_pwIcon != pe.m_pwIcon) { return(false); } if (!m_pwCustomIconID.Equals(pe.m_pwCustomIconID)) { return(false); } if (m_clrForeground != pe.m_clrForeground) { return(false); } if (m_clrBackground != pe.m_clrBackground) { return(false); } if (m_tCreation != pe.m_tCreation) { return(false); } if (!bIgnoreLastMod && (m_tLastMod != pe.m_tLastMod)) { return(false); } if (!bIgnoreLastAccess && (m_tLastAccess != pe.m_tLastAccess)) { return(false); } if (m_tExpire != pe.m_tExpire) { return(false); } if (m_bExpires != pe.m_bExpires) { return(false); } if (!bIgnoreLastAccess && (m_uUsageCount != pe.m_uUsageCount)) { return(false); } if (m_strOverrideUrl != pe.m_strOverrideUrl) { return(false); } if (m_vTags.Count != pe.m_vTags.Count) { return(false); } for (int iTag = 0; iTag < m_vTags.Count; ++iTag) { if (m_vTags[iTag] != pe.m_vTags[iTag]) { return(false); } } return(true); }
void SaveEntry() { Database db = App.Kp2a.GetDb(); EntryEditActivity act = this; if (!ValidateBeforeSaving()) { return; } PwEntry initialEntry = State.EntryInDatabase.CloneDeep(); PwEntry newEntry = State.EntryInDatabase; //Clone history and re-assign: newEntry.History = newEntry.History.CloneDeep(); //Based on KeePass Desktop bool bCreateBackup = (!State.IsNew); if (bCreateBackup) { newEntry.CreateBackup(null); } if (State.SelectedIcon) { newEntry.IconId = State.SelectedIconId; newEntry.CustomIconUuid = State.SelectedCustomIconId; } //else the State.EntryInDatabase.Icon /* KPDesktop * if(m_cbCustomForegroundColor.Checked) * newEntry.ForegroundColor = m_clrForeground; * else newEntry.ForegroundColor = Color.Empty; * if(m_cbCustomBackgroundColor.Checked) * newEntry.BackgroundColor = m_clrBackground; * else newEntry.BackgroundColor = Color.Empty; * */ UpdateEntryFromUi(newEntry); newEntry.Binaries = State.Entry.Binaries; newEntry.Expires = State.Entry.Expires; if (newEntry.Expires) { newEntry.ExpiryTime = State.Entry.ExpiryTime; } newEntry.Touch(true, false); // Touch *after* backup StrUtil.NormalizeNewLines(newEntry.Strings, true); bool bUndoBackup = false; PwCompareOptions cmpOpt = (PwCompareOptions.NullEmptyEquivStd | PwCompareOptions.IgnoreTimes); if (bCreateBackup) { cmpOpt |= PwCompareOptions.IgnoreLastBackup; } if (newEntry.EqualsEntry(initialEntry, cmpOpt, MemProtCmpMode.CustomOnly)) { // No modifications at all => restore last mod time and undo backup newEntry.LastModificationTime = initialEntry.LastModificationTime; bUndoBackup = bCreateBackup; } else if (bCreateBackup) { // If only history items have been modified (deleted) => undo // backup, but without restoring the last mod time PwCompareOptions cmpOptNh = (cmpOpt | PwCompareOptions.IgnoreHistory); if (newEntry.EqualsEntry(initialEntry, cmpOptNh, MemProtCmpMode.CustomOnly)) { bUndoBackup = true; } } if (bUndoBackup) { newEntry.History.RemoveAt(newEntry.History.UCount - 1); } newEntry.MaintainBackups(db.KpDatabase); //if ( newEntry.Strings.ReadSafe (PwDefs.TitleField).Equals(State.Entry.Strings.ReadSafe (PwDefs.TitleField)) ) { // SetResult(KeePass.EXIT_REFRESH); //} else { //it's safer to always update the title as we might add further information in the title like expiry etc. SetResult(KeePass.ExitRefreshTitle); //} RunnableOnFinish runnable; ActionOnFinish closeOrShowError = new ActionOnFinish((success, message) => { if (success) { Finish(); } else { OnFinish.DisplayMessage(this, message); } }); ActionOnFinish afterAddEntry = new ActionOnFinish((success, message) => { if (success) { _appTask.AfterAddNewEntry(this, newEntry); } }, closeOrShowError); if (State.IsNew) { runnable = AddEntry.GetInstance(this, App.Kp2a, newEntry, State.ParentGroup, afterAddEntry); } else { runnable = new UpdateEntry(this, App.Kp2a, initialEntry, newEntry, closeOrShowError); } ProgressTask pt = new ProgressTask(App.Kp2a, act, runnable); pt.Run(); }
/* * // Get all user defined strings * internal static Dictionary<string, string> GetDictEntriesUserStrings(PwGroup pwg) * { * Dictionary<string, string> strd = new Dictionary<string, string>(); * //SortedDictionary<string, string> strd = new SortedDictionary<string, string>(); * * // Add all known pwentry strings * foreach (PwEntry pe in pwg.GetEntries(true)) * { * foreach (KeyValuePair<string, ProtectedString> pstr in pe.Strings) * { * if (!strd.ContainsKey(pstr.Key)) * { * if (!PwDefs.IsStandardField(pstr.Key)) * { * strd.Add(pstr.Key, pstr.Value.ReadString()); * } * } * } * } * * return strd; * }*/ // Ported from KeePass Entry Dialog SaveEntry() and UpdateEntryStrings(...) internal static bool SaveEntry(PwDatabase pwStorage, ListViewItem Item, int SubItem, string Text) { PwListItem pli = (((ListViewItem)Item).Tag as PwListItem); if (pli == null) { Debug.Assert(false); return(false); } PwEntry pe = pli.Entry; pe = pwStorage.RootGroup.FindEntry(pe.Uuid, true); PwEntry peInit = pe.CloneDeep(); pe.CreateBackup(null); pe.Touch(true, false); // Touch *after* backup int colID = SubItem; AceColumn col = GetAceColumn(colID); AceColumnType colType = col.Type; switch (colType) { case AceColumnType.Title: //if(PwDefs.IsTanEntry(pe)) //TODO tan list TanTitle ??? pe.Strings.Set(PwDefs.TanTitle, new ProtectedString(false, Text)); //else pe.Strings.Set(PwDefs.TitleField, new ProtectedString(pwStorage.MemoryProtection.ProtectTitle, Text)); break; case AceColumnType.UserName: pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(pwStorage.MemoryProtection.ProtectUserName, Text)); break; case AceColumnType.Password: //byte[] pb = Text.ToUtf8(); //pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(pwStorage.MemoryProtection.ProtectPassword, pb)); //MemUtil.ZeroByteArray(pb); pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(pwStorage.MemoryProtection.ProtectPassword, Text)); break; case AceColumnType.Url: pe.Strings.Set(PwDefs.UrlField, new ProtectedString(pwStorage.MemoryProtection.ProtectUrl, Text)); break; case AceColumnType.Notes: pe.Strings.Set(PwDefs.NotesField, new ProtectedString(pwStorage.MemoryProtection.ProtectNotes, Text)); break; case AceColumnType.OverrideUrl: pe.OverrideUrl = Text; break; case AceColumnType.Tags: List <string> vNewTags = StrUtil.StringToTags(Text); pe.Tags.Clear(); foreach (string strTag in vNewTags) { pe.AddTag(strTag); } break; case AceColumnType.CustomString: pe.Strings.Set(col.CustomName, new ProtectedString(pe.Strings.GetSafe(col.CustomName).IsProtected, Text)); break; default: // Nothing todo break; } PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreLastMod | PwCompareOptions.IgnoreLastAccess | PwCompareOptions.IgnoreLastBackup); if (pe.EqualsEntry(peInit, cmpOpt, MemProtCmpMode.None)) { pe.LastModificationTime = peInit.LastModificationTime; pe.History.Remove(pe.History.GetAt(pe.History.UCount - 1)); // Undo backup return(false); } else { return(true); } }
public bool EqualsEntry(PwEntry pe, PwCompareOptions pwOpt, MemProtCmpMode mpCmpStr) { if (pe == null) { Debug.Assert(false); return(false); } bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) != PwCompareOptions.None); bool bIgnoreLastAccess = ((pwOpt & PwCompareOptions.IgnoreLastAccess) != PwCompareOptions.None); bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) != PwCompareOptions.None); if (!m_uuid.Equals(pe.m_uuid)) { return(false); } if ((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None) { if (m_pParentGroup != pe.m_pParentGroup) { return(false); } if (!bIgnoreLastMod && (m_tParentGroupLastMod != pe.m_tParentGroupLastMod)) { return(false); } if (!m_puPrevParentGroup.Equals(pe.m_puPrevParentGroup)) { return(false); } } if (!m_dStrings.EqualsDictionary(pe.m_dStrings, pwOpt, mpCmpStr)) { return(false); } if (!m_dBinaries.EqualsDictionary(pe.m_dBinaries)) { return(false); } if (!m_cfgAutoType.Equals(pe.m_cfgAutoType)) { return(false); } if ((pwOpt & PwCompareOptions.IgnoreHistory) == PwCompareOptions.None) { bool bIgnoreLastBackup = ((pwOpt & PwCompareOptions.IgnoreLastBackup) != PwCompareOptions.None); if (!bIgnoreLastBackup && (m_lHistory.UCount != pe.m_lHistory.UCount)) { return(false); } if (bIgnoreLastBackup && (m_lHistory.UCount == 0)) { Debug.Assert(false); return(false); } if (bIgnoreLastBackup && ((m_lHistory.UCount - 1) != pe.m_lHistory.UCount)) { return(false); } PwCompareOptions cmpSub = PwCompareOptions.IgnoreParentGroup; if (bNeEqStd) { cmpSub |= PwCompareOptions.NullEmptyEquivStd; } if (bIgnoreLastMod) { cmpSub |= PwCompareOptions.IgnoreLastMod; } if (bIgnoreLastAccess) { cmpSub |= PwCompareOptions.IgnoreLastAccess; } for (uint uHist = 0; uHist < pe.m_lHistory.UCount; ++uHist) { if (!m_lHistory.GetAt(uHist).EqualsEntry(pe.m_lHistory.GetAt( uHist), cmpSub, MemProtCmpMode.None)) { return(false); } } } if (m_pwIcon != pe.m_pwIcon) { return(false); } if (!m_puCustomIcon.Equals(pe.m_puCustomIcon)) { return(false); } if (m_clrForeground != pe.m_clrForeground) { return(false); } if (m_clrBackground != pe.m_clrBackground) { return(false); } if (m_tCreation != pe.m_tCreation) { return(false); } if (!bIgnoreLastMod && (m_tLastMod != pe.m_tLastMod)) { return(false); } if (!bIgnoreLastAccess && (m_tLastAccess != pe.m_tLastAccess)) { return(false); } if (m_tExpire != pe.m_tExpire) { return(false); } if (m_bExpires != pe.m_bExpires) { return(false); } if (!bIgnoreLastAccess && (m_uUsageCount != pe.m_uUsageCount)) { return(false); } if (m_strOverrideUrl != pe.m_strOverrideUrl) { return(false); } if (m_bQualityCheck != pe.m_bQualityCheck) { return(false); } // The Tags property normalizes if (!MemUtil.ListsEqual <string>(this.Tags, pe.Tags)) { return(false); } if (!m_dCustomData.Equals(pe.m_dCustomData)) { return(false); } return(true); }
private static void PrepareModDbForMerge(PwDatabase pd, PwDatabase pdOrg) { PwGroup pgRootOrg = pdOrg.RootGroup; PwGroup pgRootNew = pd.RootGroup; if (pgRootNew == null) { Debug.Assert(false); return; } const PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreParentGroup | PwCompareOptions.IgnoreHistory | PwCompareOptions.NullEmptyEquivStd); const MemProtCmpMode cmpMem = MemProtCmpMode.CustomOnly; DateTime dtNow = DateTime.UtcNow; GroupHandler ghOrg = delegate(PwGroup pg) { PwGroup pgNew = pgRootNew.FindGroup(pg.Uuid, true); if (pgNew == null) { AddDeletedObject(pd, pg.Uuid); return(true); } if (!pgNew.EqualsGroup(pg, (cmpOpt | PwCompareOptions.PropertiesOnly), cmpMem)) { pgNew.Touch(true, false); } PwGroup pgParentA = pg.ParentGroup; PwGroup pgParentB = pgNew.ParentGroup; if ((pgParentA != null) && (pgParentB != null)) { if (!pgParentA.Uuid.Equals(pgParentB.Uuid)) { pgNew.LocationChanged = dtNow; } } else if ((pgParentA == null) && (pgParentB == null)) { } else { pgNew.LocationChanged = dtNow; } return(true); }; EntryHandler ehOrg = delegate(PwEntry pe) { PwEntry peNew = pgRootNew.FindEntry(pe.Uuid, true); if (peNew == null) { AddDeletedObject(pd, pe.Uuid); return(true); } // Restore history entries peNew.History = pe.History.CloneDeep(); foreach (PwEntry peHistNew in peNew.History) { peHistNew.ParentGroup = peNew.ParentGroup; } if (!peNew.EqualsEntry(pe, cmpOpt, cmpMem)) { peNew.Touch(true, false); } PwGroup pgParentA = pe.ParentGroup; PwGroup pgParentB = peNew.ParentGroup; if ((pgParentA != null) && (pgParentB != null)) { if (!pgParentA.Uuid.Equals(pgParentB.Uuid)) { peNew.LocationChanged = dtNow; } } else if ((pgParentA == null) && (pgParentB == null)) { } else { peNew.LocationChanged = dtNow; } return(true); }; pgRootOrg.TraverseTree(TraversalMethod.PreOrder, ghOrg, ehOrg); }
public bool SaveEntry(EntryModel edited, PwEntry m_pwInitialEntry /*, bool bValidate*/) { const PwCompareOptions m_cmpOpt = (PwCompareOptions.NullEmptyEquivStd | PwCompareOptions.IgnoreTimes); PwEntry originalEntry = edited.Entry; //peTarget.History = m_vHistory; // Must be called before CreateBackup() bool bCreateBackup = !edited.IsNew; if (bCreateBackup) { originalEntry.CreateBackup(null); } // peTarget.IconId = m_pwEntryIcon; // peTarget.CustomIconUuid = m_pwCustomIconID; // // if(m_cbCustomForegroundColor.Checked) // peTarget.ForegroundColor = m_clrForeground; // else peTarget.ForegroundColor = Color.Empty; // if(m_cbCustomBackgroundColor.Checked) // peTarget.BackgroundColor = m_clrBackground; // else peTarget.BackgroundColor = Color.Empty; //peTarget.OverrideUrl = m_tbOverrideUrl.Text; // List<string> vNewTags = StrUtil.StringToTags(m_tbTags.Text); // peTarget.Tags.Clear(); // foreach(string strTag in vNewTags) peTarget.AddTag(strTag); originalEntry.Expires = edited.Expires; if (originalEntry.Expires) { originalEntry.ExpiryTime = edited.ExpireDate; } UpdateEntryStrings(edited, originalEntry.Strings); // peTarget.Strings = m_vStrings; // peTarget.Binaries = m_vBinaries; // m_atConfig.Enabled = m_cbAutoTypeEnabled.Checked; // m_atConfig.ObfuscationOptions = (m_cbAutoTypeObfuscation.Checked ? // AutoTypeObfuscationOptions.UseClipboard : // AutoTypeObfuscationOptions.None); // // SaveDefaultSeq(); // peTarget.AutoType = m_atConfig; originalEntry.Touch(true, false); // Touch *after* backup // if(object.ReferenceEquals(peTarget, m_pwEntry)) // m_bTouchedOnce = true; StrUtil.NormalizeNewLines(originalEntry.Strings, true); bool bUndoBackup = false; PwCompareOptions cmpOpt = m_cmpOpt; if (bCreateBackup) { cmpOpt |= PwCompareOptions.IgnoreLastBackup; } if (originalEntry.EqualsEntry(m_pwInitialEntry, cmpOpt, MemProtCmpMode.CustomOnly)) { // No modifications at all => restore last mod time and undo backup originalEntry.LastModificationTime = m_pwInitialEntry.LastModificationTime; bUndoBackup = bCreateBackup; } else if (bCreateBackup) { // If only history items have been modified (deleted) => undo // backup, but without restoring the last mod time PwCompareOptions cmpOptNH = (m_cmpOpt | PwCompareOptions.IgnoreHistory); if (originalEntry.EqualsEntry(m_pwInitialEntry, cmpOptNH, MemProtCmpMode.CustomOnly)) { bUndoBackup = true; } } if (bUndoBackup) { originalEntry.History.RemoveAt(originalEntry.History.UCount - 1); } originalEntry.MaintainBackups(db); return(true); }