2 using System.Collections.Generic;
\r
3 using System.Drawing;
\r
4 using System.Windows.Forms;
\r
5 using NaGet.Packages;
\r
6 using NaGet.Packages.Install;
\r
8 namespace AppliStation
\r
11 /// Description of PackagesInstallConfirmForm.
\r
13 public partial class InstallationConfirmForm : Form
\r
15 private Installation[] requiredInstallations = null;
\r
17 private Installation[] selectedInstallations = null;
\r
19 private PackageListsManager pkgListMan;
\r
21 public IEnumerable<Installation> Installations {
\r
23 return NaGet.Utils.MergeEnumerable<Installation>(requiredInstallations, selectedInstallations);
\r
26 requiredInstallations = null;
\r
27 selectedInstallations = NaGet.Utils.IEnumerable2Array<Installation>(value);
\r
29 updateInstsListView();
\r
33 public PackageListsManager PkgListsManager {
\r
34 get { return pkgListMan; }
\r
38 updateInstsListView();
\r
42 public InstallationConfirmForm()
\r
45 // The InitializeComponent() call is required for Windows Forms designer support.
\r
47 InitializeComponent();
\r
49 // 管理者権限で動いているならばrunasが必要にはならないので表示しない
\r
50 if (NaGet.Utils.IsAdministrators()) {
\r
51 runasCheckBox.Checked = false;
\r
52 runasCheckBox.Visible = false;
\r
56 AppliStation.Util.NativeMethods.ListView_EnableVistaExplorerTheme(instsListView);
\r
57 AppliStation.Util.NativeMethods.ListView_SetDoubleBuffer(instsListView, true);
\r
60 #region インストールリスト表示処理部
\r
62 #region インストールリストの反映
\r
65 /// インストールリストを更新したなどで、リストの表示を更新する
\r
67 private void updateInstsListView()
\r
69 if (instsListView.Items.Count > 0) {
\r
70 instsListView.Items.Clear();
\r
73 addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);
\r
74 addInstsListItemPerGroup(selectedInstallations, instsListView.Groups["install"], false);
\r
76 InstsListViewItemChecked(instsListView, null);
\r
77 instsListView.Refresh();
\r
81 /// 指定したグループのリストの表示を更新する。
\r
83 /// <param name="insts">インストールリスト</param>
\r
84 /// <param name="group">対象のグループ</param>
\r
85 /// <param name="firstAppend">先頭に追加するか</param>
\r
86 private void addInstsListItemPerGroup(IEnumerable<Installation> insts, ListViewGroup group, bool firstAppend)
\r
88 // まず所属グループのアイテムをすべて削除する
\r
89 if (insts == null) return;
\r
91 List<ListViewItem> itemsToAdd = new List<ListViewItem>();
\r
92 foreach (Installation inst in insts) {
\r
93 Package pkg = inst.InstalledPackage;
\r
95 string[] itemData = new string[instsListView.Columns.Count];
\r
96 itemData[nameColumnHeader.Index] = pkg.Name;
\r
98 inst.Silent = true; // silent install as possible!
\r
100 Package curPkg = null;
\r
101 if (pkgListMan != null) {
\r
102 curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ??
\r
103 pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name);
\r
105 itemData[versionColumnHeader.Index] = pkg.Version;
\r
106 itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-";
\r
107 // itemData[silentInstColumnHeader.Index] の設定は instViewUpdateSilentInstallView で
\r
109 ListViewItem item = new ListViewItem(itemData);
\r
111 item.ToolTipText = pkg.Summary;
\r
112 item.Checked = true;
\r
113 item.Group = group;
\r
114 instViewUpdateSilentInstallView(item);
\r
116 itemsToAdd.Add(item);
\r
120 for (int i = 0; i < itemsToAdd.Count; i++) {
\r
121 instsListView.Items.Insert(i, itemsToAdd[i]);
\r
124 instsListView.Items.AddRange(itemsToAdd.ToArray());
\r
131 /// アイテムのサイレントインストール部分の表示の更新を行う。
\r
133 /// <param name="item">対象のインストーラのリストアイテム</param>
\r
134 private void instViewUpdateSilentInstallView(ListViewItem item)
\r
136 Installation inst = (Installation) item.Tag;
\r
137 item.SubItems[silentInstColumnHeader.Index].Text =
\r
138 (inst.SupportsSilentOnly)? "サイレントインストールのみサポート" :
\r
139 (inst.Silent)? "サイレントインストール" :
\r
140 (inst.IsSupportsSilent)? "手動でインストール" :
\r
141 "サイレントインストールできませんので、手動でインストールします";
\r
144 #region instsListViewのオーナードドロー関連
\r
146 void InstsListViewDrawSubItem(object sender, DrawListViewSubItemEventArgs e)
\r
148 if (e.Header == silentInstColumnHeader) {
\r
149 Installation inst = ((Installation) e.Item.Tag);
\r
151 //e.DrawBackground();
\r
152 e.Graphics.Clip.Intersect(e.Bounds);
\r
155 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
157 instListViewSilentInstallImageList.Images[0],
\r
159 } else if (inst.IsSupportsSilent) {
\r
160 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
162 instListViewSilentInstallImageList.Images[0],
\r
164 AppliStation.Util.GUIUtils.GetImageAttributeToGrayOut(0.5f));
\r
167 e.DrawDefault = true;
\r
171 void InstsListViewDrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
\r
173 if (e.Header == silentInstColumnHeader) {
\r
174 e.DrawBackground();
\r
175 e.Graphics.Clip.Intersect(e.Bounds);
\r
176 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(
\r
178 instListViewSilentInstallImageList.Images[0],
\r
181 e.DrawDefault = true;
\r
189 void InstsListViewItemChecked(object sender, ItemCheckedEventArgs e)
\r
191 System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = instsListView.CheckedItems;
\r
193 runasCheckBox.Checked = GetShouldUseRunas();
\r
196 okButton.Enabled = (checkeds != null) && (checkeds.Count > 0);
\r
198 checkUnselectedDependencies();
\r
201 void InstsListViewContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
\r
203 System.Windows.Forms.ListView.CheckedIndexCollection chkIdxes = instsListView.CheckedIndices;
\r
204 System.Windows.Forms.ListView.SelectedIndexCollection selIdxes = instsListView.SelectedIndices;
\r
206 silentInstallStripMenuItem.Visible = selIdxes.Count > 0;
\r
207 if (selIdxes.Count > 0) {
\r
208 Installation inst0th = ((Installation) instsListView.Items[selIdxes[0]].Tag);
\r
209 bool bChecked = inst0th.Silent;
\r
210 bool bEnabled = (inst0th.IsSupportsSilent && (!inst0th.SupportsSilentOnly));
\r
211 silentInstallStripMenuItem.Checked = bChecked;
\r
212 silentInstallStripMenuItem.Enabled = bEnabled;
\r
214 for (int i = 1; i < selIdxes.Count; i++) {
\r
215 Installation inst = ((Installation) instsListView.Items[selIdxes[i]].Tag);
\r
217 if ( (bChecked != inst.Silent) ||
\r
218 (bEnabled != (inst.IsSupportsSilent && (!inst.SupportsSilentOnly))) ) {
\r
219 silentInstallStripMenuItem.CheckState = CheckState.Indeterminate;
\r
220 silentInstallStripMenuItem.Enabled = false;
\r
225 instListToolStripSeparator.Visible = selIdxes.Count > 0;
\r
228 selectAllInstsStripMenuItem.Enabled = chkIdxes.Count < instsListView.Items.Count;
\r
229 unselectAllInstsStripMenuItem.Enabled = chkIdxes.Count > 0;
\r
232 void SilentInstallStripMenuItemClick(object sender, EventArgs e)
\r
234 bool silent = ! silentInstallStripMenuItem.Checked;
\r
235 foreach (ListViewItem item in instsListView.SelectedItems) {
\r
236 ((Installation) item.Tag).Silent = silent;
\r
237 instViewUpdateSilentInstallView(item);
\r
241 void SelectAllInstsStripMenuItemClick(object sender, EventArgs e)
\r
243 foreach (ListViewItem item in instsListView.Items) {
\r
244 item.Checked = true;
\r
246 instsListView.Refresh();
\r
249 void UnselectAllInstsStripMenuItemClick(object sender, EventArgs e)
\r
251 foreach (ListViewItem item in instsListView.CheckedItems) {
\r
252 item.Checked = false;
\r
254 instsListView.Refresh();
\r
257 void InstallationConfirmFormShown(object sender, EventArgs e)
\r
259 if (InvokeRequired) {
\r
260 Invoke(new MethodInvoker(resolveDependecies));
\r
262 resolveDependecies();
\r
269 private void resolveDependecies()
\r
271 if (requiredInstallations == null) {
\r
272 Installation[] resolved, dependencies;
\r
274 DependeciesResolver.ResolveInstallations(
\r
275 selectedInstallations,
\r
280 requiredInstallations = dependencies;
\r
282 addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);
\r
284 InstsListViewItemChecked(instsListView, null);
\r
285 instsListView.Refresh();
\r
290 /// 依存関係を確認してGUIに反映させる。
\r
291 /// 選択されていないが依存関係上必要なソフトを探し出す。
\r
293 /// <returns>選択されていないが依存関係上必要なソフトの個数(何もない場合はゼロ)</returns>
\r
294 private uint checkUnselectedDependencies()
\r
298 List<Package> instPkgs = new List<Package>();
\r
299 foreach (Installation inst in Installations) {
\r
300 instPkgs.Add(inst.InstalledPackage);
\r
303 List<Package> pkg = new List<Package>();
\r
304 foreach (Installation inst in DependeciesResolver.CreateRequiresInstallations(CheckedInstallations, pkgListMan, instPkgs)) {
\r
305 pkg.Add(inst.InstalledPackage);
\r
308 foreach (ListViewItem item in instsListView.Items) {
\r
309 if ((pkg.IndexOf(((Installation) item.Tag).InstalledPackage) >= 0) && !item.Checked) {
\r
310 item.ForeColor = Color.Red;
\r
313 item.ForeColor = Color.Empty;
\r
321 /// インストールするよう選択されたパッケージの配列
\r
323 public Installation[] CheckedInstallations {
\r
325 List<Installation> insts = new List<Installation>();
\r
326 foreach (ListViewItem item in instsListView.CheckedItems) {
\r
327 insts.Add((Installation) item.Tag);
\r
329 return insts.ToArray();
\r
338 public bool UseRunas {
\r
340 runasCheckBox.Checked = (! NaGet.Utils.IsAdministrators()) && value;
\r
345 return runasCheckBox.Checked;
\r
350 /// 選択されたパッケージを調査して、Runasを使うべきかいなかを返す
\r
352 public bool GetShouldUseRunas()
\r
354 if (NaGet.Utils.IsAdministrators()) {
\r
355 // 管理者権限で動いている場合は不要
\r
357 } else if (NaGet.Utils.IsUACEnabled()) {
\r
358 // UACが適用されている場合は標準では不要とする
\r
362 // ひとつでもPCターゲットなインストーラがあれば必要とする
\r
363 foreach (Installation inst in CheckedInstallations) {
\r
364 if (inst.TargetPC) return true;
\r
370 void RunasCheckBoxCheckedChanged(object sender, EventArgs e)
\r
375 private void updateUseRunas()
\r
378 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InstallationConfirmForm));
\r
379 okButton.Image = ((System.Drawing.Bitmap)(resources.GetObject("okButton.Image")));
\r
381 okButton.Image = null;
\r