/// <summary>
        /// Deserializes the data for a bookmarks folder from <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">XML source that we're deserializing this folder from.</param>
        public void ReadXml(XmlReader reader)
        {
            // Move to the child nodes
            reader.MoveToContent();
            reader.Read();

            while (reader.MoveToContent() == XmlNodeType.Element)
            {
                switch (reader.LocalName)
                {
                case "Name":
                    Name = reader.ReadElementContentAsString();
                    break;

                case "Username":
                    Username = reader.ReadElementContentAsString();
                    break;

                case "Password":
                    EncryptedPassword = reader.ReadElementContentAsString();
                    break;

                case "ChildFolders":
                    if (!reader.IsEmptyElement)
                    {
                        reader.Read();

                        // Call this method recursively to read each child folder
                        while (reader.MoveToContent() == XmlNodeType.Element)
                        {
                            BookmarksFolder childFolder = new BookmarksFolder();
                            childFolder.ReadXml(reader);

                            ChildFolders.Add(childFolder);
                        }
                    }

                    reader.Read();

                    break;

                case "Bookmarks":
                    if (!reader.IsEmptyElement)
                    {
                        reader.Read();

                        while (reader.MoveToContent() == XmlNodeType.Element)
                        {
                            Bookmarks.Add(ConnectionFactory.Deserialize(reader));
                        }
                    }

                    reader.Read();

                    break;
                }
            }

            reader.Read();
        }
Beispiel #2
0
        /// <summary>
        /// Recursive method that searches parent <see cref="BookmarksFolder"/> instances for one that contains a value for
        /// <see cref="BookmarksFolder.Username"/> and returns that value.
        /// </summary>
        /// <param name="currentFolder">Current folder that we're looking at.</param>
        /// <returns><see cref="BookmarksFolder.Username"/> value for <paramref name="currentFolder"/> if a value is present for that property, otherwise the
        /// value for the nearest parent folder.</returns>
        public string GetInheritedUsername(BookmarksFolder currentFolder)
        {
            if (currentFolder == null)
            {
                return(null);
            }

            else if (!String.IsNullOrEmpty(currentFolder.Username))
            {
                return(currentFolder.Username);
            }

            return(GetInheritedUsername(currentFolder.ParentFolder));
        }
Beispiel #3
0
        /// <summary>
        /// Recursive method that searches parent <see cref="BookmarksFolder"/> instances for one that contains a value for
        /// <see cref="BookmarksFolder.Password"/> and returns that value.
        /// </summary>
        /// <param name="currentFolder">Current folder that we're looking at.</param>
        /// <returns><see cref="BookmarksFolder.Password"/> value for <paramref name="currentFolder"/> if a value is present for that property, otherwise the
        /// value for the nearest parent folder.</returns>
        public SecureString GetInheritedPassword(BookmarksFolder currentFolder)
        {
            if (currentFolder == null)
            {
                return(null);
            }

            else if (currentFolder.Password != null && currentFolder.Password.Length > 0)
            {
                return(currentFolder.Password);
            }

            return(GetInheritedPassword(currentFolder.ParentFolder));
        }
Beispiel #4
0
        /// <summary>
        /// Creates a cloned copy of this folder as well as all descendant folders and bookmarks.  For the bookmarks, all sensitive data, such as usernames
        /// and passwords, are scrubbed.
        /// </summary>
        /// <returns>A cloned copy of this folder as well as all descendant folders and bookmarks.</returns>
        public object CloneAnon()
        {
            BookmarksFolder clonedFolder = new BookmarksFolder
            {
                Name = Name
            };

            foreach (IConnection bookmark in Bookmarks)
            {
                clonedFolder.Bookmarks.Add((IConnection)bookmark.CloneAnon());
            }

            foreach (BookmarksFolder childFolder in ChildFolders)
            {
                clonedFolder.ChildFolders.Add((BookmarksFolder)childFolder.CloneAnon());
            }

            return(clonedFolder);
        }
