OSDN Git Service

MainFormのイベントハンドラをDesignerで設定しない
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ConfigDialog.cs
1 // Copyright (C) 2014, 2015 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 // \r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System;\r
16 using System.Collections.Generic;\r
17 using System.Diagnostics;\r
18 using System.Drawing;\r
19 using System.IO;\r
20 using System.Windows.Forms;\r
21 using KancolleSniffer.Net;\r
22 using KancolleSniffer.Util;\r
23 using KancolleSniffer.View;\r
24 \r
25 namespace KancolleSniffer\r
26 {\r
27     public partial class ConfigDialog : Form\r
28     {\r
29         private readonly Main _main;\r
30         private readonly Config _config;\r
31 \r
32         private readonly Dictionary<string, NotificationSpec> _notificationSettings =\r
33             new Dictionary<string, NotificationSpec>();\r
34 \r
35         private readonly Dictionary<string, string> _soundSettings = new Dictionary<string, string>();\r
36         private const string Home = "http://kancollesniffer.osdn.jp/";\r
37         private Point _prevPosition = new Point(int.MinValue, int.MinValue);\r
38 \r
39         public List<string> RepeatSettingsChanged { get; } = new List<string>();\r
40         public Notification.ConfigDialog NotificationConfigDialog { get; }\r
41 \r
42         public ConfigDialog(Main main)\r
43         {\r
44             InitializeComponent();\r
45             _main = main;\r
46             _config = main.Config;\r
47             // ReSharper disable once CoVariantArrayConversion\r
48             listBoxSoundFile.Items.AddRange(Config.NotificationNames);\r
49             numericUpDownMaterialLogInterval.Maximum = 1440;\r
50 \r
51             NotificationConfigDialog = new Notification.ConfigDialog(_notificationSettings,\r
52                 new Dictionary<NotificationType, CheckBox>\r
53                 {\r
54                     {NotificationType.FlashWindow, checkBoxFlash},\r
55                     {NotificationType.ShowBaloonTip, checkBoxBalloon},\r
56                     {NotificationType.PlaySound, checkBoxSound},\r
57                     {NotificationType.Repeat, checkBoxRepeat}\r
58                 });\r
59         }\r
60 \r
61         private void ConfigDialog_Load(object sender, EventArgs e)\r
62         {\r
63             if (_prevPosition.X != int.MinValue)\r
64                 Location = _prevPosition;\r
65             _main.CheckVersionUp((current, latest) =>\r
66             {\r
67                 labelVersion.Text = "バージョン" + current;\r
68                 labelLatest.Text = current == latest ? "最新です" : "最新は" + latest + "です";\r
69             });\r
70             labelCopyright.Text = FileVersionInfo.GetVersionInfo(Application.ExecutablePath).LegalCopyright;\r
71 \r
72             checkBoxTopMost.Checked = _config.TopMost;\r
73             checkBoxHideOnMinimized.Checked = _config.HideOnMinimized;\r
74             checkBoxExitSilently.Checked = _config.ExitSilently;\r
75             checkBoxLocationPerMachine.Checked = _config.SaveLocationPerMachine;\r
76             comboBoxZoom.SelectedItem = _config.Zoom + "%";\r
77             numericUpDownQuest.Value = _config.QuestLines;\r
78 \r
79             checkBoxFlash.Checked = (_config.NotificationFlags & NotificationType.FlashWindow) != 0;\r
80             checkBoxBalloon.Checked = (_config.NotificationFlags & NotificationType.ShowBaloonTip) != 0;\r
81             checkBoxSound.Checked = (_config.NotificationFlags & NotificationType.PlaySound) != 0;\r
82             checkBoxRepeat.Checked = (_config.NotificationFlags & NotificationType.Repeat) != 0;\r
83             foreach (var name in Config.NotificationNames)\r
84                 _notificationSettings[name] = _config.Notifications[name];\r
85             numericUpDownMarginShips.Value = _config.MarginShips;\r
86             numericUpDownMarginEquips.Value = _config.MarginEquips;\r
87             checkBoxCond40.Checked = _config.NotifyConditions.Contains(40);\r
88             checkBoxCond49.Checked = _config.NotifyConditions.Contains(49);\r
89 \r
90             checkBoxReset02.Checked = _config.ResetHours.Contains(2);\r
91             checkBoxReset14.Checked = _config.ResetHours.Contains(14);\r
92             checkBoxResultRank.Checked = (_config.Spoilers & Spoiler.ResultRank) != 0;\r
93             checkBoxAirBattleResult.Checked = (_config.Spoilers & Spoiler.AirBattleResult) != 0;\r
94             checkBoxBattleResult.Checked = (_config.Spoilers & Spoiler.BattleResult) != 0;\r
95             checkBoxNextCell.Checked = (_config.Spoilers & Spoiler.NextCell) != 0;\r
96             checkBoxPresetAkashi.Checked = _config.UsePresetAkashi;\r
97             checkBoxWarnBadDamageWithDamecon.Checked = _config.WarnBadDamageWithDameCon;\r
98             checkBoxAutoBattleResult.Checked = _config.ShipList.AutoBattleResult;\r
99 \r
100             numericUpDownSoundVolume.Value = _config.Sounds.Volume;\r
101             foreach (var name in Config.NotificationNames)\r
102                 _soundSettings[name] = _config.Sounds[name];\r
103             listBoxSoundFile.SelectedIndex = -1;\r
104             listBoxSoundFile.SelectedIndex = 0;\r
105 \r
106             LoadProxySettings();\r
107             LoadLogSettings();\r
108             LoadDebugSettings();\r
109 \r
110             checkBoxPushbulletOn.Checked = _config.Pushbullet.On;\r
111             textBoxPushbulletToken.Text = _config.Pushbullet.Token;\r
112             checkBoxPushoverOn.Checked = _config.Pushover.On;\r
113             textBoxPushoverApiKey.Text = _config.Pushover.ApiKey;\r
114             textBoxPushoverUserKey.Text = _config.Pushover.UserKey;\r
115         }\r
116 \r
117         private void LoadProxySettings()\r
118         {\r
119             // 見えていないTabPage上でPerformClickは使えない。\r
120             radioButtonAutoConfigOn.Checked = _config.Proxy.Auto;\r
121             radioButtonAutoConfigOff.Checked = !_config.Proxy.Auto;\r
122             textBoxListen.Text = _config.Proxy.Listen.ToString("D");\r
123             radioButtonUpstreamOn.Checked = _config.Proxy.UseUpstream;\r
124             radioButtonUpstreamOff.Checked = !_config.Proxy.UseUpstream;\r
125             textBoxPort.Text = _config.Proxy.UpstreamPort.ToString("D");\r
126         }\r
127 \r
128         private void LoadLogSettings()\r
129         {\r
130             checkBoxOutput.Checked = _config.Log.On;\r
131             textBoxOutput.Text = _config.Log.OutputDir;\r
132             textBoxOutput.Select(textBoxOutput.Text.Length, 0);\r
133             folderBrowserDialogOutputDir.SelectedPath = _config.Log.OutputDir;\r
134             numericUpDownMaterialLogInterval.Value = _config.Log.MaterialLogInterval;\r
135         }\r
136 \r
137         private void LoadDebugSettings()\r
138         {\r
139             checkBoxDebugLog.Checked = _config.DebugLogging;\r
140             textBoxDebugLog.Text = _config.DebugLogFile;\r
141         }\r
142 \r
143         private void buttonOk_Click(object sender, EventArgs e)\r
144         {\r
145             if (!ValidatePorts(out var listen, out var outbound, out _))\r
146                 return;\r
147             DialogResult = DialogResult.OK;\r
148             if (!ApplyProxySettings(listen, outbound))\r
149                 DialogResult = DialogResult.None;\r
150             ApplyLogSettings();\r
151             ApplyDebugSettings();\r
152 \r
153             _config.Pushbullet.On = checkBoxPushbulletOn.Checked;\r
154             _config.Pushbullet.Token = textBoxPushbulletToken.Text;\r
155             _config.Pushover.On = checkBoxPushoverOn.Checked;\r
156             _config.Pushover.ApiKey = textBoxPushoverApiKey.Text;\r
157             _config.Pushover.UserKey = textBoxPushoverUserKey.Text;\r
158 \r
159             _config.TopMost = checkBoxTopMost.Checked;\r
160             _config.HideOnMinimized = checkBoxHideOnMinimized.Checked;\r
161             _config.ExitSilently = checkBoxExitSilently.Checked;\r
162             _config.SaveLocationPerMachine = checkBoxLocationPerMachine.Checked;\r
163             _config.Zoom = int.Parse(comboBoxZoom.SelectedItem.ToString().Substring(0, 3));\r
164             _config.QuestLines = (int)numericUpDownQuest.Value;\r
165             _config.NotificationFlags = (checkBoxFlash.Checked ? NotificationType.FlashWindow : 0) |\r
166                                         (checkBoxBalloon.Checked ? NotificationType.ShowBaloonTip : 0) |\r
167                                         (checkBoxSound.Checked ? NotificationType.PlaySound : 0) |\r
168                                         (checkBoxRepeat.Checked ? NotificationType.Repeat : 0);\r
169             _config.MarginShips = (int)numericUpDownMarginShips.Value;\r
170             _config.MarginEquips = (int)numericUpDownMarginEquips.Value;\r
171 \r
172             RepeatSettingsChanged.Clear();\r
173             var repeatOff = (_config.NotificationFlags & NotificationType.Repeat) == 0;\r
174             foreach (var name in Config.NotificationNames)\r
175             {\r
176                 var old = _config.Notifications[name];\r
177                 var cur = _notificationSettings[name];\r
178                 if (repeatOff || old.RepeatInterval != cur.RepeatInterval ||\r
179                     (cur.Flags & NotificationType.Repeat) == 0 ||\r
180                     (cur.Flags & NotificationType.Cont) == 0)\r
181                 {\r
182                     RepeatSettingsChanged.Add(name);\r
183                 }\r
184                 _config.Notifications[name] = cur;\r
185             }\r
186 \r
187             _config.NotifyConditions.Clear();\r
188             if (checkBoxCond40.Checked)\r
189                 _config.NotifyConditions.Add(40);\r
190             if (checkBoxCond49.Checked)\r
191                 _config.NotifyConditions.Add(49);\r
192 \r
193             _config.ResetHours.Clear();\r
194             if (checkBoxReset02.Checked)\r
195                 _config.ResetHours.Add(2);\r
196             if (checkBoxReset14.Checked)\r
197                 _config.ResetHours.Add(14);\r
198 \r
199             _config.Spoilers = (checkBoxResultRank.Checked ? Spoiler.ResultRank : 0) |\r
200                                (checkBoxAirBattleResult.Checked ? Spoiler.AirBattleResult : 0) |\r
201                                (checkBoxBattleResult.Checked ? Spoiler.BattleResult : 0) |\r
202                                (checkBoxNextCell.Checked ? Spoiler.NextCell : 0);\r
203             _config.UsePresetAkashi = checkBoxPresetAkashi.Checked;\r
204             _config.WarnBadDamageWithDameCon = checkBoxWarnBadDamageWithDamecon.Checked;\r
205             _config.ShipList.AutoBattleResult = checkBoxAutoBattleResult.Checked;\r
206 \r
207             _config.Sounds.Volume = (int)numericUpDownSoundVolume.Value;\r
208             foreach (var name in Config.NotificationNames)\r
209                 _config.Sounds[name] = MakePathRooted(_soundSettings[name]);\r
210         }\r
211 \r
212         private bool ValidatePorts(out int listen, out int outbound, out int server)\r
213         {\r
214             outbound = -1;\r
215             server = -1;\r
216             if (!ValidatePortNumber(textBoxListen, out listen))\r
217                 return false;\r
218             if (radioButtonUpstreamOn.Checked && !ValidatePortNumber(textBoxPort, out outbound))\r
219                 return false;\r
220             if (radioButtonUpstreamOn.Checked && listen == outbound)\r
221             {\r
222                 ShowToolTip("受信と送信に同じポートは使えません。", textBoxPort);\r
223                 return false;\r
224             }\r
225             return true;\r
226         }\r
227 \r
228         private bool ApplyProxySettings(int listen, int port)\r
229         {\r
230             _config.Proxy.Auto = radioButtonAutoConfigOn.Checked;\r
231             _config.Proxy.Listen = listen;\r
232             _config.Proxy.UseUpstream = radioButtonUpstreamOn.Checked;\r
233             if (_config.Proxy.UseUpstream)\r
234                 _config.Proxy.UpstreamPort = port;\r
235             if (!_main.ApplyProxySetting())\r
236                 return false;\r
237             textBoxListen.Text = _config.Proxy.Listen.ToString();\r
238             return true;\r
239         }\r
240 \r
241         private void ApplyLogSettings()\r
242         {\r
243             _config.Log.On = checkBoxOutput.Checked;\r
244             _config.Log.MaterialLogInterval = (int)numericUpDownMaterialLogInterval.Value;\r
245             _config.Log.OutputDir = MakePathRooted(textBoxOutput.Text);\r
246             _main.ApplyLogSetting();\r
247         }\r
248 \r
249         private void ApplyDebugSettings()\r
250         {\r
251             _config.DebugLogging = checkBoxDebugLog.Checked;\r
252             _config.DebugLogFile = MakePathRooted(textBoxDebugLog.Text);\r
253             _main.ApplyDebugLogSetting();\r
254         }\r
255 \r
256         private string MakePathRooted(string path)\r
257         {\r
258             try\r
259             {\r
260                 return string.IsNullOrWhiteSpace(path)\r
261                     ? ""\r
262                     : Path.IsPathRooted(path)\r
263                         ? path\r
264                         : Path.Combine(Config.BaseDir, path);\r
265             }\r
266             catch (ArgumentException)\r
267             {\r
268                 return "";\r
269             }\r
270         }\r
271 \r
272         private void textBoxSoundFile_TextChanged(object sender, EventArgs e)\r
273         {\r
274             _soundSettings[(string)listBoxSoundFile.SelectedItem] = textBoxSoundFile.Text;\r
275         }\r
276 \r
277         private void listBoxSoundFile_SelectedIndexChanged(object sender, EventArgs e)\r
278         {\r
279             if (listBoxSoundFile.SelectedItem == null)\r
280                 return;\r
281             textBoxSoundFile.Text = _soundSettings[(string)listBoxSoundFile.SelectedItem];\r
282             textBoxSoundFile.Select(textBoxSoundFile.Text.Length, 0);\r
283         }\r
284 \r
285         private void buttonOpenFile_Click(object sender, EventArgs e)\r
286         {\r
287             SetInitialPath(openSoundFileDialog, textBoxSoundFile.Text);\r
288             if (openSoundFileDialog.ShowDialog() != DialogResult.OK)\r
289                 return;\r
290             textBoxSoundFile.Text = openSoundFileDialog.FileName;\r
291             textBoxSoundFile.Select(textBoxSoundFile.Text.Length, 0);\r
292         }\r
293 \r
294         private void buttonPlay_Click(object sender, EventArgs e)\r
295         {\r
296             SoundPlayer.PlaySound(Handle, _soundSettings[(string)listBoxSoundFile.SelectedItem], (int)numericUpDownSoundVolume.Value);\r
297         }\r
298 \r
299         private void buttonResetAchievement_Click(object sender, EventArgs e)\r
300         {\r
301             _main.ResetAchievement();\r
302         }\r
303 \r
304         private void linkLabelProductName_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\r
305         {\r
306             linkLabelProductName.LinkVisited = true;\r
307             Process.Start(Home);\r
308         }\r
309 \r
310         private void radioButtonUpstreamOff_CheckedChanged(object sender, EventArgs e)\r
311         {\r
312             var off = ((RadioButton)sender).Checked;\r
313             textBoxPort.Enabled = !off;\r
314         }\r
315 \r
316         private void buttonOutputDir_Click(object sender, EventArgs e)\r
317         {\r
318             if (folderBrowserDialogOutputDir.ShowDialog(this) == DialogResult.OK)\r
319                 textBoxOutput.Text = folderBrowserDialogOutputDir.SelectedPath;\r
320             textBoxOutput.Select(textBoxOutput.Text.Length, 0);\r
321         }\r
322 \r
323         private bool ValidatePortNumber(TextBox textBox, out int result)\r
324         {\r
325             var s = textBox.Text;\r
326             if (!int.TryParse(s, out result))\r
327             {\r
328                 ShowToolTip("数字を入力してください。", textBox);\r
329                 return false;\r
330             }\r
331             if (result <= 0)\r
332             {\r
333                 ShowToolTip("0より大きい数字を入力してください。", textBox);\r
334                 return false;\r
335             }\r
336             if (result > 65535)\r
337             {\r
338                 ShowToolTip("65535以下の数字を入力してください。", textBox);\r
339                 return false;\r
340             }\r
341             return true;\r
342         }\r
343 \r
344         private readonly ResizableToolTip _toolTip =\r
345             new ResizableToolTip {AutomaticDelay = 0, ToolTipIcon = ToolTipIcon.Error};\r
346 \r
347         private void ShowToolTip(string message, Control control)\r
348         {\r
349             tabControl.SelectedTab = (TabPage)control.Parent.Parent;\r
350             _toolTip.Show(message, control, 0, control.Height, 3000);\r
351         }\r
352 \r
353         private void textBox_Enter(object sender, EventArgs e)\r
354         {\r
355             _toolTip.Hide((Control)sender);\r
356         }\r
357 \r
358         private void buttonDebugLogOpenFile_Click(object sender, EventArgs e)\r
359         {\r
360             SetInitialPath(openDebugLogDialog, textBoxDebugLog.Text);\r
361             if (openDebugLogDialog.ShowDialog(this) == DialogResult.OK)\r
362                 textBoxDebugLog.Text = openDebugLogDialog.FileName;\r
363             textBoxDebugLog.Select(textBoxDebugLog.Text.Length, 0);\r
364         }\r
365 \r
366         private void SetInitialPath(OpenFileDialog dialog, string path)\r
367         {\r
368             var dir = Config.BaseDir;\r
369             var file = "";\r
370             if (!string.IsNullOrWhiteSpace(path))\r
371             {\r
372                 var res = Path.GetDirectoryName(path);\r
373                 if (res == null) // root\r
374                 {\r
375                     dir = path;\r
376                 }\r
377                 else if (res != "") // contain directory\r
378                 {\r
379                     dir = res;\r
380                     file = Path.GetFileName(path);\r
381                 }\r
382                 else\r
383                 {\r
384                     file = path;\r
385                 }\r
386             }\r
387             dialog.InitialDirectory = dir;\r
388             dialog.FileName = file;\r
389         }\r
390 \r
391         private void buttonPlayDebugLog_Click(object sender, EventArgs e)\r
392         {\r
393             _main.SetPlayLog(textBoxDebugLog.Text);\r
394             DialogResult = DialogResult.Cancel;\r
395         }\r
396 \r
397         private void buttonDetailedSettings_Click(object sender, EventArgs e)\r
398         {\r
399             NotificationConfigDialog.ShowDialog(this);\r
400         }\r
401 \r
402         private void ConfigDialog_FormClosing(object sender, FormClosingEventArgs e)\r
403         {\r
404             _prevPosition = Location;\r
405         }\r
406 \r
407         private void buttonPushbulletTest_Click(object sender, EventArgs e)\r
408         {\r
409             try\r
410             {\r
411                 PushNotification.PushToPushbullet(textBoxPushbulletToken.Text, "KancolleSniffer", "うまくいったかな?");\r
412             }\r
413             catch (Exception ex)\r
414             {\r
415                 MessageBox.Show(this, ex.Message, "Pushbulletエラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
416             }\r
417         }\r
418 \r
419         private void buttonPushoverTest_Click(object sender, EventArgs e)\r
420         {\r
421             try\r
422             {\r
423                 PushNotification.PushToPushover(textBoxPushoverApiKey.Text, textBoxPushoverUserKey.Text,\r
424                     "KancolleSniffer", "うまくいったかな?");\r
425             }\r
426             catch (Exception ex)\r
427             {\r
428                 MessageBox.Show(this, ex.Message, "Pushoverエラー", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
429             }\r
430         }\r
431 \r
432         protected override void ScaleControl(SizeF factor, BoundsSpecified specified)\r
433         {\r
434             base.ScaleControl(factor, specified);\r
435             if (factor.Height > 1)\r
436                 _toolTip.Font = new Font(_toolTip.Font.FontFamily, _toolTip.Font.Size * factor.Height);\r
437         }\r
438     }\r
439 }