OSDN Git Service

AppliStation-GUI,インストールダイアログでの表示処理等の整理
[applistation/AppliStation.git] / AppliStation / InstallationConfirmForm.cs
1 using System;\r
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
7 \r
8 namespace AppliStation\r
9 {\r
10         /// <summary>\r
11         /// Description of PackagesInstallConfirmForm.\r
12         /// </summary>\r
13         public partial class InstallationConfirmForm : Form\r
14         {\r
15                 private Installation[] requiredInstallations = null;\r
16                 \r
17                 private Installation[] selectedInstallations = null;\r
18                 \r
19                 private PackageListsManager pkgListMan;\r
20 \r
21                 public IEnumerable<Installation> Installations {\r
22                         get {\r
23                                 return NaGet.Utils.MeargeEnumerable<Installation>(requiredInstallations, selectedInstallations);\r
24                         }\r
25                         set {\r
26                                 requiredInstallations = null;\r
27                                 selectedInstallations = NaGet.Utils.IEnumerable2Array<Installation>(value);\r
28                                 \r
29                                 updateInstsListView();\r
30                         }\r
31                 }\r
32                 \r
33                 public PackageListsManager PkgListsManager {\r
34                         get { return pkgListMan; }\r
35                         set {\r
36                                 pkgListMan = value;\r
37                                 \r
38                                 updateInstsListView();\r
39                         }\r
40                 }\r
41                 \r
42                 public InstallationConfirmForm()\r
43                 {\r
44                         //\r
45                         // The InitializeComponent() call is required for Windows Forms designer support.\r
46                         //\r
47                         InitializeComponent();\r
48                         \r
49                         // 管理者権限で動いているならばrunasが必要にはならないので表示しない\r
50                         if (NaGet.Utils.IsAdministrators()) {\r
51                                 runasCheckBox.Checked = false;\r
52                                 runasCheckBox.Visible = false;\r
53                         }\r
54                         \r
55                         // ListViewの効果\r
56                         AppliStation.Util.NativeMethods.ListView_EnableVistaExplorerTheme(instsListView);\r
57                         AppliStation.Util.NativeMethods.ListView_SetDoubleBuffer(instsListView, true);\r
58                 }\r
59                 \r
60                 /// <summary>\r
61                 /// インストールリストを更新したなどで、リストの表示を更新する\r
62                 /// </summary>\r
63                 private void updateInstsListView()\r
64                 {\r
65                         instsListView.Items.Clear();\r
66                         \r
67                         updateInstsListViewPerGroup(selectedInstallations, instsListView.Groups["install"]);\r
68 \r
69 \r
70 \r
71 \r
72 \r
73 \r
74 \r
75 \r
76 \r
77 \r
78 \r
79 \r
80 \r
81 \r
82 \r
83 \r
84 \r
85 \r
86 \r
87 \r
88 \r
89 \r
90 \r
91 \r
92 \r
93                         \r
94                         InstsListViewItemChecked(instsListView, null);\r
95                         instsListView.Refresh();\r
96                 }\r
97 \r
98                 /// <summary>\r
99                 /// 指定したグループのリストの表示を更新する。\r
100                 /// </summary>\r
101                 /// <param name="insts">インストールリスト</param>\r
102                 /// <param name="group">対象のグループ</param>\r
103                 private void updateInstsListViewPerGroup(IEnumerable<Installation> insts, ListViewGroup group)\r
104                 {\r
105                         // まず所属グループのアイテムをすべて削除する\r
106                         group.Items.Clear();\r
107                         \r
108                         if (insts == null) return;\r
109                         \r
110                         foreach (Installation inst in insts) {\r
111                                 Package pkg = inst.InstalledPackage;\r
112                                 \r
113                                 string[] itemData = new string[instsListView.Columns.Count];\r
114                                 itemData[nameColumnHeader.Index] = pkg.Name;\r
115                                 \r
116                                 Package curPkg = null;\r
117                                 if (pkgListMan != null) {       \r
118                                         curPkg = pkgListMan.InstalledPkgList.GetPackageForName(pkg.Name) ??\r
119                                                 pkgListMan.SystemInstalledPkgList.GetPackageForName(pkg.Name);\r
120                                 }\r
121                                 itemData[versionColumnHeader.Index]        = pkg.Version;\r
122                                 itemData[currentVersionColumnHeader.Index] = (curPkg != null)? curPkg.Version : "-";\r
123                                 // itemData[silentInstColumnHeader.Index] の設定は instViewUpdateSilentInstallView で\r
124                                 \r
125                                 ListViewItem item = new ListViewItem(itemData);\r
126                                 item.Tag = inst;\r
127                                 item.ToolTipText = pkg.Summary;\r
128                                 item.Checked = true;\r
129                                 item.Group = group;\r
130                                 instViewUpdateSilentInstallView(item);\r
131                                 \r
132                                 instsListView.Items.Add(item);\r
133                         }\r
134                 }\r
135                 \r
136                 /// <summary>\r
137                 /// アイテムのサイレントインストール部分の表示の更新を行う。\r
138                 /// </summary>\r
139                 /// <param name="item">対象のインストーラのリストアイテム</param>\r
140                 private void instViewUpdateSilentInstallView(ListViewItem item)\r
141                 {\r
142                         Installation inst = (Installation) item.Tag;\r
143                         item.SubItems[silentInstColumnHeader.Index].Text =\r
144                                 (inst.SupportsSilentOnly)? "サイレントインストールのみサポート" :\r
145                                 (inst.Silent)? "サイレントインストール" :\r
146                                 (inst.IsSupportsSilent)? "手動でインストール" :\r
147                                 "サイレントインストールできませんので、手動でインストールします";\r
148                 }\r
149                 \r
150                 #region instsListViewのオーナードドロー関連\r
151                 \r
152                 void InstsListViewDrawSubItem(object sender, DrawListViewSubItemEventArgs e)\r
153                 {\r
154                         if (e.Header == silentInstColumnHeader) {\r
155                                 Installation inst = ((Installation) e.Item.Tag);\r
156                                 \r
157                                 //e.DrawBackground();\r
158                                 e.Graphics.Clip.Intersect(e.Bounds);\r
159                                 \r
160                                 if (inst.Silent) {\r
161                                         AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(\r
162                                                 e.Graphics,\r
163                                                 instListViewSilentInstallImageList.Images[0],\r
164                                                 e.Bounds, null);\r
165                                 } else if (inst.IsSupportsSilent) {\r
166                                         AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(\r
167                                                 e.Graphics,\r
168                                                 instListViewSilentInstallImageList.Images[0],\r
169                                                 e.Bounds,\r
170                                                 AppliStation.Util.GUIUtils.GetImageAttributeToGrayOut(0.5f));\r
171                                 }\r
172                         } else {\r
173                                 e.DrawDefault = true;\r
174                         }\r
175                 }\r
176                 \r
177                 void InstsListViewDrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)\r
178                 {\r
179                         if (e.Header == silentInstColumnHeader) {\r
180                                 e.DrawBackground();\r
181                                 e.Graphics.Clip.Intersect(e.Bounds);\r
182                                 AppliStation.Util.GUIUtils.Graphics_DrawCenterImage(\r
183                                         e.Graphics,\r
184                                         instListViewSilentInstallImageList.Images[0],\r
185                                         e.Bounds, null);\r
186                         } else {\r
187                                 e.DrawDefault = true;\r
188                         }\r
189                 }\r
190                 \r
191                 #endregion\r
192                 \r
193                 void InstsListViewItemChecked(object sender, ItemCheckedEventArgs e)\r
194                 {\r
195                         System.Windows.Forms.ListView.CheckedListViewItemCollection checkeds = instsListView.CheckedItems;\r
196                         \r
197                         okButton.Enabled = checkeds != null && checkeds.Count > 0;\r
198                 }\r
199                                 \r
200                 void InstsListViewContextMenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)\r
201                 {\r
202                         System.Windows.Forms.ListView.CheckedIndexCollection  chkIdxes = instsListView.CheckedIndices;\r
203                         System.Windows.Forms.ListView.SelectedIndexCollection selIdxes = instsListView.SelectedIndices;\r
204                         \r
205                         silentInstallStripMenuItem.Visible = selIdxes.Count > 0;\r
206                         if (selIdxes.Count > 0) {\r
207                                 Installation inst0th = ((Installation) instsListView.Items[selIdxes[0]].Tag);\r
208                                 bool bChecked = inst0th.Silent;\r
209                                 bool bEnabled = (inst0th.IsSupportsSilent && (!inst0th.SupportsSilentOnly));\r
210                                 silentInstallStripMenuItem.Checked = bChecked;\r
211                                 silentInstallStripMenuItem.Enabled = bEnabled;\r
212                                 \r
213                                 for (int i = 1; i < selIdxes.Count; i++) {\r
214                                         Installation inst = ((Installation) instsListView.Items[selIdxes[i]].Tag);\r
215                                         \r
216                                         if ( (bChecked != inst.Silent) ||\r
217                                             (bEnabled != (inst.IsSupportsSilent && (!inst.SupportsSilentOnly))) ) {\r
218                                                 silentInstallStripMenuItem.CheckState = CheckState.Indeterminate;\r
219                                                 silentInstallStripMenuItem.Enabled = false;\r
220                                                 break;\r
221                                         }\r
222                                 }\r
223                         }\r
224                         instListToolStripSeparator.Visible = selIdxes.Count > 0;\r
225                 \r
226                         \r
227                         selectAllInstsStripMenuItem.Enabled = chkIdxes.Count < instsListView.Items.Count;\r
228                         unselectAllInstsStripMenuItem.Enabled = chkIdxes.Count > 0;\r
229                 }\r
230                 \r
231                 void SilentInstallStripMenuItemClick(object sender, EventArgs e)\r
232                 {\r
233                         bool silent = ! silentInstallStripMenuItem.Checked;\r
234                         foreach (ListViewItem item in instsListView.SelectedItems) {\r
235                                 ((Installation) item.Tag).Silent = silent;\r
236                                 instViewUpdateSilentInstallView(item);\r
237                         }\r
238                 }\r
239                                 \r
240                 void SelectAllInstsStripMenuItemClick(object sender, EventArgs e)\r
241                 {\r
242                         foreach (ListViewItem item in instsListView.Items) {\r
243                                 item.Checked = true;\r
244                         }\r
245                         instsListView.Refresh();\r
246                 }\r
247                 \r
248                 void UnselectAllInstsStripMenuItemClick(object sender, EventArgs e)\r
249                 {\r
250                         foreach (ListViewItem item in instsListView.CheckedItems) {\r
251                                 item.Checked = false;\r
252                         }\r
253                         instsListView.Refresh();\r
254                 }\r
255                 \r
256                 /// <summary>\r
257                 /// インストールするよう選択されたパッケージの配列\r
258                 /// </summary>\r
259                 public Installation[] CheckedInstallations {\r
260                         get {\r
261                                 List<Installation> insts = new List<Installation>();\r
262                                 foreach (ListViewItem item in instsListView.CheckedItems) {\r
263                                         insts.Add((Installation) item.Tag);\r
264                                 }\r
265                                 return insts.ToArray();\r
266                         }\r
267                 }\r
268                 \r
269                 #region runas関連\r
270                 \r
271                 /// <summary>\r
272                 /// runasで実行するか否か\r
273                 /// </summary>\r
274                 public bool UseRunas {\r
275                         set {\r
276                                 runasCheckBox.Checked = (! NaGet.Utils.IsAdministrators()) && value;\r
277                                 \r
278                                 updateUseRunas();\r
279                         }\r
280                         get {\r
281                                 return runasCheckBox.Checked;\r
282                         }\r
283                 }\r
284                 \r
285                 /// <summary>\r
286                 /// 選択されたパッケージを調査して、Runasを使うべきかいなかを返す\r
287                 /// </summary>\r
288                 public bool GetShouldUseRunas()\r
289                 {\r
290                         if (NaGet.Utils.IsAdministrators()) {\r
291                                 // 管理者権限で動いている場合は不要\r
292                                 return false;   \r
293                         } else if (NaGet.Utils.IsUACEnabled()) {\r
294                                 // UACが適用されている場合は標準では不要とする\r
295                                 return false;   \r
296                         }\r
297                         \r
298                         // ひとつでもPCターゲットなインストーラがあれば必要とする\r
299                         foreach (Installation inst in CheckedInstallations) {\r
300                                 if (inst.TargetPC) return true;\r
301                         }\r
302                         // それ以外は不要\r
303                         return false;\r
304                 }\r
305                 \r
306                 void RunasCheckBoxCheckedChanged(object sender, EventArgs e)\r
307                 {\r
308                         updateUseRunas();\r
309                 }\r
310                 \r
311                 private void updateUseRunas()\r
312                 {\r
313                         if (UseRunas) {\r
314                                 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InstallationConfirmForm));\r
315                                 okButton.Image = ((System.Drawing.Bitmap)(resources.GetObject("okButton.Image")));\r
316                         } else {\r
317                                 okButton.Image = null;\r
318                         }\r
319                 }\r
320                 \r
321                 #endregion\r
322                 \r
323         }\r
324 }\r