示例#1
0
        /// <summary>
        /// Modifies <see cref="ListView.Groups"/> collection to match supplied one.
        /// </summary>
        /// <remarks>
        /// The order of newly inserted groups is preserved.
        /// The mutual order of already existing groups is left intact to keep algorithm simpler and non-destructive.
        /// </remarks>
        public void SetGroups(IReadOnlyList <ListViewGroup> groups, StringComparer nameComparer)
        {
            var groupNames = new HashSet <string>(groups.Select(g => g.Name), nameComparer);

            BeginGroupInsertion();

            try
            {
                var toRemove = GetGroups().Where(grp => !groupNames.Contains(grp.Name)).ToArray();
                foreach (var grp in toRemove)
                {
                    Groups.Remove(grp);
                }

                var existingGroups = GetGroups().ToArray();

                // leave only names to be inserted
                groupNames.ExceptWith(existingGroups.Select(g => g.Name));
                for (int i = 0; i < groups.Count; i++)
                {
                    if (groupNames.Contains(groups[i].Name))
                    {
                        Groups.Insert(i + _minGroupInsertionIndex, groups[i]);
                    }
                }
            }
            finally
            {
                EndGroupInsertion();
            }

            IEnumerable <ListViewGroup> GetGroups() =>
            Groups.Cast <ListViewGroup>().Skip(_minGroupInsertionIndex);
        }
示例#2
0
 public void RefreshGroupsHeader()
 {
     foreach (var g in Groups.Cast <ListViewGroup>())
     {
         g.Header = $"{g.Name} ({g.Items.Count})";
     }
 }
示例#3
0
        internal void UpdateGroups()
        {
            IMergeRequestCache mergeRequestCache = _dataCache?.MergeRequestCache;

            if (mergeRequestCache == null)
            {
                return;
            }

            BeginUpdate();

            // Add missing project groups
            IEnumerable <ProjectKey> allProjects = mergeRequestCache.GetProjects();

            foreach (ProjectKey projectKey in allProjects)
            {
                if (!Groups.Cast <ListViewGroup>().Any(x => projectKey.Equals((ProjectKey)(x.Tag))))
                {
                    CreateGroupForProject(projectKey, true);
                }
            }

            // Remove deleted project groups
            for (int index = Groups.Count - 1; index >= 0; --index)
            {
                ListViewGroup group = Groups[index];
                if (!allProjects.Any(x => x.Equals((ProjectKey)group.Tag)))
                {
                    Groups.Remove(group);
                }
            }

            EndUpdate();
        }
示例#4
0
        public ListViewGroup GroupHitTest(int x, int y)
        {
            if (View == View.Details || !ClientRectangle.Contains(x, y))
            {
                return(null);
            }

            // TODO: Surely this needs to be marshalled?
            // Pinning using GCHandle does not work
            // This code was taken from the dot net implementation of ListView so I guess it must be right
            var lParam = new LVHITTESTINFO {
                pt_x = x, pt_y = y
            };

            var index = SendMessage(new HandleRef(this, Handle), 4114, -1, lParam);

            return((LVHTFlags)lParam.flags == LVHTFlags.LVHT_EX_GROUP_BACKGROUND
                ? Groups.Cast <ListViewGroup>().SingleOrDefault(g => index == GetGroupId(g))
                : null);
        }
示例#5
0
        /// <summary> Creates list view items and groups for the given data <paramref name="elements"/>. </summary>
        /// <param name="elements">Data element collection</param>
        private void CreateGroupsAndItems(object[] elements)
        {
            Items.Clear();
//            Groups.Clear();

            for (int i = -1; ++i != elements.Length;)
            {
                object element     = elements[i];
                bool   hasChildren = ContentProvider.HasChildren(element);
                if (hasChildren)
                {
                    object[] children = ContentProvider.GetChildren(element);

                    // Don't create empty groups
                    if (children == null || children.Length == 0)
                    {
                        continue;
                    }

                    // Try to re-use existing groups
                    ListViewGroup group = Groups.Cast <ListViewGroup>().FirstOrDefault(grp => Equals(grp.Tag, element));
                    if (group == null)
                    {
                        group = new ListViewGroup {
                            Tag = element
                        };
                        Groups.Add(group);
                    }

                    for (int j = -1; ++j != children.Length;)
                    {
                        CreateListViewItem(children[j], group);
                    }
                }
                else
                {
                    CreateListViewItem(element, null);
                }
            }
        }
