You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
12 KiB
341 lines
12 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using System.IO;
|
|
|
|
namespace photo_sorter
|
|
{
|
|
/*public static class Extensions
|
|
{
|
|
public static T[] RemoveAt<T>(this T[] source, int index)
|
|
{
|
|
var work = new List<T>(source);
|
|
work.RemoveAt(index);
|
|
return work.ToArray();
|
|
}
|
|
}*/
|
|
|
|
public partial class form_main : Form
|
|
{
|
|
public form_main()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
static class global
|
|
{
|
|
public static string dest = "";
|
|
public static string src;
|
|
public static string[] filenames;
|
|
public static int filecount;
|
|
public static int position = 0;
|
|
}
|
|
|
|
public void status_msg(string msg, int lvl = 1)
|
|
{
|
|
string mtype = "UNDEFINED";
|
|
switch (lvl)
|
|
{
|
|
case 1:
|
|
mtype = "INFO";
|
|
//stat_last_action.ForeColor = new System.Drawing.Color();
|
|
stat_last_action.ForeColor = Color.Black;
|
|
break;
|
|
case 2:
|
|
mtype = "WARN";
|
|
stat_last_action.ForeColor = Color.Olive;
|
|
break;
|
|
case 3:
|
|
mtype = "ERROR";
|
|
System.Media.SystemSounds.Asterisk.Play();
|
|
stat_last_action.ForeColor = Color.Red;
|
|
break;
|
|
case 4:
|
|
mtype = "CRITICAL";
|
|
System.Media.SystemSounds.Exclamation.Play();
|
|
stat_last_action.ForeColor = Color.Red;
|
|
break;
|
|
}
|
|
stat_last_action.Text = mtype + ": " + msg;
|
|
}
|
|
|
|
private void update_counter()
|
|
{
|
|
lbl_counter.Text = (global.position + 1).ToString() + " of " + global.filecount.ToString();
|
|
}
|
|
|
|
private void reload_source()
|
|
{
|
|
global.filenames = populate_file_names();
|
|
global.filecount = global.filenames.Length;
|
|
global.position = 0;
|
|
status_msg("Source directory updated, found " + global.filecount.ToString() + " images");
|
|
if (global.filecount > 0)
|
|
{
|
|
gbox_preview.Enabled = true;
|
|
lbl_counter.Text = (global.position + 1).ToString() + " of " + global.filecount.ToString();
|
|
update_image();
|
|
}
|
|
else
|
|
{
|
|
gbox_preview.Enabled = false;
|
|
status_msg("Source directory updated, but no images found!",3);
|
|
}
|
|
}
|
|
|
|
private void select_source_dir()
|
|
{
|
|
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
|
|
{
|
|
global.src = folderBrowserDialog1.SelectedPath;
|
|
tbox_source_dir.Text = global.src;
|
|
btn_reload_src.Enabled = true;
|
|
reload_source();
|
|
}
|
|
}
|
|
|
|
private void select_dest_dir()
|
|
{
|
|
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
|
|
{
|
|
global.dest = folderBrowserDialog1.SelectedPath;
|
|
tbox_dest_dir.Text = global.dest;
|
|
status_msg("Destination directory updated");
|
|
}
|
|
}
|
|
|
|
private void update_image()
|
|
{
|
|
string fname;
|
|
if (global.filecount == 0)
|
|
{
|
|
fname = "EMPTY - Select new source";
|
|
img_preview.Visible = false;
|
|
gbox_preview.Enabled = false;
|
|
}
|
|
else
|
|
{
|
|
fname = global.filenames[global.position];
|
|
Image img;
|
|
using (var bmp = new Bitmap(fname))
|
|
{
|
|
img = new Bitmap(bmp);
|
|
}
|
|
img_preview.Image = img;
|
|
img_preview.Visible = true;
|
|
GC.Collect();
|
|
GC.WaitForPendingFinalizers();
|
|
}
|
|
lbl_current_fname.Text = Path.GetFileName(fname);
|
|
update_counter();
|
|
}
|
|
|
|
public string[] populate_file_names()
|
|
{
|
|
string[] files = Directory.GetFiles(global.src, "*.jpg");
|
|
return files;
|
|
}
|
|
|
|
public void remove_index(int index)
|
|
{
|
|
for (int i = index; i < global.filenames.Length - 1; i++)
|
|
{
|
|
global.filenames[i] = global.filenames[i + 1];
|
|
}
|
|
Array.Resize(ref global.filenames, global.filenames.Length - 1);
|
|
global.filecount--;
|
|
if (global.position > global.filecount - 1)
|
|
{
|
|
global.position = global.filecount - 1;
|
|
}
|
|
}
|
|
|
|
//
|
|
// UI Interactions
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
private void btn_open_dir_Click(object sender, EventArgs e)
|
|
{
|
|
select_dest_dir();
|
|
}
|
|
|
|
private void openDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
select_source_dir();
|
|
}
|
|
|
|
private void selectDestinationDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
select_dest_dir();
|
|
}
|
|
|
|
private void quitApplicationToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (MessageBox.Show("Are you sure you want to quit the Photo Sorter application?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
|
{
|
|
this.Close();
|
|
}
|
|
}
|
|
|
|
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
MessageBox.Show("This application is Copyright Skyfall Tech, 2022.\n\nPlease visit https://www.skyfall.tech/ for more information.");
|
|
}
|
|
|
|
private void btn_open_src_dir_Click(object sender, EventArgs e)
|
|
{
|
|
select_source_dir();
|
|
}
|
|
|
|
private void btn_prev_Click(object sender, EventArgs e)
|
|
{
|
|
if (global.position > 0)
|
|
{
|
|
global.position -= 1;
|
|
}
|
|
else
|
|
{
|
|
global.position = global.filecount - 1;
|
|
}
|
|
update_image();
|
|
}
|
|
|
|
private void btn_next_Click(object sender, EventArgs e)
|
|
{
|
|
if (global.position < global.filecount - 1)
|
|
{
|
|
global.position += 1;
|
|
}
|
|
else
|
|
{
|
|
global.position = 0;
|
|
}
|
|
update_image();
|
|
}
|
|
|
|
private void btn_sort_Click(object sender, EventArgs e)
|
|
{
|
|
string prim_dir = global.dest + '\\' + tbox_sort_primary.Text;
|
|
string sec_dir = prim_dir + '\\' + tbox_sort_secondary.Text;
|
|
string dpath;
|
|
|
|
if (global.dest == "")
|
|
{
|
|
status_msg("Destination directory must be set first!", 3);
|
|
//System.Media.SystemSounds.Exclamation.Play();
|
|
//MessageBox.Show("Destination directory must be set\nbefore images can be sorted!", "Error: Primary Sort", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
return;
|
|
}
|
|
|
|
if (tbox_sort_primary.Text == "")
|
|
{
|
|
status_msg("Primary sort field required to sort!",3);
|
|
//System.Media.SystemSounds.Exclamation.Play();
|
|
//MessageBox.Show("Primary sort directory name is required!", "Error: Primary Sort", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
return;
|
|
}
|
|
if (tbox_sort_secondary.Text == "")
|
|
{
|
|
dpath = prim_dir;
|
|
}
|
|
else
|
|
{
|
|
dpath = sec_dir;
|
|
if (!Directory.Exists(sec_dir))
|
|
{
|
|
Directory.CreateDirectory(sec_dir);
|
|
status_msg("Created directory '" + sec_dir + "'", 2);
|
|
}
|
|
}
|
|
if (!Directory.Exists(prim_dir))
|
|
{
|
|
Directory.CreateDirectory(prim_dir);
|
|
status_msg("Created directory '" + prim_dir + "'", 2);
|
|
}
|
|
string src_fname = global.filenames[global.position];
|
|
string dst_fname = dpath + "\\" + Path.GetFileName(global.filenames[global.position]);
|
|
if (rad_sort_move.Checked)
|
|
{
|
|
try
|
|
{
|
|
if (File.Exists(@dst_fname))
|
|
{
|
|
if (MessageBox.Show("This file already exists in the destination directory. Would you like to overwrite it?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
|
{
|
|
File.Delete(dst_fname);
|
|
status_msg("Deleted " + dst_fname, 2);
|
|
}
|
|
else
|
|
{
|
|
status_msg("Move aborted for " + src_fname, 2);
|
|
}
|
|
}
|
|
File.Move(@src_fname, @dst_fname);
|
|
//status_msg("Moved " + lbl_current_fname.Text + " to " + dpath);
|
|
status_msg("Moved " + global.filenames[global.position] + " to " + dpath);
|
|
remove_index(global.position);
|
|
update_image();
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
status_msg("Unable to move " + global.filenames[global.position] + " to " + dpath + "!", 4);
|
|
MessageBox.Show(ex.ToString(), "Critical: IO Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
if (File.Exists(@dst_fname))
|
|
{
|
|
if (MessageBox.Show("This file already exists in the destination directory. Would you like to overwrite it?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
|
{
|
|
File.Delete(dst_fname);
|
|
status_msg("Deleted " + dst_fname, 2);
|
|
}
|
|
else
|
|
{
|
|
status_msg("Copy aborted for " + src_fname, 2);
|
|
return;
|
|
}
|
|
}
|
|
File.Copy(@src_fname, @dst_fname);
|
|
//status_msg("Copied " + lbl_current_fname.Text + " to " + dpath);
|
|
status_msg("Copied " + global.filenames[global.position] + " to " + dpath);
|
|
remove_index(global.position);
|
|
update_image();
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
status_msg("Unable to copy " + global.filenames[global.position] + " to " + dpath + "!", 4);
|
|
MessageBox.Show(ex.ToString(), "Critical: IO Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void btn_reload_src_Click(object sender, EventArgs e)
|
|
{
|
|
reload_source();
|
|
}
|
|
|
|
|
|
/*private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
|
|
{
|
|
if (MessageBox.Show("Are you sure you want to quit the Photo Sorter application?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
|
{
|
|
this.Close();
|
|
}
|
|
else
|
|
{
|
|
e.Cancel = true;
|
|
}
|
|
}*/
|
|
}
|
|
}
|