-
-
Notifications
You must be signed in to change notification settings - Fork 348
/
Changeset.cs
154 lines (137 loc) · 5.47 KB
/
Changeset.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Linq;
using System.Drawing;
using System.Collections.Generic;
using System.Windows.Forms;
using CKAN.Extensions;
namespace CKAN
{
public partial class Changeset : UserControl
{
public Changeset()
{
InitializeComponent();
}
public void LoadChangeset(List<ModChange> changes, List<ModuleLabel> AlertLabels)
{
alertLabels = AlertLabels;
ChangesListView.Items.Clear();
if (changes != null)
{
// We're going to split our change-set into two parts: updated/removed mods,
// and everything else (which right now is replacing and installing mods, but we may have
// other types in the future).
sortedChangeSet.Clear();
sortedChangeSet.AddRange(changes.Where(change => change.ChangeType == GUIModChangeType.Remove));
sortedChangeSet.AddRange(changes.Where(change => change.ChangeType == GUIModChangeType.Update));
// Now make our list more human-friendly (dependencies for a mod are listed directly
// after it.)
CreateSortedModList(changes
.Where(change => change.ChangeType != GUIModChangeType.Remove
&& change.ChangeType != GUIModChangeType.Update)
.ToList());
ChangesListView.Items.AddRange(sortedChangeSet
.Where(ch => ch.ChangeType != GUIModChangeType.None)
.Select(makeItem)
.ToArray());
}
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (Visible && Platform.IsMono)
{
// Workaround: make sure the ListView headers are drawn
Util.Invoke(ChangesListView, () => ChangesListView.EndUpdate());
}
}
public ListView.SelectedListViewItemCollection SelectedItems
{
get
{
return ChangesListView.SelectedItems;
}
}
public event Action<ListView.SelectedListViewItemCollection> OnSelectedItemsChanged;
public event Action OnConfirmChanges;
public event Action<bool> OnCancelChanges;
private void ChangesListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (OnSelectedItemsChanged != null)
{
OnSelectedItemsChanged(ChangesListView.SelectedItems);
}
}
private void ConfirmChangesButton_Click(object sender, EventArgs e)
{
if (OnConfirmChanges != null)
{
OnConfirmChanges();
}
}
private void CancelChangesButton_Click(object sender, EventArgs e)
{
if (OnCancelChanges != null)
{
OnCancelChanges(true);
}
}
private void BackButton_Click(object sender, EventArgs e)
{
if (OnCancelChanges != null)
{
OnCancelChanges(false);
}
}
private ListViewItem makeItem(ModChange change)
{
CkanModule m = change.Mod;
ModuleLabel warnLbl = alertLabels?.FirstOrDefault(l => l.ModuleIdentifiers.Contains(m.identifier));
return new ListViewItem(new string[]
{
change.NameAndStatus,
change.ChangeType.ToString(),
warnLbl != null
? string.Format(
Properties.Resources.MainChangesetWarningInstallingModuleWithLabel,
warnLbl.Name,
change.Description
)
: change.Description
})
{
Tag = m,
ForeColor = warnLbl != null ? Color.Red : SystemColors.WindowText
};
}
/// <summary>
/// This method creates the Install part of the changeset
/// It arranges the changeset in a human-friendly order
/// The requested mod is listed first, its dependencies right after it
/// So we get for example "ModuleRCSFX" directly after "USI Exploration Pack"
///
/// It is very likely that this is forward-compatible with new ChangeTypes's,
/// like a "reconfigure" changetype, but only the future will tell
/// </summary>
/// <param name="changes">Every leftover ModChange that should be sorted</param>
/// <param name="parent"></param>
private void CreateSortedModList(IEnumerable<ModChange> changes, ModChange parent = null)
{
var notUserReq = changes
.Where(c => !(c.Reason is SelectionReason.UserRequested))
.Memoize();
foreach (ModChange change in changes)
{
bool goDeeper = parent == null || change.Reason.Parent.identifier == parent.Mod.identifier;
if (goDeeper)
{
if (!sortedChangeSet.Any(c => c.Mod.identifier == change.Mod.identifier && c.ChangeType != GUIModChangeType.Remove))
sortedChangeSet.Add(change);
CreateSortedModList(notUserReq, change);
}
}
}
private List<ModChange> sortedChangeSet = new List<ModChange>();
private List<ModuleLabel> alertLabels;
}
}