示例#6
0
 private void LayoutItems()
 {
     // Lay out each group
     StackLayoutEngine.HorizontalExpand.Layout(Bounds, Groups.Cast <ILayoutable> ());
 }
示例#7
0
 private IEnumerable <FullMergeRequestKey> getMatchingFilterMergeRequests()
 {
     return(Groups
            .Cast <ListViewGroup>()
            .SelectMany(group => getMatchingFilterProjectItems(getGroupProjectKey(group))));
 }
示例#8
0
        internal void UpdateItems()
        {
            IMergeRequestCache mergeRequestCache = _dataCache?.MergeRequestCache;

            if (mergeRequestCache == null)
            {
                return;
            }

            IEnumerable <ProjectKey> projectKeys = Groups.Cast <ListViewGroup>().Select(x => (ProjectKey)x.Tag);

            BeginUpdate();

            // Add missing merge requests and update existing ones
            foreach (ProjectKey projectKey in projectKeys)
            {
                if (isGroupCollapsed(projectKey))
                {
                    continue;
                }
                foreach (FullMergeRequestKey fmk in getAllProjectItems(projectKey))
                {
                    ListViewItem item = Items.Cast <ListViewItem>().FirstOrDefault(
                        x => ((FullMergeRequestKey)x.Tag).Equals(fmk)); // item=`null` if not found
                    if (item == null)
                    {
                        item = createListViewMergeRequestItem(fmk);
                        Items.Add(item);
                    }
                    else
                    {
                        item.Tag = fmk;
                    }
                    setListViewSubItemsTags(item, fmk);
                }
            }

            // Delete summary items from groups that are no longer collapsed
            for (int index = Items.Count - 1; index >= 0; --index)
            {
                FullMergeRequestKey fmk = (FullMergeRequestKey)Items[index].Tag;
                if (!isGroupCollapsed(Items[index].Group) && isSummaryItem(Items[index]))
                {
                    Items.RemoveAt(index);
                }
            }

            // Remove normal items from collapsed groups
            for (int index = Items.Count - 1; index >= 0; --index)
            {
                if (isGroupCollapsed(Items[index].Group))
                {
                    Items.RemoveAt(index);
                }
            }

            // Create summary items
            foreach (ListViewGroup group in Groups)
            {
                if (isGroupCollapsed(group))
                {
                    string[]            subitems = Enumerable.Repeat(String.Empty, Columns.Count).ToArray();
                    FullMergeRequestKey fmk      = new FullMergeRequestKey(getGroupProjectKey(group), null);
                    ListViewItem        item     = createListViewMergeRequestItem(fmk);
                    Items.Add(item);
                    setListViewSubItemsTagsForSummary(item);
                }
            }

            // Remove deleted merge requests
            for (int index = Items.Count - 1; index >= 0; --index)
            {
                FullMergeRequestKey fmk = (FullMergeRequestKey)Items[index].Tag;
                if (!isGroupCollapsed(fmk.ProjectKey) &&
                    !getAllProjectItems(fmk.ProjectKey).Any(x => x.MergeRequest.IId == fmk.MergeRequest.IId))
                {
                    Items.RemoveAt(index);
                }
            }

            // Hide filtered ones
            for (int index = Items.Count - 1; index >= 0; --index)
            {
                FullMergeRequestKey fmk = (FullMergeRequestKey)Items[index].Tag;
                bool isCollapsed        = isGroupCollapsed(fmk.ProjectKey);
                bool removeItem         = false;
                if (isCollapsed)
                {
                    bool isThereAnyMatchingItem = getMatchingFilterProjectItems(fmk.ProjectKey).Any();
                    removeItem = !isThereAnyMatchingItem;
                }
                else
                {
                    bool doesItemMatchFilter = doesMatchFilter(fmk.MergeRequest);
                    removeItem = !doesItemMatchFilter;
                }
                if (removeItem)
                {
                    Items.RemoveAt(index);
                }
            }

            // update a number of MR which is probably displayed
            _suppressSelectionChange = true;
            try
            {
                Groups.Cast <ListViewGroup>().ToList().ForEach(group => updateGroupCaption(group));
            }
            finally
            {
                _suppressSelectionChange = false;
            }

            recalcRowHeightForMergeRequestListView();

            EndUpdate();
        }