Example #1
0
        /// <summary>
        /// Gets the path to a specified iter.
        /// </summary>
        /// <param name="iter">The iter to get the path of.</param>
        /// <returns>The TreePath corresponding to the given iter.</returns>
        public TreePath GetPath(TreeIter iter)
        {
            if (iter.Stamp != this.Stamp)
            {
                throw new InvalidDataException("The given iter was not valid for this model.");
            }

            TreePath result = new TreePath();
            FileNode node   = this.Tree.GetNode((ulong)iter.UserData);

            if (node == null)
            {
                return(result);
            }

            while (node.ParentOffset > -1)
            {
                FileNode parentNode = this.Tree.GetNode((ulong)node.ParentOffset);
                ulong    nodeOffset = this.Tree.GetNodeOffset(node);
                result.PrependIndex(parentNode.ChildOffsets.IndexOf(nodeOffset));

                node = parentNode;
            }

            result.PrependIndex(this.Tree.Root.ChildOffsets.IndexOf((ulong)iter.UserData));
            return(result);
        }
Example #2
0
        /// <summary>
        /// Gets the iter of the first child of the given iter.
        /// </summary>
        /// <param name="iter">Will contain the first child.</param>
        /// <param name="parent">The iter to get the first child from.</param>
        /// <returns>true if the iter is now set to the first child of the parent; false otherwise</returns>
        /// <exception cref="InvalidDataException">Thrown if the iter doesn't belong to the model.</exception>
        /// <exception cref="ArgumentException">Thrown if the iter is not valid.</exception>
        public bool IterChildren(out TreeIter iter, TreeIter parent)
        {
            if (parent.Stamp != this.Stamp)
            {
                throw new InvalidDataException("The given parent was not valid for this model.");
            }

            iter = TreeIter.Zero;

            FileNode node = parent.Equals(TreeIter.Zero) ? this.Tree.Root : this.Tree.GetNode((ulong)parent.UserData);

            if (node == null)
            {
                throw new ArgumentException("The given iter was not valid.", nameof(parent));
            }

            if (!node.HasChildren())
            {
                return(false);
            }

            iter.UserData = new IntPtr((long)node.ChildOffsets.First());
            iter.Stamp    = this.Stamp;
            return(true);
        }
Example #3
0
        /// <summary>
        /// Gets the parent of the given iter.
        /// </summary>
        /// <param name="iter">Will contain the parent iter.</param>
        /// <param name="child">The iter to get the parent of.</param>
        /// <returns>true if the iter is now set to the parent iter of the child; false otherwise</returns>
        /// <exception cref="InvalidDataException">Thrown if the iter doesn't belong to the model.</exception>
        /// <exception cref="ArgumentException">Thrown if the iter is not valid.</exception>
        public bool IterParent(out TreeIter iter, TreeIter child)
        {
            if (child.Stamp != this.Stamp)
            {
                throw new InvalidDataException("The given child was not valid for this model.");
            }

            iter = TreeIter.Zero;

            FileNode childNode = this.Tree.GetNode((ulong)child.UserData);

            if (childNode == null)
            {
                throw new ArgumentException("The given iter was not valid.", nameof(child));
            }

            FileNode parentNode = this.Tree.GetNode((ulong)childNode.ParentOffset);

            if (parentNode == null)
            {
                return(false);
            }

            iter.UserData = new IntPtr((long)this.Tree.GetNodeOffset(parentNode));
            iter.Stamp    = this.Stamp;
            return(true);
        }
Example #4
0
        /// <summary>
        /// Gets the nth child of the provided iter.
        /// </summary>
        /// <param name="iter">Will contain the nth child.</param>
        /// <param name="parent">The iter to get the child of.</param>
        /// <param name="n">The value of n.</param>
        /// <returns>true if the iter is now set to the nth child of the parent; false otherwise</returns>
        /// <exception cref="InvalidDataException">Thrown if the iter doesn't belong to the model.</exception>
        /// <exception cref="ArgumentException">Thrown if the iter is not valid.</exception>
        public bool IterNthChild(out TreeIter iter, TreeIter parent, int n)
        {
            if (parent.Stamp != this.Stamp && !parent.Equals(TreeIter.Zero))
            {
                throw new InvalidDataException("The given parent was not valid for this model.");
            }

            iter = TreeIter.Zero;

            if (n < 0)
            {
                return(false);
            }

            FileNode node = iter.Equals(TreeIter.Zero) ? this.Tree.Root : this.Tree.GetNode((ulong)iter.UserData);

            if (node == null)
            {
                throw new ArgumentException("The given iter was not valid.", nameof(parent));
            }

            if (!node.HasChildren() || n > (int)node.ChildCount - 1)
            {
                return(false);
            }

            iter.UserData = new IntPtr((long)node.ChildOffsets[n]);
            iter.Stamp    = this.Stamp;
            return(true);
        }
