X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;ds=sidebyside;f=AppliStation%2FInstallationConfirmForm.cs;h=4233484cae3299d4b6415ea3daa2492da0720a0b;hb=817145a5290ce2f6f238b03b27c4b0aeb1c09e9f;hp=13f812feecd154678e4ad5434fd3cc41565fbe4e;hpb=b6930a26b129b060e618fc71d0dd4cde15ed4aaa;p=applistation%2FAppliStation.git diff --git a/AppliStation/InstallationConfirmForm.cs b/AppliStation/InstallationConfirmForm.cs index 13f812f..4233484 100644 --- a/AppliStation/InstallationConfirmForm.cs +++ b/AppliStation/InstallationConfirmForm.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using NaGet.Packages; @@ -11,17 +12,35 @@ namespace AppliStation /// public partial class InstallationConfirmForm : Form { - private Installation[] installations; + private Installation[] selectedInstallations = null; - private PackageListsManager pkgListMan; + private Installation[] updateInstallations = null; - /// - /// ƒpƒbƒP[ƒWƒCƒ“ƒXƒg[ƒ‹ˆ—‚̏W‡ - /// - public Installation[] Installations { - get { return installations; } + private Installation[] requiredInstallations = null; + + private PackageListsManager pkgListMan; + + public IEnumerable Installations { + get { + return NaGet.Utils.MergeEnumerable(requiredInstallations, selectedInstallations); + } set { - installations = value; + List selectedInstList = new List(); + List updateInstList = new List(); + + requiredInstallations = null; + foreach (Installation inst in value) { + Package instPkg = pkgListMan.InstalledPkgList.GetPackageForName(inst.InstalledPackage.Name) ?? + pkgListMan.SystemInstalledPkgList.GetPackageForName(inst.InstalledPackage.Name); + + if (instPkg != null) { + updateInstList.Add(inst); + } else { + selectedInstList.Add(inst); + } + } + selectedInstallations = selectedInstList.ToArray(); + updateInstallations = updateInstList.ToArray(); updateInstsListView(); } @@ -43,87 +62,173 @@ namespace AppliStation // InitializeComponent(); - // ŠÇ—ŽÒŒ ŒÀ‚Å“®‚¢‚Ä‚¢‚é‚È‚ç‚Îrunas‚ª•K—v‚É‚Í‚È‚ç‚È‚¢‚Ì‚Å•\Ž¦‚µ‚È‚¢ + // 管理者権限で動いているならばrunasが必要にはならないので表示しない if (NaGet.Utils.IsAdministrators()) { runasCheckBox.Checked = false; runasCheckBox.Visible = false; } + + // ListViewの効果 + AppliStation.Util.NativeMethods.ListView_EnableVistaExplorerTheme(instsListView); + AppliStation.Util.NativeMethods.ListView_SetDoubleBuffer(instsListView, true); } + #region インストールリスト表示処理部 + + #region インストールリストの反映 + + /// + /// インストールリストを更新したなどで、リストの表示を更新する + /// private void updateInstsListView() { - instsListView.Items.Clear(); + instsListView.BeginUpdate(); - if (installations != null) { - foreach (Installation inst in installations) { - Package pkg = inst.InstalledPackage; - - string[] itemData = new string[instsListView.Columns.Count]; - itemData[nameColumnHeader.Index] = pkg.Name; - - Package curPkg = null; - if (pkgListMan != null) { - curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ?? - pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name); - } - itemData[versionColumnHeader.Index] = pkg.Version; - itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-"; - - itemData[instOptsColumnHeader.Index] = inst.Silent? "ƒTƒCƒŒƒ“ƒg" : string.Empty; - - ListViewItem item = new ListViewItem(itemData); - item.Tag = inst; - item.ToolTipText = pkg.Summary; - item.Checked = true; - - instsListView.Items.Add(item); - } + if (instsListView.Items.Count > 0) { + instsListView.Items.Clear(); } + addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true); + addInstsListItemPerGroup(selectedInstallations, instsListView.Groups["install"], false); + addInstsListItemPerGroup(updateInstallations, instsListView.Groups["update"], false); + InstsListViewItemChecked(instsListView, null); - instsListView.Refresh(); - } - - void InstsListViewItemChecked(object sender, ItemCheckedEventArgs e) - { - System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = instsListView.CheckedItems; + updateSilentInstallAsPossibleCheckBox(); - okButton.Enabled = checkeds != null && checkeds.Count > 0; + instsListView.EndUpdate(); } - - AppliStation.Util.ListViewItemSortComparer packageListViewSortComparer; - void InstsListViewColumnClick(object sender, ColumnClickEventArgs e) + /// + /// 指定したグループのリストの表示を更新する。 + /// + /// インストールリスト + /// 対象のグループ + /// 先頭に追加するか + private void addInstsListItemPerGroup(IEnumerable insts, ListViewGroup group, bool firstAppend) { - SortOrder order = SortOrder.None; + // まず所属グループのアイテムをすべて削除する + if (insts == null) return; - if (packageListViewSortComparer == null) { - order = SortOrder.Ascending; - packageListViewSortComparer = new AppliStation.Util.ListViewItemSortComparer(e.Column, order); - instsListView.ListViewItemSorter = packageListViewSortComparer; - } else { - if (packageListViewSortComparer.Column == e.Column) { - order = (packageListViewSortComparer.Order == SortOrder.Ascending)? SortOrder.Descending : SortOrder.Ascending; - - packageListViewSortComparer.Order = order; - } else { - order = packageListViewSortComparer.Order; - packageListViewSortComparer.Column = e.Column; + List itemsToAdd = new List(); + foreach (Installation inst in insts) { + Package pkg = inst.InstalledPackage; + + string[] itemData = new string[instsListView.Columns.Count]; + itemData[nameColumnHeader.Index] = pkg.Name; + + inst.Silent = true; // silent install as possible! + + Package curPkg = null; + if (pkgListMan != null) { + curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ?? + pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name); } + itemData[versionColumnHeader.Index] = pkg.Version; + itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-"; + // itemData[silentInstColumnHeader.Index] の設定は instViewUpdateSilentInstallView で + itemData[pkgListNameColumnHeader.Index] = pkg.PackageListName; + + ListViewItem item = new ListViewItem(itemData); + item.Tag = inst; + item.ToolTipText = pkg.Summary; + item.Checked = true; + item.Group = group; + instViewUpdateSilentInstallView(item); - instsListView.Sort(); + itemsToAdd.Add(item); } - AppliStation.Util.NativeMethods.ColumnHeader_SetSortState(instsListView, e.Column, order); - // ƒ\[ƒg‘Ώۗñ‚̐F•t‚¯ - try { - // SendMessage(hWnd, LVM_SETSELECTEDCOLUMN, column, NULL); - AppliStation.Util.NativeMethods.SendMessage(instsListView.Handle, 0x1000+140, (uint) e.Column, 0); - } catch (Exception) { + if (firstAppend) { + for (int i = 0; i < itemsToAdd.Count; i++) { + instsListView.Items.Insert(i, itemsToAdd[i]); + } + } else { + instsListView.Items.AddRange(itemsToAdd.ToArray()); } } + + #endregion + + /// + /// アイテムのサイレントインストール部分の表示の更新を行う。 + /// + /// 対象のインストーラーのリストアイテム + private void instViewUpdateSilentInstallView(ListViewItem item) + { + Installation inst = (Installation) item.Tag; + item.SubItems[silentInstColumnHeader.Index].Text = + (inst.SupportsSilentOnly)? "サイレントインストールのみサポート" : + (inst.Silent)? "サイレントインストール" : + (inst.IsSupportsSilent)? "手動でインストール" : + "サイレントインストールできませんので、手動でインストールします"; + } + #region instsListViewのオーナードドロー関連 + + void InstsListViewDrawSubItem(object sender, DrawListViewSubItemEventArgs e) + { + if (e.Header == silentInstColumnHeader) { + Installation inst = ((Installation) e.Item.Tag); + //e.DrawBackground(); + e.Graphics.Clip.Intersect(e.Bounds); + + if (inst.Silent) { + AppliStation.Util.GUIUtils.Graphics_DrawCenterImage( + e.Graphics, + instListViewSilentInstallImageList.Images[0], + e.Bounds, null); + } else if (inst.IsSupportsSilent) { + AppliStation.Util.GUIUtils.Graphics_DrawCenterImage( + e.Graphics, + instListViewSilentInstallImageList.Images[0], + e.Bounds, + AppliStation.Util.GUIUtils.GetImageAttributeToGrayOut(0.5f)); + } + } else { + e.DrawDefault = true; + } + } + + void InstsListViewDrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e) + { + if (e.Header == silentInstColumnHeader) { + e.DrawBackground(); + e.Graphics.Clip.Intersect(e.Bounds); + AppliStation.Util.GUIUtils.Graphics_DrawCenterImage( + e.Graphics, + instListViewSilentInstallImageList.Images[0], + e.Bounds, null); + } else { + e.DrawDefault = true; + } + } + + #endregion + + #endregion + + void InstsListViewItemChecked(object sender, ItemCheckedEventArgs e) + { + System.Windows.Forms.ListView.ListViewItemCollection items = instsListView.Items; + System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = instsListView.CheckedItems; + + // すべて選択/非選択 + selectAllCheckBox.CheckState = + (checkeds == null || checkeds.Count == 0)? CheckState.Unchecked : + (checkeds.Count == items.Count)? CheckState.Checked : + CheckState.Indeterminate; + + // runas情報 + runasCheckBox.Checked = GetShouldUseRunas(); + updateUseRunas(); + + // インストール可能か + okButton.Enabled = (checkeds != null) && (checkeds.Count > 0); + + checkUnselectedDependencies(); + } + void InstsListViewContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e) { System.Windows.Forms.ListView.CheckedIndexCollection chkIdxes = instsListView.CheckedIndices; @@ -147,45 +252,169 @@ namespace AppliStation break; } } + } else { + e.Cancel = true; } - instListToolStripSeparator.Visible = selIdxes.Count > 0; - - - selectAllInstsStripMenuItem.Enabled = chkIdxes.Count < instsListView.Items.Count; - unselectAllInstsStripMenuItem.Enabled = chkIdxes.Count > 0; } void SilentInstallStripMenuItemClick(object sender, EventArgs e) { + instsListView.BeginUpdate(); bool silent = ! silentInstallStripMenuItem.Checked; - foreach (ListViewItem item in instsListView.CheckedItems) { + foreach (ListViewItem item in instsListView.SelectedItems) { ((Installation) item.Tag).Silent = silent; + instViewUpdateSilentInstallView(item); } - updateInstsListView(); + updateSilentInstallAsPossibleCheckBox(); + instsListView.EndUpdate(); } - - void SelectAllInstsStripMenuItemClick(object sender, EventArgs e) + + void SelectAllCheckBoxCheckedChanged(object sender, EventArgs e) + { + instsListView.BeginUpdate(); + if (selectAllCheckBox.CheckState == CheckState.Checked) { + foreach (ListViewItem item in instsListView.Items) { + item.Checked = true; + } + } + if (selectAllCheckBox.CheckState == CheckState.Unchecked) { + foreach (ListViewItem item in instsListView.Items) { + item.Checked = false; + } + } + instsListView.EndUpdate(); + } + + void updateSilentInstallAsPossibleCheckBox() { + bool isAllSilentAsPossible = true; + bool isAllNotSilentAsPossible = true; + bool canChangeSilent = false; + foreach (ListViewItem item in instsListView.Items) { - item.Checked = true; + Installation inst = item.Tag as Installation; + if (inst != null) { + if (inst.Silent) { + if (! inst.SupportsSilentOnly) { + isAllNotSilentAsPossible = false; + canChangeSilent = true; + } + } else { + if (inst.IsSupportsSilent) { + isAllSilentAsPossible = false; + canChangeSilent = true; + } + } + } } - instsListView.Refresh(); + + silentInstallAsPossibleCheckBox.Enabled = canChangeSilent; + silentInstallAsPossibleCheckBox.CheckState = + (isAllSilentAsPossible)? CheckState.Checked : + (isAllNotSilentAsPossible)? CheckState.Unchecked : + CheckState.Indeterminate; } - void UnselectAllInstsStripMenuItemClick(object sender, EventArgs e) + void SilentInstallAsPossibleCheckBoxCheckedChanged(object sender, EventArgs e) { - foreach (ListViewItem item in instsListView.CheckedItems) { - item.Checked = false; + instsListView.BeginUpdate(); + if (silentInstallAsPossibleCheckBox.CheckState == CheckState.Checked) { + foreach (ListViewItem item in instsListView.Items) { + Installation inst = item.Tag as Installation; + if (inst != null) { + if (inst.IsSupportsSilent && inst.Silent == false) { + inst.Silent = true; + instViewUpdateSilentInstallView(item); + } + } + } + } + if (silentInstallAsPossibleCheckBox.CheckState == CheckState.Unchecked) { + foreach (ListViewItem item in instsListView.Items) { + Installation inst = item.Tag as Installation; + if (inst != null) { + if ((!inst.SupportsSilentOnly) && inst.Silent == true) { + inst.Silent = false; + instViewUpdateSilentInstallView(item); + } + } + } + } + instsListView.EndUpdate(); + } + + void InstallationConfirmFormShown(object sender, EventArgs e) + { + if (InvokeRequired) { + Invoke(new MethodInvoker(resolveDependecies)); + } else { + resolveDependecies(); } - instsListView.Refresh(); } /// - /// ƒCƒ“ƒXƒg[ƒ‹‚·‚é‚悤‘I‘ð‚³‚ê‚½ƒpƒbƒP[ƒW‚Ì”z—ñ + /// 依存関係を解決する + /// + private void resolveDependecies() + { + if (requiredInstallations == null) { + Installation[] resolved, dependencies; + + instsListView.BeginUpdate(); + + DependeciesResolver.ResolveInstallations( + selectedInstallations, + pkgListMan, + out resolved, + out dependencies); + + requiredInstallations = dependencies; + + addInstsListItemPerGroup(requiredInstallations, instsListView.Groups["requires"], true); + + InstsListViewItemChecked(instsListView, null); + updateSilentInstallAsPossibleCheckBox(); + instsListView.EndUpdate(); + } + } + + /// + /// 依存関係を確認してGUIに反映させる。 + /// 選択されていないが依存関係上必要なソフトを探し出す。 + /// + /// 選択されていないが依存関係上必要なソフトの個数(何もない場合はゼロ) + private uint checkUnselectedDependencies() + { + uint retVal = 0; + + List instPkgs = new List(); + foreach (Installation inst in Installations) { + instPkgs.Add(inst.InstalledPackage); + } + + List pkg = new List(); + foreach (Installation inst in DependeciesResolver.CreateRequiresInstallations(CheckedInstallations, pkgListMan, instPkgs)) { + pkg.Add(inst.InstalledPackage); + } + + foreach (ListViewItem item in instsListView.Items) { + if ((pkg.IndexOf(((Installation) item.Tag).InstalledPackage) >= 0) && !item.Checked) { + item.ForeColor = Color.Red; + retVal++; + } else { + item.ForeColor = Color.Empty; + } + + } + return retVal; + } + + /// + /// インストールするよう選択されたパッケージの配列 /// public Installation[] CheckedInstallations { get { - System.Collections.Generic.List insts = new System.Collections.Generic.List(); + List insts = new List(); foreach (ListViewItem item in instsListView.CheckedItems) { insts.Add((Installation) item.Tag); } @@ -193,10 +422,10 @@ namespace AppliStation } } - #region runasŠÖ˜A + #region runas関連 /// - /// runas‚ÅŽÀs‚·‚é‚©”Û‚© + /// runasで実行するか否か /// public bool UseRunas { set { @@ -210,23 +439,23 @@ namespace AppliStation } /// - /// ‘I‘ð‚³‚ê‚½ƒpƒbƒP[ƒW‚𒲍¸‚µ‚āARunas‚ðŽg‚¤‚ׂ«‚©‚¢‚È‚©‚ð•Ô‚· + /// 選択されたパッケージを調査して、Runasを使うべきかいなかを返す /// public bool GetShouldUseRunas() { if (NaGet.Utils.IsAdministrators()) { - // ŠÇ—ŽÒŒ ŒÀ‚Å“®‚¢‚Ä‚¢‚éê‡‚Í•s—v - return false; + // 管理者権限で動いている場合は不要 + return false; } else if (NaGet.Utils.IsUACEnabled()) { - // UAC‚ª“K—p‚³‚ê‚Ä‚¢‚éê‡‚Í•W€‚Å‚Í•s—v‚Æ‚·‚é - return false; + // UACが適用されている場合は標準では不要とする + return false; } - // ‚ЂƂ‚łàPCƒ^[ƒQƒbƒg‚ȃCƒ“ƒXƒg[ƒ‰‚ª‚ ‚ê‚ΕK—v‚Æ‚·‚é + // ひとつでもPCターゲットなインストーラーがあれば必要とする foreach (Installation inst in CheckedInstallations) { if (inst.TargetPC) return true; } - // ‚»‚êˆÈŠO‚Í•s—v + // それ以外は不要 return false; } @@ -237,12 +466,7 @@ namespace AppliStation private void updateUseRunas() { - if (UseRunas) { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InstallationConfirmForm)); - okButton.Image = ((System.Drawing.Bitmap)(resources.GetObject("okButton.Image"))); - } else { - okButton.Image = null; - } + AppliStation.Util.NativeMethods.Button_SetElevationRequiredState(okButton, UseRunas); } #endregion