Add project files.

This commit is contained in:
2025-07-29 08:31:00 -06:00
commit 296738f5ed
58 changed files with 7095 additions and 0 deletions

View File

@@ -0,0 +1,787 @@
using Serilog;
using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
namespace Files2Folders2Files_GUI
{
/// <summary>
/// FrmFiles2Folders2Files Form Class.
/// </summary>
public partial class FrmFiles2Folders2Files : Form
{
#region Constructors
Files2Folders2Files.Files2Folders2Files f2f2f = new Files2Folders2Files.Files2Folders2Files();
/// <summary>
/// FrmFiles2Folders2Files-GUI Constructor
/// </summary>
public FrmFiles2Folders2Files()
{
// Initialize the form.
InitializeComponent();
// Print the version.
f2f2f.PrintVersion();
// Load the default options passed from the default options file.
f2f2f.LoadOptionsFromFile();
// Load the default options passed from the command line arguments.
f2f2f.LoadOptionsFromCLI(Environment.GetCommandLineArgs());
// Add data bindings.
chkDeleteEmptyFolders.DataBindings.Add("Checked", f2f2f, "DeleteEmptyFolders");
txtDirectoryPath.DataBindings.Add("Text", f2f2f, "DirectoryPath");
lblRegistrationKey.DataBindings.Add("Text", f2f2f, "RegistrationKey");
lblRegistrationStatus.DataBindings.Add("Text", f2f2f, "RegistrationStatus");
txtRegisterAppUsername.DataBindings.Add("Text", f2f2f, "RegisterAppUsername");
txtRegisterAppEmailAddress.DataBindings.Add("Text", f2f2f, "RegisterAppEmailAddress");
txtRegisterAppPassword.DataBindings.Add("Text", f2f2f, "RegisterAppPassword");
// Hide some tabs.
tcMain.TabPages.Remove(tabHelp);
tcMain.TabPages.Remove(tabLicense);
tcMain.TabPages.Remove(tabDonations);
tcMain.TabPages.Remove(tabRegistration);
// Update the title.
UpdateTitle();
// Load the GUI RichTextBoxes from resources.
rtbHelp.Text = Files2Folders2Files.Properties.Resources.Files2Folders2Files_HELP;
rtbLicense.Text = Files2Folders2Files.Properties.Resources.Files2Folders2Files_LICENSE;
rtbDonations.Text = Files2Folders2Files.Properties.Resources.Files2Folders2Files_DONATIONS;
}
#endregion
#region Public Accessors
/// LogLines
public string[] LogLines
{
get { return rtblLog.Lines; }
set { rtblLog.Lines = value; }
}
#endregion
#region Log
/// <summary>
/// Saves the log to a text file.
/// </summary>
/// <param name="strPath"></param>
/// <returns></returns>
public bool SaveLogToFile(string strPath = null)
{
try
{
if (strPath != null)
{
f2f2f.PathLogFile = strPath;
}
// Determine if the user selected a log filename.
if (f2f2f.PathLogFile.Length == 0)
{
// Return a bool value.
return false;
}
else
{
// Print to screen
Log.Information("Saving log file ...");
// Create log file directory if it doesn't exist.
if (Directory.Exists(Path.GetDirectoryName(f2f2f.PathLogFile)) == false) Directory.CreateDirectory(Path.GetDirectoryName(f2f2f.PathLogFile));
// Save the contents of the log to a text file.
File.WriteAllLines(f2f2f.PathLogFile, LogLines);
// Print to screen
Log.Information("Log file saved (" + f2f2f.PathLogFile + ")");
// Return a bool value.
return true;
}
}
catch (Exception ex)
{
// Print to screen
Log.Error("Saving log file failed");
Log.Error(ex.Message);
// Return a bool value.
return false;
}
}
#endregion
#region Startup Tasks
/// <summary>
/// Performs the startup tasks.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StartupTasks_DoWork(object sender, DoWorkEventArgs e)
{
// Stub
}
/// <summary>
/// StartupTasks Progress Changed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StartupTasks_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Stub
}
/// <summary>
/// StartupTasks RunWorker Completed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StartupTasks_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Print to screen
Log.Information("Ready");
}
#endregion
#region GUI Methods
/// <summary>
/// Sets the application title.
/// </summary>
/// <param name="strTitle"></param>
private void UpdateTitle(string strTitle = "")
{
if (this.InvokeRequired && !this.IsDisposed)
{
Invoke(new MethodInvoker(delegate ()
{
// Update the application title.
this.Text = f2f2f.AppName + " v" + f2f2f.AppVersion + strTitle;
}));
}
else if (!this.IsDisposed)
{
// Update the application title.
this.Text = f2f2f.AppName + " v" + f2f2f.AppVersion + strTitle;
}
}
/// <summary>
/// Updates the status message label.
/// </summary>
/// <param name="strMsg"></param>
private void UpdateStatusMessageLabel(string strMsg)
{
if (this.InvokeRequired && !this.IsDisposed)
{
Invoke(new MethodInvoker(delegate ()
{
// Update the progress status message label.
this.tsslStatus.Text = strMsg;
}));
}
else if (!this.IsDisposed)
{
// Update the progress status message label.
this.tsslStatus.Text = strMsg;
}
}
private delegate void DisableAllButtonsDelegate();
/// <summary>
/// Disables all the buttons and textboxes and checkboxes.
/// </summary>
private void DisableAllButtons()
{
// Disable the toolstrip buttons.
tsbFiles2Folders.Enabled = false;
tsbFolders2Files.Enabled = false;
// Disable the menustrip buttons.
tsmiFiles2Folders.Enabled = false;
tsmiFolders2Files.Enabled = false;
// Disable the textboxes.
txtDirectoryPath.Enabled = false;
// Disable the checkboxes.
chkDeleteEmptyFolders.Enabled = false;
}
private delegate void EnableAllButtonsDelegate();
/// <summary>
/// Enables all the buttons and textboxes and checkboxes.
/// </summary>
private void EnableAllButtons()
{
// Enable the toolstrip buttons.
tsbFiles2Folders.Enabled = true;
tsbFolders2Files.Enabled = true;
// Disable the menustrip buttons.
tsmiFiles2Folders.Enabled = true;
tsmiFolders2Files.Enabled = true;
// Enable the textboxes.
txtDirectoryPath.Enabled = true;
// Enable the checkboxes.
chkDeleteEmptyFolders.Enabled = true;
}
#endregion
#region GUI Events
/// <summary>
/// Builds files to folders.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Files2Folders_Click(object sender, EventArgs e)
{
// Select the Log tab.
if (tcMain.TabPages.Contains(tabLog)) { tcMain.SelectTab(tabLog); }
// Disable all buttons.
DisableAllButtons();
// Enable the Cancel Button.
tsbCancel.Enabled = true;
// Update the status message label.
UpdateStatusMessageLabel("Building Files 2 Folders ...");
// Build Files 2 Folders.
bgwFiles2Folders.RunWorkerAsync();
}
/// <summary>
/// Builds folders to files.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Folders2Files_Click(object sender, EventArgs e)
{
// Select the Log tab.
if (tcMain.TabPages.Contains(tabLog)) { tcMain.SelectTab(tabLog); }
// Disable all buttons.
DisableAllButtons();
// Enable the Cancel Button.
tsbCancel.Enabled = true;
// Update the status message label.
UpdateStatusMessageLabel("Building Folders 2 Files ...");
// Build Folders 2 Files.
bgwFolders2Files.RunWorkerAsync();
}
/// <summary>
/// Updates the directory path.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DirectoryPath_Click(object sender, EventArgs e)
{
// Disable all buttons.
DisableAllButtons();
if (txtDirectoryPath.Text == "") { txtDirectoryPath.Text = "."; }
// Create and initialize a FolderBrowserDialog for the directory path.
FolderBrowserDialog fbdSelectDir = new FolderBrowserDialog
{
ShowNewFolderButton = true,
Description = "Please enter a directory path: ",
SelectedPath = Path.GetFullPath(Path.Combine(txtDirectoryPath.Text))
};
// Determine if the user selected OK from the FolderBrowserDialog.
if (fbdSelectDir.ShowDialog() == DialogResult.OK)
{
// Set both variables for compatibility for Windows .NET and Mono.
this.f2f2f.DirectoryPath = fbdSelectDir.SelectedPath;
txtDirectoryPath.Text = fbdSelectDir.SelectedPath;
}
// Enable all buttons.
EnableAllButtons();
}
/// <summary>
/// Loads an options file.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LoadOptions_Click(object sender, EventArgs e)
{
// Disable all buttons.
DisableAllButtons();
// Create and initialize an OpenFileDialog for the options file.
OpenFileDialog ofdOptions = new OpenFileDialog
{
DefaultExt = "*.xml",
Filter = "XML Files|*.xml",
Title = "Please enter a path to the options file: ",
InitialDirectory = Path.Combine(Application.StartupPath, "Options")
};
// Determine if the user selected a file name from the OpenFileDialog.
if (ofdOptions.ShowDialog() == DialogResult.OK && ofdOptions.FileName.Length > 0)
{
// Set the options file path.
f2f2f.PathOptionsFile = ofdOptions.FileName;
// Select the Log tab.
if (tcMain.TabPages.Contains(tabLog)) { tcMain.SelectTab(tabLog); }
// Load the options.
f2f2f.LoadOptionsFromFile();
// Print to screen
Log.Information("Ready");
}
// Dispose of the OpenFileDialog.
ofdOptions.Dispose();
// Enable all buttons.
EnableAllButtons();
}
/// <summary>
/// Saves an options file.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveOptions_Click(object sender, EventArgs e)
{
// Disable all buttons.
DisableAllButtons();
// Create and initialize a SaveFileDialog for the options file.
SaveFileDialog sfdOptions = new SaveFileDialog
{
DefaultExt = "*.xml",
Filter = "XML Files|*.xml",
FileName = "Files2Folders2Files-Options.xml",
Title = "Please enter a path to the options file: ",
InitialDirectory = Path.Combine(Application.StartupPath, "Options")
};
// Determine if the user selected a file name from the SaveFileDialog.
if (sfdOptions.ShowDialog() == DialogResult.OK && sfdOptions.FileName.Length > 0)
{
// Set the options file path.
f2f2f.PathOptionsFile = sfdOptions.FileName;
// Select the Log tab.
if (tcMain.TabPages.Contains(tabLog)) { tcMain.SelectTab(tabLog); }
// Save the options.
f2f2f.SaveOptionsToFile();
// Print to screen
Log.Information("Ready");
}
// Dispose of the SaveFileDialog.
sfdOptions.Dispose();
// Enable all buttons.
EnableAllButtons();
}
/// <summary>
/// Saves the log to a text file.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveLog_Click(object sender, EventArgs e)
{
// Disable all buttons.
DisableAllButtons();
// Create and initialize a SaveFileDialog for the log file.
SaveFileDialog sfdLog = new SaveFileDialog
{
DefaultExt = "*.txt",
Filter = "TXT Files|*.txt",
FileName = "Files2Folders2Files-Log-" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".txt",
Title = "Please enter a path to the log file: ",
InitialDirectory = Path.Combine(Application.StartupPath, "Logs")
};
// Determine if the user selected a log filename.
if (sfdLog.ShowDialog() == DialogResult.OK && sfdLog.FileName.Length > 0)
{
// Set the log file path.
f2f2f.PathLogFile = sfdLog.FileName;
// Select the Log tab.
if (tcMain.TabPages.Contains(tabLog)) { tcMain.SelectTab(tabLog); }
// Save the log.
SaveLogToFile(f2f2f.PathLogFile);
// Print to screen
Log.Information("Ready");
}
// Dispose of the SaveFileDialog.
sfdLog.Dispose();
// Enable all buttons.
EnableAllButtons();
}
/// <summary>
/// Toggles the visibility of the log.
/// </summary>
private void ViewLog_Click(object sender, EventArgs e)
{
if (tsmiLog.Checked)
{
tsmiLog.Checked = false;
tsmiLog.CheckState = CheckState.Unchecked;
tcMain.TabPages.Remove(tabLog);
}
else
{
tsmiLog.Checked = true;
tsmiLog.CheckState = CheckState.Checked;
tcMain.TabPages.Add(tabLog);
tcMain.SelectTab(tabLog);
}
}
/// <summary>
/// Toggles the visibility of the options.
/// </summary>
private void ViewOptions_Click(object sender, EventArgs e)
{
if (tsmiOptions.Checked)
{
tsmiOptions.Checked = false;
tsmiOptions.CheckState = CheckState.Unchecked;
tcMain.TabPages.Remove(tabOptions);
}
else
{
tsmiOptions.Checked = true;
tsmiOptions.CheckState = CheckState.Checked;
tcMain.TabPages.Add(tabOptions);
tcMain.SelectTab(tabOptions);
}
}
/// <summary>
/// Toggles the visibility of the help.
/// </summary>
private void ViewHelp_Click(object sender, EventArgs e)
{
if (tsmiHelp.Checked)
{
tsmiHelp.Checked = false;
tsmiHelp.CheckState = CheckState.Unchecked;
tcMain.TabPages.Remove(tabHelp);
}
else
{
tsmiHelp.Checked = true;
tsmiHelp.CheckState = CheckState.Checked;
tcMain.TabPages.Add(tabHelp);
tcMain.SelectTab(tabHelp);
}
}
/// <summary>
/// Toggles the visibility of the license.
/// </summary>
private void ViewLicense_Click(object sender, EventArgs e)
{
if (tsmiLicense.Checked)
{
tsmiLicense.Checked = false;
tsmiLicense.CheckState = CheckState.Unchecked;
tcMain.TabPages.Remove(tabLicense);
}
else
{
tsmiLicense.Checked = true;
tsmiLicense.CheckState = CheckState.Checked;
tcMain.TabPages.Add(tabLicense);
tcMain.SelectTab(tabLicense);
}
}
/// <summary>
/// Toggles the visibility of the registration.
/// </summary>
private void ViewRegistration_Click(object sender, EventArgs e)
{
if (tsmiRegistration.Checked)
{
tsmiRegistration.Checked = false;
tsmiRegistration.CheckState = CheckState.Unchecked;
tcMain.TabPages.Remove(tabRegistration);
}
else
{
tsmiRegistration.Checked = true;
tsmiRegistration.CheckState = CheckState.Checked;
tcMain.TabPages.Add(tabRegistration);
tcMain.SelectTab(tabRegistration);
}
}
/// <summary>
/// Toggles the visibility of the Donations.
/// </summary>
private void ViewDonations_Click(object sender, EventArgs e)
{
if (tsmiDonations.Checked)
{
tsmiDonations.Checked = false;
tsmiDonations.CheckState = CheckState.Unchecked;
tcMain.TabPages.Remove(tabDonations);
}
else
{
tsmiDonations.Checked = true;
tsmiDonations.CheckState = CheckState.Checked;
tcMain.TabPages.Add(tabDonations);
tcMain.SelectTab(tabDonations);
}
}
/// <summary>
/// Toggles the visibility of the toolbar.
/// </summary>
private void ViewToolbar_Click(object sender, EventArgs e)
{
if (tsMain.Visible)
{
tsMain.Visible = false;
tsmiToolbar.Checked = false;
tsmiToolbar.CheckState = CheckState.Unchecked;
}
else
{
tsMain.Visible = true;
tsmiToolbar.Checked = true;
tsmiToolbar.CheckState = CheckState.Checked;
}
}
/// <summary>
/// Cancels the build.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Cancel_Click(object sender, EventArgs e)
{
if (bgwFiles2Folders.IsBusy == true || bgwFolders2Files.IsBusy == true)
{
// Print to screen
Log.Information("Info: Cancellation pending after current operation ...");
// Disable the cancel button.
tsbCancel.Enabled = false;
// Cancel the asynchronous operation.
if (bgwFiles2Folders.IsBusy == true) { bgwFiles2Folders.CancelAsync(); }
if (bgwFolders2Files.IsBusy == true) { bgwFolders2Files.CancelAsync(); }
// Update the status message label.
UpdateStatusMessageLabel("Cancellation Pending ...");
}
}
/// <summary>
/// Exits the WinForms app.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
/// <summary>
/// After the form is shown, run the startup tasks.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form_Shown(object sender, EventArgs e)
{
// Perform the application startup tasks.
bgwStartupTasks.RunWorkerAsync();
}
/// <summary>
/// Checks things to make sure it is safe, before closing the form.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Files2Folders2Files_FormClosing(object sender, FormClosingEventArgs e)
{
if (bgwFiles2Folders.IsBusy == true || bgwFolders2Files.IsBusy == true)
{
if (MessageBox.Show("The builder is currently running. Exiting now may cause corrupt or incomplete files! Are you sure you want to exit now?", "Confirm Exit", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
{
e.Cancel = true;
}
}
}
#endregion
#region Builders
/// <summary>
/// Moves all pf the files from a single directory into folders of matching names.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Files2Folders_DoWork(object sender, DoWorkEventArgs e)
{
// Run Files2Folders builder.
f2f2f.BuildFiles2Folders(sender, e);
}
/// <summary>
/// Changes the progress of the Files 2 Folders background worker.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Files2Folders_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Update the overall progress bar.
tspbOverallProgress.Value = e.ProgressPercentage;
}
/// <summary>
/// Completes the Files 2 Folders background worker.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Files2Folders_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
// Print to screen
Log.Information("Info: Files 2 Folders cancelled");
}
else if (e.Error != null)
{
// Print to screen
Log.Information("Error: Files 2 Folders failed");
Log.Information("Error: " + e.Error.Message);
}
else
{
//
}
// Reset the overall progress bar.
tspbOverallProgress.Value = 0;
// Disable the cancel button.
tsbCancel.Enabled = false;
// Print to screen
Log.Information("Info: Ready");
// Update the status message label.
UpdateStatusMessageLabel("Ready");
// Enable all buttons.
Invoke(new EnableAllButtonsDelegate(EnableAllButtons));
}
/// <summary>
/// Moves all of the files from all of the folders into a single directory.
/// Optionally deletes all of the empty folders.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Folders2Files_DoWork(object sender, DoWorkEventArgs e)
{
// Run Files2Folders builder.
f2f2f.BuildFolders2Files(sender, e);
}
/// <summary>
/// Changes the progress of the Folders 2 Files background worker.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Folders2Files_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Update the overall progress bar.
tspbOverallProgress.Value = e.ProgressPercentage;
}
/// <summary>
/// Completes the Folders 2 Files background worker.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Folders2Files_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
// Print to screen
Log.Information("Info: Folders 2 Files cancelled");
}
else if (e.Error != null)
{
// Print to screen
Log.Information("Error: Folders 2 Files failed");
Log.Information("Error: " + e.Error.Message);
}
else
{
//
}
// Reset the overall progress bar.
tspbOverallProgress.Value = 0;
// Disable the cancel button.
tsbCancel.Enabled = false;
// Update the status message label.
UpdateStatusMessageLabel("Ready");
// Print to screen
Log.Information("Info: Ready");
// Enable all buttons.
Invoke(new EnableAllButtonsDelegate(EnableAllButtons));
}
#endregion
}
}