OSDN Git Service

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