private async void bOK_Click(object sender, System.EventArgs e)
        {
            Enabled = false;
            bool   merge = rbMerge.Checked;
            string rpath = tbFilepath.Text;
            string rootDir;

            ResourceExportINIFile rfile = new ResourceExportINIFile();

            try
            {
                rootDir = Path.GetDirectoryName(rpath);
                rfile.ReadFromFile(rpath);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Import failed.\nThe data file is in the incorrect format.\n\nException: {0}".F(ex.Message));
                Enabled = true;
                return;
            }

            try
            {
                if (rfile.EntryCount < _resourceFile.Resources.Count)
                {
                    if (MessageBox.Show("The entry count declared in the import data is {0}, but the current resource file has {1} entries.\nIf you continue, the resource file will be truncated. Entries above {0:0000} will be cleared.\nAre you sure you want to proceed?".F(rfile.EntryCount, _resourceFile.Resources.Count)
                                        , "Dune 2000 Editor"
                                        , MessageBoxButtons.YesNo)
                        != DialogResult.Yes)
                    {
                        return;
                    }
                }

                Progress <int> p = new Progress <int>();
                pbarProgress.Maximum = rfile.EntryCount;
                pbarProgress.Value   = 0;
                lblProgress.Text     = "Setting up...";
                p.ProgressChanged   += (s, id) =>
                {
                    pbarProgress.Value = id;
                    lblProgress.Text   = "{0} / {1}".F(id, rfile.EntryCount);
                };

                Palette_18Bit pal = BasePalette.Clone();
                await Task.Factory.StartNew(() =>
                {
                    if (merge)
                    {
                        rfile.ImportMerge(_resourceFile.Resources, pal, rootDir, p);
                    }
                    else
                    {
                        rfile.ImportReplace(_resourceFile.Resources, pal, rootDir, p);
                    }
                });

                //t.Wait();

                pbarProgress.Value = pbarProgress.Maximum;
                lblProgress.Text   = "Finished!";
                MessageBox.Show("Import completed!");
                DialogResult = DialogResult.OK;
                Close();
            }
            catch (AggregateException ex)
            {
                MessageBox.Show("Import failed.\n\nReason: {0}".F(ex.InnerException?.Message ?? ex.Message));
            }
            finally
            {
                pbarProgress.Value = 0;
                lblProgress.Text   = "";
                Enabled            = true;
            }
        }
        private async void bOK_Click(object sender, System.EventArgs e)
        {
            Enabled = false;
            bool exportAll = cbSelectAll.Checked;

            List <int> selected = new List <int>(lboxItems.SelectedIndices.Count);

            if (!exportAll)
            {
                foreach (int s in lboxItems.SelectedIndices)
                {
                    selected.Add(s);
                }
            }

            try
            {
                string        rpath             = tbFilepath.Text;
                string        rootDir           = Path.GetDirectoryName(rpath);
                string        relImagePathFmt   = @"images\img_{0:0000}.png";
                string        relPalettePathFmt = @"palettes\pal_{0:0000}.bin";
                Palette_18Bit pal = BasePalette.Clone();
                Directory.CreateDirectory(rootDir);
                Directory.CreateDirectory(Path.Combine(rootDir, "images"));
                Directory.CreateDirectory(Path.Combine(rootDir, "palettes"));

                ResourceExportINIFile rfile = new ResourceExportINIFile();
                rfile.EntryCount = _resource.Resources.Count;

                Progress <int> p = new Progress <int>();
                pbarProgress.Maximum = rfile.EntryCount;
                pbarProgress.Value   = 0;
                lblProgress.Text     = "Setting up...";
                p.ProgressChanged   += (s, id) =>
                {
                    pbarProgress.Value = id;
                    lblProgress.Text   = "{0} / {1}".F(id, rfile.EntryCount);
                };

                await Task.Factory.StartNew(() =>
                {
                    if (exportAll)
                    {
                        rfile.Export(pal, _resource.Resources, rootDir, relImagePathFmt, relPalettePathFmt, p);
                    }
                    else
                    {
                        foreach (int index in selected.ToArray())
                        {
                            rfile.Export(pal, index, _resource.Resources[index], rootDir, relImagePathFmt.F(index), relPalettePathFmt.F(index), p);
                        }
                    }
                    rfile.WriteToFile(rpath);
                });

                pbarProgress.Value = pbarProgress.Maximum;
                lblProgress.Text   = "Finished!";
                MessageBox.Show("Export completed!");
            }
            catch (AggregateException ex)
            {
                MessageBox.Show("Export failed.\n\nReason: {0}".F(ex.InnerException?.Message ?? ex.Message));
            }
            finally
            {
                pbarProgress.Value = 0;
                lblProgress.Text   = "";
                Enabled            = true;
            }
        }