コード例 #1
0
        private void OnStart()
        {
            // Form size
            MinimumSize = Size;
            if (!FeatureConfig["AllowWindowResize"])
            {
                MaximumSize = Size;
                MaximizeBox = false;
            }

            // Create the supported extensions to a filter
            extsFilter = FormMethods.CreateExtensionFilter(extsArray);

            // Listen to pressed keys
            this.KeyPreview = true;
            this.KeyDown   += new KeyEventHandler(FormMethods.ActionListener);

            // Set the app's theme
            AppTheme = new Theme();
            AppTheme.Apply(this);

            // Properly render the status strip in dark mode
            statusStrip.Renderer = new FormMethods.ToolStripLightRenderer();
            if (FormMethods.IsAppInDarkMode())
            {
                statusStrip.Renderer = new FormMethods.ToolStripDarkRenderer();
            }
        }
コード例 #2
0
ファイル: AboutBox.cs プロジェクト: DavidL344/VGAudio.Win32
 private string GetCliProperties()
 {
     if (FormMethods.VerifyIntegrity())
     {
         // https://stackoverflow.com/a/11350038
         var    cliProperties = FileVersionInfo.GetVersionInfo(Main.VGAudioCli);
         string cliName       = cliProperties.ProductName;
         string cliVersion    = cliProperties.FileVersion;
         return(string.Format("{0} {1}", cliName, cliVersion));
     }
     return("(Unknown)");
 }
コード例 #3
0
ファイル: OpenedFile.cs プロジェクト: DavidL344/VGAudio.Win32
        public string LoadCommand(string arguments = null, string workingDirectory = null)
        {
            if (!FormMethods.VerifyIntegrity())
            {
                return(null);
            }

            // If there's an opened file, use its location as a working directory
            if (workingDirectory == null)
            {
                if (Info.ContainsKey("Path"))
                {
                    workingDirectory = Path.GetDirectoryName(Info["Path"]);
                }
                else
                {
                    workingDirectory = Path.GetDirectoryName(Main.VGAudioCli);
                }
            }
            else
            {
                if (!Directory.Exists(workingDirectory))
                {
                    workingDirectory = Path.GetDirectoryName(Main.VGAudioCli);
                }
            }

            ProcessStartInfo procInfo = new ProcessStartInfo
            {
                FileName               = Main.VGAudioCli,
                WorkingDirectory       = workingDirectory,
                Arguments              = arguments,
                RedirectStandardOutput = true,
                UseShellExecute        = false,
                CreateNoWindow         = true,
                WindowStyle            = ProcessWindowStyle.Hidden
            };
            var proc = Process.Start(procInfo);

            proc.WaitForExit();
            if (proc.ExitCode == 0)
            {
                return(proc.StandardOutput.ReadToEnd());
            }
            else
            {
                return(null);
            }
        }
コード例 #4
0
        public async void UpdateStatus(string message = "Ready")
        {
            FormMethods.EnableCloseButton(this);
            switch (message)
            {
            case "Ready":
                if (OpenedFile.Initialized)
                {
                    if (File.Exists(OpenedFile.Info["Path"]))
                    {
                        slb_status.Text = OpenedFile.Metadata["Status"];
                    }
                    else
                    {
                        slb_status.Text = "Please check the path of " + OpenedFile.Info["NameShort_OnError"] + "!";
                    }
                    return;
                }
                slb_status.Text = message;
                break;

            case "Close":
                // The key won't be set if user tries to drag and drop
                // an invalid file while no other file is opened
                if (OpenedFile.Info.ContainsKey("NameShort"))
                {
                    slb_status.Text = "Closed the file: " + OpenedFile.Info["NameShort"];
                    await Task.Delay(2000);
                }

                // Another file might've been opened in the meantime when the previous file was closed
                // Was another file opened during the Task.Delay?
                if (OpenedFile.Initialized)
                {
                    slb_status.Text = "Opened the file: " + OpenedFile.Info["NameShort"];
                    return;
                }
                else
                {
                    slb_status.Text = "Ready";
                }
                break;

            default:
                slb_status.Text = message;
                break;
            }
        }