Beispiel #5
0
        /// <summary>
        /// When pasting a child folder into this folder, if a child folder by the same name already exists, we merge the contents of
        /// <paramref name="childFolder"/> with that folder.  Bookmarks in <paramref name="childFolder"/> are copied to the destination folder; we don't
        /// overwrite any bookmarks that have the same name.  This merge process is then carried out recursively on all descendant folders of
        /// <paramref name="childFolder"/>.
        /// </summary>
        /// <param name="childFolder">Child folder that we are copying or merging into this folder.</param>
        public void MergeFolder(BookmarksFolder childFolder)
        {
            if (ChildFolders.Any(f => f.Name == childFolder.Name))
            {
                BookmarksFolder mergeTarget = ChildFolders.First(f => f.Name == childFolder.Name);

                foreach (IConnection bookmark in childFolder.Bookmarks)
                {
                    mergeTarget.Bookmarks.Add(bookmark);
                }

                foreach (BookmarksFolder folder in childFolder.ChildFolders)
                {
                    mergeTarget.MergeFolder(folder);
                }
            }

            else
            {
                ChildFolders.Add(childFolder);
            }
        }
        /// <summary>
        /// Handler method that's called when the user clicks the "Add folder..." menu item in the context menu that appears when the user right-clicks in the
        /// tree view.  Adds a new node to the tree view and the parent <see cref="BookmarksFolder"/> instance.
        /// </summary>
        /// <param name="sender">Object from which this event originated.</param>
        /// <param name="e">Arguments associated with this event</param>
        private void _addFolderMenuItem_Click(object sender, EventArgs e)
        {
            // Create a new BookmarksFolder, add it to the tree view, and add it to the parent folder instance
            BookmarksFolder newFolder = new BookmarksFolder
                                            {
                                                Name = "New folder"
                                            };

            _deferSort = true;
            (_contextMenuItem as BookmarksFolder).ChildFolders.Add(newFolder);
            _deferSort = false;

            TreeNode newNode = _folderTreeNodes.SingleOrDefault(kvp => kvp.Value == newFolder).Key;

            _bookmarksFoldersTreeView.SelectedNode.Expand();
            _bookmarksFoldersTreeView.SelectedNode = newNode;

            SortTreeView();
            Save();
            newNode.BeginEdit();
        }
        /// <summary>
        /// Recursive method to initialize the UI for <see cref="_bookmarksFoldersTreeView"/> by adding each <see cref="BookmarksFolder"/> to it and populate
        /// <see cref="_folderTreeNodes"/>.
        /// </summary>
        /// <param name="currentFolder">Current folder being processed.</param>
        protected void InitializeTreeView(BookmarksFolder currentFolder)
        {
            // Simulate adding all of the bookmarks in the folder to the bookmarks collection
            if (currentFolder.Bookmarks != null && currentFolder.Bookmarks.Count > 0)
            {
                currentFolder.Bookmarks.ForEach(b => b.ParentFolder = currentFolder);
                Bookmarks_CollectionModified(
                    currentFolder.Bookmarks, new ListModificationEventArgs(ListModification.RangeAdded, 0, currentFolder.Bookmarks.Count));
            }

            // Simulate adding each child folder to the folders collection
            if (currentFolder.ChildFolders != null && currentFolder.ChildFolders.Count > 0)
            {
                currentFolder.ChildFolders.ForEach(f => f.ParentFolder = currentFolder);
                ChildFolders_CollectionModified(
                    currentFolder.ChildFolders, new ListModificationEventArgs(ListModification.RangeAdded, 0, currentFolder.ChildFolders.Count));

                // Call this recursively for each child folder
                foreach (BookmarksFolder childFolder in currentFolder.ChildFolders)
                    InitializeTreeView(childFolder);
            }
        }
        /// <summary>
        /// Recursive method that searches <paramref name="searchFolder"/> and its descendants for an <see cref="IConnection"/> instance whose 
        /// <see cref="IConnection.Guid"/> property corresponds to <paramref name="bookmarkGuid"/>.  Called from <see cref="FindBookmark(Guid)"/>.
        /// </summary>
        /// <param name="bookmarkGuid"><see cref="IConnection.Guid"/> value of the <see cref="IConnection"/> that we're searching for.</param>
        /// <param name="searchFolder">Current folder that we're searching.</param>
        /// <returns>The <see cref="IConnection"/> bookmark corresponding to <paramref name="bookmarkGuid"/> if it exists, null otherwise.</returns>
        protected IConnection FindBookmark(Guid bookmarkGuid, BookmarksFolder searchFolder)
        {
            IConnection bookmark = searchFolder.Bookmarks.FirstOrDefault(b => b.Guid == bookmarkGuid);

            if (bookmark != null)
                return bookmark;

            foreach (BookmarksFolder childFolder in searchFolder.ChildFolders)
            {
                bookmark = FindBookmark(bookmarkGuid, childFolder);

                if (bookmark != null)
                    return bookmark;
            }

            return null;
        }
