OSDN Git Service

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