Exemple #1
0
        private static PwGroup FilterCloneGroup(PwGroup pg, Dictionary <PwUuid, bool> dUuids)
        {
            PwGroup pgNew = new PwGroup();

            pgNew.Uuid = pg.Uuid;
            pgNew.AssignProperties(pg, false, true);
            Debug.Assert(pgNew.EqualsGroup(pg, (PwCompareOptions.IgnoreParentGroup |
                                                PwCompareOptions.PropertiesOnly), MemProtCmpMode.Full));

            foreach (PwEntry pe in pg.Entries)
            {
                if (dUuids.ContainsKey(pe.Uuid))
                {
                    pgNew.AddEntry(pe.CloneDeep(), true, false);
                }
            }

            foreach (PwGroup pgSub in pg.Groups)
            {
                if (dUuids.ContainsKey(pgSub.Uuid))
                {
                    pgNew.AddGroup(FilterCloneGroup(pgSub, dUuids), true, false);
                }
            }

            return(pgNew);
        }
Exemple #2
0
        public static PwGroup DuplicateTo(this PwGroup group, PwGroup parent)
        {
            PwGroup copy = new PwGroup();

            copy.Uuid = group.Uuid;
            copy.AssignProperties(group, false, true);
            //TODO MST: clear this comment and it's ramifications!
            //HACK: CloneDeep introduces the copy into the parent node, therefore SetParent triggers a change of the parent
            //      which shouldn't be - the extended ProtectionSection in KeeShare should prevent interference, but a
            //      a clean way to clone a node without cloning children and without hooking it into a tree would be nice
            copy.SetParent(parent);
            return(copy);
        }
Exemple #3
0
        /// <summary>
        /// Get or create the target group of an entry in the target database (including hierarchy).
        /// </summary>
        /// <param name="entry">An entry wich is located in the folder with the target structure.</param>
        /// <param name="targetDatabase">The target database in which the folder structure should be created.</param>
        /// <param name="sourceDatabase">The source database from which the folder properties should be taken.</param>
        /// <returns>The target folder in the target database.</returns>
        private static PwGroup CreateTargetGroupInDatebase(PwEntry entry, PwDatabase targetDatabase, PwDatabase sourceDatabase)
        {
            // Collect all group names from the entry up to the root group
            PwGroup       group = entry.ParentGroup;
            List <PwUuid> list  = new List <PwUuid>();

            while (group != null)
            {
                list.Add(group.Uuid);
                group = group.ParentGroup;
            }

            // Remove root group (we already changed the root group name)
            list.RemoveAt(list.Count - 1);
            // groups are in a bottom-up oder -> reverse to get top-down
            list.Reverse();

            // Create group structure for the new entry (copying group properties)
            PwGroup lastGroup = targetDatabase.RootGroup;

            foreach (PwUuid id in list)
            {
                // Does the target group already exist?
                PwGroup newGroup = lastGroup.FindGroup(id, false);
                if (newGroup != null)
                {
                    lastGroup = newGroup;
                    continue;
                }

                // Get the source group
                PwGroup sourceGroup = sourceDatabase.RootGroup.FindGroup(id, true);

                // Create a new group and asign all properties from the source group
                newGroup = new PwGroup();
                newGroup.AssignProperties(sourceGroup, false, true);
                HandleCustomIcon(targetDatabase, sourceDatabase, sourceGroup);

                // Add the new group at the right position in the target database
                lastGroup.AddGroup(newGroup, true);

                lastGroup = newGroup;
            }

            // Return the target folder (leaf folder)
            return(lastGroup);
        }
Exemple #4
0
        /// <summary>
        /// Synchronize the current database with another one.
        /// </summary>
        /// <param name="pwSource">Input database to synchronize with. This input
        /// database is used to update the current one, but is not modified! You
        /// must copy the current object if you want a second instance of the
        /// synchronized database. The input database must not be seen as valid
        /// database any more after calling <c>Synchronize</c>.</param>
        /// <param name="mm">Merge method.</param>
        public void MergeIn(PwDatabase pwSource, PwMergeMethod mm)
        {
            if(mm == PwMergeMethod.CreateNewUuids)
            {
                pwSource.RootGroup.CreateNewItemUuids(true, true, true);
            }

            GroupHandler gh = delegate(PwGroup pg)
            {
                if(pg == pwSource.m_pgRootGroup) return true;

                PwGroup pgLocal = m_pgRootGroup.FindGroup(pg.Uuid, true);
                if(pgLocal == null)
                {
                    PwGroup pgSourceParent = pg.ParentGroup;
                    PwGroup pgLocalContainer;
                    if(pgSourceParent == pwSource.m_pgRootGroup)
                        pgLocalContainer = m_pgRootGroup;
                    else
                        pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
                    Debug.Assert(pgLocalContainer != null);

                    PwGroup pgNew = new PwGroup();
                    pgNew.Uuid = pg.Uuid;
                    pgNew.AssignProperties(pg, false);
                    pgLocalContainer.AddGroup(pgNew, true);
                }
                else // pgLocal != null
                {
                    Debug.Assert(mm != PwMergeMethod.CreateNewUuids);

                    if(mm == PwMergeMethod.OverwriteExisting)
                        pgLocal.AssignProperties(pg, false);
                    else if((mm == PwMergeMethod.OverwriteIfNewer) ||
                        (mm == PwMergeMethod.Synchronize))
                    {
                        pgLocal.AssignProperties(pg, true);
                    }
                    // else if(mm == PwMergeMethod.KeepExisting) ...
                }

                return true;
            };

            EntryHandler eh = delegate(PwEntry pe)
            {
                PwEntry peLocal = m_pgRootGroup.FindEntry(pe.Uuid, true);
                if(peLocal == null)
                {
                    PwGroup pgSourceParent = pe.ParentGroup;
                    PwGroup pgLocalContainer;
                    if(pgSourceParent == pwSource.m_pgRootGroup)
                        pgLocalContainer = m_pgRootGroup;
                    else
                        pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
                    Debug.Assert(pgLocalContainer != null);

                    PwEntry peNew = new PwEntry(false, false);
                    peNew.Uuid = pe.Uuid;
                    peNew.AssignProperties(pe, false, true);
                    pgLocalContainer.AddEntry(peNew, true);
                }
                else // peLocal == null
                {
                    Debug.Assert(mm != PwMergeMethod.CreateNewUuids);

                    if(mm == PwMergeMethod.OverwriteExisting)
                        peLocal.AssignProperties(pe, false, true);
                    else if((mm == PwMergeMethod.OverwriteIfNewer) ||
                        (mm == PwMergeMethod.Synchronize))
                    {
                        peLocal.AssignProperties(pe, true, true);
                    }
                    // else if(mm == PwMergeMethod.KeepExisting) ...
                }

                return true;
            };

            if(!pwSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh))
                throw new InvalidOperationException();

            if(mm == PwMergeMethod.Synchronize)
            {
                ApplyDeletions(pwSource.m_vDeletedObjects, true);
                ApplyDeletions(m_vDeletedObjects, false);
            }
        }