Example #5
0
        /// <summary>
        /// Gets the package the given node belongs to.
        /// </summary>
        /// <param name="node">The node to get the package of.</param>
        /// <returns>The name of the package.</returns>
        public string GetNodePackage(FileNode node)
        {
            var currentNode = node;

            while (!(currentNode.Type.HasFlag(NodeType.Package) || currentNode.Type.HasFlag(NodeType.Meta)))
            {
                currentNode = this.Tree.GetNode((ulong)currentNode.ParentOffset);
            }

            return(GetNodeName(currentNode));
        }
Example #6
0
        /// <summary>
        /// Sorts the game explorer row.
        /// </summary>
        /// <returns>The sorting priority of the row. This value can be -1, 0 or 1 if
        /// A sorts before B, A sorts with B or A sorts after B, respectively.</returns>
        /// <param name="model">Model.</param>
        /// <param name="a">Iter a.</param>
        /// <param name="b">Iter b.</param>
        private int SortGameTreeRow(ITreeModel model, TreeIter a, TreeIter b)
        {
            const int sortABeforeB = -1;
            const int sortAWithB   = 0;
            const int sortAAfterB  = 1;

            FileNode nodeA = (FileNode)model.GetValue(a, 0);
            FileNode nodeB = (FileNode)model.GetValue(b, 0);

            NodeType typeofA = nodeA.Type;
            NodeType typeofB = nodeB.Type;

            // Special case for meta nodes - if A is a meta node, but B is not
            if (typeofA.HasFlag(NodeType.Meta) && !typeofB.HasFlag(NodeType.Meta))
            {
                // Then it should always sort after B
                return(sortAAfterB);
            }

            if (typeofB.HasFlag(NodeType.Meta) && !typeofA.HasFlag(NodeType.Meta))
            {
                // Then it should always sort before B
                return(sortABeforeB);
            }

            if (typeofA < typeofB)
            {
                return(sortAAfterB);
            }
            if (typeofA > typeofB)
            {
                return(sortABeforeB);
            }

            string nodeAName = this.TreeModel.GetNodeName(nodeA);

            string nodeBName = this.TreeModel.GetNodeName(nodeB);

            int result = string.CompareOrdinal(nodeAName, nodeBName);

            if (result <= sortABeforeB)
            {
                return(sortAAfterB);
            }

            if (result >= sortAAfterB)
            {
                return(sortABeforeB);
            }

            return(sortAWithB);
        }
Example #7
0
        /// <summary>
        /// Gets a <see cref="FileReference"/> from a given iter in the tree.
        /// </summary>
        /// <param name="packageGroup">The package group to create a reference for.</param>
        /// <param name="iter">The iter in the tree.</param>
        /// <returns>The FileReference pointed to by the given iter.</returns>
        /// <exception cref="InvalidDataException">Thrown if the iter doesn't belong to the model.</exception>
        public FileReference GetReferenceByIter(PackageGroup packageGroup, TreeIter iter)
        {
            if (iter.Stamp != this.Stamp)
            {
                throw new InvalidDataException("The given iter was not valid for this model.");
            }

            FileNode node = this.Tree.GetNode((ulong)iter.UserData);

            if (node == null)
            {
                return(null);
            }

            return(new FileReference(packageGroup, node, GetNodePackage(node), GetNodeFilePath(node)));
        }
Example #8
0
        /// <summary>
        /// Determines whether or not the given iter has any children.
        /// </summary>
        /// <param name="iter">The iter to check.</param>
        /// <returns>true if the iter has any children; false otherwise</returns>
        /// <exception cref="InvalidDataException">Thrown if the iter doesn't belong to the model.</exception>
        /// <exception cref="ArgumentException">Thrown if the iter is not valid.</exception>
        public bool IterHasChild(TreeIter iter)
        {
            if (iter.Stamp != this.Stamp)
            {
                throw new InvalidDataException("The given iter was not valid for this model.");
            }

            FileNode node = iter.Equals(TreeIter.Zero) ? this.Tree.Root : this.Tree.GetNode((ulong)iter.UserData);

            if (node == null)
            {
                throw new ArgumentException("The given iter was not valid.", nameof(iter));
            }

            return(node.HasChildren());
        }
