From: Latif Khalifa Date: Sun, 3 Mar 2013 11:06:48 +0000 (+0100) Subject: RAD-406: Improved performance of group info dialog X-Git-Tag: 2.10~18 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=209d611ca25b7a995250053b80bf5c7d6595520f;p=radegast%2Fradegast.git RAD-406: Improved performance of group info dialog --- diff --git a/Radegast/GUI/Consoles/GroupDetails.Designer.cs b/Radegast/GUI/Consoles/GroupDetails.Designer.cs index ad86c68..599b5b0 100644 --- a/Radegast/GUI/Consoles/GroupDetails.Designer.cs +++ b/Radegast/GUI/Consoles/GroupDetails.Designer.cs @@ -61,6 +61,7 @@ namespace Radegast this.components = new System.ComponentModel.Container(); this.tcGroupDetails = new System.Windows.Forms.TabControl(); this.tpGeneral = new System.Windows.Forms.TabPage(); + this.txtGroupID = new System.Windows.Forms.TextBox(); this.btnJoin = new System.Windows.Forms.Button(); this.lvwGeneralMembers = new Radegast.ListViewNoFlicker(); this.chGenMemberName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); @@ -155,7 +156,6 @@ namespace Radegast this.btnClose = new System.Windows.Forms.Button(); this.btnApply = new System.Windows.Forms.Button(); this.btnRefresh = new System.Windows.Forms.Button(); - this.txtGroupID = new System.Windows.Forms.TextBox(); this.tcGroupDetails.SuspendLayout(); this.tpGeneral.SuspendLayout(); this.memberListContextMenu.SuspendLayout(); @@ -211,6 +211,16 @@ namespace Radegast this.tpGeneral.Text = "General"; this.tpGeneral.UseVisualStyleBackColor = true; // + // txtGroupID + // + this.txtGroupID.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtGroupID.Location = new System.Drawing.Point(155, 198); + this.txtGroupID.Name = "txtGroupID"; + this.txtGroupID.ReadOnly = true; + this.txtGroupID.Size = new System.Drawing.Size(239, 20); + this.txtGroupID.TabIndex = 7; + // // btnJoin // this.btnJoin.Location = new System.Drawing.Point(9, 195); @@ -241,11 +251,12 @@ namespace Radegast this.lvwGeneralMembers.Name = "lvwGeneralMembers"; this.lvwGeneralMembers.ShowGroups = false; this.lvwGeneralMembers.Size = new System.Drawing.Size(385, 82); - this.lvwGeneralMembers.Sorting = System.Windows.Forms.SortOrder.Ascending; this.lvwGeneralMembers.TabIndex = 8; this.lvwGeneralMembers.UseCompatibleStateImageBehavior = false; this.lvwGeneralMembers.View = System.Windows.Forms.View.Details; + this.lvwGeneralMembers.VirtualMode = true; this.lvwGeneralMembers.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lvwGeneralMembers_ColumnClick); + this.lvwGeneralMembers.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.lvwGeneralMembers_RetrieveVirtualItem); this.lvwGeneralMembers.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lvwGeneralMembers_MouseDoubleClick); // // chGenMemberName @@ -268,7 +279,7 @@ namespace Radegast this.memberListContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.memberListContextMenuSave}); this.memberListContextMenu.Name = "contextMenuStrip1"; - this.memberListContextMenu.Size = new System.Drawing.Size(168, 48); + this.memberListContextMenu.Size = new System.Drawing.Size(168, 26); // // memberListContextMenuSave // @@ -467,7 +478,7 @@ namespace Radegast this.tpMembersRoles.Location = new System.Drawing.Point(4, 22); this.tpMembersRoles.Name = "tpMembersRoles"; this.tpMembersRoles.Padding = new System.Windows.Forms.Padding(3); - this.tpMembersRoles.Size = new System.Drawing.Size(400, 437); + this.tpMembersRoles.Size = new System.Drawing.Size(400, 439); this.tpMembersRoles.TabIndex = 3; this.tpMembersRoles.Text = "Members && Roles"; this.tpMembersRoles.UseVisualStyleBackColor = true; @@ -482,7 +493,7 @@ namespace Radegast this.tcMembersRoles.Location = new System.Drawing.Point(9, 23); this.tcMembersRoles.Name = "tcMembersRoles"; this.tcMembersRoles.SelectedIndex = 0; - this.tcMembersRoles.Size = new System.Drawing.Size(385, 404); + this.tcMembersRoles.Size = new System.Drawing.Size(385, 406); this.tcMembersRoles.TabIndex = 2; this.tcMembersRoles.SelectedIndexChanged += new System.EventHandler(this.tcMembersRoles_SelectedIndexChanged); // @@ -493,7 +504,7 @@ namespace Radegast this.tpMembers.Location = new System.Drawing.Point(4, 22); this.tpMembers.Name = "tpMembers"; this.tpMembers.Padding = new System.Windows.Forms.Padding(3); - this.tpMembers.Size = new System.Drawing.Size(377, 378); + this.tpMembers.Size = new System.Drawing.Size(377, 380); this.tpMembers.TabIndex = 0; this.tpMembers.Text = "Members"; this.tpMembers.UseVisualStyleBackColor = true; @@ -508,7 +519,7 @@ namespace Radegast this.panel1.Controls.Add(this.btnEjectMember); this.panel1.Controls.Add(this.label3); this.panel1.Controls.Add(this.lblAssignedRoles); - this.panel1.Location = new System.Drawing.Point(0, 130); + this.panel1.Location = new System.Drawing.Point(0, 132); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(377, 248); this.panel1.TabIndex = 12; @@ -615,12 +626,13 @@ namespace Radegast this.lvwMemberDetails.MultiSelect = false; this.lvwMemberDetails.Name = "lvwMemberDetails"; this.lvwMemberDetails.ShowGroups = false; - this.lvwMemberDetails.Size = new System.Drawing.Size(377, 124); - this.lvwMemberDetails.Sorting = System.Windows.Forms.SortOrder.Ascending; + this.lvwMemberDetails.Size = new System.Drawing.Size(377, 126); this.lvwMemberDetails.TabIndex = 9; this.lvwMemberDetails.UseCompatibleStateImageBehavior = false; this.lvwMemberDetails.View = System.Windows.Forms.View.Details; + this.lvwMemberDetails.VirtualMode = true; this.lvwMemberDetails.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lvwGeneralMembers_ColumnClick); + this.lvwMemberDetails.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.lvwMemberDetails_RetrieveVirtualItem); this.lvwMemberDetails.SelectedIndexChanged += new System.EventHandler(this.lvwMemberDetails_SelectedIndexChanged); this.lvwMemberDetails.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lvwMemberDetails_MouseDoubleClick); // @@ -646,7 +658,7 @@ namespace Radegast this.tpRoles.Location = new System.Drawing.Point(4, 22); this.tpRoles.Name = "tpRoles"; this.tpRoles.Padding = new System.Windows.Forms.Padding(3); - this.tpRoles.Size = new System.Drawing.Size(377, 378); + this.tpRoles.Size = new System.Drawing.Size(377, 380); this.tpRoles.TabIndex = 1; this.tpRoles.Text = "Roles"; this.tpRoles.UseVisualStyleBackColor = true; @@ -668,7 +680,7 @@ namespace Radegast this.pnlRoleDetaiils.Controls.Add(this.txtRoleTitle); this.pnlRoleDetaiils.Controls.Add(this.txtRoleDescription); this.pnlRoleDetaiils.Controls.Add(this.txtRoleName); - this.pnlRoleDetaiils.Location = new System.Drawing.Point(-4, 130); + this.pnlRoleDetaiils.Location = new System.Drawing.Point(-4, 132); this.pnlRoleDetaiils.Name = "pnlRoleDetaiils"; this.pnlRoleDetaiils.Size = new System.Drawing.Size(384, 252); this.pnlRoleDetaiils.TabIndex = 11; @@ -841,7 +853,7 @@ namespace Radegast this.lvwRoles.MultiSelect = false; this.lvwRoles.Name = "lvwRoles"; this.lvwRoles.ShowGroups = false; - this.lvwRoles.Size = new System.Drawing.Size(377, 124); + this.lvwRoles.Size = new System.Drawing.Size(377, 126); this.lvwRoles.Sorting = System.Windows.Forms.SortOrder.Ascending; this.lvwRoles.TabIndex = 10; this.lvwRoles.UseCompatibleStateImageBehavior = false; @@ -879,7 +891,7 @@ namespace Radegast this.tpNotices.Location = new System.Drawing.Point(4, 22); this.tpNotices.Name = "tpNotices"; this.tpNotices.Padding = new System.Windows.Forms.Padding(3); - this.tpNotices.Size = new System.Drawing.Size(400, 437); + this.tpNotices.Size = new System.Drawing.Size(400, 439); this.tpNotices.TabIndex = 2; this.tpNotices.Text = "Notices"; this.tpNotices.UseVisualStyleBackColor = true; @@ -961,7 +973,7 @@ namespace Radegast this.pnlNewNotice.Controls.Add(this.label11); this.pnlNewNotice.Location = new System.Drawing.Point(6, 224); this.pnlNewNotice.Name = "pnlNewNotice"; - this.pnlNewNotice.Size = new System.Drawing.Size(385, 210); + this.pnlNewNotice.Size = new System.Drawing.Size(385, 212); this.pnlNewNotice.TabIndex = 25; this.pnlNewNotice.Visible = false; // @@ -973,7 +985,7 @@ namespace Radegast this.pnlNoticeAttachment.Controls.Add(this.btnRemoveAttachment); this.pnlNoticeAttachment.Controls.Add(this.icnNewNoticeAtt); this.pnlNoticeAttachment.Controls.Add(this.txtNewNoteAtt); - this.pnlNoticeAttachment.Location = new System.Drawing.Point(3, 165); + this.pnlNoticeAttachment.Location = new System.Drawing.Point(3, 167); this.pnlNoticeAttachment.Name = "pnlNoticeAttachment"; this.pnlNoticeAttachment.Size = new System.Drawing.Size(276, 44); this.pnlNoticeAttachment.TabIndex = 3; @@ -1037,7 +1049,7 @@ namespace Radegast // btnSend // this.btnSend.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnSend.Location = new System.Drawing.Point(285, 180); + this.btnSend.Location = new System.Drawing.Point(285, 182); this.btnSend.Name = "btnSend"; this.btnSend.Size = new System.Drawing.Size(97, 23); this.btnSend.TabIndex = 6; @@ -1056,7 +1068,7 @@ namespace Radegast this.txtNewNoticeBody.Multiline = true; this.txtNewNoticeBody.Name = "txtNewNoticeBody"; this.txtNewNoticeBody.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.txtNewNoticeBody.Size = new System.Drawing.Size(375, 101); + this.txtNewNoticeBody.Size = new System.Drawing.Size(375, 103); this.txtNewNoticeBody.TabIndex = 2; // // label10 @@ -1093,7 +1105,7 @@ namespace Radegast this.pnlArchivedNotice.Controls.Add(this.label1); this.pnlArchivedNotice.Location = new System.Drawing.Point(6, 224); this.pnlArchivedNotice.Name = "pnlArchivedNotice"; - this.pnlArchivedNotice.Size = new System.Drawing.Size(385, 207); + this.pnlArchivedNotice.Size = new System.Drawing.Size(385, 209); this.pnlArchivedNotice.TabIndex = 11; this.pnlArchivedNotice.Visible = false; // @@ -1102,7 +1114,7 @@ namespace Radegast this.txtItemName.AccessibleName = "Notice attachment"; this.txtItemName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.txtItemName.Location = new System.Drawing.Point(25, 183); + this.txtItemName.Location = new System.Drawing.Point(25, 185); this.txtItemName.Name = "txtItemName"; this.txtItemName.ReadOnly = true; this.txtItemName.Size = new System.Drawing.Size(302, 20); @@ -1112,7 +1124,7 @@ namespace Radegast // icnItem // this.icnItem.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.icnItem.Location = new System.Drawing.Point(3, 185); + this.icnItem.Location = new System.Drawing.Point(3, 187); this.icnItem.Name = "icnItem"; this.icnItem.Size = new System.Drawing.Size(16, 16); this.icnItem.TabIndex = 23; @@ -1123,7 +1135,7 @@ namespace Radegast // this.btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnSave.Enabled = false; - this.btnSave.Location = new System.Drawing.Point(333, 183); + this.btnSave.Location = new System.Drawing.Point(333, 185); this.btnSave.Name = "btnSave"; this.btnSave.Size = new System.Drawing.Size(49, 23); this.btnSave.TabIndex = 18; @@ -1144,7 +1156,7 @@ namespace Radegast this.txtNotice.Name = "txtNotice"; this.txtNotice.ReadOnly = true; this.txtNotice.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.txtNotice.Size = new System.Drawing.Size(375, 119); + this.txtNotice.Size = new System.Drawing.Size(375, 121); this.txtNotice.TabIndex = 19; // // lblTitle @@ -1226,16 +1238,6 @@ namespace Radegast this.btnRefresh.UseVisualStyleBackColor = true; this.btnRefresh.Click += new System.EventHandler(this.btnRefresh_Click); // - // txtGroupID - // - this.txtGroupID.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.txtGroupID.Location = new System.Drawing.Point(155, 198); - this.txtGroupID.Name = "txtGroupID"; - this.txtGroupID.ReadOnly = true; - this.txtGroupID.Size = new System.Drawing.Size(239, 20); - this.txtGroupID.TabIndex = 7; - // // GroupDetails // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; diff --git a/Radegast/GUI/Consoles/GroupDetails.cs b/Radegast/GUI/Consoles/GroupDetails.cs index 2415a56..c06389d 100644 --- a/Radegast/GUI/Consoles/GroupDetails.cs +++ b/Radegast/GUI/Consoles/GroupDetails.cs @@ -54,6 +54,7 @@ namespace Radegast private List> roleMembers; private Dictionary roles; private bool isMember; + private GroupMemberSorter memberSorter = new GroupMemberSorter(); private UUID groupTitlesRequest, groupMembersRequest, groupRolesRequest, groupRolesMembersRequest; @@ -75,8 +76,6 @@ namespace Radegast txtGroupID.Text = group.ID.ToString(); lblGroupName.Text = group.Name; - lvwGeneralMembers.ListViewItemSorter = new GroupMemberSorter(); - lvwMemberDetails.ListViewItemSorter = new GroupMemberSorter(); isMember = instance.Groups.ContainsKey(group.ID); @@ -345,45 +344,66 @@ namespace Radegast void ProcessNameUpdate(Dictionary Names) { - if (instance.MainForm.InvokeRequired) - { - instance.MainForm.BeginInvoke(new MethodInvoker(() => ProcessNameUpdate(Names))); - return; - } - if (Names.ContainsKey(group.FounderID)) { - lblFounded.Text = "Founded by: " + Names[group.FounderID]; + if (InvokeRequired) + { + BeginInvoke(new MethodInvoker(() => { lblFounded.Text = "Founded by: " + Names[group.FounderID]; })); + } + else + { + lblFounded.Text = "Founded by: " + Names[group.FounderID]; + } } - lvwMemberDetails.BeginUpdate(); - lvwGeneralMembers.BeginUpdate(); - - bool modified = false; - - foreach (KeyValuePair name in Names) + ThreadPool.QueueUserWorkItem(sync => { - if (lvwGeneralMembers.Items.ContainsKey(name.Key.ToString())) + try { - lvwGeneralMembers.Items[name.Key.ToString()].Text = name.Value; - modified = true; - } + int minIndex = int.MaxValue; + int maxIndex = int.MinValue; + bool hasUpdates = false; - if (!isMember) - continue; + foreach (var name in Names) + { + var member = GroupMembers.Find((m) => m.Base.ID == name.Key); + if (member == null) continue; + + hasUpdates = true; + member.Name = name.Value; + int ix = GroupMembers.IndexOf(member); + if (ix < minIndex) minIndex = ix; + if (ix > maxIndex) maxIndex = ix; + } - if (lvwMemberDetails.Items.ContainsKey(name.Key.ToString())) + if (hasUpdates) + { + if (minIndex < 0) minIndex = 0; + if (maxIndex < 0) maxIndex = 0; + if (InvokeRequired) + { + BeginInvoke(new MethodInvoker(() => + { + try + { + lvwGeneralMembers.RedrawItems(minIndex, maxIndex, true); + lvwMemberDetails.RedrawItems(minIndex, maxIndex, true); + } + catch { } + })); + } + else + { + lvwGeneralMembers.RedrawItems(minIndex, maxIndex, true); + lvwMemberDetails.RedrawItems(minIndex, maxIndex, true); + } + } + } + catch (Exception ex) { - lvwMemberDetails.Items[name.Key.ToString()].Text = name.Value; + Logger.DebugLog("Failed updating group member names: " + ex.ToString()); } - } - if (modified) - { - lvwGeneralMembers.Sort(); - if (isMember) lvwMemberDetails.Sort(); - } - lvwGeneralMembers.EndUpdate(); - lvwMemberDetails.EndUpdate(); + }); } void Groups_GroupTitlesReply(object sender, GroupTitlesReplyEventArgs e) @@ -410,142 +430,81 @@ namespace Radegast cbxActiveTitle.SelectedIndexChanged += cbxActiveTitle_SelectedIndexChanged; } + List GroupMembers = new List(); + void Groups_GroupMembersReply(object sender, GroupMembersReplyEventArgs e) { - if (groupMembersRequest != e.RequestID) return; - - ThreadPool.QueueUserWorkItem(sync => + if (InvokeRequired) { - List newItems = new List(); - List memberDetails = new List(); - int namesToFetch = 0; - AutoResetEvent gotNames = new AutoResetEvent(false); - - EventHandler handler = (xsender, xe) => - { - lock (newItems) - { - foreach (var item in newItems) - { - foreach (var name in xe.Names) - { - if (item.Name == name.Key.ToString()) - { - item.Text = name.Value; - namesToFetch--; - } - } - } - } - - if (isMember) - { - lock (memberDetails) - { - foreach (var item in memberDetails) - { - foreach (var name in xe.Names) - { - if (item.Name == name.Key.ToString()) - { - item.Text = name.Value; - } - } - } - } - } - - if (namesToFetch < 20) - { - gotNames.Set(); - } - Logger.DebugLog("Names to fetch: " + namesToFetch.ToString()); - }; - - instance.Names.NameUpdated += handler; - - foreach (GroupMember baseMember in e.Members.Values) - { - EnhancedGroupMember member = new EnhancedGroupMember(baseMember); - string name; - - name = instance.Names.Get(member.Base.ID); - if (name == RadegastInstance.INCOMPLETE_NAME) - { - namesToFetch++; - } - - { - ListViewItem item = new ListViewItem(name); - item.Tag = member; - item.Name = member.Base.ID.ToString(); - item.SubItems.Add(new ListViewItem.ListViewSubItem(item, member.Base.Title)); - if (member.LastOnline != DateTime.MinValue) - { - item.SubItems.Add(new ListViewItem.ListViewSubItem(item, member.Base.OnlineStatus)); - } - - newItems.Add(item); - } - - if (isMember) - { - ListViewItem item = new ListViewItem(name); - item.Tag = member; - item.Name = member.Base.ID.ToString(); - item.SubItems.Add(new ListViewItem.ListViewSubItem(item, member.Base.Contribution.ToString())); - if (member.LastOnline != DateTime.MinValue) - { - item.SubItems.Add(new ListViewItem.ListViewSubItem(item, member.Base.OnlineStatus)); - } - lock (memberDetails) - { - memberDetails.Add(item); - } - } - } + BeginInvoke(new MethodInvoker(() => Groups_GroupMembersReply(sender, e))); + return; + } - if (namesToFetch >= 20) + lvwGeneralMembers.VirtualListSize = 0; + lvwMemberDetails.VirtualListSize = 0; + + GroupMembers = new List(e.Members.Count); + lock (GroupMembers) + { + foreach (var member in e.Members) { - gotNames.WaitOne(120 * 1000); + GroupMembers.Add(new EnhancedGroupMember(instance.Names.Get(member.Key), member.Value)); } - instance.Names.NameUpdated -= handler; - - UpdateGeneralMembers(newItems); + } - if (isMember && memberDetails.Count > 0) - { - UpdateMemberDetails(memberDetails); - } - }); + GroupMembers.Sort(memberSorter); + lvwGeneralMembers.VirtualListSize = GroupMembers.Count; + lvwMemberDetails.VirtualListSize = GroupMembers.Count; } - void UpdateGeneralMembers(List newItems) + void lvwMemberDetails_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { - if (instance.MainForm.InvokeRequired) + EnhancedGroupMember member = null; + try + { + member = GroupMembers[e.ItemIndex]; + } + catch { - instance.MainForm.BeginInvoke(new MethodInvoker(() => UpdateGeneralMembers(newItems))); + e.Item = new ListViewItem(); return; } - lvwGeneralMembers.BeginUpdate(); - lvwGeneralMembers.Items.AddRange(newItems.ToArray()); - lvwGeneralMembers.Sort(); - lvwGeneralMembers.EndUpdate(); + ListViewItem item = new ListViewItem(member.Name); + item.Tag = member; + item.Name = member.Base.ID.ToString(); + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, member.Base.Contribution.ToString())); + if (member.LastOnline != DateTime.MinValue) + { + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, member.Base.OnlineStatus)); + } + + e.Item = item; } - void UpdateMemberDetails(List memberDetails) + void lvwGeneralMembers_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { - if (instance.MainForm.InvokeRequired) + EnhancedGroupMember member = null; + try { - instance.MainForm.BeginInvoke(new MethodInvoker(() => UpdateMemberDetails(memberDetails))); + member = GroupMembers[e.ItemIndex]; + } + catch + { + e.Item = new ListViewItem(); return; } + ListViewItem item = new ListViewItem(member.Name); + + item.Tag = member; + item.Name = member.Base.ID.ToString(); + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, member.Base.Title)); + if (member.LastOnline != DateTime.MinValue) + { + item.SubItems.Add(new ListViewItem.ListViewSubItem(item, member.Base.OnlineStatus)); + } - lvwMemberDetails.BeginUpdate(); - lvwMemberDetails.Items.AddRange(memberDetails.ToArray()); - lvwMemberDetails.Sort(); - lvwMemberDetails.EndUpdate(); + e.Item = item; } #endregion @@ -611,8 +570,8 @@ namespace Radegast private void RefreshGroupInfo() { - lvwGeneralMembers.Items.Clear(); - if (isMember) lvwMemberDetails.Items.Clear(); + lvwGeneralMembers.VirtualListSize = 0; + if (isMember) lvwMemberDetails.VirtualListSize = 0; cbxActiveTitle.SelectedIndexChanged -= cbxActiveTitle_SelectedIndexChanged; cbxReceiveNotices.CheckedChanged -= new EventHandler(cbxListInProfile_CheckedChanged); @@ -644,11 +603,7 @@ namespace Radegast if (!isMember) return; btnApply.Enabled = false; - //lvwGeneralMembers.Items.Clear(); - //lvwMemberDetails.Items.Clear(); - //lvwAllowedAbilities.Items.Clear(); lvwAssignedRoles.Items.Clear(); - //groupMembersRequest = client.Groups.RequestGroupMembers(group.ID); groupRolesRequest = client.Groups.RequestGroupRoles(group.ID); } #endregion @@ -694,31 +649,31 @@ namespace Radegast void lvwGeneralMembers_ColumnClick(object sender, ColumnClickEventArgs e) { ListView lb = (ListView)sender; - GroupMemberSorter sorter = (GroupMemberSorter)lb.ListViewItemSorter; switch (e.Column) { case 0: - sorter.SortBy = GroupMemberSorter.SortByColumn.Name; + memberSorter.SortBy = GroupMemberSorter.SortByColumn.Name; break; case 1: if (lb.Name == "lvwMemberDetails") - sorter.SortBy = GroupMemberSorter.SortByColumn.Contribution; + memberSorter.SortBy = GroupMemberSorter.SortByColumn.Contribution; else - sorter.SortBy = GroupMemberSorter.SortByColumn.Title; + memberSorter.SortBy = GroupMemberSorter.SortByColumn.Title; break; case 2: - sorter.SortBy = GroupMemberSorter.SortByColumn.LastOnline; + memberSorter.SortBy = GroupMemberSorter.SortByColumn.LastOnline; break; } - if (sorter.CurrentOrder == GroupMemberSorter.SortOrder.Ascending) - sorter.CurrentOrder = GroupMemberSorter.SortOrder.Descending; + if (memberSorter.CurrentOrder == GroupMemberSorter.SortOrder.Ascending) + memberSorter.CurrentOrder = GroupMemberSorter.SortOrder.Descending; else - sorter.CurrentOrder = GroupMemberSorter.SortOrder.Ascending; + memberSorter.CurrentOrder = GroupMemberSorter.SortOrder.Ascending; - lb.Sort(); + GroupMembers.Sort(memberSorter); + lb.Invalidate(); } private void lvwNoticeArchive_ColumnClick(object sender, ColumnClickEventArgs e) @@ -842,8 +797,8 @@ namespace Radegast private void lvwMemberDetails_SelectedIndexChanged(object sender, EventArgs e) { - if (lvwMemberDetails.SelectedItems.Count != 1 || roles == null || roleMembers == null) return; - EnhancedGroupMember m = (EnhancedGroupMember)lvwMemberDetails.SelectedItems[0].Tag; + if (lvwMemberDetails.SelectedIndices.Count != 1 || roles == null || roleMembers == null) return; + EnhancedGroupMember m = GroupMembers[lvwMemberDetails.SelectedIndices[0]]; btnApply.Enabled = false; @@ -1048,11 +1003,12 @@ namespace Radegast } btnSaveRole.Tag = role; - + + lvwAssignedMembers.BeginUpdate(); if (role.ID == UUID.Zero) { - foreach (ListViewItem item in lvwMemberDetails.Items) - lvwAssignedMembers.Items.Add(item.Text); + foreach (var member in GroupMembers) + lvwAssignedMembers.Items.Add(member.Name); } else if (roleMembers != null) { @@ -1062,6 +1018,7 @@ namespace Radegast lvwAssignedMembers.Items.Add(instance.Names.Get(m.Value)); } } + lvwAssignedMembers.EndUpdate(); lvwRoleAbilitis.Tag = role; @@ -1212,26 +1169,26 @@ namespace Radegast System.IO.FileStream fs = (System.IO.FileStream)saveMembers.OpenFile(); System.IO.StreamWriter sw = new System.IO.StreamWriter(fs, System.Text.Encoding.UTF8); sw.WriteLine("UUID,Name"); - foreach (ListViewItem item in lvwGeneralMembers.Items) + foreach (var item in GroupMembers) { - sw.WriteLine("{0},{1}", item.Name, item.Text); + sw.WriteLine("{0},{1}", item.Base.ID, item.Name); } sw.Close(); break; case 2: - OpenMetaverse.StructuredData.OSDArray members = new OpenMetaverse.StructuredData.OSDArray(lvwGeneralMembers.Items.Count); - foreach (ListViewItem item in lvwGeneralMembers.Items) + OpenMetaverse.StructuredData.OSDArray members = new OpenMetaverse.StructuredData.OSDArray(GroupMembers.Count); + foreach (var item in GroupMembers) { OpenMetaverse.StructuredData.OSDMap member = new OpenMetaverse.StructuredData.OSDMap(2); - member["UUID"] = item.Name; - member["Name"] = item.Text; + member["UUID"] = item.Base.ID; + member["Name"] = item.Name; members.Add(member); } System.IO.File.WriteAllText(saveMembers.FileName, OpenMetaverse.StructuredData.OSDParser.SerializeJsonString(members)); break; } - instance.TabConsole.DisplayNotificationInChat(string.Format("Saved {0} members to {1}", lvwGeneralMembers.Items.Count, saveMembers.FileName)); + instance.TabConsole.DisplayNotificationInChat(string.Format("Saved {0} members to {1}", GroupMembers.Count, saveMembers.FileName)); } catch (Exception ex) { @@ -1239,16 +1196,19 @@ namespace Radegast } } } + } public class EnhancedGroupMember { public GroupMember Base; public DateTime LastOnline; + public string Name; - public EnhancedGroupMember(GroupMember baseMember) + public EnhancedGroupMember(string name, GroupMember baseMember) { Base = baseMember; + Name = name; if (baseMember.OnlineStatus == "Online") { @@ -1273,7 +1233,7 @@ namespace Radegast } #region Sorter classes - public class GroupMemberSorter : IComparer + public class GroupMemberSorter : IComparer { public enum SortByColumn { @@ -1292,20 +1252,15 @@ namespace Radegast public SortOrder CurrentOrder = SortOrder.Ascending; public SortByColumn SortBy = SortByColumn.Name; - public int Compare(object x, object y) + public int Compare(EnhancedGroupMember member1, EnhancedGroupMember member2) { - ListViewItem item1 = (ListViewItem)x; - ListViewItem item2 = (ListViewItem)y; - EnhancedGroupMember member1 = (EnhancedGroupMember)item1.Tag; - EnhancedGroupMember member2 = (EnhancedGroupMember)item2.Tag; - switch (SortBy) { case SortByColumn.Name: if (CurrentOrder == SortOrder.Ascending) - return string.Compare(item1.Text, item2.Text); + return string.Compare(member1.Name, member2.Name); else - return string.Compare(item2.Text, item1.Text); + return string.Compare(member2.Name, member1.Name); case SortByColumn.Title: if (CurrentOrder == SortOrder.Ascending)