From 3214c186e8cb7c60ffb4470d01fedc08477a2c0d Mon Sep 17 00:00:00 2001 From: Daniel Brunner <0xFEEDC0DE64@gmail.com> Date: Sun, 9 Jul 2017 16:57:27 +0200 Subject: [PATCH] Implemented progress dialog while indexing music --- MusicOrganizer/IndexDialog.Designer.cs | 112 ++++++++++++++++ MusicOrganizer/IndexDialog.cs | 170 +++++++++++++++++++++++++ MusicOrganizer/IndexDialog.resx | 123 ++++++++++++++++++ MusicOrganizer/Item.cs | 13 ++ MusicOrganizer/MainForm.cs | 94 +------------- MusicOrganizer/MusicOrganizer.csproj | 15 ++- 6 files changed, 439 insertions(+), 88 deletions(-) create mode 100644 MusicOrganizer/IndexDialog.Designer.cs create mode 100644 MusicOrganizer/IndexDialog.cs create mode 100644 MusicOrganizer/IndexDialog.resx create mode 100644 MusicOrganizer/Item.cs diff --git a/MusicOrganizer/IndexDialog.Designer.cs b/MusicOrganizer/IndexDialog.Designer.cs new file mode 100644 index 0000000..30c2d91 --- /dev/null +++ b/MusicOrganizer/IndexDialog.Designer.cs @@ -0,0 +1,112 @@ +namespace MusicOrganizer +{ + partial class IndexDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.statusLabel = new System.Windows.Forms.Label(); + this.progressBar = new System.Windows.Forms.ProgressBar(); + this.continueButton = new System.Windows.Forms.Button(); + this.cancelButton = new System.Windows.Forms.Button(); + this.backgroundWorker = new System.ComponentModel.BackgroundWorker(); + this.SuspendLayout(); + // + // statusLabel + // + this.statusLabel.AutoSize = true; + this.statusLabel.Location = new System.Drawing.Point(13, 13); + this.statusLabel.Name = "statusLabel"; + this.statusLabel.Size = new System.Drawing.Size(92, 20); + this.statusLabel.TabIndex = 0; + this.statusLabel.Text = "statusLabel"; + // + // progressBar + // + this.progressBar.Location = new System.Drawing.Point(17, 36); + this.progressBar.Name = "progressBar"; + this.progressBar.Size = new System.Drawing.Size(568, 35); + this.progressBar.TabIndex = 1; + // + // continueButton + // + this.continueButton.Enabled = false; + this.continueButton.Location = new System.Drawing.Point(469, 77); + this.continueButton.Name = "continueButton"; + this.continueButton.Size = new System.Drawing.Size(116, 41); + this.continueButton.TabIndex = 3; + this.continueButton.Text = "Continue"; + this.continueButton.UseVisualStyleBackColor = true; + this.continueButton.Click += new System.EventHandler(this.continueButton_Click); + // + // cancelButton + // + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(347, 77); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(116, 41); + this.cancelButton.TabIndex = 4; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); + // + // backgroundWorker + // + this.backgroundWorker.WorkerReportsProgress = true; + this.backgroundWorker.WorkerSupportsCancellation = true; + this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_DoWork); + this.backgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker_ProgressChanged); + this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_RunWorkerCompleted); + // + // IndexDialog + // + this.AcceptButton = this.continueButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(597, 130); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.continueButton); + this.Controls.Add(this.progressBar); + this.Controls.Add(this.statusLabel); + this.Name = "IndexDialog"; + this.Text = "IndexDialog"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.IndexDialog_FormClosing); + this.Load += new System.EventHandler(this.IndexDialog_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label statusLabel; + private System.Windows.Forms.ProgressBar progressBar; + private System.Windows.Forms.Button continueButton; + private System.Windows.Forms.Button cancelButton; + private System.ComponentModel.BackgroundWorker backgroundWorker; + } +} \ No newline at end of file diff --git a/MusicOrganizer/IndexDialog.cs b/MusicOrganizer/IndexDialog.cs new file mode 100644 index 0000000..edc9516 --- /dev/null +++ b/MusicOrganizer/IndexDialog.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Threading; +using System.Windows.Forms; + +namespace MusicOrganizer +{ + internal partial class IndexDialog : Form + { + private string musicFolder; + private List items; + private string[] paths; + + public List Items { get { return items; } } + + public IndexDialog() + { + InitializeComponent(); + } + + public DialogResult Execute() + { + using (var dialog = new FolderBrowserDialog()) + { + var result = dialog.ShowDialog(); + + if (result != DialogResult.OK) + return DialogResult.Cancel; + + if (string.IsNullOrWhiteSpace(dialog.SelectedPath)) + return DialogResult.Cancel; + + musicFolder = dialog.SelectedPath; + } + + if (!musicFolder.EndsWith("\\") && !musicFolder.EndsWith("/")) + musicFolder += Path.DirectorySeparatorChar; + + again0: + try + { + paths = Directory.GetFileSystemEntries(musicFolder, "*.mp3", SearchOption.AllDirectories); + } + catch (Exception ex) + { + var result = MessageBox.Show(string.Format("Error occured when collecting files\n\n{0}", ex.Message), "Error occured", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); + + switch (result) + { + case DialogResult.Retry: goto again0; + case DialogResult.Cancel: return DialogResult.Cancel; + default: throw new Exception("Unknown option clicked."); + } + } + + return ShowDialog(); + } + + private void IndexDialog_Load(object sender, EventArgs e) + { + backgroundWorker.RunWorkerAsync(); + } + + private void IndexDialog_FormClosing(object sender, FormClosingEventArgs e) + { + if (backgroundWorker.IsBusy) + { + e.Cancel = true; + if (!backgroundWorker.CancellationPending) + backgroundWorker.CancelAsync(); + } + } + + private void continueButton_Click(object sender, EventArgs e) + { + if (!backgroundWorker.IsBusy) + { + DialogResult = DialogResult.OK; + Close(); + } + } + + private void cancelButton_Click(object sender, EventArgs e) + { + if (backgroundWorker.IsBusy) + { + if(!backgroundWorker.CancellationPending) + backgroundWorker.CancelAsync(); + cancelButton.Enabled = false; + } + else + { + DialogResult = DialogResult.Cancel; + Close(); + } + } + + private void backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) + { + var worker = sender as BackgroundWorker; + + items = new List(); + + for (int i = 0; i < paths.Length; i++) + { + var path = paths[i]; + var statusStr = Path.GetFileName(path) + ": "; + + if(worker.CancellationPending) + { + worker.ReportProgress(i * 100 / paths.Length, statusStr + "Cancelled!"); + e.Cancel = true; + return; + } + + TagLib.File file; + + try + { + file = TagLib.File.Create(path); + } + catch (Exception ex) + { + worker.ReportProgress(i * 100 / paths.Length, statusStr + "Exception!\r\n" + ex.Message); + Thread.Sleep(5000); + continue; + } + + string relativePath; + if (path.StartsWith(musicFolder)) + relativePath = path.Remove(0, musicFolder.Length); + else + relativePath = path; + + items.Add(new Item + { + filename = path, + relativeFilename = relativePath, + artist = file.Tag.FirstPerformer, + title = file.Tag.Title, + bpm = string.Format("{0}BPM", file.Tag.BeatsPerMinute) + }); + + worker.ReportProgress((i + 1) * 100 / paths.Length, statusStr + "Ok!"); + } + } + + private void backgroundWorker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) + { + progressBar.Value = e.ProgressPercentage; + statusLabel.Text = e.UserState as string; + } + + private void backgroundWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) + { + if(e.Cancelled) + { + DialogResult = DialogResult.Cancel; + Close(); + } + else + { + cancelButton.Enabled = false; + continueButton.Enabled = true; + } + } + } +} diff --git a/MusicOrganizer/IndexDialog.resx b/MusicOrganizer/IndexDialog.resx new file mode 100644 index 0000000..975fd0d --- /dev/null +++ b/MusicOrganizer/IndexDialog.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/MusicOrganizer/Item.cs b/MusicOrganizer/Item.cs new file mode 100644 index 0000000..782045f --- /dev/null +++ b/MusicOrganizer/Item.cs @@ -0,0 +1,13 @@ +using System; + +namespace MusicOrganizer +{ + internal struct Item + { + public string filename; + public string relativeFilename; + public string artist; + public string title; + public string bpm; + } +} diff --git a/MusicOrganizer/MainForm.cs b/MusicOrganizer/MainForm.cs index 51ddc21..94b6be1 100644 --- a/MusicOrganizer/MainForm.cs +++ b/MusicOrganizer/MainForm.cs @@ -7,15 +7,6 @@ namespace MusicOrganizer { public partial class MainForm : Form { - struct Item - { - public string filename; - public string relativeFilename; - public string artist; - public string title; - public string bpm; - } - private List items; public MainForm() @@ -28,88 +19,17 @@ namespace MusicOrganizer private void button1_Click(object sender, EventArgs e) { - string musicFolder; - - using (var dialog = new FolderBrowserDialog()) + using (var dialog = new IndexDialog()) { - var result = dialog.ShowDialog(); - - if (result != DialogResult.OK) - return; - - if (string.IsNullOrWhiteSpace(dialog.SelectedPath)) - return; - - musicFolder = dialog.SelectedPath; - } - - if (!musicFolder.EndsWith("\\") && !musicFolder.EndsWith("/")) - musicFolder += Path.DirectorySeparatorChar; - - string[] paths; - - again1: - try - { - paths = Directory.GetFileSystemEntries(musicFolder, "*.mp3", SearchOption.AllDirectories); - } - catch(Exception ex) - { - var result = MessageBox.Show(string.Format("Error occured when collecting files\n\n{0}", ex.Message), "Error occured", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); - - switch(result) + if(dialog.Execute() == DialogResult.OK) { - case DialogResult.Retry: goto again1; - case DialogResult.Cancel: return; - default: throw new Exception("Unknown option clicked."); + items = dialog.Items; + objectListView1.SetObjects(items); + objectListView1.AutoResizeColumns(); + + button2.Enabled = items.Count > 0; } } - - var newItems = new List(); - - foreach (var path in paths) - { - TagLib.File file; - - again2: - try - { - file = TagLib.File.Create(path); - } - catch(Exception ex) - { - var result = MessageBox.Show(string.Format("Error occured when processing file\n\n{0}\n\n{1}", path, ex.Message), "Error occured", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error); - - switch(result) - { - case DialogResult.Abort: return; - case DialogResult.Retry: goto again2; - case DialogResult.Ignore: continue; - default: throw new Exception("Unknown option clicked."); - } - } - - string relativePath; - if (path.StartsWith(musicFolder)) - relativePath = path.Remove(0, musicFolder.Length); - else - relativePath = path; - - newItems.Add(new Item - { - filename = path, - relativeFilename = relativePath, - artist = file.Tag.FirstPerformer, - title = file.Tag.Title, - bpm = string.Format("{0}BPM", file.Tag.BeatsPerMinute) - }); - } - - items = newItems; - objectListView1.SetObjects(items); - objectListView1.AutoResizeColumns(); - - button2.Enabled = items.Count > 0; } private void button2_Click(object sender, EventArgs e) diff --git a/MusicOrganizer/MusicOrganizer.csproj b/MusicOrganizer/MusicOrganizer.csproj index 2da38df..14be6bb 100644 --- a/MusicOrganizer/MusicOrganizer.csproj +++ b/MusicOrganizer/MusicOrganizer.csproj @@ -5,7 +5,7 @@ Debug AnyCPU {FCCFFEFE-15D8-47CF-8345-1B901C7B105A} - Exe + WinExe MusicOrganizer MusicOrganizer v4.6.1 @@ -31,6 +31,9 @@ prompt 4 + + MusicOrganizer.Program + ..\packages\taglib.2.1.0.0\lib\policy.2.0.taglib-sharp.dll @@ -50,6 +53,13 @@ + + Form + + + IndexDialog.cs + + Form @@ -78,6 +88,9 @@ + + IndexDialog.cs + MainForm.cs