Beispiel #9
0
        /// <summary>
        /// Recursive method that searches parent <see cref="BookmarksFolder"/> instances for one that contains a value for 
        /// <see cref="BookmarksFolder.Password"/> and returns that value.
        /// </summary>
        /// <param name="currentFolder">Current folder that we're looking at.</param>
        /// <returns><see cref="BookmarksFolder.Password"/> value for <paramref name="currentFolder"/> if a value is present for that property, otherwise the
        /// value for the nearest parent folder.</returns>
        public SecureString GetInheritedPassword(BookmarksFolder currentFolder)
        {
            if (currentFolder == null)
                return null;

            else if (currentFolder.Password != null && currentFolder.Password.Length > 0)
                return currentFolder.Password;

            return GetInheritedPassword(currentFolder.ParentFolder);
        }
Beispiel #10
0
        /// <summary>
        /// Recursive method that searches parent <see cref="BookmarksFolder"/> instances for one that contains a value for 
        /// <see cref="BookmarksFolder.Username"/> and returns that value.
        /// </summary>
        /// <param name="currentFolder">Current folder that we're looking at.</param>
        /// <returns><see cref="BookmarksFolder.Username"/> value for <paramref name="currentFolder"/> if a value is present for that property, otherwise the
        /// value for the nearest parent folder.</returns>
        public string GetInheritedUsername(BookmarksFolder currentFolder)
        {
            if (currentFolder == null)
                return null;

            else if (!String.IsNullOrEmpty(currentFolder.Username))
                return currentFolder.Username;

            return GetInheritedUsername(currentFolder.ParentFolder);
        }
Beispiel #11
0
        /// <summary>
        /// When pasting a child folder into this folder, if a child folder by the same name already exists, we merge the contents of 
        /// <paramref name="childFolder"/> with that folder.  Bookmarks in <paramref name="childFolder"/> are copied to the destination folder; we don't
        /// overwrite any bookmarks that have the same name.  This merge process is then carried out recursively on all descendant folders of 
        /// <paramref name="childFolder"/>.
        /// </summary>
        /// <param name="childFolder">Child folder that we are copying or merging into this folder.</param>
        public void MergeFolder(BookmarksFolder childFolder)
        {
            if (ChildFolders.Any(f => f.Name == childFolder.Name))
            {
                BookmarksFolder mergeTarget = ChildFolders.First(f => f.Name == childFolder.Name);

                foreach (IConnection bookmark in childFolder.Bookmarks)
                    mergeTarget.Bookmarks.Add(bookmark);

                foreach (BookmarksFolder folder in childFolder.ChildFolders)
                    mergeTarget.MergeFolder(folder);
            }

            else
                ChildFolders.Add(childFolder);
        }
