OSDN Git Service

ShipListForm→ListFormなどの名前の変更を行う
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ListForm.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.Drawing;\r
18 using System.Linq;\r
19 using System.Windows.Forms;\r
20 using static System.Math;\r
21 \r
22 namespace KancolleSniffer\r
23 {\r
24     public partial class ListForm : Form\r
25     {\r
26         private readonly Sniffer _sniffer;\r
27         private readonly Config _config;\r
28         private const int LabelHeight = 12;\r
29         private const int LineHeight = 16;\r
30         public const int PanelWidth = 217;\r
31         private ShipStatus[] _shipList;\r
32         private readonly List<ShipLabel[]> _labelList = new List<ShipLabel[]>();\r
33         private readonly List<Panel> _labelPanelList = new List<Panel>();\r
34         private readonly List<CheckBox[]> _checkBoxesList = new List<CheckBox[]>();\r
35         private readonly List<ShipLabel[]> _configLabelList = new List<ShipLabel[]>();\r
36         private readonly List<Panel> _checkBoxPanelList = new List<Panel>();\r
37         private readonly List<ShipLabel[]> _repairLabelList = new List<ShipLabel[]>();\r
38         private readonly List<Panel> _repairPanelList = new List<Panel>();\r
39         public const int GroupCount = 4;\r
40         private readonly HashSet<int>[] _groupSettings = new HashSet<int>[GroupCount];\r
41 \r
42         public enum SortOrder\r
43         {\r
44             None,\r
45             Cond,\r
46             ExpToNext,\r
47             Repair\r
48         }\r
49 \r
50         public ListForm(Sniffer sniffer, Config config)\r
51         {\r
52             InitializeComponent();\r
53             _sniffer = sniffer;\r
54             _config = config;\r
55             var swipe = new SwipeScrollify();\r
56             swipe.AddPanel(panelShipList);\r
57             swipe.AddTreeView(itemTreeView);\r
58             swipe.AddPanel(equipPanel);\r
59         }\r
60 \r
61         public void UpdateList()\r
62         {\r
63             panelItemHeader.Visible = InItemList || InEquip || InMiscText;\r
64             panelGroupHeader.Visible = InGroupConfig;\r
65             panelRepairHeader.Visible = InRepairList;\r
66             // SwipeScrollifyが誤作動するのでEnabledも切り替える\r
67             panelShipList.Visible = panelShipList.Enabled = InShipStatus || InGroupConfig || InRepairList;\r
68             itemTreeView.Visible = itemTreeView.Enabled = InItemList;\r
69             equipPanel.Visible = equipPanel.Enabled = InEquip;\r
70             richTextBoxMiscText.Visible = InMiscText;\r
71             if (InItemList)\r
72             {\r
73                 itemTreeView.SetNodes(_sniffer.ItemList);\r
74             }\r
75             else if (InEquip)\r
76             {\r
77                 equipPanel.UpdateEquip(_sniffer);\r
78             }\r
79             else if (InMiscText)\r
80             {\r
81                 richTextBoxMiscText.Text = _sniffer.MiscText;\r
82             }\r
83             else\r
84             {\r
85                 SetHeaderSortOrder();\r
86                 CreateShipList();\r
87                 CreateListLabels();\r
88                 SetShipLabels();\r
89             }\r
90         }\r
91 \r
92         private void SetHeaderSortOrder()\r
93         {\r
94             switch (_config.ShipList.SortOrder)\r
95             {\r
96                 case SortOrder.None:\r
97                     labelHeaderCond.Text = "cond";\r
98                     labelHeaderExp.Text = "Exp";\r
99                     break;\r
100                 case SortOrder.Cond:\r
101                     labelHeaderCond.Text = "cond▴";\r
102                     labelHeaderExp.Text = "Exp";\r
103                     break;\r
104                 case SortOrder.ExpToNext:\r
105                     labelHeaderCond.Text = "cond";\r
106                     labelHeaderExp.Text = "Exp▴";\r
107                     break;\r
108             }\r
109         }\r
110 \r
111         private void CreateShipList()\r
112         {\r
113             var ships = InRepairList ? _sniffer.RepairList : FilterByGroup(_sniffer.ShipList).ToArray();\r
114             var order = InRepairList ? SortOrder.Repair : _config.ShipList.SortOrder;\r
115             if (!_config.ShipList.ShipType)\r
116             {\r
117                 _shipList = ships.OrderBy(s => s, new CompareShip(false, order)).ToArray();\r
118                 return;\r
119             }\r
120             var types = ships.Select(s => new {Id = s.Spec.ShipType, Name = s.Spec.ShipTypeName}).Distinct().\r
121                 Select(stype =>\r
122                     new ShipStatus\r
123                     {\r
124                         Spec = new ShipSpec {Name = stype.Name, ShipType = stype.Id},\r
125                         Level = 1000,\r
126                         NowHp = -1000,\r
127                         Cond = -1000\r
128                     });\r
129             _shipList = ships.Concat(types).OrderBy(s => s, new CompareShip(true, order)).ToArray();\r
130         }\r
131 \r
132         private IEnumerable<ShipStatus> FilterByGroup(IEnumerable<ShipStatus> ships)\r
133         {\r
134             var g = Array.FindIndex(new[] {"A", "B", "C", "D"}, x => x == comboBoxGroup.Text);\r
135             if (g == -1)\r
136                 return ships;\r
137             return from s in ships where _groupSettings[g].Contains(s.Id) select s;\r
138         }\r
139 \r
140         private class CompareShip : IComparer<ShipStatus>\r
141         {\r
142             private readonly bool _type;\r
143             private readonly SortOrder _order;\r
144 \r
145             public CompareShip(bool type, SortOrder order)\r
146             {\r
147                 _type = type;\r
148                 _order = order;\r
149             }\r
150 \r
151             public int Compare(ShipStatus a, ShipStatus b)\r
152             {\r
153                 if (_type && a.Spec.ShipType != b.Spec.ShipType)\r
154                     return a.Spec.ShipType - b.Spec.ShipType;\r
155                 switch (_order)\r
156                 {\r
157                     case SortOrder.None:\r
158                     case SortOrder.ExpToNext:\r
159                         break;\r
160                     case SortOrder.Cond:\r
161                         if (a.Cond != b.Cond)\r
162                             return a.Cond - b.Cond;\r
163                         break;\r
164                     case SortOrder.Repair:\r
165                         if (a.RepairTime != b.RepairTime)\r
166                             return (int)(b.RepairTime - a.RepairTime).TotalSeconds;\r
167                         break;\r
168                 }\r
169                 if ((!_type || _order == SortOrder.ExpToNext) && a.Level != b.Level)\r
170                     return b.Level - a.Level;\r
171                 if (_order == SortOrder.ExpToNext && a.ExpToNext != b.ExpToNext)\r
172                     return a.ExpToNext - b.ExpToNext;\r
173                 if (a.Spec.SortNo != b.Spec.SortNo)\r
174                     return a.Spec.SortNo - b.Spec.SortNo;\r
175                 return a.Id - b.Id;\r
176             }\r
177         }\r
178 \r
179         private void CreateListLabels()\r
180         {\r
181             panelShipList.SuspendLayout();\r
182             for (var i = _labelList.Count; i < _shipList.Length; i++)\r
183             {\r
184                 CreateConfigComponents(i);\r
185                 CreateRepairLabels(i);\r
186                 CreateShipLabels(i);\r
187             }\r
188             panelShipList.ResumeLayout();\r
189         }\r
190 \r
191         private void CreateConfigComponents(int i)\r
192         {\r
193             var y = 3 + LineHeight * i;\r
194             var cfgp = new Panel\r
195             {\r
196                 Location = new Point(0, y - 2),\r
197                 Size = new Size(PanelWidth, LineHeight - 1),\r
198                 BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
199                 Visible = false\r
200             };\r
201             cfgp.Scale(ShipLabel.ScaleFactor);\r
202             cfgp.Tag = cfgp.Location.Y;\r
203             var cfgl = new[]\r
204             {\r
205                 new ShipLabel\r
206                 {\r
207                     Location = new Point(91, 2),\r
208                     Size = new Size(23, LabelHeight),\r
209                     TextAlign = ContentAlignment.MiddleRight,\r
210                 },\r
211                 new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
212                 new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
213             };\r
214 \r
215             var cb = new CheckBox[GroupCount];\r
216             for (var j = 0; j < cb.Length; j++)\r
217             {\r
218                 cb[j] = new CheckBox\r
219                 {\r
220                     Location = new Point(125 + j * 24, 2),\r
221                     FlatStyle = FlatStyle.Flat,\r
222                     Size = new Size(12, 11),\r
223                     Tag = i * 10 + j\r
224                 };\r
225                 cb[j].Scale(ShipLabel.ScaleFactor);\r
226                 cb[j].CheckedChanged += checkboxGroup_CheckedChanged;\r
227             }\r
228             _configLabelList.Add(cfgl);\r
229             _checkBoxesList.Add(cb);\r
230             _checkBoxPanelList.Add(cfgp);\r
231             // ReSharper disable CoVariantArrayConversion\r
232             cfgp.Controls.AddRange(cfgl);\r
233             cfgp.Controls.AddRange(cb);\r
234             // ReSharper restore CoVariantArrayConversion\r
235             panelShipList.Controls.Add(cfgp);\r
236             foreach (var label in cfgl)\r
237             {\r
238                 label.Scale();\r
239                 label.PresetColor =\r
240                     label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
241             }\r
242         }\r
243 \r
244         private void CreateRepairLabels(int i)\r
245         {\r
246             var y = 3 + LineHeight * i;\r
247             const int height = LabelHeight;\r
248             var rpp = new Panel\r
249             {\r
250                 Location = new Point(0, y - 2),\r
251                 Size = new Size(PanelWidth, LineHeight - 1),\r
252                 BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
253                 Visible = false\r
254             };\r
255             rpp.Scale(ShipLabel.ScaleFactor);\r
256             rpp.Tag = rpp.Location.Y;\r
257             var rpl = new[]\r
258             {\r
259                 new ShipLabel {Location = new Point(118, 2), AutoSize = true, AnchorRight = true},\r
260                 new ShipLabel\r
261                 {\r
262                     Location = new Point(117, 2),\r
263                     Size = new Size(23, height),\r
264                     TextAlign = ContentAlignment.MiddleRight\r
265                 },\r
266                 new ShipLabel {Location = new Point(141, 2), AutoSize = true},\r
267                 new ShipLabel {Location = new Point(186, 2), AutoSize = true},\r
268                 new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
269                 new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
270             };\r
271             _repairLabelList.Add(rpl);\r
272             _repairPanelList.Add(rpp);\r
273 // ReSharper disable once CoVariantArrayConversion\r
274             rpp.Controls.AddRange(rpl);\r
275             panelShipList.Controls.Add(rpp);\r
276             foreach (var label in rpl)\r
277             {\r
278                 label.Scale();\r
279                 label.PresetColor =\r
280                     label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
281             }\r
282         }\r
283 \r
284         private void CreateShipLabels(int i)\r
285         {\r
286             var y = 3 + LineHeight * i;\r
287             const int height = LabelHeight;\r
288             var lbp = new Panel\r
289             {\r
290                 Location = new Point(0, y - 2),\r
291                 Size = new Size(PanelWidth, LineHeight - 1),\r
292                 BackColor = ShipLabels.ColumnColors[(i + 1) % 2],\r
293                 Visible = false\r
294             };\r
295             lbp.Scale(ShipLabel.ScaleFactor);\r
296             lbp.Tag = lbp.Location.Y;\r
297             var labels = new[]\r
298             {\r
299                 new ShipLabel {Location = new Point(126, 2), AutoSize = true, AnchorRight = true},\r
300                 new ShipLabel\r
301                 {\r
302                     Location = new Point(129, 2),\r
303                     Size = new Size(23, height),\r
304                     TextAlign = ContentAlignment.MiddleRight\r
305                 },\r
306                 new ShipLabel\r
307                 {\r
308                     Location = new Point(155, 2),\r
309                     Size = new Size(23, height),\r
310                     TextAlign = ContentAlignment.MiddleRight\r
311                 },\r
312                 new ShipLabel\r
313                 {\r
314                     Location = new Point(176, 2),\r
315                     Size = new Size(41, height),\r
316                     TextAlign = ContentAlignment.MiddleRight\r
317                 },\r
318                 new ShipLabel {Location = new Point(10, 2), AutoSize = true},\r
319                 new ShipLabel {Location = new Point(1, 2), AutoSize = true}\r
320             };\r
321             _labelList.Add(labels);\r
322             _labelPanelList.Add(lbp);\r
323 // ReSharper disable once CoVariantArrayConversion\r
324             lbp.Controls.AddRange(labels);\r
325             panelShipList.Controls.Add(lbp);\r
326             foreach (var label in labels)\r
327             {\r
328                 label.Scale();\r
329                 label.PresetColor =\r
330                     label.BackColor = ShipLabels.ColumnColors[(i + 1) % 2];\r
331             }\r
332         }\r
333 \r
334         private void SetShipLabels()\r
335         {\r
336             panelShipList.SuspendLayout();\r
337             for (var i = 0; i < _shipList.Length; i++)\r
338             {\r
339                 if (!InShipStatus)\r
340                     _labelPanelList[i].Visible = false;\r
341                 if (!InGroupConfig)\r
342                     _checkBoxPanelList[i].Visible = false;\r
343                 if (!InRepairList)\r
344                     _repairPanelList[i].Visible = false;\r
345             }\r
346             for (var i = 0; i < _shipList.Length; i++)\r
347             {\r
348                 if (InShipStatus)\r
349                     SetShipStatus(i);\r
350                 if (InGroupConfig)\r
351                     SetGroupConfig(i);\r
352                 if (InRepairList)\r
353                     SetRepairList(i);\r
354             }\r
355             for (var i = _shipList.Length; i < _labelPanelList.Count; i++)\r
356             {\r
357                 _labelPanelList[i].Visible = _checkBoxPanelList[i].Visible = _repairPanelList[i].Visible = false;\r
358             }\r
359             panelShipList.ResumeLayout();\r
360         }\r
361 \r
362         private void SetShipStatus(int i)\r
363         {\r
364             var lbp = _labelPanelList[i];\r
365             if (!lbp.Visible)\r
366                 lbp.Location = new Point(lbp.Left, (int)lbp.Tag + panelShipList.AutoScrollPosition.Y);\r
367             var s = _shipList[i];\r
368             var labels = _labelList[i];\r
369             if (s.Level == 1000) // 艦種の表示\r
370             {\r
371                 SetShipType(i);\r
372                 return;\r
373             }\r
374             labels[0].SetHp(s);\r
375             labels[1].SetCond(s);\r
376             labels[2].SetLevel(s);\r
377             labels[3].SetExpToNext(s);\r
378             labels[4].SetName(s);\r
379             labels[5].SetFleet(s);\r
380             lbp.Visible = true;\r
381         }\r
382 \r
383         private void SetShipType(int i)\r
384         {\r
385             var lbp = _labelPanelList[i];\r
386             if (!lbp.Visible)\r
387                 lbp.Location = new Point(lbp.Left, (int)lbp.Tag + panelShipList.AutoScrollPosition.Y);\r
388             var s = _shipList[i];\r
389             var labels = _labelList[i];\r
390             for (var c = 0; c < 4; c++)\r
391             {\r
392                 labels[c].Text = "";\r
393                 labels[c].BackColor = labels[c].PresetColor;\r
394             }\r
395             labels[4].SetName("");\r
396             labels[5].Text = s.Name;\r
397             lbp.Visible = true;\r
398         }\r
399 \r
400         private void SetGroupConfig(int i)\r
401         {\r
402             var cbp = _checkBoxPanelList[i];\r
403             var s = _shipList[i];\r
404             if (s.Level == 1000)\r
405             {\r
406                 SetShipType(i);\r
407                 cbp.Visible = false;\r
408                 return;\r
409             }\r
410             if (!cbp.Visible)\r
411                 cbp.Location = new Point(cbp.Left, (int)cbp.Tag + panelShipList.AutoScrollPosition.Y);\r
412             var cfgl = _configLabelList[i];\r
413             cfgl[0].SetLevel(s);\r
414             cfgl[1].SetName(s);\r
415             cfgl[2].SetFleet(s);\r
416             var cb = _checkBoxesList[i];\r
417             for (var j = 0; j < cb.Length; j++)\r
418                 cb[j].Checked = _groupSettings[j].Contains(s.Id);\r
419             cbp.Visible = true;\r
420         }\r
421 \r
422         private void SetRepairList(int i)\r
423         {\r
424             var rpp = _repairPanelList[i];\r
425             var s = _shipList[i];\r
426             if (s.Level == 1000)\r
427             {\r
428                 SetShipType(i);\r
429                 rpp.Visible = false;\r
430                 return;\r
431             }\r
432             if (!rpp.Visible)\r
433                 rpp.Location = new Point(rpp.Left, (int)rpp.Tag + panelShipList.AutoScrollPosition.Y);\r
434             var rpl = _repairLabelList[i];\r
435             rpl[0].SetHp(s);\r
436             rpl[1].SetLevel(s);\r
437             rpl[2].SetRepairTime(s);\r
438             rpl[3].Text = TimeSpan.FromSeconds(s.RepairSecPerHp).ToString(@"mm\:ss");\r
439             rpl[4].SetName(s, new Dictionary<string, string> {{"Graf Zeppelin改", "Graf Zeppelin"}, {"千代田航改二", "千代田航改"}});\r
440             rpl[5].SetFleet(s);\r
441             rpp.Visible = true;\r
442         }\r
443 \r
444         private bool InShipStatus => Array.Exists(new[] {"全員", "A", "B", "C", "D"}, x => comboBoxGroup.Text == x);\r
445 \r
446         private bool InGroupConfig => comboBoxGroup.Text == "分類";\r
447 \r
448         private bool InRepairList => comboBoxGroup.Text == "修復";\r
449 \r
450         private bool InItemList => comboBoxGroup.Text == "装備";\r
451 \r
452         private bool InEquip => comboBoxGroup.Text == "艦隊";\r
453 \r
454         private bool InMiscText => comboBoxGroup.Text == "情報";\r
455 \r
456         private void ShipListForm_Load(object sender, EventArgs e)\r
457         {\r
458             panelShipList.Width = itemTreeView.Width = equipPanel.Width =\r
459                 (int)Round(PanelWidth * ShipLabel.ScaleFactor.Width) + 3 + SystemInformation.VerticalScrollBarWidth;\r
460             Width = panelShipList.Width + 12 + (Width - ClientSize.Width);\r
461             MinimumSize = new Size(Width, 0);\r
462             MaximumSize = new Size(Width, int.MaxValue);\r
463             var config = _config.ShipList;\r
464             checkBoxShipType.Checked = config.ShipType;\r
465             ActiveControl = panelShipList;\r
466             for (var i = 0; i < GroupCount; i++)\r
467                 _groupSettings[i] = i < config.ShipGroup.Count\r
468                     ? new HashSet<int>(config.ShipGroup[i])\r
469                     : new HashSet<int>();\r
470             comboBoxGroup.SelectedIndex = 0;\r
471             if (config.Location.X == int.MinValue)\r
472                 return;\r
473             var bounds = new Rectangle(config.Location, config.Size);\r
474             if (MainForm.IsVisibleOnAnyScreen(bounds))\r
475                 Location = bounds.Location;\r
476             Height = bounds.Height;\r
477         }\r
478 \r
479         private void ShipListForm_FormClosing(object sender, FormClosingEventArgs e)\r
480         {\r
481             e.Cancel = true;\r
482             if (!Visible)\r
483                 return;\r
484             var config = _config.ShipList;\r
485             var all = _sniffer.ShipList.Select(s => s.Id).ToArray();\r
486             config.ShipGroup.Clear();\r
487             for (var i = 0; i < GroupCount; i++)\r
488             {\r
489                 if (all.Length > 0)\r
490                     _groupSettings[i].IntersectWith(all);\r
491                 config.ShipGroup.Add(_groupSettings[i].ToList());\r
492             }\r
493             var bounds = WindowState == FormWindowState.Normal ? Bounds : RestoreBounds;\r
494             config.Location = bounds.Location;\r
495             config.Size = bounds.Size;\r
496             Hide();\r
497         }\r
498 \r
499         public void ShowShip(int id)\r
500         {\r
501             if (InShipStatus)\r
502             {\r
503                 var i = Array.FindIndex(_shipList, s => s.Id == id);\r
504                 if (i == -1)\r
505                     return;\r
506                 var y = (int)Round(ShipLabel.ScaleFactor.Height * LineHeight * i);\r
507                 panelShipList.AutoScrollPosition = new Point(0, y);\r
508             }\r
509             else if (InEquip)\r
510             {\r
511                 equipPanel.ShowShip(id);\r
512             }\r
513         }\r
514 \r
515         private void checkBoxShipType_CheckedChanged(object sender, EventArgs e)\r
516         {\r
517             _config.ShipList.ShipType = checkBoxShipType.Checked;\r
518             UpdateList();\r
519             SetActiveControl();\r
520         }\r
521 \r
522         private void checkboxGroup_CheckedChanged(object sender, EventArgs e)\r
523         {\r
524             var cb = (CheckBox)sender;\r
525             var group = (int)cb.Tag % 10;\r
526             var idx = (int)cb.Tag / 10;\r
527             if (cb.Checked)\r
528                 _groupSettings[group].Add(_shipList[idx].Id);\r
529             else\r
530                 _groupSettings[group].Remove(_shipList[idx].Id);\r
531         }\r
532 \r
533         private void comboBoxGroup_SelectedIndexChanged(object sender, EventArgs e)\r
534         {\r
535             UpdateList();\r
536             SetActiveControl();\r
537             copyToolStripMenuItem.Enabled = InShipStatus | InItemList;\r
538         }\r
539 \r
540         private void ShipListForm_KeyPress(object sender, KeyPressEventArgs e)\r
541         {\r
542             var g = Array.FindIndex(new[] {'Z', 'A', 'B', 'C', 'D', 'G', 'R', 'W', 'X', 'I'},\r
543                 x => x == char.ToUpper(e.KeyChar));\r
544             if (g == -1)\r
545                 return;\r
546             comboBoxGroup.SelectedIndex = g;\r
547             e.Handled = true;\r
548         }\r
549 \r
550         // マウスホイールでスクロールするためにコントロールにフォーカスを合わせる。\r
551         private void SetActiveControl()\r
552         {\r
553             if (InItemList)\r
554                 ActiveControl = itemTreeView;\r
555             else if (InEquip)\r
556                 ActiveControl = equipPanel;\r
557             else\r
558                 ActiveControl = panelShipList;\r
559         }\r
560 \r
561         private void copyToolStripMenuItem_Click(object sender, EventArgs e)\r
562         {\r
563             Clipboard.SetText(TextGenerator.GenerateItemList(_sniffer.ItemList));\r
564         }\r
565 \r
566         private void textToolStripMenuItem_Click(object sender, EventArgs e)\r
567         {\r
568             Clipboard.SetText(TextGenerator.GenerateFleetData(_sniffer));\r
569         }\r
570 \r
571         private void deckBuilderToolStripMenuItem_Click(object sender, EventArgs e)\r
572         {\r
573             Clipboard.SetText(TextGenerator.GenerateDeckBuilderData(_sniffer));\r
574         }\r
575 \r
576         private void labelHeaderCond_Click(object sender, EventArgs e)\r
577         {\r
578             _config.ShipList.SortOrder = _config.ShipList.SortOrder == SortOrder.Cond ? SortOrder.None : SortOrder.Cond;\r
579             UpdateList();\r
580         }\r
581 \r
582         private void labelHeaderExp_Click(object sender, EventArgs e)\r
583         {\r
584             _config.ShipList.SortOrder = _config.ShipList.SortOrder == SortOrder.ExpToNext ? SortOrder.None : SortOrder.ExpToNext;\r
585             UpdateList();\r
586         }\r
587 \r
588         private void csvToolStripMenuItem_Click(object sender, EventArgs e)\r
589         {\r
590             Clipboard.SetText(TextGenerator.GenerateShipList(FilterByGroup(_sniffer.ShipList)));\r
591         }\r
592 \r
593         private void kantaiSarashiToolStripMenuItem_Click(object sender, EventArgs e)\r
594         {\r
595             Clipboard.SetText(TextGenerator.GenerateKantaiSarashiData(FilterByGroup(_sniffer.ShipList)));\r
596         }\r
597     }\r
598 }