Example #9
0
        /// <summary>
        /// Enumerates all references pointing to files under the given reference. If the reference already points to
        /// a file, it is returned back. If it is null, nothing is returned. The search is performed as a depth-first
        /// level scan.
        /// </summary>
        /// <param name="fileReference">The reference to enumerate.</param>
        /// <returns>A set of all the child references of the given reference.</returns>
        public IEnumerable <FileReference> EnumerateFilesOfReference(FileReference fileReference)
        {
            if (fileReference == null)
            {
                yield break;
            }

            if (fileReference.IsFile)
            {
                yield return(fileReference);

                yield break;
            }

            List <FileNode> folderNodes = new List <FileNode> {
                fileReference.Node
            };

            while (folderNodes.Count > 0)
            {
                FileNode folderNode = folderNodes.First();

                foreach (ulong offset in folderNode.ChildOffsets)
                {
                    FileNode childNode = this.Tree.GetNode(offset);

                    if (childNode.Type.HasFlag(NodeType.File))
                    {
                        yield return(new FileReference
                                     (
                                         fileReference.PackageGroup,
                                         childNode,
                                         fileReference.PackageName,
                                         GetNodeFilePath(childNode)
                                     ));
                    }

                    if (childNode.Type.HasFlag(NodeType.Directory))
                    {
                        folderNodes.Add(childNode);
                    }
                }

                folderNodes.Remove(folderNode);
            }
        }
Example #10
0
        /// <summary>
        /// Gets the value stored in the model at a given iter.
        /// </summary>
        /// <param name="iter">The iter where the value is stored.</param>
        /// <param name="column">The column to get the value from</param>
        /// <param name="value">Will contain the value.</param>
        /// <exception cref="InvalidDataException">Thrown if the iter doesn't belong to the model.</exception>
        public void GetValue(TreeIter iter, int column, ref Value value)
        {
            if (iter.Stamp != this.Stamp && !iter.Equals(TreeIter.Zero))
            {
                throw new InvalidDataException("The given iter was not valid for this model.");
            }

            FileNode node = iter.Equals(TreeIter.Zero) ? this.Tree.Root : this.Tree.GetNode((ulong)iter.UserData);

            if (node == null)
            {
                return;
            }

            value.Init(LookupGType(typeof(FileNode)));
            value.Val = node;
        }
Example #11
0
        /// <summary>
        /// This function is used internally by the tree filter to determine which rows are visible and which are not.
        /// </summary>
        /// <param name="model">The model of the tree.</param>
        /// <param name="iter">The iter to determine visibility for.</param>
        /// <returns>true if the iter should be visible; false otherwise.</returns>
        private bool TreeModelVisibilityFunc(ITreeModel model, TreeIter iter)
        {
            if (!this.IsFiltered)
            {
                return(true);
            }

            FileNode         node      = (FileNode)model.GetValue(iter, 0);
            WarcraftFileType nodeTypes = node.FileType;

            // If the file types of the node and the filtered types overlap in any way, then it should
            // be displayed.
            if ((nodeTypes & this.FilteredFileTypes) != 0)
            {
                return(true);
            }

            return(false);
        }
Example #12
0
        /// <summary>
        /// Gets the absolute file path of a node within the package.
        /// </summary>
        /// <param name="node">The node to get the path of.</param>
        /// <returns>The file path of the node in the package.</returns>
        public string GetNodeFilePath(FileNode node)
        {
            StringBuilder sb = new StringBuilder();

            var currentNode = node;

            while (!(currentNode.Type.HasFlag(NodeType.Package) || currentNode.Type.HasFlag(NodeType.Meta)))
            {
                if (currentNode.Type.HasFlag(NodeType.Directory))
                {
                    sb.Insert(0, '\\');
                }

                sb.Insert(0, GetNodeName(currentNode));

                currentNode = this.Tree.GetNode((ulong)currentNode.ParentOffset);
            }

            return(sb.ToString());
        }
Example #13
0
        /// <summary>
        /// Determines the number of children an iter has.
        /// </summary>
        /// <param name="iter">The iter to count the children of.</param>
        /// <returns>The number of children that the iter has.</returns>
        /// <exception cref="InvalidDataException">Thrown if the iter doesn't belong to the model.</exception>
        /// <exception cref="ArgumentException">Thrown if the iter is not valid.</exception>
        public int IterNChildren(TreeIter iter)
        {
            if (iter.Equals(TreeIter.Zero))
            {
                return((int)this.Tree.Root.ChildCount);
            }

            if (iter.Stamp != this.Stamp)
            {
                throw new InvalidDataException("The given iter was not valid for this model.");
            }

            FileNode node = this.Tree.GetNode((ulong)iter.UserData);

            if (node == null)
            {
                throw new ArgumentException("The given iter was not valid.", nameof(iter));
            }

            return((int)node.ChildCount);
        }