Beispiel #12
0
        /// <summary>
        /// Deserializes the data for a bookmarks folder from <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">XML source that we're deserializing this folder from.</param>
        public void ReadXml(XmlReader reader)
        {
            // Move to the child nodes
            reader.MoveToContent();
            reader.Read();

            while (reader.MoveToContent() == XmlNodeType.Element)
            {
                switch (reader.LocalName)
                {
                    case "Name":
                        Name = reader.ReadElementContentAsString();
                        break;

                    case "Username":
                        Username = reader.ReadElementContentAsString();
                        break;

                    case "Password":
                        EncryptedPassword = reader.ReadElementContentAsString();
                        break;

                    case "ChildFolders":
                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();

                            // Call this method recursively to read each child folder
                            while (reader.MoveToContent() == XmlNodeType.Element)
                            {
                                BookmarksFolder childFolder = new BookmarksFolder();
                                childFolder.ReadXml(reader);

                                ChildFolders.Add(childFolder);
                            }
                        }

                        reader.Read();

                        break;

                    case "Bookmarks":
                        if (!reader.IsEmptyElement)
                        {
                            reader.Read();

                            while (reader.MoveToContent() == XmlNodeType.Element)
                                Bookmarks.Add(ConnectionFactory.Deserialize(reader));
                        }

                        reader.Read();

                        break;
                }
            }

            reader.Read();
        }
        /// <summary>
        /// Imports bookmarks previously saved via a call to <see cref="Export"/> and overwrites any existing bookmarks data.
        /// </summary>
        /// <param name="path">Path of the file that we're loading from.</param>
        public void Import(string path)
        {
            //ISSUE: Display shows old and new Bookmark items
            //ISSUE: Dialog shows truncated suggested file name

            if (
                MessageBox.Show(
                    "This will erase any currently saved bookmarks and import the contents of the selected file. Do you wish to continue?",
                    "Continue with import?", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK)
            {
                if (File.Exists(path))
                {
                    XmlSerializer bookmarksSerializer = new XmlSerializer(typeof (BookmarksFolder));

                    using (XmlReader bookmarksReader = new XmlTextReader(path))
                    {
                        BookmarksFolder importedRootFolder = (BookmarksFolder) bookmarksSerializer.Deserialize(bookmarksReader);

                        // Set the handler methods for changing the bookmarks or child folders; these are responsible for updating the tree view and list view
                        // UI when items are added or removed from the bookmarks or child folders collections
                        importedRootFolder.Bookmarks.CollectionModified += Bookmarks_CollectionModified;
                        importedRootFolder.ChildFolders.CollectionModified += ChildFolders_CollectionModified;

                        _rootFolder = importedRootFolder;
                        _folderTreeNodes[_bookmarksFoldersTreeView.Nodes[0]] = _rootFolder;

                        // Call Bookmarks_CollectionModified and ChildFolders_CollectionModified recursively through the folder structure to "simulate"
                        // bookmarks and folders being added to the collection so that the initial UI state for the tree view can be created
                        InitializeTreeView(_rootFolder);
                    }

                    _bookmarksFoldersTreeView.Nodes[0].Expand();
                    Save();
                }
            }
        }
        /// <summary>
        /// Recursive method that searches <paramref name="bookmarksFolder"/> and its descendants for all bookmarks.  Called from 
        /// <see cref="_folderOpenAllNewWindowMenuItem_Click"/>.
        /// </summary>
        /// <param name="bookmarks">List of bookmarks that have been assembled so far.</param>
        /// <param name="bookmarksFolder">Current folder that we're searching.</param>
        private void FindAllBookmarks(BookmarksFolder bookmarksFolder, List<IConnection> bookmarks)
        {
            bookmarks.AddRange(bookmarksFolder.Bookmarks);

            foreach (BookmarksFolder childFolder in bookmarksFolder.ChildFolders)
                FindAllBookmarks(childFolder, bookmarks);
        }
        /// <summary>
        /// Adds the <see cref="IConnection"/> and <see cref="BookmarksFolder"/> items in <see cref="_copiedItems"/> or <see cref="_cutItems"/> to 
        /// <paramref name="targetFolder"/>.  Called from <see cref="_pasteFolderMenuItem_Click"/>.
        /// </summary>
        /// <param name="targetFolder">Target folder that we're pasting items into.</param>
        private void PasteItems(BookmarksFolder targetFolder)
        {
            _deferSort = true;

            List<object> source = _cutItems.Union(_copiedItems).ToList();

            // Make sure that the source items aren't from folder that we're trying to paste into
            if ((source[0] is BookmarksFolder && ((BookmarksFolder) source[0]).ParentFolder == targetFolder) ||
                (source[0] is IConnection && ((IConnection) source[0]).ParentFolder == targetFolder))
            {
                MessageBox.Show(this, "You cannot paste items into their existing parent folders.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            List<object> clonedItems = (from item in source
                                        select ((ICloneable) item).Clone()).ToList();

            // Add the items to the target folder
            foreach (object clonedItem in clonedItems)
            {
                IConnection item = clonedItem as IConnection;

                if (item != null)
                    targetFolder.Bookmarks.Add(item);

                else
                    targetFolder.MergeFolder((BookmarksFolder) clonedItem);
            }

            // If we're pasting cut items, remove those items from their previous parent folders
            if (_cutItems.Count > 0)
            {
                foreach (object cutItem in _cutItems)
                {
                    IConnection connection = cutItem as IConnection;

                    if (connection != null)
                    {
                        connection.ParentFolder.Bookmarks.Remove(connection);

                        if (_listViewConnections.ContainsValue(connection))
                            _bookmarksListView.Items.Remove(_listViewConnections.First(kvp => kvp.Value == connection).Key);
                    }

                    else
                    {
                        BookmarksFolder folder = cutItem as BookmarksFolder;

                        folder.ParentFolder.ChildFolders.Remove(folder);

                        if (_listViewFolders.ContainsValue(folder))
                            _bookmarksListView.Items.Remove(_listViewFolders.First(kvp => kvp.Value == folder).Key);
                    }
                }

                _cutItems.Clear();
            }

            _bookmarksFoldersTreeView.BeginInvoke(new Action(SortTreeView));
            _bookmarksListView.BeginInvoke(new Action(_bookmarksListView.Sort));

            _deferSort = false;

            Save();
        }
        /// <summary>
        /// Recursive method that opens all the descendant bookmarks in <paramref name="folder"/> in separate tabs.
        /// </summary>
        /// <param name="folder">Current folder for which we are opening bookmarks.</param>
        private void OpenAllBookmarks(BookmarksFolder folder)
        {
            foreach (IConnection connection in folder.Bookmarks)
                _applicationForm.Connect(connection);

            foreach (BookmarksFolder childFolder in folder.ChildFolders)
                OpenAllBookmarks(childFolder);
        }
        private bool IsDescendantOf(BookmarksFolder checkFolder, BookmarksFolder potentialParent)
        {
            while (checkFolder != null)
            {
                if (checkFolder == potentialParent)
                    return true;

                checkFolder = checkFolder.ParentFolder;
            }

            return false;
        }
Beispiel #18
0
        /// <summary>
        /// Creates a cloned copy of this folder as well as all descendant folders and bookmarks.  For the bookmarks, all sensitive data, such as usernames
        /// and passwords, are scrubbed.
        /// </summary>
        /// <returns>A cloned copy of this folder as well as all descendant folders and bookmarks.</returns>
        public object CloneAnon()
        {
            BookmarksFolder clonedFolder = new BookmarksFolder
                                               {
                                                   Name = Name
                                               };

            foreach (IConnection bookmark in Bookmarks)
                clonedFolder.Bookmarks.Add((IConnection) bookmark.CloneAnon());

            foreach (BookmarksFolder childFolder in ChildFolders)
                clonedFolder.ChildFolders.Add((BookmarksFolder) childFolder.CloneAnon());

            return clonedFolder;
        }
        /// <summary>
        /// Constructor; deserializes the bookmarks folder structure, adds the various folder nodes to <see cref="_bookmarksFoldersTreeView"/>, and gets the
        /// icons for each protocol.
        /// </summary>
        /// <param name="applicationForm">Main application instance.</param>
        public BookmarksWindow(MainForm applicationForm)
        {
            InitializeComponent();

            _applicationForm = applicationForm;
            _bookmarksFoldersTreeView.Sorted = true;
            _bookmarksListView.ListViewItemSorter = new BookmarksListViewComparer();

            if (File.Exists(BookmarksFileName))
            {
                // Deserialize the bookmarks folder structure from BookmarksFileName; BookmarksFolder.ReadXml() will call itself recursively to deserialize
                // child folders, so all we have to do is start the deserialization process from the root folder
                XmlSerializer bookmarksSerializer = new XmlSerializer(typeof (BookmarksFolder));

                using (XmlReader bookmarksReader = new XmlTextReader(BookmarksFileName))
                    _rootFolder = (BookmarksFolder) bookmarksSerializer.Deserialize(bookmarksReader);
            }

            // Set the handler methods for changing the bookmarks or child folders; these are responsible for updating the tree view and list view UI when
            // items are added or removed from the bookmarks or child folders collections
            _rootFolder.Bookmarks.CollectionModified += Bookmarks_CollectionModified;
            _rootFolder.ChildFolders.CollectionModified += ChildFolders_CollectionModified;

            _folderTreeNodes[_bookmarksFoldersTreeView.Nodes[0]] = _rootFolder;

            // Call Bookmarks_CollectionModified and ChildFolders_CollectionModified recursively through the folder structure to "simulate" bookmarks and
            // folders being added to the collection so that the initial UI state for the tree view can be created
            InitializeTreeView(_rootFolder);

            _bookmarksFoldersTreeView.Nodes[0].Expand();

            foreach (IProtocol protocol in ConnectionFactory.GetProtocols())
            {
                // Get the icon for each protocol type and add an entry for it to the "Add bookmark" menu item
                Icon icon = new Icon(protocol.ProtocolIcon, 16, 16);

                _listViewImageList.Images.Add(icon);
                _connectionTypeIcons[protocol.ConnectionType] = _listViewImageList.Images.Count - 1;

                IProtocol currentProtocol = protocol;
                ToolStripMenuItem protocolMenuItem = new ToolStripMenuItem(
                    protocol.ProtocolTitle, null, (sender, args) => _addBookmarkMenuItem_Click(currentProtocol));
                _addBookmarkMenuItem.DropDownItems.Add(protocolMenuItem);
            }
        }