using System;\r
+using System.Collections.Generic;\r
using System.Drawing;\r
using System.Windows.Forms;\r
using NaGet.Packages;\r
/// </summary>\r
public partial class InstallationConfirmForm : Form\r
{\r
- private Installation[] installations;\r
+ private Installation[] selectedInstallations = null;\r
\r
- private PackageListsManager pkgListMan;\r
+ private Installation[] updateInstallations = null;\r
\r
- /// <summary>\r
- /// パッケージインストール処理の集合\r
- /// </summary>\r
- public Installation[] Installations {\r
- get { return installations; }\r
+ private Installation[] requiredInstallations = null;\r
+ \r
+ private PackageListsManager pkgListMan;\r
+\r
+ public IEnumerable<Installation> Installations {\r
+ get {\r
+ return NaGet.Utils.MergeEnumerable<Installation>(requiredInstallations, selectedInstallations);\r
+ }\r
set {\r
- installations = value;\r
+ List<Installation> selectedInstList = new List<Installation>();\r
+ List<Installation> updateInstList = new List<Installation>();\r
\r
- // 基本はサイレントインストールを行うこととする\r
- foreach (Installation inst in installations) {\r
- inst.Silent = inst.IsSupportsSilent;\r
+ requiredInstallations = null;\r
+ foreach (Installation inst in value) {\r
+ Package instPkg = pkgListMan.InstalledPkgList.GetPackageForName(inst.InstalledPackage.Name) ??\r
+ pkgListMan.SystemInstalledPkgList.GetPackageForName(inst.InstalledPackage.Name);\r
+ \r
+ if (instPkg != null) {\r
+ updateInstList.Add(inst);\r
+ } else {\r
+ selectedInstList.Add(inst);\r
+ }\r
}\r
+ selectedInstallations = selectedInstList.ToArray();\r
+ updateInstallations = updateInstList.ToArray();\r
\r
updateInstsListView();\r
}\r
runasCheckBox.Checked = false;\r
runasCheckBox.Visible = false;\r
}\r
+ \r
+ // ListViewの効果\r
+ AppliStation.Util.NativeMethods.ListView_EnableVistaExplorerTheme(instsListView);\r
+ AppliStation.Util.NativeMethods.ListView_SetDoubleBuffer(instsListView, true);\r
}\r
\r
+ #region インストールリスト表示処理部\r
+ \r
+ #region インストールリストの反映\r
+ \r
/// <summary>\r
/// インストールリストを更新したなどで、リストの表示を更新する\r
/// </summary>\r
private void updateInstsListView()\r
{\r
- instsListView.Items.Clear();\r
- \r
- if (installations != null) {\r
- foreach (Installation inst in installations) {\r
- Package pkg = inst.InstalledPackage;\r
- \r
- string[] itemData = new string[instsListView.Columns.Count];\r
- itemData[nameColumnHeader.Index] = pkg.Name;\r
- \r
- Package curPkg = null;\r
- if (pkgListMan != null) { \r
- curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ??\r
- pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name);\r
- }\r
- itemData[versionColumnHeader.Index] = pkg.Version;\r
- itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-";\r
- // itemData[silentInstColumnHeader.Index] の設定は instViewUpdateSilentInstallView で\r
- \r
- ListViewItem item = new ListViewItem(itemData);\r
- item.Tag = inst;\r
- item.ToolTipText = pkg.Summary;\r
- item.Checked = true;\r
- instViewUpdateSilentInstallView(item);\r
- \r
- instsListView.Items.Add(item);\r
- }\r
+ if (instsListView.Items.Count > 0) {\r
+ instsListView.Items.Clear();\r
}\r
\r
+ addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);\r
+ addInstsListItemPerGroup(selectedInstallations, instsListView.Groups["install"], false);\r
+ addInstsListItemPerGroup(updateInstallations, instsListView.Groups["update"], false);\r
+ \r
InstsListViewItemChecked(instsListView, null);\r
instsListView.Refresh();\r
}\r
+\r
+ /// <summary>\r
+ /// 指定したグループのリストの表示を更新する。\r
+ /// </summary>\r
+ /// <param name="insts">インストールリスト</param>\r
+ /// <param name="group">対象のグループ</param>\r
+ /// <param name="firstAppend">先頭に追加するか</param>\r
+ private void addInstsListItemPerGroup(IEnumerable<Installation> insts, ListViewGroup group, bool firstAppend)\r
+ {\r
+ // まず所属グループのアイテムをすべて削除する\r
+ if (insts == null) return;\r
+ \r
+ List<ListViewItem> itemsToAdd = new List<ListViewItem>();\r
+ foreach (Installation inst in insts) {\r
+ Package pkg = inst.InstalledPackage;\r
+ \r
+ string[] itemData = new string[instsListView.Columns.Count];\r
+ itemData[nameColumnHeader.Index] = pkg.Name;\r
+ \r
+ inst.Silent = true; // silent install as possible!\r
+ \r
+ Package curPkg = null;\r
+ if (pkgListMan != null) { \r
+ curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ??\r
+ pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name);\r
+ }\r
+ itemData[versionColumnHeader.Index] = pkg.Version;\r
+ itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-";\r
+ // itemData[silentInstColumnHeader.Index] の設定は instViewUpdateSilentInstallView で\r
+ itemData[pkgListNameColumnHeader.Index] = pkg.PackageListName;\r
+ \r
+ ListViewItem item = new ListViewItem(itemData);\r
+ item.Tag = inst;\r
+ item.ToolTipText = pkg.Summary;\r
+ item.Checked = true;\r
+ item.Group = group;\r
+ instViewUpdateSilentInstallView(item);\r
+ \r
+ itemsToAdd.Add(item);\r
+ }\r
+ \r
+ if (firstAppend) {\r
+ for (int i = 0; i < itemsToAdd.Count; i++) {\r
+ instsListView.Items.Insert(i, itemsToAdd[i]);\r
+ }\r
+ } else {\r
+ instsListView.Items.AddRange(itemsToAdd.ToArray());\r
+ }\r
+ }\r
+\r
+ #endregion\r
\r
/// <summary>\r
/// アイテムのサイレントインストール部分の表示の更新を行う。\r
\r
#endregion\r
\r
+ #endregion\r
+ \r
void InstsListViewItemChecked(object sender, ItemCheckedEventArgs e)\r
{\r
System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = instsListView.CheckedItems;\r
\r
- okButton.Enabled = checkeds != null && checkeds.Count > 0;\r
- }\r
- \r
- AppliStation.Util.ListViewItemSortComparer packageListViewSortComparer;\r
-\r
- void InstsListViewColumnClick(object sender, ColumnClickEventArgs e)\r
- {\r
- SortOrder order = SortOrder.None;\r
- \r
- if (packageListViewSortComparer == null) {\r
- order = SortOrder.Ascending;\r
- packageListViewSortComparer = new AppliStation.Util.ListViewItemSortComparer(e.Column, order);\r
- instsListView.ListViewItemSorter = packageListViewSortComparer;\r
- } else {\r
- if (packageListViewSortComparer.Column == e.Column) {\r
- order = (packageListViewSortComparer.Order == SortOrder.Ascending)? SortOrder.Descending : SortOrder.Ascending;\r
- \r
- packageListViewSortComparer.Order = order;\r
- } else {\r
- order = packageListViewSortComparer.Order;\r
- packageListViewSortComparer.Column = e.Column;\r
- }\r
- \r
- instsListView.Sort();\r
- }\r
- AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(instsListView, e.Column, order);\r
+ runasCheckBox.Checked = GetShouldUseRunas();\r
+ updateUseRunas();\r
+ \r
+ okButton.Enabled = (checkeds != null) && (checkeds.Count > 0);\r
\r
- // ソート対象列の色付け\r
- try {\r
- // SendMessage(hWnd, LVM_SETSELECTEDCOLUMN, column, NULL);\r
- AppliStation.Util.NativeMethods.SendMessage(instsListView.Handle, 0x1000+140, (uint) e.Column, 0);\r
- } catch (Exception) { \r
- }\r
+ checkUnselectedDependencies();\r
}\r
- \r
\r
void InstsListViewContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)\r
{\r
}\r
instsListView.Refresh();\r
}\r
+\r
+ void InstallationConfirmFormShown(object sender, EventArgs e)\r
+ {\r
+ if (InvokeRequired) {\r
+ Invoke(new MethodInvoker(resolveDependecies));\r
+ } else {\r
+ resolveDependecies();\r
+ }\r
+ }\r
+ \r
+ /// <summary>\r
+ /// 依存関係を解決する\r
+ /// </summary>\r
+ private void resolveDependecies()\r
+ {\r
+ if (requiredInstallations == null) {\r
+ Installation[] resolved, dependencies;\r
+ \r
+ DependeciesResolver.ResolveInstallations(\r
+ selectedInstallations,\r
+ pkgListMan,\r
+ out resolved,\r
+ out dependencies);\r
+ \r
+ requiredInstallations = dependencies;\r
+ \r
+ addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true);\r
+ \r
+ InstsListViewItemChecked(instsListView, null);\r
+ instsListView.Refresh();\r
+ }\r
+ }\r
+ \r
+ /// <summary>\r
+ /// 依存関係を確認してGUIに反映させる。\r
+ /// 選択されていないが依存関係上必要なソフトを探し出す。\r
+ /// </summary>\r
+ /// <returns>選択されていないが依存関係上必要なソフトの個数(何もない場合はゼロ)</returns>\r
+ private uint checkUnselectedDependencies()\r
+ {\r
+ uint retVal = 0;\r
+ \r
+ List<Package> instPkgs = new List<Package>();\r
+ foreach (Installation inst in Installations) {\r
+ instPkgs.Add(inst.InstalledPackage);\r
+ }\r
+ \r
+ List<Package> pkg = new List<Package>();\r
+ foreach (Installation inst in DependeciesResolver.CreateRequiresInstallations(CheckedInstallations, pkgListMan, instPkgs)) {\r
+ pkg.Add(inst.InstalledPackage);\r
+ }\r
+ \r
+ foreach (ListViewItem item in instsListView.Items) {\r
+ if ((pkg.IndexOf(((Installation) item.Tag).InstalledPackage) >= 0) && !item.Checked) {\r
+ item.ForeColor = Color.Red;\r
+ retVal++;\r
+ } else {\r
+ item.ForeColor = Color.Empty;\r
+ }\r
+ \r
+ }\r
+ return retVal;\r
+ }\r
\r
/// <summary>\r
/// インストールするよう選択されたパッケージの配列\r
/// </summary>\r
public Installation[] CheckedInstallations {\r
get {\r
- System.Collections.Generic.List<Installation> insts = new System.Collections.Generic.List<Installation>();\r
+ List<Installation> insts = new List<Installation>();\r
foreach (ListViewItem item in instsListView.CheckedItems) {\r
insts.Add((Installation) item.Tag);\r
}\r
}\r
\r
#endregion\r
- \r
}\r
}\r