OSDN Git Service

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