コード例 #5
0
        private void FileDump(object sender, EventArgs e)
        {
            MainDump mainDump = new MainDump(OpenedFile.Info["Path"], lst_exportExtensions.SelectedItem.ToString().ToLower())
            {
                StartPosition = FormStartPosition.CenterParent,
                Text          = String.Format("Dump Info | {0}", Text)
            };

            mainDump.Size = (this.Width / 2 > 832 && this.Height / 2 > 538) ? new Size(this.Width / 2, 538) : new Size(this.Width, 538);
            mainDump.ShowDialog();

            if (mainDump.Confirmed)
            {
                UpdateStatus("Dumping info...");
                FormMethods.EnableCloseButton(this, false);
                Dictionary <string, Dictionary <string, object> > Options = mainDump.Options;

                try
                {
                    if ((bool)Options["DumpFileInfo"]["Use"])
                    {
                        string   path  = (string)Options["DumpFileInfo"]["FileLocation"];
                        string[] lines = OpenedFile.DumpInformation(Options);
                        File.WriteAllLines(path, lines);
                    }

                    if ((bool)Options["SaveExportInfo"]["Use"])
                    {
                        string path = (string)Options["SaveExportInfo"]["FileLocation"];
                        string line = OpenedFile.GenerateConversionParams(null, false, true);
                        File.WriteAllText(path, String.Format("{0}\r\n", line));
                    }
                }
                catch (Exception ex)
                {
                    UpdateStatus();
                    MessageBox.Show(ex.Message, "Error dumping file information | " + Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                UpdateStatus();
                MessageBox.Show("Info dumped successfully!", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
コード例 #6
0
        public void Apply(Control control)
        {
            // Don't apply the light theme to prevent visual glitches (it is already applied anyway)
            if (!Main.FeatureConfig["AdaptiveDarkMode"] || !FormMethods.IsWindowsInDarkMode())
            {
                return;
            }

            control.ForeColor = ColorScheme["Fore"]["Text"];
            string[] controlName = control.Name.Split('_');
            if (string.IsNullOrWhiteSpace(controlName[0]))
            {
                return;
            }

            switch (controlName[0])
            {
            case "btn":
                control.BackColor = ColorScheme["Back"]["Button"];
                break;

            case "lst":
            case "num":
            case "txt":
                control.BackColor = ColorScheme["Back"]["Window"];
                break;

            default:
                control.BackColor = ColorScheme["Back"]["Control"];
                break;
            }

            if (control.HasChildren)
            {
                foreach (Control c in control.Controls)
                {
                    Apply(c);
                }
            }
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: DavidL344/VGAudio.Win32
        static void Main(string[] args)
        {
            switch (args.Length)
            {
            case 1:
                switch (args[0])
                {
                case "--extract":
                    FormMethods.ExtractCli(true);
                    Environment.Exit(0);
                    break;

                default:
                    break;
                }
                break;

            default:
                break;
            }
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Main());
        }
コード例 #8
0
ファイル: OpenedFile.cs プロジェクト: DavidL344/VGAudio.Win32
        public string TruncateName(int maxLength = 20)
        {
            string fileExtInfo = "... (" + Info["Extension"] + ")";

            // The trim length shouldn't be bigger than the length of the file name itself
            if (fileExtInfo.Length > maxLength)
            {
                return(fileExtInfo);
            }
            int trimLength = maxLength - fileExtInfo.Length;

            if (Info["Name"].Length > maxLength)
            {
                if (Info["Name"].Length > trimLength)
                {
                    string truncate = FormMethods.Truncate(Info["Name"], trimLength);
                    if (Info["Name"] != truncate)
                    {
                        return(truncate + fileExtInfo);
                    }
                }
            }
            return(Info["Name"]);
        }
コード例 #9
0
        public void Load()
        {
            bool DarkMode = false;

            if (Main.FeatureConfig["AdaptiveDarkMode"])
            {
                DarkMode = FormMethods.IsWindowsInDarkMode();
            }

            if (DarkMode)
            {
                ColorScheme["Fore"]["Text"]    = SystemColors.Window;
                ColorScheme["Back"]["Button"]  = SystemColors.ControlDarkDark;
                ColorScheme["Back"]["Control"] = SystemColors.ControlDarkDark;
                ColorScheme["Back"]["Window"]  = SystemColors.ControlDarkDark;
            }
            else
            {
                ColorScheme["Fore"]["Text"]    = SystemColors.ControlText;
                ColorScheme["Back"]["Button"]  = SystemColors.ControlLight;
                ColorScheme["Back"]["Control"] = SystemColors.Control;
                ColorScheme["Back"]["Window"]  = SystemColors.Window;
            }
        }
コード例 #10
0
ファイル: OpenedFile.cs プロジェクト: DavidL344/VGAudio.Win32
        public bool Convert()
        {
            if (!File.Exists(Info["Path"]))
            {
                throw new FileNotFoundException("The opened file no longer exists!");
            }

            // Check if the export file extension is the correct one
            if (Path.GetExtension(ExportInfo["Path"]).ToLower() != ExportInfo["Extension"].ToLower())
            {
                // Error occurs when the user replaces an existing file
                // with invalid export extension through the dialog box
                throw new ArgumentException("The file extension selected is invalid!");
            }

            string arguments = GenerateConversionParams(ExportInfo["PathEscaped"]);

            if (string.IsNullOrEmpty(arguments))
            {
                throw new Exception("Internal Error: No parameters!");
            }
            if (!FormMethods.VerifyIntegrity())
            {
                return(false);
            }
            Lock(false); // Unlock the file

            ProcessStartInfo procInfo = new ProcessStartInfo
            {
                FileName               = Main.VGAudioCli,
                WorkingDirectory       = Path.GetDirectoryName(Info["Path"]),
                Arguments              = arguments,
                RedirectStandardOutput = true,
                UseShellExecute        = false,
                CreateNoWindow         = true,
                WindowStyle            = ProcessWindowStyle.Hidden
            };
            var proc = Process.Start(procInfo);

            string line = "";

            while (!proc.StandardOutput.EndOfStream)
            {
                line += proc.StandardOutput.ReadLine() + "\r\n";
            }
            string[] standardConsoleOutput = line.Split(
                new[] { "\r\n", "\r", "\n" },
                StringSplitOptions.None
                );
            Lock(true); // Relock the file

            // Invalid parameter passed to the CLI
            if (proc.ExitCode != 0)
            {
                throw new ArgumentException(standardConsoleOutput[0]);
            }

            // Progress bar [####   ] starts with '[' and success starts with, well, 'Success!'
            if (!standardConsoleOutput[0].StartsWith("[") && !standardConsoleOutput[0].StartsWith("Success!"))
            {
                throw new NotSupportedException(standardConsoleOutput[0]);
            }

            // Get the time elapsed during the conversion
            string timeElapsed = standardConsoleOutput[1].Substring(standardConsoleOutput[1].IndexOf(":") + 1);

            ExportResult["TimeElapsed"] = TimeSpan.FromSeconds(System.Convert.ToDouble(timeElapsed)).ToString(@"hh\:mm\:ss\.fff");
            return(true);
        }
コード例 #11
0
ファイル: OpenedFile.cs プロジェクト: DavidL344/VGAudio.Win32
        public string GenerateConversionParams(string exportLocation = null, bool silent = true, bool batchFormat = false)
        {
            if (exportLocation == null)
            {
                exportLocation = String.Format("\"{0}\"", Path.ChangeExtension(Info["Path"], ExportInfo["Extension"]));
            }
            string arguments = String.Format("-i {0} -o {1}", Info["PathEscaped"], exportLocation);

            GetWarnings(); // This won't be necessary once the controls use GetWarnings() on value change

            if (ExportLoop["Enabled"] == 1)
            {
                if (ExportLoop["Start"] > ExportLoop["End"])
                {
                    // The loop information is invalid - the file would contain a negative number of samples
                    arguments += " --no-loop";
                }
                else
                {
                    arguments += String.Format(" -l {0}-{1}", ExportLoop["Start"], ExportLoop["End"]);
                }
            }
            else
            {
                arguments += " --no-loop";
            }

            if ((bool)AdvancedExportInfo["Apply"])
            {
                switch (ExportInfo["ExtensionNoDot"])
                {
                case "adx":
                    if ((bool)AdvancedExportInfo["ADX_encrypt"])
                    {
                        switch (AdvancedExportInfo["ADX_type"])
                        {
                        case "Linear":
                        case "Fixed":
                            arguments += " --adxtype " + AdvancedExportInfo["ADX_type"];
                            break;

                        case "Exponential":
                            arguments += " --adxtype Exp";
                            break;

                        default:
                            break;
                        }

                        if ((bool)AdvancedExportInfo["ADX_keystring_use"])
                        {
                            if (AdvancedExportInfo.TryGetValue("ADX_keystring", out object keystring))
                            {
                                arguments += " --keystring " + keystring;
                            }
                        }

                        if ((bool)AdvancedExportInfo["ADX_keycode_use"])
                        {
                            if (AdvancedExportInfo.TryGetValue("ADX_keycode", out object keycode))
                            {
                                arguments += " --keycode " + keycode;
                            }
                        }

                        switch (AdvancedExportInfo["ADX_filter"])
                        {
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                            arguments += " --filter " + AdvancedExportInfo["ADX_filter"];
                            break;

                        default:
                            break;
                        }

                        switch (AdvancedExportInfo["ADX_version"])
                        {
                        case 3:
                        case 4:
                            arguments += " --version " + AdvancedExportInfo["ADX_version"];
                            break;

                        default:
                            break;
                        }
                    }
                    break;

                case "brstm":
                    switch (AdvancedExportInfo["BRSTM_audioFormat"])
                    {
                    case "DSP-ADPCM":
                        // If not specified, the file is converted to DSP-ADPCM audio format
                        break;

                    case "16-bit PCM":
                        arguments += " -f pcm16";
                        break;

                    case "8-bit PCM":
                        arguments += " -f pcm8";
                        break;

                    default:
                        break;
                    }
                    break;

                case "hca":
                    switch (AdvancedExportInfo["HCA_audioRadioButtonSelector"])
                    {
                    case "quality":
                        arguments += " --hcaquality " + AdvancedExportInfo["HCA_audioQuality"];
                        break;

                    case "bitrate":
                        arguments += " --bitrate " + AdvancedExportInfo["HCA_audioBitrate"];
                        break;

                    default:
                        break;
                    }
                    if ((bool)AdvancedExportInfo["HCA_limitBitrate"])
                    {
                        arguments += " --limit-bitrate";
                    }
                    break;

                default:
                    break;
                }
            }

            int chcp = 65001;

            if (!silent)
            {
                string commentCharacter = "";
                if (batchFormat)
                {
                    commentCharacter = ":: ";
                }
                string warnings = "";
                if (Warnings.Count > 0)
                {
                    foreach (var warning in Warnings)
                    {
                        warnings += String.Format("\r\n{0}[WARNING] {1}", commentCharacter, warning.ToString());
                    }
                }
                else
                {
                    warnings = null;
                }

                string title = FormMethods.GetAppInfo("name") + " (" + FormMethods.GetAppInfo("version") + ")";
                if (batchFormat)
                {
                    arguments = String.Format(":: {0}\r\n:: Original file: {1}\r\n:: The converted file: {2}{3}\r\n\r\n@echo off\r\nchcp {4}>nul\r\nVGAudioCli.exe {5}\r\npause>nul", title, Info["Path"], exportLocation, warnings, chcp, arguments);
                }
                else
                {
                    if (warnings != null)
                    {
                        warnings = String.Format("\r\n{0}", warnings);
                    }
                    arguments += warnings;
                }
            }
            else
            {
                if (batchFormat)
                {
                    arguments = String.Format("@echo off\r\nchcp {0}>nul\r\nVGAudioCli.exe {1}\r\npause>nul", chcp, arguments);
                }
            }
            return(arguments);
        }
コード例 #12
0
ファイル: OpenedFile.cs プロジェクト: DavidL344/VGAudio.Win32
        public string[] DumpInformation(Dictionary <string, Dictionary <string, object> > Options)
        {
            bool dumpExportInfo = (bool)Options["DumpFileInfo"]["IncludeExportInformation"];

            string[] lines;
            int?     exportLoop = ExportLoop["Enabled"];

            List <string> lineList = new List <string>
            {
                FormMethods.GetAppInfo("name") + " (" + FormMethods.GetAppInfo("version") + ")",
                "Dumped Info (" + Info["Name"] + ")\r\n",
                Metadata["Full"]
            };

            if (dumpExportInfo)
            {
                lineList.Add("----------\r\n");
                lineList.Add("Custom Export Info:");
                lineList.Add("Target file: " + ExportInfo["ExtensionNoDot"]);

                if (exportLoop == 1)
                {
                    lineList.Add("Loop start: " + ExportLoop["Start"]);
                    lineList.Add("Loop end: " + ExportLoop["End"]);
                }

                if ((bool)AdvancedExportInfo["Apply"])
                {
                    switch (ExportInfo["ExtensionNoDot"])
                    {
                    case "adx":
                        if ((bool)AdvancedExportInfo["ADX_encrypt"])
                        {
                            lineList.Add("Encoding type: " + AdvancedExportInfo["ADX_type"]);
                            if ((bool)AdvancedExportInfo["ADX_keystring_use"])
                            {
                                lineList.Add("Keystring: " + AdvancedExportInfo["ADX_keystring"]);
                            }
                            if ((bool)AdvancedExportInfo["ADX_keycode_use"])
                            {
                                lineList.Add("Keycode: " + AdvancedExportInfo["ADX_keycode"]);
                            }
                            if ((bool)AdvancedExportInfo["ADX_filter_use"])
                            {
                                lineList.Add("Encoding filter: " + AdvancedExportInfo["ADX_filter"]);
                            }
                            if ((bool)AdvancedExportInfo["ADX_version_use"])
                            {
                                lineList.Add("Header version: " + AdvancedExportInfo["ADX_version"]);
                            }
                        }
                        break;

                    case "brstm":
                        lineList.Add("Audio format: " + AdvancedExportInfo["BRSTM_audioFormat"]);
                        break;

                    case "hca":
                        switch (AdvancedExportInfo["HCA_audioRadioButtonSelector"])
                        {
                        case "quality":
                            lineList.Add("Audio quality: " + AdvancedExportInfo["HCA_audioQuality"]);
                            break;

                        case "bitrate":
                            lineList.Add("Audio bitrate: " + AdvancedExportInfo["HCA_audioBitrate"]);
                            break;

                        default:
                            break;
                        }
                        break;

                    default:
                        break;
                    }
                }

                string conversionCommand = GenerateConversionParams(null, false);
                if (conversionCommand == null)
                {
                    conversionCommand = "(unable to generate)";
                }
                else
                {
                    conversionCommand = "VGAudioCli.exe " + conversionCommand;
                }
                lineList.Add("\r\nConversion command:\r\n" + conversionCommand);
            }
            lines = lineList.ToArray();
            return(lines);
        }
コード例 #13
0
ファイル: OpenedFile.cs プロジェクト: DavidL344/VGAudio.Win32
        public bool ParseMetadata(string metadata)
        {
            // Parse the file information - if it fails, close the file
            Metadata["Full"]           = metadata;
            Metadata["EncodingFormat"] = FormMethods.GetBetween(metadata, "Encoding format: ", "\r\n");
            Metadata["SampleCount"]    = FormMethods.GetBetween(metadata, "Sample count: ", " (");
            Metadata["SampleRate"]     = FormMethods.GetBetween(metadata, "Sample rate: ", "\r\n");
            Metadata["ChannelCount"]   = FormMethods.GetBetween(metadata, "Channel count: ", "\r\n");
            Metadata["Short"]          = Metadata["EncodingFormat"] + "\r\nSample Rate: " + Metadata["SampleRate"] + "\r\nChannel Count: " + Metadata["ChannelCount"];

            string channelSetup;

            switch (int.Parse(Metadata["ChannelCount"]))
            {
            case 0:
                channelSetup = "no channels";
                break;

            case 1:
                channelSetup = "mono";
                break;

            case 2:
                channelSetup = "stereo";
                break;

            default:
                channelSetup = Metadata["ChannelCount"];
                break;
            }

            Metadata["Status"] = String.Format("{0} | {1} | {2}", Metadata["EncodingFormat"], Metadata["SampleRate"], channelSetup);

            // Check if the file has a valid sample count
            if (!int.TryParse(Metadata["SampleCount"], out int mSampleCount))
            {
                // The file contains invalid sample count
                return(false);
            }

            // Parse the loop information
            string mLoopStartVar = FormMethods.GetBetween(metadata, "Loop start: ", " samples");
            string mLoopEndVar   = FormMethods.GetBetween(metadata, "Loop end: ", " samples");

            // Note: Loop["StartMax"] and Loop["EndMin"] are valid only upon loading the file
            // These two variables should be updated dynamically directly in the form to prevent overlapping
            if (int.TryParse(mLoopStartVar, out int mLoopStart) && int.TryParse(mLoopEndVar, out int mLoopEnd))
            {
                Loop["Enabled"] = 1;

                Loop["Start"]  = mLoopStart;   // Save the loop start
                Loop["End"]    = mLoopEnd;     // Save the loop start
                Loop["EndMax"] = mSampleCount; // Makes sure the user doesn't input more samples than the file has
            }
            else
            {
                Loop["Enabled"] = 0;
                Loop["Start"]   = 0;

                // If there's no loop, the loop end is set as the end of the file by default
                Loop["EndMax"] = Loop["End"] = mSampleCount;
            }

            // Set default loop information for the imported file
            Loop["StartMin"] = 0;                 // The loop start value cannot be lower than the beginning of the file
            Loop["StartMax"] = Loop["End"] - 1;   // Makes sure the user can only input lower number than the loop's end
            Loop["EndMin"]   = Loop["Start"] + 1; // Loop end has to be a bigger number than loop start

            // These values can be modified and will be used upon export
            ExportLoop["Enabled"]  = Loop["Enabled"];
            ExportLoop["StartMin"] = Loop["StartMin"];
            ExportLoop["Start"]    = Loop["Start"];
            ExportLoop["StartMax"] = Loop["StartMax"];
            ExportLoop["EndMin"]   = Loop["EndMin"];
            ExportLoop["End"]      = Loop["End"];
            ExportLoop["EndMax"]   = Loop["EndMax"];
            return(true);
        }
コード例 #14
0
        private void FileExport(object sender, EventArgs e)
        {
            UpdateStatus("Converting the file...");

            // If the file was missing or inaccessible, but suddenly is, relock it again
            OpenedFile.Lock(true);

            if (OpenedFile.ExportInfo["ExtensionNoDot"] == null)
            {
                UpdateStatus();
                MessageBox.Show("Please select the exported file's extension!", Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (OpenedFile.Info["ExtensionNoDot"] == OpenedFile.ExportInfo["ExtensionNoDot"])
            {
                DialogResult dialogResult = MessageBox.Show("The file you're trying to export has the same extension as the original file. Some of the changes might not be applied.\r\nContinue?", Text, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                if (dialogResult != DialogResult.Yes)
                {
                    UpdateStatus();
                    return;
                }
            }

            if (OpenedFile.ExportLoop["Enabled"] == 1)
            {
                if (OpenedFile.ExportInfo["ExtensionNoDot"] == "wav")
                {
                    // Encoding the loop information into the wave file
                    // is useful only for conversions done later on (to a format that supports it)
                    DialogResult dialogResult = MessageBox.Show("While the wave file can hold loop information, it won't be read by most media players.\r\nExport the loop information anyway?", Text, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                    switch (dialogResult)
                    {
                    case DialogResult.Yes:
                        break;

                    case DialogResult.No:
                        chk_loop.Checked = false;
                        break;

                    case DialogResult.Cancel:
                    default:
                        UpdateStatus();
                        return;
                    }
                }
            }
            else
            {
                if (OpenedFile.ExportLoop["Enabled"] == 1)
                {
                    DialogResult dialogResult = MessageBox.Show("The imported file has loop information, which will be lost upon export.\r\nContinue the export without the loop information?", Text, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                    if (dialogResult != DialogResult.Yes)
                    {
                        UpdateStatus();
                        return;
                    }
                }
            }

            // Select the save location
            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                InitialDirectory = Path.GetDirectoryName(OpenedFile.Info["Path"]),
                Title            = "Export " + OpenedFile.Info["NameNoExtension"] + "." + OpenedFile.ExportInfo["ExtensionNoDot"],
                CheckFileExists  = false,
                CheckPathExists  = true,
                DefaultExt       = OpenedFile.ExportInfo["ExtensionNoDot"],
                Filter           = OpenedFile.ExportInfo["ExtensionNoDot"].ToUpper() + " audio file (*." + OpenedFile.ExportInfo["ExtensionNoDot"] + ")|*." + OpenedFile.ExportInfo["ExtensionNoDot"],
                FilterIndex      = 1,
                RestoreDirectory = true
            };

            if (FeatureConfig["PrefillExportFileName"])
            {
                saveFileDialog.FileName = OpenedFile.Info["NameNoExtension"] + "." + OpenedFile.ExportInfo["ExtensionNoDot"];
            }

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                OpenedFile.ExportInfo["Path"]        = saveFileDialog.FileName;
                OpenedFile.ExportInfo["PathEscaped"] = String.Format("\"{0}\"", Path.GetFullPath(OpenedFile.ExportInfo["Path"]));
                FormMethods.EnableCloseButton(this, false);
                try
                {
                    if (OpenedFile.Convert())
                    {
                        UpdateStatus();
                        string successMessage = "Task performed successfully.";
                        if (FeatureConfig["ShowTimeElapsed"])
                        {
                            successMessage += String.Format(" Time elapsed: {0}", OpenedFile.ExportResult["TimeElapsed"]);
                        }
                        MessageBox.Show(successMessage, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
                catch (Exception ex)
                {
                    OpenedFile.Lock(true);
                    UpdateStatus();

                    string exceptionTitle = "Fatal Error";
                    if (ex is NotSupportedException)
                    {
                        exceptionTitle = "Conversion Error";
                    }
                    if (ex is ArgumentException)
                    {
                        exceptionTitle = "Error";
                    }
                    MessageBox.Show(ex.Message, String.Format("{0} | {1}", exceptionTitle, Text), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                finally
                {
                    FormMethods.EnableCloseButton(this);
                }
            }
            UpdateStatus();
            return;
        }