Example #14
0
        /// <summary>
        /// Moves the given iter to the next one at the same level.
        /// </summary>
        /// <param name="iter">The iter to move.</param>
        /// <returns>true if the iter is now set to the next iter at the same level; false otherwise</returns>
        /// <exception cref="InvalidDataException">Thrown if the iter doesn't belong to the model.</exception>
        public bool IterNext(ref TreeIter iter)
        {
            if (iter.Stamp != this.Stamp)
            {
                throw new InvalidDataException("The given iter was not valid for this model.");
            }

            ulong    currentOffset = (ulong)iter.UserData;
            FileNode currentNode   = this.Tree.GetNode(currentOffset);
            FileNode parentNode    = this.Tree.GetNode((ulong)currentNode.ParentOffset);

            int currentIndex = parentNode.ChildOffsets.IndexOf(currentOffset);
            int nextIndex    = currentIndex + 1;

            if (nextIndex < (int)parentNode.ChildCount)
            {
                iter.UserData = new IntPtr((long)parentNode.ChildOffsets[nextIndex]);
                return(true);
            }

            return(false);
        }
Example #15
0
        /// <summary>
        /// Handles rendering of the name of a node in the tree.
        /// </summary>
        /// <param name="column">The column which the cell is in.</param>
        /// <param name="cell">The cell which the name is in.</param>
        /// <param name="model">The model of the treeview.</param>
        /// <param name="iter">The <see cref="TreeIter"/> pointing to the row the name is in.</param>
        private void RenderNodeName(TreeViewColumn column, CellRenderer cell, ITreeModel model, TreeIter iter)
        {
            CellRendererText cellText = cell as CellRendererText;
            FileNode         node     = (FileNode)model.GetValue(iter, 0);

            if (node == null || cellText == null)
            {
                return;
            }

            cellText.Text = this.TreeModel.GetNodeName(node);

            if (node.Type.HasFlag(NodeType.Deleted))
            {
                cellText.Style      = Style.Italic;
                cellText.Foreground = "#D74328";
            }
            else
            {
                cellText.Style      = Style.Normal;
                cellText.Foreground = null;
            }
        }
Example #16
0
        /// <summary>
        /// Gets an iter at a specified path.
        /// </summary>
        /// <param name="iter">Will contain the iter.</param>
        /// <param name="path">The path to the iter.</param>
        /// <returns>true if the iter is now set to the iter at the given path; false otherwise.</returns>
        public bool GetIter(out TreeIter iter, TreePath path)
        {
            iter = TreeIter.Zero;

            ulong    currentOffset = 0;
            FileNode currentNode   = this.Tree.Root;

            foreach (int index in path.Indices)
            {
                ulong longIndex = (ulong)index;
                if (longIndex > currentNode.ChildCount - 1)
                {
                    return(false);
                }

                currentOffset = currentNode.ChildOffsets[index];
                currentNode   = this.Tree.GetNode(currentOffset);
            }

            iter.UserData = new IntPtr((long)currentOffset);
            iter.Stamp    = this.Stamp;
            return(true);
        }
Example #17
0
        /// <summary>
        /// Handles rendering of the icon of a node in the tree.
        /// </summary>
        /// <param name="column">The column which the icon is in.</param>
        /// <param name="cell">The cell which the reference is in.</param>
        /// <param name="model">The model of the treeview.</param>
        /// <param name="iter">The <see cref="TreeIter"/> pointing to the row the icon is in.</param>
        private void RenderNodeIcon(TreeViewColumn column, CellRenderer cell, ITreeModel model, TreeIter iter)
        {
            CellRendererPixbuf cellIcon = cell as CellRendererPixbuf;
            FileNode           node     = (FileNode)model.GetValue(iter, 0);

            if (node == null || cellIcon == null)
            {
                return;
            }

            if (node.Type.HasFlag(NodeType.Directory))
            {
                cellIcon.Pixbuf = IconManager.GetIconForFiletype(WarcraftFileType.Directory);
                return;
            }

            if (node.Type.HasFlag(NodeType.Deleted))
            {
                cellIcon.Pixbuf = IconManager.GetIcon("package-broken");
                return;
            }

            if (node.Type.HasFlag(NodeType.Meta) && this.TreeModel.GetNodeName(node) == "Packages")
            {
                cellIcon.Pixbuf = IconManager.GetIcon("applications-other");
                return;
            }

            if (node.Type.HasFlag(NodeType.Package))
            {
                cellIcon.Pixbuf = IconManager.GetIcon("package-x-generic");
                return;
            }

            cellIcon.Pixbuf = IconManager.GetIconForFiletype(node.FileType);
        }
Example #18
0
 /// <summary>
 /// Gets the name of a given node.
 /// </summary>
 /// <param name="node">The node to get the name of.</param>
 /// <returns>The name of the node.</returns>
 public string GetNodeName(FileNode node)
 {
     return(this.Tree.GetNodeName(node));
 }