PKHeX/PKHeX.WinForms/Subforms/SAV_Database.cs
Kurt 99c790a4b0 Update File name/path/folder fields
original file path is not saved with the two listed properties, add
FileFolder and relcoate existing FilePath functions to that field

move some GetVariantSAV usages to the string method instead of byte[]
2018-07-16 21:00:43 -07:00

742 lines
29 KiB
C#

#define LOADALL
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using PKHeX.Core;
using PKHeX.WinForms.Controls;
using static PKHeX.Core.MessageStrings;
namespace PKHeX.WinForms
{
public partial class SAV_Database : Form
{
private readonly SaveFile SAV;
private readonly SAVEditor BoxView;
private readonly PKMEditor PKME_Tabs;
public SAV_Database(PKMEditor f1, SAVEditor saveditor)
{
InitializeComponent();
ToolStripMenuItem mnuView = new ToolStripMenuItem {Name = "mnuView", Text = "View"};
ToolStripMenuItem mnuDelete = new ToolStripMenuItem {Name = "mnuDelete", Text = "Delete" };
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
ContextMenuStrip mnu = new ContextMenuStrip();
mnu.Items.AddRange(new ToolStripItem[] { mnuView, mnuDelete });
SAV = saveditor.SAV;
BoxView = saveditor;
PKME_Tabs = f1;
// Preset Filters to only show PKM available for loaded save
CB_FormatComparator.SelectedIndex = 3; // <=
PKXBOXES = new[]
{
bpkx1, bpkx2, bpkx3, bpkx4, bpkx5, bpkx6,
bpkx7, bpkx8, bpkx9, bpkx10,bpkx11,bpkx12,
bpkx13,bpkx14,bpkx15,bpkx16,bpkx17,bpkx18,
bpkx19,bpkx20,bpkx21,bpkx22,bpkx23,bpkx24,
bpkx25,bpkx26,bpkx27,bpkx28,bpkx29,bpkx30,
bpkx31,bpkx32,bpkx33,bpkx34,bpkx35,bpkx36,
bpkx37,bpkx38,bpkx39,bpkx40,bpkx41,bpkx42,
bpkx43,bpkx44,bpkx45,bpkx46,bpkx47,bpkx48,
bpkx49,bpkx50,bpkx51,bpkx52,bpkx53,bpkx54,
bpkx55,bpkx56,bpkx57,bpkx58,bpkx59,bpkx60,
bpkx61,bpkx62,bpkx63,bpkx64,bpkx65,bpkx66,
};
// Enable Scrolling when hovered over
foreach (var slot in PKXBOXES)
{
// Enable Click
slot.MouseClick += (sender, e) =>
{
if (ModifierKeys == Keys.Control)
ClickView(sender, e);
else if (ModifierKeys == Keys.Alt)
ClickDelete(sender, e);
else if (ModifierKeys == Keys.Shift)
ClickSet(sender, e);
};
}
Counter = L_Count.Text;
Viewed = L_Viewed.Text;
L_Viewed.Text = string.Empty; // invis for now
var hover = new ToolTip();
L_Viewed.MouseEnter += (sender, e) => hover.SetToolTip(L_Viewed, L_Viewed.Text);
PopulateComboBoxes();
// Assign event handlers
mnuView.Click += ClickView;
mnuDelete.Click += ClickDelete;
// Add to main context menu
// Assign to datagridview
foreach (PictureBox p in PKXBOXES)
p.ContextMenuStrip = mnu;
// Load Data
B_Search.Enabled = false;
L_Count.Text = "Loading...";
new Task(LoadDatabase).Start();
Menu_SearchSettings.DropDown.Closing += (sender, e) =>
{
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
e.Cancel = true;
};
CB_Format.Items[0] = MsgAny;
CenterToParent();
}
private readonly PictureBox[] PKXBOXES;
private readonly string DatabasePath = Main.DatabasePath;
private List<PKM> Results;
private List<PKM> RawDB;
private int slotSelected = -1; // = null;
private Image slotColor;
private const int RES_MAX = 66;
private const int RES_MIN = 6;
private readonly string Counter;
private readonly string Viewed;
private const int MAXFORMAT = PKX.Generation;
private readonly string EXTERNAL_SAV = new DirectoryInfo(Main.BackupPath).Name + Path.DirectorySeparatorChar;
private static string Hash(PKM pk)
{
switch (pk.Format)
{
case 1: return $"{pk.Species:000}{((PK1) pk).DV16:X4}";
case 2: return $"{pk.Species:000}{((PK2) pk).DV16:X4}";
default: return $"{pk.Species:000}{pk.PID:X8}{string.Join(" ", pk.IVs)}{pk.AltForm:00}";
}
}
// Important Events
private void ClickView(object sender, EventArgs e)
{
sender = WinFormsUtil.GetUnderlyingControl(sender);
int index = Array.IndexOf(PKXBOXES, sender);
if (index >= RES_MAX)
{
System.Media.SystemSounds.Exclamation.Play();
return;
}
index += SCR_Box.Value * RES_MIN;
if (index >= Results.Count)
{
System.Media.SystemSounds.Exclamation.Play();
return;
}
PKME_Tabs.PopulateFields(Results[index], false);
slotSelected = index;
slotColor = Properties.Resources.slotView;
FillPKXBoxes(SCR_Box.Value);
L_Viewed.Text = string.Format(Viewed, Results[index].Identifier);
}
private void ClickDelete(object sender, EventArgs e)
{
sender = WinFormsUtil.GetUnderlyingControl(sender);
int index = Array.IndexOf(PKXBOXES, sender);
if (index >= RES_MAX)
{
System.Media.SystemSounds.Exclamation.Play();
return;
}
index += SCR_Box.Value * RES_MIN;
if (index >= Results.Count)
{
System.Media.SystemSounds.Exclamation.Play();
return;
}
var pk = Results[index];
string path = pk.Identifier;
#if LOADALL
if (path.StartsWith(EXTERNAL_SAV))
{
WinFormsUtil.Alert(MsgDBDeleteFailBackup);
return;
}
#endif
if (path.Contains(Path.DirectorySeparatorChar))
{
// Data from Database: Delete file from disk
if (File.Exists(path))
File.Delete(path);
}
else
{
// Data from Box: Delete from save file
int box = pk.Box-1;
int slot = pk.Slot-1;
int offset = SAV.GetBoxOffset(box) + slot*SAV.SIZE_STORED;
PKM pkSAV = SAV.GetStoredSlot(offset);
if (!pkSAV.DecryptedBoxData.SequenceEqual(pk.DecryptedBoxData)) // data still exists in SAV, unmodified
{
WinFormsUtil.Error(MsgDBDeleteFailModified, MsgDBDeleteFailWarning);
return;
}
var change = new SlotChange {Box = box, Offset = offset, Slot = slot};
BoxView.M.SetPKM(BoxView.SAV.BlankPKM, change, true, Properties.Resources.slotDel);
}
// Remove from database.
RawDB.Remove(pk);
Results.Remove(pk);
// Refresh database view.
L_Count.Text = string.Format(Counter, Results.Count);
slotSelected = -1;
FillPKXBoxes(SCR_Box.Value);
System.Media.SystemSounds.Asterisk.Play();
}
private void ClickSet(object sender, EventArgs e)
{
// Don't care what slot was clicked, just add it to the database
if (!PKME_Tabs.VerifiedPKM())
return;
PKM pk = PKME_Tabs.PreparePKM();
Directory.CreateDirectory(DatabasePath);
string path = Path.Combine(DatabasePath, Util.CleanFileName(pk.FileName));
if (RawDB.Any(p => p.Identifier == path))
{
WinFormsUtil.Alert(MsgDBAddFailExistsFile);
return;
}
File.WriteAllBytes(path, pk.Data.Take(pk.SIZE_STORED).ToArray());
pk.Identifier = path;
int pre = RawDB.Count;
RawDB.Add(pk);
RawDB = new List<PKM>(RawDB);
int post = RawDB.Count;
if (pre == post)
{ WinFormsUtil.Alert(MsgDBAddFailExistsPKM); return; }
Results.Add(pk);
// Refresh database view.
L_Count.Text = string.Format(Counter, Results.Count);
slotSelected = Results.Count - 1;
slotColor = Properties.Resources.slotSet;
if ((SCR_Box.Maximum+1)*6 < Results.Count)
SCR_Box.Maximum++;
SCR_Box.Value = Math.Max(0, SCR_Box.Maximum - PKXBOXES.Length/6 + 1);
FillPKXBoxes(SCR_Box.Value);
WinFormsUtil.Alert(MsgDBAddFromTabsSuccess);
}
private void PopulateComboBoxes()
{
// Set the Text
CB_HeldItem.InitializeBinding();
CB_Species.InitializeBinding();
CB_Ability.InitializeBinding();
CB_Nature.InitializeBinding();
CB_GameOrigin.InitializeBinding();
CB_HPType.InitializeBinding();
var Any = new ComboItem {Text = MsgAny, Value = -1};
var DS_Species = new List<ComboItem>(GameInfo.SpeciesDataSource);
DS_Species.RemoveAt(0); DS_Species.Insert(0, Any); CB_Species.DataSource = DS_Species;
var DS_Item = new List<ComboItem>(GameInfo.ItemDataSource);
DS_Item.Insert(0, Any); CB_HeldItem.DataSource = DS_Item;
var DS_Nature = new List<ComboItem>(GameInfo.NatureDataSource);
DS_Nature.Insert(0, Any); CB_Nature.DataSource = DS_Nature;
var DS_Ability = new List<ComboItem>(GameInfo.AbilityDataSource);
DS_Ability.Insert(0, Any); CB_Ability.DataSource = DS_Ability;
var DS_Version = new List<ComboItem>(GameInfo.VersionDataSource);
DS_Version.Insert(0, Any); CB_GameOrigin.DataSource = DS_Version;
string[] hptypes = new string[GameInfo.Strings.types.Length - 2]; Array.Copy(GameInfo.Strings.types, 1, hptypes, 0, hptypes.Length);
var DS_Type = Util.GetCBList(hptypes, null);
DS_Type.Insert(0, Any); CB_HPType.DataSource = DS_Type;
// Set the Move ComboBoxes too..
var DS_Move = new List<ComboItem>(GameInfo.MoveDataSource);
DS_Move.RemoveAt(0); DS_Move.Insert(0, Any);
{
foreach (ComboBox cb in new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 })
{
cb.InitializeBinding();
cb.DataSource = new BindingSource(DS_Move, null);
}
}
// Trigger a Reset
ResetFilters(null, null);
}
private void ResetFilters(object sender, EventArgs e)
{
CHK_Shiny.Checked = CHK_IsEgg.Checked = true;
CHK_Shiny.CheckState = CHK_IsEgg.CheckState = CheckState.Indeterminate;
MT_ESV.Text = string.Empty;
CB_HeldItem.SelectedIndex = 0;
CB_Species.SelectedIndex = 0;
CB_Ability.SelectedIndex = 0;
CB_Nature.SelectedIndex = 0;
CB_HPType.SelectedIndex = 0;
CB_Level.SelectedIndex = 0;
TB_Level.Text = string.Empty;
CB_EVTrain.SelectedIndex = 0;
CB_IV.SelectedIndex = 0;
CB_Move1.SelectedIndex = CB_Move2.SelectedIndex = CB_Move3.SelectedIndex = CB_Move4.SelectedIndex = 0;
CB_GameOrigin.SelectedIndex = 0;
CB_Generation.SelectedIndex = 0;
MT_ESV.Visible = L_ESV.Visible = false;
RTB_Instructions.Clear();
if (sender != null)
System.Media.SystemSounds.Asterisk.Play();
}
private void GenerateDBReport(object sender, EventArgs e)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgDBCreateReportPrompt, MsgDBCreateReportWarning)
!= DialogResult.Yes)
return;
ReportGrid reportGrid = new ReportGrid();
reportGrid.Show();
reportGrid.PopulateData(Results.ToArray());
}
private void LoadDatabase()
{
var dbTemp = new ConcurrentBag<PKM>();
var files = Directory.EnumerateFiles(DatabasePath, "*", SearchOption.AllDirectories);
Parallel.ForEach(files, file =>
{
FileInfo fi = new FileInfo(file);
if (!fi.Extension.Contains(".pk") || !PKX.IsPKM(fi.Length)) return;
var data = File.ReadAllBytes(file);
var prefer = PKX.GetPKMFormatFromExtension(fi.Extension, SAV.Generation);
var pk = PKMConverter.GetPKMfromBytes(data, file, prefer);
if (pk != null)
dbTemp.Add(pk);
});
#if LOADALL
if (SaveUtil.GetSavesFromFolder(Main.BackupPath, false, out IEnumerable<string> result))
{
Parallel.ForEach(result, file =>
{
var sav = SaveUtil.GetVariantSAV(file);
var path = EXTERNAL_SAV + new FileInfo(file).Name;
if (sav.HasBox)
foreach (var pk in sav.BoxData)
addPKM(pk);
void addPKM(PKM pk)
{
pk.Identifier = Path.Combine(path, pk.Identifier);
dbTemp.Add(pk);
}
});
}
#endif
// Prepare Database
RawDB = new List<PKM>(dbTemp.OrderBy(pk => pk.Identifier)
.Concat(SAV.BoxData.Where(pk => pk.Species != 0)) // Fetch from save file
.Where(pk => pk.ChecksumValid && pk.Species != 0 && pk.Sanity == 0)
.Distinct());
// Load stats for pkm who do not have any
foreach (var pk in RawDB.Where(z => z.Stat_Level == 0))
{
pk.Stat_Level = pk.CurrentLevel;
pk.SetStats(pk.GetStats(pk.PersonalInfo));
}
try
{
BeginInvoke(new MethodInvoker(() => SetResults(RawDB)));
}
catch { /* Window Closed? */ }
}
// IO Usage
private void OpenDB(object sender, EventArgs e)
{
if (Directory.Exists(DatabasePath))
Process.Start("explorer.exe", DatabasePath);
}
private void Menu_Export_Click(object sender, EventArgs e)
{
if (Results == null || Results.Count == 0)
{ WinFormsUtil.Alert(MsgDBCreateReportFail); return; }
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgDBExportResultsPrompt))
return;
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (DialogResult.OK != fbd.ShowDialog())
return;
string path = fbd.SelectedPath;
Directory.CreateDirectory(path);
foreach (PKM pkm in Results)
File.WriteAllBytes(Path.Combine(path, Util.CleanFileName(pkm.FileName)), pkm.DecryptedBoxData);
}
private void Menu_Import_Click(object sender, EventArgs e)
{
if (!BoxView.GetBulkImportSettings(out var clearAll, out var noSetb))
return;
int box = BoxView.Box.CurrentBox;
if (!SAV.LoadBoxes(Results, out var result, box, clearAll, noSetb))
return;
BoxView.SetPKMBoxes();
BoxView.UpdateBoxViewers();
WinFormsUtil.Alert(result);
}
// View Updates
private IEnumerable<PKM> SearchDatabase()
{
// Populate Search Query Result
IEnumerable<PKM> res = RawDB;
// Filter for Selected Source
if (!Menu_SearchBoxes.Checked)
res = res.Where(pk => pk.Identifier.StartsWith(DatabasePath + Path.DirectorySeparatorChar, StringComparison.Ordinal));
if (!Menu_SearchDatabase.Checked)
{
res = res.Where(pk => !pk.Identifier.StartsWith(DatabasePath + Path.DirectorySeparatorChar, StringComparison.Ordinal));
#if LOADALL
res = res.Where(pk => !pk.Identifier.StartsWith(EXTERNAL_SAV, StringComparison.Ordinal));
#endif
}
int formatOption = (MAXFORMAT - CB_Format.SelectedIndex) + 1; // 0->(n-1) => 1->n
int formatOperand = CB_FormatComparator.SelectedIndex;
res = FilterByFormat(res, formatOption, formatOperand);
res = FilterByGeneration(res, CB_Generation.SelectedIndex);
// Primary Searchables
int species = WinFormsUtil.GetIndex(CB_Species);
int ability = WinFormsUtil.GetIndex(CB_Ability);
int nature = WinFormsUtil.GetIndex(CB_Nature);
int item = WinFormsUtil.GetIndex(CB_HeldItem);
if (species != -1) res = res.Where(pk => pk.Species == species);
if (ability != -1) res = res.Where(pk => pk.Ability == ability);
if (nature != -1) res = res.Where(pk => pk.Nature == nature);
if (item != -1) res = res.Where(pk => pk.HeldItem == item);
// Secondary Searchables
int move1 = WinFormsUtil.GetIndex(CB_Move1);
int move2 = WinFormsUtil.GetIndex(CB_Move2);
int move3 = WinFormsUtil.GetIndex(CB_Move3);
int move4 = WinFormsUtil.GetIndex(CB_Move4);
var moves = new[] { move1, move2, move3, move4 }.Where(z => z > 0).ToList();
int count = moves.Count;
if (count > 0) res = res.Where(pk => pk.Moves.Intersect(moves).Count() == count);
int vers = WinFormsUtil.GetIndex(CB_GameOrigin);
if (vers != -1) res = res.Where(pk => pk.Version == vers);
int hptype = WinFormsUtil.GetIndex(CB_HPType);
if (hptype != -1) res = res.Where(pk => pk.HPType == hptype);
switch (CHK_Shiny.CheckState)
{
case CheckState.Checked:
res = res.Where(pk => pk.IsShiny);
break;
case CheckState.Unchecked:
res = res.Where(pk => !pk.IsShiny);
break;
}
switch (CHK_IsEgg.CheckState)
{
case CheckState.Checked when int.TryParse(MT_ESV.Text, out int esv):
res = res.Where(pk => pk.IsEgg && pk.PSV == esv);
break;
case CheckState.Checked:
res = res.Where(pk => pk.IsEgg);
break;
case CheckState.Unchecked:
res = res.Where(pk => !pk.IsEgg);
break;
}
// Tertiary Searchables
res = FilterByLVL(res, CB_Level.SelectedIndex, TB_Level.Text);
res = FilterByIVs(res, CB_IV.SelectedIndex);
res = FilterByEVs(res, CB_EVTrain.SelectedIndex);
if (Menu_SearchLegal.Checked && !Menu_SearchIllegal.Checked)
res = res.Where(pk => new LegalityAnalysis(pk).Valid);
if (!Menu_SearchLegal.Checked && Menu_SearchIllegal.Checked)
res = res.Where(pk => !new LegalityAnalysis(pk).Valid);
if (RTB_Instructions.Lines.Any(line => line.Length > 0))
{
var filters = StringInstruction.GetFilters(RTB_Instructions.Lines).ToArray();
BatchEditing.ScreenStrings(filters);
res = res.Where(pkm => BatchEditing.IsFilterMatch(filters, pkm)); // Compare across all filters
}
if (Menu_SearchClones.Checked)
res = res.GroupBy(Hash).Where(group => group.Count() > 1).SelectMany(z => z);
return res;
}
private static IEnumerable<PKM> FilterByFormat(IEnumerable<PKM> res, int format, int formatOperand)
{
switch (formatOperand)
{
default: return res; /* Do nothing */
case 1: res = res.Where(pk => pk.Format >= format); break;
case 2: res = res.Where(pk => pk.Format == format); break;
case 3: res = res.Where(pk => pk.Format <= format); break;
}
if (format <= 2) // 1-2
return res.Where(pk => pk.Format <= 2);
if (format >= 3 && format <= 6) // 3-6
return res.Where(pk => pk.Format >= 3);
return res;
}
private static IEnumerable<PKM> FilterByGeneration(IEnumerable<PKM> res, int option)
{
switch (option)
{
default: return res; /* Do nothing */
case 1: return res.Where(pk => pk.Gen7);
case 2: return res.Where(pk => pk.Gen6);
case 3: return res.Where(pk => pk.Gen5);
case 4: return res.Where(pk => pk.Gen4);
case 5: return res.Where(pk => pk.Gen3);
case 6: return res.Where(pk => pk.VC || pk.Format < 3);
}
}
private static IEnumerable<PKM> FilterByLVL(IEnumerable<PKM> res, int option, string lvl)
{
if (string.IsNullOrWhiteSpace(lvl))
return res;
if (!int.TryParse(lvl, out int level))
return res;
if (level > 100)
return res;
switch (option)
{
default: return res; // Any (Do nothing)
case 3: // <=
return res.Where(pk => pk.Stat_Level <= level);
case 2: // ==
return res.Where(pk => pk.Stat_Level == level);
case 1: // >=
return res.Where(pk => pk.Stat_Level >= level);
}
}
private static IEnumerable<PKM> FilterByEVs(IEnumerable<PKM> res, int option)
{
switch (option)
{
default: return res; // Any (Do nothing)
case 1: // None (0)
return res.Where(pk => pk.EVTotal == 0);
case 2: // Some (127-0)
return res.Where(pk => pk.EVTotal < 128);
case 3: // Half (128-507)
return res.Where(pk => pk.EVTotal >= 128 && pk.EVTotal < 508);
case 4: // Full (508+)
return res.Where(pk => pk.EVTotal >= 508);
}
}
private static IEnumerable<PKM> FilterByIVs(IEnumerable<PKM> res, int option)
{
switch (option)
{
default: return res; // Do nothing
case 1: // <= 90
return res.Where(pk => pk.IVTotal <= 90);
case 2: // 91-120
return res.Where(pk => pk.IVTotal > 90 && pk.IVTotal <= 120);
case 3: // 121-150
return res.Where(pk => pk.IVTotal > 120 && pk.IVTotal <= 150);
case 4: // 151-179
return res.Where(pk => pk.IVTotal > 150 && pk.IVTotal < 180);
case 5: // 180+
return res.Where(pk => pk.IVTotal >= 180);
case 6: // == 186
return res.Where(pk => pk.IVTotal == 186);
}
}
private async void B_Search_Click(object sender, EventArgs e)
{
B_Search.Enabled = false;
var search = SearchDatabase();
bool legalSearch = Menu_SearchLegal.Checked ^ Menu_SearchIllegal.Checked;
if (legalSearch && WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgDBSearchLegalityWordfilter) == DialogResult.No)
Legal.CheckWordFilter = false;
var results = await Task.Run(() => search.ToList()).ConfigureAwait(true);
Legal.CheckWordFilter = true;
if (results.Count == 0)
{
if (!Menu_SearchBoxes.Checked && !Menu_SearchDatabase.Checked)
WinFormsUtil.Alert(MsgDBSearchFail, MsgDBSearchNone);
else
WinFormsUtil.Alert(MsgDBSearchNone);
}
SetResults(results); // updates Count Label as well.
System.Media.SystemSounds.Asterisk.Play();
B_Search.Enabled = true;
}
private void UpdateScroll(object sender, ScrollEventArgs e)
{
if (e.OldValue != e.NewValue)
FillPKXBoxes(e.NewValue);
}
private void SetResults(List<PKM> res)
{
Results = res;
SCR_Box.Maximum = (int)Math.Ceiling((decimal)Results.Count / RES_MIN);
if (SCR_Box.Maximum > 0) SCR_Box.Maximum--;
slotSelected = -1; // reset the slot last viewed
SCR_Box.Value = 0;
FillPKXBoxes(0);
L_Count.Text = string.Format(Counter, Results.Count);
B_Search.Enabled = true;
}
private void FillPKXBoxes(int start)
{
if (Results == null)
{
for (int i = 0; i < RES_MAX; i++)
PKXBOXES[i].Image = null;
return;
}
int begin = start*RES_MIN;
int end = Math.Min(RES_MAX, Results.Count - start*RES_MIN);
for (int i = 0; i < end; i++)
PKXBOXES[i].Image = Results[i + begin].Sprite();
for (int i = end; i < RES_MAX; i++)
PKXBOXES[i].Image = null;
for (int i = 0; i < RES_MAX; i++)
PKXBOXES[i].BackgroundImage = Properties.Resources.slotTrans;
if (slotSelected != -1 && slotSelected >= RES_MIN * start && slotSelected < RES_MIN * start + RES_MAX)
PKXBOXES[slotSelected - start * RES_MIN].BackgroundImage = slotColor ?? Properties.Resources.slotView;
}
// Misc Update Methods
private void ToggleESV(object sender, EventArgs e)
{
L_ESV.Visible = MT_ESV.Visible = CHK_IsEgg.CheckState == CheckState.Checked;
}
private void ChangeLevel(object sender, EventArgs e)
{
if (CB_Level.SelectedIndex == 0)
TB_Level.Text = string.Empty;
}
private void ChangeGame(object sender, EventArgs e)
{
if (CB_GameOrigin.SelectedIndex != 0)
CB_Generation.SelectedIndex = 0;
}
private void ChangeGeneration(object sender, EventArgs e)
{
if (CB_Generation.SelectedIndex != 0)
CB_GameOrigin.SelectedIndex = 0;
}
private void Menu_SearchAdvanced_Click(object sender, EventArgs e)
{
if (!Menu_SearchAdvanced.Checked)
{ Size = MinimumSize; RTB_Instructions.Clear(); }
else Size = MaximumSize;
}
private void Menu_Exit_Click(object sender, EventArgs e)
{
Close();
}
protected override void OnMouseWheel(MouseEventArgs e)
{
if (!PAN_Box.RectangleToScreen(PAN_Box.ClientRectangle).Contains(MousePosition))
return;
int oldval = SCR_Box.Value;
int newval = oldval + (e.Delta < 0 ? 1 : -1);
if (newval >= SCR_Box.Minimum && SCR_Box.Maximum >= newval)
FillPKXBoxes(SCR_Box.Value = newval);
}
private void ChangeFormatFilter(object sender, EventArgs e)
{
if (CB_FormatComparator.SelectedIndex == 0)
{
CB_Format.Visible = false; // !any
CB_Format.SelectedIndex = 0;
}
else
{
CB_Format.Visible = true;
int index = MAXFORMAT - SAV.Generation + 1;
CB_Format.SelectedIndex = index < CB_Format.Items.Count ? index : 0; // SAV generation (offset by 1 for "Any")
}
}
private void Menu_DeleteClones_Click(object sender, EventArgs e)
{
var dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNo,
MsgDBDeleteCloneWarning + Environment.NewLine +
MsgDBDeleteCloneAdvice, MsgContinue);
if (dr != DialogResult.Yes)
return;
var deleted = 0;
var db = RawDB.Where(pk => pk.Identifier.StartsWith(DatabasePath + Path.DirectorySeparatorChar, StringComparison.Ordinal))
.OrderByDescending(file => new FileInfo(file.Identifier).LastWriteTime);
var clones = db.GroupBy(Hash).Where(group => group.Count() > 1).SelectMany(z => z.Skip(1));
foreach (var pk in clones)
{
try { File.Delete(pk.Identifier); ++deleted; }
catch { WinFormsUtil.Error(MsgDBDeleteCloneFail + Environment.NewLine + pk.Identifier); }
}
if (deleted == 0)
{ WinFormsUtil.Alert(MsgDBDeleteCloneNone); return; }
WinFormsUtil.Alert(string.Format(MsgFileDeleteCount, deleted), MsgWindowClose);
Close();
}
}
}